34124c2d6fb6f066049148e863d2dbc9344617be
[metze/wireshark/wip.git] / epan / dissectors / packet-ansi_a.c
1 /* packet-ansi_a.c
2  * Routines for ANSI A Interface (IS-634/IOS) dissection
3  *
4  * Copyright 2003, Michael Lum <mlum [AT] telostech.com>
5  * In association with Telos Technology Inc.
6  * Copyright 2008, Michael Lum <michael.lum [AT] utstar.com>
7  * In association with UTStarcom Inc.
8  * Copyright 2008, Michael Lum <michael.lum [AT] starsolutions.com>
9  * In association with Star Solutions
10  *
11  * Title                3GPP2                   Other
12  *
13  *   Inter-operability Specification (IOS) for CDMA
14  *   2000 Access Network Interfaces
15  *                      3GPP2 A.S0001-1         TIA/EIA-2001
16  *
17  * $Id$
18  *
19  * Wireshark - Network traffic analyzer
20  * By Gerald Combs <gerald@wireshark.org>
21  * Copyright 1998 Gerald Combs
22  *
23  * This program is free software; you can redistribute it and/or
24  * modify it under the terms of the GNU General Public License
25  * as published by the Free Software Foundation; either version 2
26  * of the License, or (at your option) any later version.
27  *
28  * This program is distributed in the hope that it will be useful,
29  * but WITHOUT ANY WARRANTY; without even the implied warranty of
30  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
31  * GNU General Public License for more details.
32  *
33  * You should have received a copy of the GNU General Public License
34  * along with this program; if not, write to the Free Software
35  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
36  */
37
38 #ifdef HAVE_CONFIG_H
39 # include "config.h"
40 #endif
41
42 #include <string.h>
43
44 #include <epan/packet.h>
45 #include <epan/prefs.h>
46 #include <epan/tap.h>
47 #include <epan/strutil.h>
48 #include <epan/emem.h>
49 #include <epan/expert.h>
50
51 #include "packet-rtp.h"
52 #include "packet-bssap.h"
53 #include "packet-ansi_a.h"
54
55 /*
56  * IOS 4, probably most common
57  */
58 static gint global_a_variant = A_VARIANT_IOS401;
59
60
61 /* PROTOTYPES/FORWARDS */
62
63 void proto_reg_handoff_ansi_a(void);
64
65 static const gchar *
66 my_match_strval_idx(guint32 val, const ext_value_string_t *vs, gint *idx, gint *dec_idx)
67 {
68     gint i = 0;
69
70     while (vs[i].strptr)
71     {
72         if (vs[i].value == val)
73         {
74             *idx = i;
75             *dec_idx = vs[i].dec_index;
76             return(vs[i].strptr);
77         }
78
79         i++;
80     }
81
82     *idx = -1;
83     *dec_idx = -1;
84     return(NULL);
85 }
86
87 const ext_value_string_t ansi_a_ios401_bsmap_strings[] =
88 {
89     { 0x69,     "Additional Service Notification",      0 },
90     { 0x65,     "ADDS Page",    1 },
91     { 0x66,     "ADDS Page Ack",        2 },
92     { 0x67,     "ADDS Transfer",        3 },
93     { 0x68,     "ADDS Transfer Ack",    4 },
94     { 0x02,     "Assignment Complete",  5 },
95     { 0x03,     "Assignment Failure",   6 },
96     { 0x01,     "Assignment Request",   7 },
97     { 0x45,     "Authentication Request",       8 },
98     { 0x46,     "Authentication Response",      9 },
99     { 0x48,     "Base Station Challenge",       10 },
100     { 0x49,     "Base Station Challenge Response",      11 },
101     { 0x40,     "Block",        12 },
102     { 0x41,     "Block Acknowledge",    13 },
103     { 0x09,     "BS Service Request",   14 },
104     { 0x0A,     "BS Service Response",  15 },
105     { 0x20,     "Clear Command",        16 },
106     { 0x21,     "Clear Complete",       17 },
107     { 0x22,     "Clear Request",        18 },
108     { 0x57,     "Complete Layer 3 Information", 19 },
109     { 0x60,     "Feature Notification", 20 },
110     { 0x61,     "Feature Notification Ack",     21 },
111     { 0x13,     "Handoff Command",      22 },
112     { 0x15,     "Handoff Commenced",    23 },
113     { 0x14,     "Handoff Complete",     24 },
114     { 0x16,     "Handoff Failure",      25 },
115     { 0x17,     "Handoff Performed",    26 },
116     { 0x10,     "Handoff Request",      27 },
117     { 0x12,     "Handoff Request Acknowledge",  28 },
118     { 0x11,     "Handoff Required",     29 },
119     { 0x1A,     "Handoff Required Reject",      30 },
120     { 0x6C,     "PACA Command", 31 },
121     { 0x6D,     "PACA Command Ack",     32 },
122     { 0x6E,     "PACA Update",  33 },
123     { 0x6F,     "PACA Update Ack",      34 },
124     { 0x52,     "Paging Request",       35 },
125     { 0x53,     "Privacy Mode Command", 36 },
126     { 0x55,     "Privacy Mode Complete",        37 },
127     { 0x23,     "Radio Measurements for Position Request",      38 },
128     { 0x25,     "Radio Measurements for Position Response",     39 },
129     { 0x56,     "Rejection",    40 },
130     { 0x05,     "Registration Request", 41 },
131     { 0x30,     "Reset",        42 },
132     { 0x31,     "Reset Acknowledge",    43 },
133     { 0x34,     "Reset Circuit",        44 },
134     { 0x35,     "Reset Circuit Acknowledge",    45 },
135     { 0x47,     "SSD Update Request",   46 },
136     { 0x4A,     "SSD Update Response",  47 },
137     { 0x6A,     "Status Request",       48 },
138     { 0x6B,     "Status Response",      49 },
139     { 0x39,     "Transcoder Control Acknowledge",       50 },
140     { 0x38,     "Transcoder Control Request",   51 },
141     { 0x42,     "Unblock",      52 },
142     { 0x43,     "Unblock Acknowledge",  53 },
143     { 0x0B,     "User Zone Reject",     54 },
144     { 0x04,     "User Zone Update",     55 },
145     { 0, NULL, 0 }
146 };
147
148 const ext_value_string_t ansi_a_ios401_dtap_strings[] =
149 {
150     { 0x62,     "Additional Service Request",   0 },
151     { 0x53,     "ADDS Deliver", 1 },
152     { 0x54,     "ADDS Deliver Ack",     2 },
153     { 0x26,     "Alert With Information",       3 },
154     { 0x45,     "Authentication Request",       4 },
155     { 0x46,     "Authentication Response",      5 },
156     { 0x48,     "Base Station Challenge",       6 },
157     { 0x49,     "Base Station Challenge Response",      7 },
158     { 0x24,     "CM Service Request",   8 },
159     { 0x25,     "CM Service Request Continuation",      9 },
160     { 0x07,     "Connect",      10 },
161     { 0x10,     "Flash with Information",       11 },
162     { 0x50,     "Flash with Information Ack",   12 },
163     { 0x02,     "Location Updating Accept",     13 },
164     { 0x04,     "Location Updating Reject",     14 },
165     { 0x08,     "Location Updating Request",    15 },
166     { 0x27,     "Paging Response",      16 },
167     { 0x2B,     "Parameter Update Confirm",     17 },
168     { 0x2C,     "Parameter Update Request",     18 },
169     { 0x56,     "Rejection",    19 },
170     { 0x03,     "Progress",     20 },
171     { 0x70,     "Service Redirection",  21 },
172     { 0x2E,     "Service Release",      22 },
173     { 0x2F,     "Service Release Complete",     23 },
174     { 0x47,     "SSD Update Request",   24 },
175     { 0x4A,     "SSD Update Response",  25 },
176     { 0x6A,     "Status Request",       26 },
177     { 0x6B,     "Status Response",      27 },
178     { 0x0B,     "User Zone Reject",     28 },
179     { 0x0C,     "User Zone Update",     29 },
180     { 0x0D,     "User Zone Update Request",     30 },
181     { 0, NULL, 0 }
182 };
183
184 const ext_value_string_t ansi_a_ios401_elem_1_strings[] =
185 {
186     { 0x20,     "Access Network Identifiers",   0 },
187     { 0x3D,     "ADDS User Part",       1 },
188     { 0x25,     "AMPS Hard Handoff Parameters", 2 },
189     { 0x30,     "Anchor PDSN Address",  3 },
190     { 0x7C,     "Anchor P-P Address",   4 },
191     { 0x41,     "Authentication Challenge Parameter",   5 },
192     { 0x28,     "Authentication Confirmation Parameter (RANDC)",        6 },
193     { 0x59,     "Authentication Data",  7 },
194     { 0x4A,     "Authentication Event", 8 },
195     { 0x40,     "Authentication Parameter COUNT",       9 },
196     { 0x42,     "Authentication Response Parameter",    10 },
197     { 0x37,     "Band Class",   11 },
198     { 0x5B,     "Called Party ASCII Number",    12 },
199     { 0x5E,     "Called Party BCD Number",      13 },
200     { 0x4B,     "Calling Party ASCII Number",   14 },
201     { 0x04,     "Cause",        15 },
202     { 0x08,     "Cause Layer 3",        16 },
203     { 0x0C,     "CDMA Serving One Way Delay",   17 },
204     { 0x05,     "Cell Identifier",      18 },
205     { 0x1A,     "Cell Identifier List", 19 },
206     { 0x23,     "Channel Number",       20 },
207     { 0x0B,     "Channel Type", 21 },
208     { 0x19,     "Circuit Group",        22 },
209     { 0x01,     "Circuit Identity Code",        23 },
210     { 0x24,     "Circuit Identity Code Extension",      24 },
211     { 0x12,     "Classmark Information Type 2", 25 },
212     { 0x29,     "Downlink Radio Environment",   26 },
213     { 0x2B,     "Downlink Radio Environment List",      27 },
214     { 0x0A,     "Encryption Information",       28 },
215     { 0x10,     "Extended Handoff Direction Parameters",        29 },
216     { 0x2C,     "Geographic Location",  30 },
217     { 0x5A,     "Special Service Call Indicator",       31 },
218     { 0x26,     "Handoff Power Level",  32 },
219     { 0x16,     "Hard Handoff Parameters",      33 },
220     { 0x2E,     "Information Element Requested",        34 },
221     { 0x09,     "IS-2000 Channel Identity",     35 },
222     { 0x27,     "IS-2000 Channel Identity 3X",  36 },
223     { 0x11,     "IS-2000 Mobile Capabilities",  37 },
224     { 0x0F,     "IS-2000 Non-Negotiable Service Configuration Record",  38 },
225     { 0x0E,     "IS-2000 Service Configuration Record", 39 },
226     { 0x62,     "IS-95/IS-2000 Cause Value",    40 },
227     { 0x67,     "IS-2000 Redirection Record",   41 },
228     { 0x22,     "IS-95 Channel Identity",       42 },
229     { 0x64,     "IS-95 MS Measured Channel Identity",   43 },
230     { 0x17,     "Layer 3 Information",  44 },
231     { 0x13,     "Location Area Information",    45 },
232     { 0x38,     "Message Waiting Indication",   46 },
233     { 0x0D,     "Mobile Identity",      47 },
234     { 0x15,     "MS Information Records (Forward)",     48 },
235     { 0xA0,     "Origination Continuation Indicator",   49 },
236     { 0x5F,     "PACA Order",   50 },
237     { 0x60,     "PACA Reorigination Indicator", 51 },
238     { 0x4E,     "PACA Timestamp",       52 },
239     { 0x70,     "Packet Session Parameters",    53 },
240     { 0x14,     "PDSN IP Address",      54 },
241     { 0xA2,     "Power Down Indicator", 55 },
242     { 0x06,     "Priority",     56 },
243     { 0x3B,     "Protocol Revision",    57 },
244     { 0x18,     "Protocol Type",        58 },
245     { 0x2D,     "PSMM Count",   59 },
246     { 0x07,     "Quality of Service Parameters",        60 },
247     { 0x1D,     "Radio Environment and Resources",      61 },
248     { 0x1F,     "Registration Type",    62 },
249     { 0x44,     "Reject Cause", 63 },
250     { 0x1B,     "Response Request",     64 },
251     { 0x68,     "Return Cause", 65 },
252     { 0x21,     "RF Channel Identity",  66 },
253     { 0x03,     "Service Option",       67 },
254     { 0x1E,     "Service Option Connection Identifier (SOCI)",  68 },
255     { 0x2A,     "Service Option List",  69 },
256     { 0x69,     "Service Redirection Info",     70 },
257     { 0x71,     "Service Reference Identifier (SR_ID)", 71 },
258     { 0x32,     "SID",  72 },
259     { 0x34,     "Signal",       73 },
260     { 0x35,     "Slot Cycle Index",     74 },
261     { 0x31,     "Software Version",     75 },
262     { 0x39,     "Source RNC to Target RNC Transparent Container",       76 },
263     { 0x14,     "Source PDSN Address",  77 },
264     { 0x33,     "Tag",  78 },
265     { 0x3A,     "Target RNC to Source RNC Transparent Container",       79 },
266     { 0x36,     "Transcoder Mode",      80 }, /* XXX 0x1C in IOS 4.0.1 */
267     { 0x02,     "User Zone ID", 81 },
268     { 0xA1,     "Voice Privacy Request",        82 },
269     { 0x15,     "MS Information Records (Reverse)",     88 },
270     { 0, NULL, 0 }
271 };
272
273 const ext_value_string_t ansi_a_ios501_bsmap_strings[] =
274 {
275     { 0x69,     "Additional Service Notification",      0 },
276     { 0x65,     "ADDS Page",    1 },
277     { 0x66,     "ADDS Page Ack",        2 },
278     { 0x67,     "ADDS Transfer",        3 },
279     { 0x68,     "ADDS Transfer Ack",    4 },
280     { 0x02,     "Assignment Complete",  5 },
281     { 0x03,     "Assignment Failure",   6 },
282     { 0x01,     "Assignment Request",   7 },
283     { 0x45,     "Authentication Request",       8 },
284     { 0x46,     "Authentication Response",      9 },
285     { 0x48,     "Base Station Challenge",       10 },
286     { 0x49,     "Base Station Challenge Response",      11 },
287     { 0x40,     "Block",        12 },
288     { 0x41,     "Block Acknowledge",    13 },
289     { 0x09,     "BS Service Request",   14 },
290     { 0x0A,     "BS Service Response",  15 },
291     { 0x20,     "Clear Command",        16 },
292     { 0x21,     "Clear Complete",       17 },
293     { 0x22,     "Clear Request",        18 },
294     { 0x57,     "Complete Layer 3 Information", 19 },
295     { 0x60,     "Feature Notification", 20 },
296     { 0x61,     "Feature Notification Ack",     21 },
297     { 0x13,     "Handoff Command",      22 },
298     { 0x15,     "Handoff Commenced",    23 },
299     { 0x14,     "Handoff Complete",     24 },
300     { 0x16,     "Handoff Failure",      25 },
301     { 0x17,     "Handoff Performed",    26 },
302     { 0x10,     "Handoff Request",      27 },
303     { 0x12,     "Handoff Request Acknowledge",  28 },
304     { 0x11,     "Handoff Required",     29 },
305     { 0x1A,     "Handoff Required Reject",      30 },
306     { 0x6C,     "PACA Command", 31 },
307     { 0x6D,     "PACA Command Ack",     32 },
308     { 0x6E,     "PACA Update",  33 },
309     { 0x6F,     "PACA Update Ack",      34 },
310     { 0x52,     "Paging Request",       35 },
311     { 0x53,     "Privacy Mode Command", 36 },
312     { 0x55,     "Privacy Mode Complete",        37 },
313     { 0x23,     "Radio Measurements for Position Request",      38 },
314     { 0x25,     "Radio Measurements for Position Response",     39 },
315     { 0x56,     "Rejection",    40 },
316     { 0x05,     "Registration Request", 41 },
317     { 0x30,     "Reset",        42 },
318     { 0x31,     "Reset Acknowledge",    43 },
319     { 0x34,     "Reset Circuit",        44 },
320     { 0x35,     "Reset Circuit Acknowledge",    45 },
321     { 0x47,     "SSD Update Request",   46 },
322     { 0x4A,     "SSD Update Response",  47 },
323     { 0x6A,     "Status Request",       48 },
324     { 0x6B,     "Status Response",      49 },
325     { 0x39,     "Transcoder Control Acknowledge",       50 },
326     { 0x38,     "Transcoder Control Request",   51 },
327     { 0x42,     "Unblock",      52 },
328     { 0x43,     "Unblock Acknowledge",  53 },
329     { 0x0B,     "User Zone Reject",     54 },
330     { 0x04,     "User Zone Update",     55 },
331     { 0x58,     "Bearer Update Request",        56 },
332     { 0x59,     "Bearer Update Response",       58 },
333     { 0x5A,     "Bearer Update Required",       57 },
334     { 0x71,     "Mobile Station Registered Notification",       59 },
335     { 0x07,     "BS Authentication Request",    60 },
336     { 0x08,     "BS Authentication Request Ack",        61 },
337     { 0, NULL, 0 }
338 };
339
340 const ext_value_string_t ansi_a_ios501_dtap_strings[] =
341 {
342     { 0x62,     "Additional Service Request",   0 },
343     { 0x53,     "ADDS Deliver", 1 },
344     { 0x54,     "ADDS Deliver Ack",     2 },
345     { 0x26,     "Alert With Information",       3 },
346     { 0x45,     "Authentication Request",       4 },
347     { 0x46,     "Authentication Response",      5 },
348     { 0x48,     "Base Station Challenge",       6 },
349     { 0x49,     "Base Station Challenge Response",      7 },
350     { 0x24,     "CM Service Request",   8 },
351     { 0x25,     "CM Service Request Continuation",      9 },
352     { 0x07,     "Connect",      10 },
353     { 0x10,     "Flash with Information",       11 },
354     { 0x50,     "Flash with Information Ack",   12 },
355     { 0x02,     "Location Updating Accept",     13 },
356     { 0x04,     "Location Updating Reject",     14 },
357     { 0x08,     "Location Updating Request",    15 },
358     { 0x27,     "Paging Response",      16 },
359     { 0x2B,     "Parameter Update Confirm",     17 },
360     { 0x2C,     "Parameter Update Request",     18 },
361     { 0x56,     "Rejection",    19 },
362     { 0x03,     "Progress",     20 },
363     { 0x70,     "Service Redirection",  21 },
364     { 0x2E,     "Service Release",      22 },
365     { 0x2F,     "Service Release Complete",     23 },
366     { 0x47,     "SSD Update Request",   24 },
367     { 0x4A,     "SSD Update Response",  25 },
368     { 0x6A,     "Status Request",       26 },
369     { 0x6B,     "Status Response",      27 },
370     { 0x0B,     "User Zone Reject",     28 },
371     { 0x0C,     "User Zone Update",     29 },
372     { 0x0D,     "User Zone Update Request",     30 },
373     { 0, NULL, 0 }
374 };
375
376 /*
377  * ORDER MUST MATCH
378  * ansi_a_ios401_elem_1_strings when the same element
379  * is being described.
380  */
381 const ext_value_string_t ansi_a_ios501_elem_1_strings[] =
382 {
383     { 0x20,     "Access Network Identifiers",   0 },
384     { 0x3D,     "ADDS User Part",       1 },
385     { 0x25,     "AMPS Hard Handoff Parameters", 2 },
386     { 0x30,     "Anchor PDSN Address",  3 },
387     { 0x7C,     "Anchor P-P Address",   4 },
388     { 0x41,     "Authentication Challenge Parameter",   5 },
389     { 0x28,     "Authentication Confirmation Parameter (RANDC)",        6 },
390     { 0x59,     "Authentication Data",  7 },
391     { 0x4A,     "Authentication Event", 8 },
392     { 0x40,     "Authentication Parameter COUNT",       9 },
393     { 0x42,     "Authentication Response Parameter",    10 },
394     { 0x37,     "Band Class",   11 },
395     { 0x5B,     "Called Party ASCII Number",    12 },
396     { 0x5E,     "Called Party BCD Number",      13 },
397     { 0x4B,     "Calling Party ASCII Number",   14 },
398     { 0x04,     "Cause",        15 },
399     { 0x08,     "Cause Layer 3",        16 },
400     { 0x0C,     "CDMA Serving One Way Delay",   17 },
401     { 0x05,     "Cell Identifier",      18 },
402     { 0x1A,     "Cell Identifier List", 19 },
403     { 0x23,     "Channel Number",       20 },
404     { 0x0B,     "Channel Type", 21 },
405     { 0x19,     "Circuit Group",        22 },
406     { 0x01,     "Circuit Identity Code",        23 },
407     { 0x24,     "Circuit Identity Code Extension",      24 },
408     { 0x12,     "Classmark Information Type 2", 25 },
409     { 0x29,     "Downlink Radio Environment",   26 },
410     { 0x2B,     "Downlink Radio Environment List",      27 },
411     { 0x0A,     "Encryption Information",       28 },
412     { 0x10,     "Extended Handoff Direction Parameters",        29 },
413     { 0x2C,     "Geographic Location",  30 },
414     { 0x5A,     "Special Service Call Indicator",       31 },
415     { 0x26,     "Handoff Power Level",  32 },
416     { 0x16,     "Hard Handoff Parameters",      33 },
417     { 0x2E,     "Information Element Requested",        34 },
418     { 0x09,     "IS-2000 Channel Identity",     35 },
419     { 0x27,     "IS-2000 Channel Identity 3X",  36 },
420     { 0x11,     "IS-2000 Mobile Capabilities",  37 },
421     { 0x0F,     "IS-2000 Non-Negotiable Service Configuration Record",  38 },
422     { 0x0E,     "IS-2000 Service Configuration Record", 39 },
423     { 0x62,     "IS-95/IS-2000 Cause Value",    40 },
424     { 0x67,     "IS-2000 Redirection Record",   41 },
425     { 0x22,     "IS-95 Channel Identity",       42 },
426     { 0x64,     "IS-95 MS Measured Channel Identity",   43 },
427     { 0x17,     "Layer 3 Information",  44 },
428     { 0x13,     "Location Area Information",    45 },
429     { 0x38,     "Message Waiting Indication",   46 },
430     { 0x0D,     "Mobile Identity",      47 },
431     { 0x15,     "MS Information Records (Forward)",     48 },
432     { 0xA0,     "Origination Continuation Indicator",   49 },
433     { 0x5F,     "PACA Order",   50 },
434     { 0x60,     "PACA Reorigination Indicator", 51 },
435     { 0x4E,     "PACA Timestamp",       52 },
436     { 0x70,     "Packet Session Parameters",    53 },
437     { 0x14,     "PDSN IP Address",      54 },
438     { 0xA2,     "Power Down Indicator", 55 },
439     { 0x06,     "Priority",     56 },
440     { 0x3B,     "Protocol Revision",    57 },
441     { 0x18,     "Protocol Type",        58 },
442     { 0x2D,     "PSMM Count",   59 },
443     { 0x07,     "Quality of Service Parameters",        60 },
444     { 0x1D,     "Radio Environment and Resources",      61 },
445     { 0x1F,     "Registration Type",    62 },
446     { 0x44,     "Reject Cause", 63 },
447     { 0x1B,     "Response Request",     64 },
448     { 0x68,     "Return Cause", 65 },
449     { 0x21,     "RF Channel Identity",  66 },
450     { 0x03,     "Service Option",       67 },
451     { 0x1E,     "Service Option Connection Identifier (SOCI)",  68 },
452     { 0x2A,     "Service Option List",  69 },
453     { 0x69,     "Service Redirection Info",     70 },
454     { 0x71,     "Service Reference Identifier (SR_ID)", 71 },
455     { 0x32,     "SID",  72 },
456     { 0x34,     "Signal",       73 },
457     { 0x35,     "Slot Cycle Index",     74 },
458     { 0x31,     "Software Version",     75 },
459     { 0x39,     "Source RNC to Target RNC Transparent Container",       76 },
460     { 0x14,     "Source PDSN Address",  77 },
461     { 0x33,     "Tag",  78 },
462     { 0x3A,     "Target RNC to Source RNC Transparent Container",       79 },
463     { 0x36,     "Transcoder Mode",      80 }, /* XXX 0x1C in IOS 4.0.1 */
464     { 0x02,     "User Zone ID", 81 },
465     { 0xA1,     "Voice Privacy Request",        82 },
466     { 0x45,     "A2p Bearer Session-Level Parameters",  83 },
467     { 0x46,     "A2p Bearer Format-Specific Parameters",        84 },
468     { 0x73,     "MS Designated Frequency",      85 },
469     { 0x7D,     "Mobile Subscription Information",      86 },
470     { 0x72,     "Public Long Code Mask Identification", 87 },
471     { 0x15,     "MS Information Records (Reverse)",     88 },
472     { 0, NULL, 0 }
473 };
474
475 /*
476  * From Table 3.7.5-1 C.S0005-D v1.0 L3
477  */
478 #define ANSI_FWD_MS_INFO_REC_DISPLAY            0x01
479 #define ANSI_FWD_MS_INFO_REC_CLD_PN             0x02
480 #define ANSI_FWD_MS_INFO_REC_CLG_PN             0x03
481 #define ANSI_FWD_MS_INFO_REC_CONN_N             0x04
482 #define ANSI_FWD_MS_INFO_REC_SIGNAL             0x05
483 #define ANSI_FWD_MS_INFO_REC_MW                 0x06
484 #define ANSI_FWD_MS_INFO_REC_SC                 0x07
485 #define ANSI_FWD_MS_INFO_REC_CLD_PSA            0x08
486 #define ANSI_FWD_MS_INFO_REC_CLG_PSA            0x09
487 #define ANSI_FWD_MS_INFO_REC_CONN_SA            0x0a
488 #define ANSI_FWD_MS_INFO_REC_RED_N              0x0b
489 #define ANSI_FWD_MS_INFO_REC_RED_SA             0x0c
490 #define ANSI_FWD_MS_INFO_REC_MP                 0x0d
491 #define ANSI_FWD_MS_INFO_REC_PA                 0x0e
492 #define ANSI_FWD_MS_INFO_REC_LC                 0x0f
493 #define ANSI_FWD_MS_INFO_REC_EDISPLAY           0x10
494 #define ANSI_FWD_MS_INFO_REC_NNSC               0x13
495 #define ANSI_FWD_MS_INFO_REC_MC_EDISPLAY        0x14
496 #define ANSI_FWD_MS_INFO_REC_CWI                0x15
497 #define ANSI_FWD_MS_INFO_REC_EMC_EDISPLAY       0x16
498 #define ANSI_FWD_MS_INFO_REC_ERTI               0xfe
499
500 static const value_string ansi_fwd_ms_info_rec_str[] = {
501     { ANSI_FWD_MS_INFO_REC_DISPLAY,             "Display" },
502     { ANSI_FWD_MS_INFO_REC_CLD_PN,              "Called Party Number" },
503     { ANSI_FWD_MS_INFO_REC_CLG_PN,              "Calling Party Number" },
504     { ANSI_FWD_MS_INFO_REC_CONN_N,              "Connected Number" },
505     { ANSI_FWD_MS_INFO_REC_SIGNAL,              "Signal" },
506     { ANSI_FWD_MS_INFO_REC_MW,                  "Message Waiting" },
507     { ANSI_FWD_MS_INFO_REC_SC,                  "Service Configuration" },
508     { ANSI_FWD_MS_INFO_REC_CLD_PSA,             "Called Party Subaddress" },
509     { ANSI_FWD_MS_INFO_REC_CLG_PSA,             "Calling Party Subaddress" },
510     { ANSI_FWD_MS_INFO_REC_CONN_SA,             "Connected Subaddress" },
511     { ANSI_FWD_MS_INFO_REC_RED_N,               "Redirecting Number" },
512     { ANSI_FWD_MS_INFO_REC_RED_SA,              "Redirecting Subaddress" },
513     { ANSI_FWD_MS_INFO_REC_MP,                  "Meter Pulses" },
514     { ANSI_FWD_MS_INFO_REC_PA,                  "Parametric Alerting" },
515     { ANSI_FWD_MS_INFO_REC_LC,                  "Line Control" },
516     { ANSI_FWD_MS_INFO_REC_EDISPLAY,            "Extended Display" },
517     { ANSI_FWD_MS_INFO_REC_NNSC,                "Non-Negotiable Service Configuration" },
518     { ANSI_FWD_MS_INFO_REC_MC_EDISPLAY,         "Multiple Character Extended Display" },
519     { ANSI_FWD_MS_INFO_REC_CWI,                 "Call Waiting Indicator" },
520     { ANSI_FWD_MS_INFO_REC_EMC_EDISPLAY,        "Enhanced Multiple Character Extended Display" },
521     { ANSI_FWD_MS_INFO_REC_ERTI,                "Extended Record Type International" },
522     { 0, NULL }
523 };
524 #define NUM_FWD_MS_INFO_REC (sizeof(ansi_fwd_ms_info_rec_str)/sizeof(value_string))
525 static gint ett_ansi_fwd_ms_info_rec[NUM_FWD_MS_INFO_REC];
526
527 /*
528  * From Table 2.7.4-1 C.S0005-D v1.0 L3
529  */
530 #define ANSI_REV_MS_INFO_REC_KEYPAD_FAC         0x03
531 #define ANSI_REV_MS_INFO_REC_CLD_PN             0x04
532 #define ANSI_REV_MS_INFO_REC_CLG_PN             0x05
533 #define ANSI_REV_MS_INFO_REC_CALL_MODE          0x07
534 #define ANSI_REV_MS_INFO_REC_TERM_INFO          0x08
535 #define ANSI_REV_MS_INFO_REC_ROAM_INFO          0x09
536 #define ANSI_REV_MS_INFO_REC_SECUR_STS          0x0a
537 #define ANSI_REV_MS_INFO_REC_CONN_N             0x0b
538 #define ANSI_REV_MS_INFO_REC_IMSI               0x0c
539 #define ANSI_REV_MS_INFO_REC_ESN                0x0d
540 #define ANSI_REV_MS_INFO_REC_BAND_INFO          0x0e
541 #define ANSI_REV_MS_INFO_REC_POWER_INFO         0x0f
542 #define ANSI_REV_MS_INFO_REC_OP_MODE_INFO       0x10
543 #define ANSI_REV_MS_INFO_REC_SO_INFO            0x11
544 #define ANSI_REV_MS_INFO_REC_MO_INFO            0x12
545 #define ANSI_REV_MS_INFO_REC_SC_INFO            0x13
546 #define ANSI_REV_MS_INFO_REC_CLD_PSA            0x14
547 #define ANSI_REV_MS_INFO_REC_CLG_PSA            0x15
548 #define ANSI_REV_MS_INFO_REC_CONN_SA            0x16
549 #define ANSI_REV_MS_INFO_REC_PCI                0x17
550 #define ANSI_REV_MS_INFO_REC_IMSI_M             0x18
551 #define ANSI_REV_MS_INFO_REC_IMSI_T             0x19
552 #define ANSI_REV_MS_INFO_REC_CAP_INFO           0x1a
553 #define ANSI_REV_MS_INFO_REC_CCC_INFO           0x1b
554 #define ANSI_REV_MS_INFO_REC_EMO_INFO           0x1c
555 #define ANSI_REV_MS_INFO_REC_GEO_CAP            0x1e
556 #define ANSI_REV_MS_INFO_REC_BAND_SUB           0x1f
557 #define ANSI_REV_MS_INFO_REC_GECO               0x20
558 #define ANSI_REV_MS_INFO_REC_HOOK               0x21
559 #define ANSI_REV_MS_INFO_REC_QOS_PARAM          0x22
560 #define ANSI_REV_MS_INFO_REC_ENCRYPT_CAP        0x23
561 #define ANSI_REV_MS_INFO_REC_SMI_CAP            0x24
562 #define ANSI_REV_MS_INFO_REC_UIM_ID             0x25
563 #define ANSI_REV_MS_INFO_REC_ESN_ME             0x26
564 #define ANSI_REV_MS_INFO_REC_MEID               0x27
565 #define ANSI_REV_MS_INFO_REC_EKEYPAD_FAC        0x28
566 #define ANSI_REV_MS_INFO_REC_SYNC_ID            0x29
567 #define ANSI_REV_MS_INFO_REC_ERTI               0xfe
568
569 static const value_string ansi_rev_ms_info_rec_str[] = {
570     { ANSI_REV_MS_INFO_REC_KEYPAD_FAC,          "Keypad Facility" },
571     { ANSI_REV_MS_INFO_REC_CLD_PN,              "Called Party Number" },
572     { ANSI_REV_MS_INFO_REC_CLG_PN,              "Calling Party Number" },
573     { ANSI_REV_MS_INFO_REC_CALL_MODE,           "Call Mode" },
574     { ANSI_REV_MS_INFO_REC_TERM_INFO,           "Terminal Information" },
575     { ANSI_REV_MS_INFO_REC_ROAM_INFO,           "Roaming Information" },
576     { ANSI_REV_MS_INFO_REC_SECUR_STS,           "Security Status" },
577     { ANSI_REV_MS_INFO_REC_CONN_N,              "Connected Number" },
578     { ANSI_REV_MS_INFO_REC_IMSI,                "IMSI" },
579     { ANSI_REV_MS_INFO_REC_ESN,                 "ESN" },
580     { ANSI_REV_MS_INFO_REC_BAND_INFO,           "Band Class Information" },
581     { ANSI_REV_MS_INFO_REC_POWER_INFO,          "Power Class Information" },
582     { ANSI_REV_MS_INFO_REC_OP_MODE_INFO,        "Operating Mode Information" },
583     { ANSI_REV_MS_INFO_REC_SO_INFO,             "Service Option Information" },
584     { ANSI_REV_MS_INFO_REC_MO_INFO,             "Multiplex Option Information" },
585     { ANSI_REV_MS_INFO_REC_SC_INFO,             "Service Configuration Information" },
586     { ANSI_REV_MS_INFO_REC_CLD_PSA,             "Called Party Subaddress" },
587     { ANSI_REV_MS_INFO_REC_CLG_PSA,             "Calling Party Subaddress" },
588     { ANSI_REV_MS_INFO_REC_CONN_SA,             "Connected Subaddress" },
589     { ANSI_REV_MS_INFO_REC_PCI,                 "Power Control Information" },
590     { ANSI_REV_MS_INFO_REC_IMSI_M,              "IMSI_M" },
591     { ANSI_REV_MS_INFO_REC_IMSI_T,              "IMSI_T" },
592     { ANSI_REV_MS_INFO_REC_CAP_INFO,            "Capability Information" },
593     { ANSI_REV_MS_INFO_REC_CCC_INFO,            "Channel Configuration Capability Information" },
594     { ANSI_REV_MS_INFO_REC_EMO_INFO,            "Extended Multiplex Option Information" },
595     { ANSI_REV_MS_INFO_REC_GEO_CAP,             "Geo-Location Capability" },
596     { ANSI_REV_MS_INFO_REC_BAND_SUB,            "Band Subclass Information" },
597     { ANSI_REV_MS_INFO_REC_GECO,                "Global Emergency Call" },
598     { ANSI_REV_MS_INFO_REC_HOOK,                "Hook Status" },
599     { ANSI_REV_MS_INFO_REC_QOS_PARAM,           "QoS Parameters" },
600     { ANSI_REV_MS_INFO_REC_ENCRYPT_CAP,         "Encryption Capability" },
601     { ANSI_REV_MS_INFO_REC_SMI_CAP,             "Signaling Message Integrity Capability" },
602     { ANSI_REV_MS_INFO_REC_UIM_ID,              "UIM_ID" },
603     { ANSI_REV_MS_INFO_REC_ESN_ME,              "ESN_ME" },
604     { ANSI_REV_MS_INFO_REC_MEID,                "MEID" },
605     { ANSI_REV_MS_INFO_REC_EKEYPAD_FAC,         "Extended Keypad Facility" },
606     { ANSI_REV_MS_INFO_REC_SYNC_ID,             "SYNC_ID" },
607     { ANSI_REV_MS_INFO_REC_ERTI,                "Extended Record Type International" },
608     { 0, NULL }
609 };
610 #define NUM_REV_MS_INFO_REC (sizeof(ansi_rev_ms_info_rec_str)/sizeof(value_string))
611 static gint ett_ansi_rev_ms_info_rec[NUM_REV_MS_INFO_REC];
612
613 /*
614  * C.S0057 Table 1.5-1
615  */
616 static const gchar *band_class_str[] = {
617     "800 MHz Cellular System",
618     "1.850 to 1.990 GHz Broadband PCS",
619     "872 to 960 MHz TACS Band",
620     "832 to 925 MHz JTACS Band",
621     "1.750 to 1.870 GHz Korean PCS",
622     "450 MHz NMT",
623     "2 GHz IMT-2000",
624     "Upper 700 MHz",
625     "1.710 to 1.880 GHz PCS",
626     "880 to 960 MHz",
627     "Secondary 800 MHz",
628     "400 MHz European PAMR",
629     "800 MHz European PAMR",
630     "2.5 GHz IMT-2000 Extension",
631     "US PCS 1.9 GHz",
632     "AWS",
633     "US 2.5 GHz",
634     "US 2.5 GHz Forward Link Only",
635     "700 MHz Public Safety",
636     "Lower 700 MHz"
637 };
638 #define NUM_BAND_CLASS_STR      (sizeof(band_class_str)/sizeof(gchar *))
639
640 static const gchar *cell_disc_str[] = {
641     "whole Cell Global Identification (CGI)",
642     "LAC/CI",
643     "Cell Identity (CI)",
644     "None",
645     "Location Area Identification (LAI)",
646     "Location Area Code (LAC)",
647     "ALL",
648     "IS-41 whole Cell Global Identification (ICGI)",
649     "Enhanced whole Cell Global Identification (ECGI)"
650 };
651 #define NUM_CELL_DISC_STR       (sizeof(cell_disc_str)/sizeof(gchar *))
652
653 /* Initialize the protocol and registered fields */
654 static int proto_a_bsmap = -1;
655 static int proto_a_dtap = -1;
656
657 const ext_value_string_t *ansi_a_bsmap_strings = NULL;
658 const ext_value_string_t *ansi_a_dtap_strings = NULL;
659 const ext_value_string_t *ansi_a_elem_1_strings = NULL;
660
661 static int ansi_a_tap = -1;
662
663 static int hf_ansi_a_none = -1;
664 static int hf_ansi_a_bsmap_msgtype = -1;
665 static int hf_ansi_a_dtap_msgtype = -1;
666 static int hf_ansi_a_length = -1;
667 static int hf_ansi_a_elem_id = -1;
668 static int hf_ansi_a_esn = -1;
669 static int hf_ansi_a_imsi = -1;
670 static int hf_ansi_a_min = -1;
671 static int hf_ansi_a_meid = -1;
672 static int hf_ansi_a_cld_party_bcd_num = -1;
673 static int hf_ansi_a_clg_party_bcd_num = -1;
674 static int hf_ansi_a_cld_party_ascii_num = -1;
675 static int hf_ansi_a_clg_party_ascii_num = -1;
676 static int hf_ansi_a_cell_ci = -1;
677 static int hf_ansi_a_cell_lac = -1;
678 static int hf_ansi_a_cell_mscid = -1;
679 static int hf_ansi_a_pdsn_ip_addr = -1;
680 static int hf_ansi_a_s_pdsn_ip_addr = -1;
681 static int hf_ansi_a_anchor_ip_addr = -1;
682 static int hf_ansi_a_anchor_pp_ip_addr = -1;
683 static int hf_ansi_a_a2p_bearer_ipv4_addr = -1;
684 static int hf_ansi_a_a2p_bearer_ipv6_addr = -1;
685 static int hf_ansi_a_a2p_bearer_udp_port = -1;
686 static int hf_ansi_a_so = -1;
687 static int hf_ansi_a_cause_1 = -1;      /* 1 octet cause */
688 static int hf_ansi_a_cause_2 = -1;      /* 2 octet cause */
689 static int hf_ansi_a_meid_configured = -1;
690
691
692 /* Initialize the subtree pointers */
693 static gint ett_bsmap = -1;
694 static gint ett_dtap = -1;
695 static gint ett_elems = -1;
696 static gint ett_elem = -1;
697 static gint ett_dtap_oct_1 = -1;
698 static gint ett_cm_srvc_type = -1;
699 static gint ett_ansi_ms_info_rec_reserved = -1;
700 static gint ett_ansi_enc_info = -1;
701 static gint ett_scm = -1;
702 static gint ett_cell_list = -1;
703 static gint ett_bearer_list = -1;
704 static gint ett_re_list = -1;
705 static gint ett_so_list = -1;
706 static gint ett_adds_user_part = -1;
707 static gint ett_scr = -1;
708 static gint ett_srvc_con_rec = -1;
709 static gint ett_cm2_band_class = -1;
710 static gint ett_vp_algs = -1;
711
712 static char a_bigbuf[1024];
713 static dissector_handle_t rtp_handle=NULL;
714 static dissector_handle_t data_handle;
715 static dissector_handle_t dtap_handle;
716 static dissector_table_t is637_dissector_table; /* IS-637-A Transport Layer (SMS) */
717 static dissector_table_t is683_dissector_table; /* IS-683-A (OTA) */
718 static dissector_table_t is801_dissector_table; /* IS-801 (PLD) */
719 static proto_tree *g_tree;
720 static address rtp_src_addr;
721 static guint32 rtp_ipv4_addr;
722 static struct e_in6_addr rtp_ipv6_addr;
723 static guint16 rtp_port;
724 static gboolean a_meid_configured = FALSE;
725
726
727 typedef struct ansi_a_dgt_set_t
728 {
729     /*
730      * would typically be 15 but to allow MEID decoding this
731      * needs to have room for full hexadecimal representation
732      */
733     unsigned char out[16];
734 }
735 ansi_a_dgt_set_t;
736
737 /*
738  * As per A.S0001 Called Party BCD Number
739  */
740 static ansi_a_dgt_set_t Dgt_tbcd = {
741     {
742   /*  0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f */
743      '0','1','2','3','4','5','6','7','8','9','*','#','a','b','c', 0
744     }
745 };
746
747 static ansi_a_dgt_set_t Dgt_msid = {
748     {
749   /*  0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f */
750      '0','1','2','3','4','5','6','7','8','9','?','?','?','?','?', 0
751     }
752 };
753
754 static ansi_a_dgt_set_t Dgt_meid = {
755     {
756   /*  0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f */
757      '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
758     }
759 };
760
761 /* FUNCTIONS */
762
763 /*
764  * Unpack BCD input pattern into output ASCII pattern
765  *
766  * Input Pattern is supplied using the same format as the digits
767  *
768  * Returns: length of unpacked pattern
769  */
770 static int
771 my_dgt_tbcd_unpack(
772     char        *out,           /* ASCII pattern out */
773     guchar      *in,            /* packed pattern in */
774     int         num_octs,       /* Number of octets to unpack */
775     ansi_a_dgt_set_t   *dgt            /* Digit definitions */
776     )
777 {
778     int cnt = 0;
779     unsigned char i;
780
781     while (num_octs)
782     {
783         /*
784          * unpack first value in byte
785          */
786         i = *in++;
787         *out++ = dgt->out[i & 0x0f];
788         cnt++;
789
790         /*
791          * unpack second value in byte
792          */
793         i >>= 4;
794
795         if ((num_octs == 1) && (i == 0x0f))  /* odd number bytes - hit filler */
796             break;
797
798         *out++ = dgt->out[i];
799         cnt++;
800         num_octs--;
801     }
802
803     *out = '\0';
804
805     return(cnt);
806 }
807
808 static const gchar *
809 ansi_a_so_int_to_str(
810     gint32      so)
811 {
812     const gchar *str = NULL;
813
814     switch (so)
815     {
816     case 1: str = "Basic Variable Rate Voice Service (8 kbps)"; break;
817     case 2: str = "Mobile Station Loopback (8 kbps)"; break;
818     case 3: str = "(EVRC) Enhanced Variable Rate Voice Service (8 kbps)"; break;
819     case 4: str = "Asynchronous Data Service (9.6 kbps)"; break;
820     case 5: str = "Group 3 Facsimile (9.6 kbps)"; break;
821     case 6: str = "Short Message Services (Rate Set 1)"; break;
822     case 7: str = "Packet Data Service: Internet or ISO Protocol Stack (9.6 kbps)"; break;
823     case 8: str = "Packet Data Service: CDPD Protocol Stack (9.6 kbps)"; break;
824     case 9: str = "Mobile Station Loopback (13 kbps)"; break;
825     case 10: str = "STU-III Transparent Service"; break;
826     case 11: str = "STU-III Non-Transparent Service"; break;
827     case 12: str = "Asynchronous Data Service (14.4 or 9.6 kbps)"; break;
828     case 13: str = "Group 3 Facsimile (14.4 or 9.6 kbps)"; break;
829     case 14: str = "Short Message Services (Rate Set 2)"; break;
830     case 15: str = "Packet Data Service: Internet or ISO Protocol Stack (14.4 kbps)"; break;
831     case 16: str = "Packet Data Service: CDPD Protocol Stack (14.4 kbps)"; break;
832     case 17: str = "High Rate Voice Service (13 kbps)"; break;
833     case 32768: str = "QCELP (13 kbps)"; break;
834     case 32798: /* 0x801e */ str = "Qualcomm Loopback"; break;
835     case 32799: /* 0x801f */ str = "Qualcomm Markov 8 kbps Loopback"; break;
836     case 32800: /* 0x8020 */ str = "Qualcomm Packet Data"; break;
837     case 32801: /* 0x8021 */ str = "Qualcomm Async Data"; break;
838     case 18: str = "Over-the-Air Parameter Administration (Rate Set 1)"; break;
839     case 19: str = "Over-the-Air Parameter Administration (Rate Set 2)"; break;
840     case 20: str = "Group 3 Analog Facsimile (Rate Set 1)"; break;
841     case 21: str = "Group 3 Analog Facsimile (Rate Set 2)"; break;
842     case 22: str = "High Speed Packet Data Service: Internet or ISO Protocol Stack (RS1 forward, RS1 reverse)"; break;
843     case 23: str = "High Speed Packet Data Service: Internet or ISO Protocol Stack (RS1 forward, RS2 reverse)"; break;
844     case 24: str = "High Speed Packet Data Service: Internet or ISO Protocol Stack (RS2 forward, RS1 reverse)"; break;
845     case 25: str = "High Speed Packet Data Service: Internet or ISO Protocol Stack (RS2 forward, RS2 reverse)"; break;
846     case 26: str = "High Speed Packet Data Service: CDPD Protocol Stack (RS1 forward, RS1 reverse)"; break;
847     case 27: str = "High Speed Packet Data Service: CDPD Protocol Stack (RS1 forward, RS2 reverse)"; break;
848     case 28: str = "High Speed Packet Data Service: CDPD Protocol Stack (RS2 forward, RS1 reverse)"; break;
849     case 29: str = "High Speed Packet Data Service: CDPD Protocol Stack (RS2 forward, RS2 reverse)"; break;
850     case 30: str = "Supplemental Channel Loopback Test for Rate Set 1"; break;
851     case 31: str = "Supplemental Channel Loopback Test for Rate Set 2"; break;
852     case 32: str = "Test Data Service Option (TDSO)"; break;
853     case 33: str = "cdma2000 High Speed Packet Data Service, Internet or ISO Protocol Stack"; break;
854     case 34: str = "cdma2000 High Speed Packet Data Service, CDPD Protocol Stack"; break;
855     case 35: str = "Location Services (PDS), Rate Set 1 (9.6 kbps)"; break;
856     case 36: str = "Location Services (PDS), Rate Set 2 (14.4 kbps)"; break;
857     case 37: str = "ISDN Interworking Service (64 kbps)"; break;
858     case 38: str = "GSM Voice"; break;
859     case 39: str = "GSM Circuit Data"; break;
860     case 40: str = "GSM Packet Data"; break;
861     case 41: str = "GSM Short Message Service"; break;
862     case 42: str = "None Reserved for MC-MAP standard service options"; break;
863     case 54: str = "Markov Service Option (MSO)"; break;
864     case 55: str = "Loopback Service Option (LSO)"; break;
865     case 56: str = "Selectable Mode Vocoder"; break;
866     case 57: str = "32 kbps Circuit Video Conferencing"; break;
867     case 58: str = "64 kbps Circuit Video Conferencing"; break;
868     case 59: str = "HRPD Accounting Records Identifier"; break;
869     case 60: str = "Link Layer Assisted Robust Header Compression (LLA ROHC) - Header Removal"; break;
870     case 61: str = "Link Layer Assisted Robust Header Compression (LLA ROHC) - Header Compression"; break;
871     case 62: str = "- 4099 None Reserved for standard service options"; break;
872     case 68: str = "(EVRC-B NB) Enhanced Variable Rate Voice Service"; break;
873     case 70: str = "(EVRC-B WB) Enhanced Variable Rate Voice Service"; break;
874     case 73: str = "(EVRC-NW) Enhanced Variable Rate Voice Service"; break;
875     case 4100: str = "Asynchronous Data Service, Revision 1 (9.6 or 14.4 kbps)"; break;
876     case 4101: str = "Group 3 Facsimile, Revision 1 (9.6 or 14.4 kbps)"; break;
877     case 4102: str = "Reserved for standard service option"; break;
878     case 4103: str = "Packet Data Service: Internet or ISO Protocol Stack, Revision 1 (9.6 or 14.4 kbps)"; break;
879     case 4104: str = "Packet Data Service: CDPD Protocol Stack, Revision 1 (9.6 or 14.4 kbps)"; break;
880     default:
881         if ((so >= 4105) && (so <= 32767)) { str = "Reserved for standard service options"; }
882         else if ((so >= 32769) && (so <= 32771)) { str = "Proprietary QUALCOMM Incorporated"; }
883         else if ((so >= 32772) && (so <= 32775)) { str = "Proprietary OKI Telecom"; }
884         else if ((so >= 32776) && (so <= 32779)) { str = "Proprietary Lucent Technologies"; }
885         else if ((so >= 32780) && (so <=32783)) { str = "Nokia"; }
886         else if ((so >= 32784) && (so <=32787)) { str = "NORTEL NETWORKS"; }
887         else if ((so >= 32788) && (so <=32791)) { str = "Sony Electronics Inc."; }
888         else if ((so >= 32792) && (so <=32795)) { str = "Motorola"; }
889         else if ((so >= 32796) && (so <=32799)) { str = "QUALCOMM Incorporated"; }
890         else if ((so >= 32800) && (so <=32803)) { str = "QUALCOMM Incorporated"; }
891         else if ((so >= 32804) && (so <=32807)) { str = "QUALCOMM Incorporated"; }
892         else if ((so >= 32808) && (so <=32811)) { str = "QUALCOMM Incorporated"; }
893         else if ((so >= 32812) && (so <=32815)) { str = "Lucent Technologies"; }
894         else if ((so >= 32816) && (so <=32819)) { str = "Denso International"; }
895         else if ((so >= 32820) && (so <=32823)) { str = "Motorola"; }
896         else if ((so >= 32824) && (so <=32827)) { str = "Denso International"; }
897         else if ((so >= 32828) && (so <=32831)) { str = "Denso International"; }
898         else if ((so >= 32832) && (so <=32835)) { str = "Denso International"; }
899         else if ((so >= 32836) && (so <=32839)) { str = "NEC America"; }
900         else if ((so >= 32840) && (so <=32843)) { str = "Samsung Electronics"; }
901         else if ((so >= 32844) && (so <=32847)) { str = "Texas Instruments Incorporated"; }
902         else if ((so >= 32848) && (so <=32851)) { str = "Toshiba Corporation"; }
903         else if ((so >= 32852) && (so <=32855)) { str = "LG Electronics Inc."; }
904         else if ((so >= 32856) && (so <=32859)) { str = "VIA Telecom Inc."; }
905         else { str = "Reserved"; }
906         break;
907     }
908
909     return(str);
910 }
911
912
913 /* ELEMENT FUNCTIONS */
914
915 #define EXTRANEOUS_DATA_CHECK(edc_len, edc_max_len) \
916     if ((edc_len) > (edc_max_len)) \
917     { \
918         proto_tree_add_text(tree, tvb, \
919             curr_offset, (edc_len) - (edc_max_len), "Extraneous Data"); \
920         curr_offset += ((edc_len) - (edc_max_len)); \
921     }
922
923 #define EXTRANEOUS_DATA_CHECK_EXPERT(edc_len, edc_max_len) \
924     if ((edc_len) > (edc_max_len)) \
925     { \
926         proto_item *expert_item; \
927         expert_item = proto_tree_add_text(tree, tvb, \
928             curr_offset, (edc_len) - (edc_max_len), "Extraneous Data, dissector bug or later version spec(report to wireshark.org)"); \
929         expert_add_info_format(pinfo, expert_item, PI_PROTOCOL, PI_NOTE, "Extraneous Data, dissector bug or later version spec(report to wireshark.org)"); \
930         curr_offset += ((edc_len) - (edc_max_len)); \
931     }
932
933 #define SHORT_DATA_CHECK(sdc_len, sdc_min_len) \
934     if ((sdc_len) < (sdc_min_len)) \
935     { \
936         proto_tree_add_text(tree, tvb, \
937             curr_offset, (sdc_len), "Short Data (?)"); \
938         curr_offset += (sdc_len); \
939         return(curr_offset - offset); \
940     }
941
942 #define EXACT_DATA_CHECK(edc_len, edc_eq_len) \
943     if ((edc_len) != (edc_eq_len)) \
944     { \
945         proto_tree_add_text(tree, tvb, \
946             asn1->offset, (edc_len), "Unexpected Data Length"); \
947         asn1->offset += (edc_len); \
948         return; \
949     }
950
951 #define NO_MORE_DATA_CHECK(nmdc_len) \
952     if ((nmdc_len) == (curr_offset - offset)) return(nmdc_len);
953
954
955 /*
956  * IOS 6.2.2.6
957  */
958 static guint8
959 elem_chan_num(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string, int string_len)
960 {
961     guint32     value;
962     guint32     curr_offset;
963
964     curr_offset = offset;
965
966     value = tvb_get_ntohs(tvb, curr_offset);
967
968     switch (global_a_variant)
969     {
970     case A_VARIANT_IOS401:
971         proto_tree_add_text(tree,
972             tvb, curr_offset, 2,
973             "Channel Number: %u",
974             value);
975
976         g_snprintf(add_string, string_len, " - (%u)", value);
977         break;
978
979     case A_VARIANT_IOS501:
980         other_decode_bitfield_value(a_bigbuf, value >> 8, 0xf8, 8);
981         proto_tree_add_text(tree,
982             tvb, curr_offset, 1,
983             "%s :  Reserved",
984             a_bigbuf);
985
986         other_decode_bitfield_value(a_bigbuf, value >> 8, 0x07, 8);
987         proto_tree_add_text(tree, tvb, curr_offset, 1,
988             "%s :  ARFCN (MSB): %u",
989             a_bigbuf,
990             value & 0x07ff);
991
992         other_decode_bitfield_value(a_bigbuf, value & 0x00ff, 0xff, 8);
993         proto_tree_add_text(tree, tvb, curr_offset + 1, 1,
994             "%s :  ARFCN (LSB)",
995             a_bigbuf);
996
997         g_snprintf(add_string, string_len, " - (ARFCN: %u)", value & 0x07ff);
998         break;
999     }
1000
1001     curr_offset += 2;
1002
1003     /* no length check possible */
1004
1005     return(curr_offset - offset);
1006 }
1007
1008 /*
1009  * IOS 6.2.2.7
1010  */
1011 static guint8
1012 elem_chan_type(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
1013 {
1014     guint8      oct;
1015     guint32     curr_offset;
1016     const gchar *str = NULL;
1017     gboolean    data;
1018
1019     curr_offset = offset;
1020     data = FALSE;
1021
1022     oct = tvb_get_guint8(tvb, curr_offset);
1023
1024     switch (oct)
1025     {
1026     case 0: str = "No Alert"; break;
1027     case 1: str = "Speech"; break;
1028     case 2: str = "Data"; data = TRUE; break;
1029     case 3: str = "Signaling"; break;
1030     default:
1031         str = "Unknown";
1032         break;
1033     }
1034
1035     proto_tree_add_text(tree,
1036         tvb, curr_offset, 1,
1037         "Speech or Data Indicator: %s",
1038         str);
1039
1040     g_snprintf(add_string, string_len, " - (%s)", str);
1041
1042     curr_offset++;
1043
1044     NO_MORE_DATA_CHECK(len);
1045
1046     oct = tvb_get_guint8(tvb, curr_offset);
1047
1048     switch (oct)
1049     {
1050     case 0: str = "Reserved (invalid)"; break;
1051     case 1: str = "DCCH"; break;
1052     case 2: str = "Reserved for future use (invalid)"; break;
1053     case 8: str = "Full rate TCH channel Bm"; break;
1054     case 9: str = "Half rate TCH channel Lm"; break;
1055     default:
1056         str = "Unknown";
1057         break;
1058     }
1059
1060     proto_tree_add_text(tree,
1061         tvb, curr_offset, 1,
1062         "Channel Rate and Type: %s",
1063         str);
1064
1065     curr_offset++;
1066
1067     NO_MORE_DATA_CHECK(len);
1068
1069     oct = tvb_get_guint8(tvb, curr_offset);
1070
1071     if (data)
1072     {
1073         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
1074         proto_tree_add_text(tree,
1075             tvb, curr_offset, 1,
1076             "%s :  Extension",
1077             a_bigbuf);
1078
1079         other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
1080         proto_tree_add_text(tree,
1081             tvb, curr_offset, 1,
1082             "%s :  %sTransparent service",
1083             a_bigbuf,
1084             (oct & 0x40) ? "Non-" : "");
1085
1086         other_decode_bitfield_value(a_bigbuf, oct, 0x3f, 8);
1087         proto_tree_add_text(tree,
1088             tvb, curr_offset, 1,
1089             "%s :  Reserved",
1090             a_bigbuf);
1091     }
1092     else
1093     {
1094         switch (oct)
1095         {
1096         case 0: str = "No Resources Required (invalid)"; break;
1097         case 1: str = "Reserved"; break;
1098         case 2: str = "Reserved"; break;
1099         case 3: str = "TIA/EIA-IS-2000 8 kb/s vocoder"; break;
1100         case 4: str = "8 kb/s enhanced vocoder (EVRC)"; break;
1101         case 5: str = "13 kb/s vocoder"; break;
1102         case 6: str = "ADPCM"; break;
1103         default:
1104             str = "Reserved";
1105             break;
1106         }
1107
1108         proto_tree_add_text(tree,
1109             tvb, curr_offset, 1,
1110             "Speech Encoding Algorithm/data rate + Transparency Indicator: %s",
1111             str);
1112     }
1113
1114     curr_offset++;
1115
1116     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
1117
1118     return(curr_offset - offset);
1119 }
1120
1121 /*
1122  * IOS 5 4.2.83
1123  */
1124 static guint8
1125 elem_return_cause(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
1126 {
1127     guint8      oct;
1128     const gchar *str;
1129     guint32     curr_offset;
1130
1131     curr_offset = offset;
1132
1133     oct = tvb_get_guint8(tvb, curr_offset);
1134
1135     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
1136     proto_tree_add_text(tree, tvb, curr_offset, 1,
1137         "%s :  Reserved",
1138         a_bigbuf);
1139
1140     switch (oct & 0x0f)
1141     {
1142     case 0: str = "Normal access"; break;
1143     case 1: str = "Service redirection failed as a result of system not found"; break;
1144     case 2: str = "Service redirection failed as a result of protocol mismatch"; break;
1145     case 3: str = "Service redirection failed as a result of registration rejection"; break;
1146     case 4: str = "Service redirection failed as a result of wrong SID"; break;
1147     case 5: str = "Service redirection failed as a result of wrong NID"; break;
1148     default:
1149         str = "Reserved";
1150         break;
1151     }
1152
1153     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
1154     proto_tree_add_text(tree, tvb, curr_offset, 1,
1155         "%s :  Return Cause: %s",
1156         a_bigbuf,
1157         str);
1158
1159     curr_offset++;
1160
1161     /* no length check possible */
1162
1163     return(curr_offset - offset);
1164 }
1165
1166 /*
1167  * IOS 6.2.2.8
1168  */
1169 static guint8
1170 elem_rf_chan_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string, int string_len)
1171 {
1172     guint8      oct;
1173     guint32     value;
1174     guint32     curr_offset;
1175
1176     curr_offset = offset;
1177
1178     proto_tree_add_text(tree, tvb, curr_offset, 1,
1179         "Color Code");
1180
1181     curr_offset++;
1182
1183     oct = tvb_get_guint8(tvb, curr_offset);
1184
1185     other_decode_bitfield_value(a_bigbuf, oct, 0xfc, 8);
1186     proto_tree_add_text(tree, tvb, curr_offset, 1,
1187         "%s :  Reserved",
1188         a_bigbuf);
1189
1190     other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
1191     proto_tree_add_text(tree, tvb, curr_offset, 1,
1192         "%s :  N-AMPS",
1193         a_bigbuf);
1194
1195     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
1196     proto_tree_add_text(tree, tvb, curr_offset, 1,
1197         "%s :  ANSI/EIA/TIA-553",
1198         a_bigbuf);
1199
1200     curr_offset++;
1201
1202     oct = tvb_get_guint8(tvb, curr_offset);
1203
1204     other_decode_bitfield_value(a_bigbuf, oct, 0xfc, 8);
1205     proto_tree_add_text(tree, tvb, curr_offset, 1,
1206         "%s :  Reserved",
1207         a_bigbuf);
1208
1209     other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
1210     proto_tree_add_text(tree, tvb, curr_offset, 1,
1211         "%s :  Timeslot Number",
1212         a_bigbuf);
1213
1214     curr_offset++;
1215
1216     value = tvb_get_ntohs(tvb, curr_offset);
1217
1218     other_decode_bitfield_value(a_bigbuf, value >> 8, 0xf8, 8);
1219     proto_tree_add_text(tree, tvb, curr_offset, 1,
1220         "%s :  Reserved",
1221         a_bigbuf);
1222
1223     other_decode_bitfield_value(a_bigbuf, value >> 8, 0x07, 8);
1224     proto_tree_add_text(tree, tvb, curr_offset, 1,
1225         "%s :  ARFCN (MSB): %u",
1226         a_bigbuf,
1227         value & 0x07ff);
1228
1229     other_decode_bitfield_value(a_bigbuf, value & 0x00ff, 0xff, 8);
1230     proto_tree_add_text(tree, tvb, curr_offset + 1, 1,
1231         "%s :  ARFCN (LSB)",
1232         a_bigbuf);
1233
1234     g_snprintf(add_string, string_len, " - (ARFCN: %u)", value & 0x07ff);
1235
1236     curr_offset += 2;
1237
1238     /* no length check possible */
1239
1240     return(curr_offset - offset);
1241 }
1242
1243 /*
1244  * IOS 5 4.2.86
1245  */
1246 static guint8
1247 elem_sr_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
1248 {
1249     guint8      oct;
1250     guint32     curr_offset;
1251
1252     curr_offset = offset;
1253
1254     oct = tvb_get_guint8(tvb, curr_offset);
1255
1256     other_decode_bitfield_value(a_bigbuf, oct, 0xf8, 8);
1257     proto_tree_add_text(tree,
1258         tvb, curr_offset, 1,
1259         "%s :  Reserved",
1260         a_bigbuf);
1261
1262     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
1263     proto_tree_add_text(tree,
1264         tvb, curr_offset, 1,
1265         "%s :  SR_ID: %u",
1266         a_bigbuf,
1267         oct & 0x07);
1268
1269     g_snprintf(add_string, string_len, " - (%u)", oct);
1270
1271     curr_offset++;
1272
1273     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
1274
1275     return(curr_offset - offset);
1276 }
1277
1278 /*
1279  * IOS 6.2.2.9
1280  */
1281 static guint8
1282 elem_sid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string, int string_len)
1283 {
1284     guint32     value;
1285     guint32     curr_offset;
1286
1287     curr_offset = offset;
1288
1289     value = tvb_get_ntohs(tvb, curr_offset);
1290
1291     other_decode_bitfield_value(a_bigbuf, value >> 8, 0x80, 8);
1292     proto_tree_add_text(tree, tvb, curr_offset, 1,
1293         "%s :  Reserved",
1294         a_bigbuf);
1295
1296     other_decode_bitfield_value(a_bigbuf, value >> 8, 0x7f, 8);
1297     proto_tree_add_text(tree, tvb, curr_offset, 1,
1298         "%s :  SID (MSB), %u",
1299         a_bigbuf,
1300         value & 0x7fff);
1301
1302     other_decode_bitfield_value(a_bigbuf, value & 0x00ff, 0xff, 8);
1303     proto_tree_add_text(tree, tvb, curr_offset + 1, 1,
1304         "%s :  SID (LSB)",
1305         a_bigbuf);
1306
1307     g_snprintf(add_string, string_len, " - (SID: %u)", value & 0x7fff);
1308
1309     curr_offset += 2;
1310
1311     /* no length check possible */
1312
1313     return(curr_offset - offset);
1314 }
1315
1316 /*
1317  * IOS 6.2.2.10
1318  */
1319 static guint8
1320 elem_is95_chan_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
1321 {
1322     guint8      oct;
1323     guint32     value;
1324     guint32     curr_offset;
1325
1326     curr_offset = offset;
1327
1328     oct = tvb_get_guint8(tvb, curr_offset);
1329
1330     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
1331     proto_tree_add_text(tree, tvb, curr_offset, 1,
1332         "%s :  Hard Handoff",
1333         a_bigbuf);
1334
1335     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
1336     proto_tree_add_text(tree, tvb, curr_offset, 1,
1337         "%s :  Number of Channels to Add: %u",
1338         a_bigbuf,
1339         (oct & 0x70) >> 4);
1340
1341     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
1342     proto_tree_add_text(tree, tvb, curr_offset, 1,
1343         "%s :  Frame Offset: (%u), %.2f ms",
1344         a_bigbuf,
1345         oct & 0x0f,
1346         (oct & 0x0f) * 1.25);
1347
1348     curr_offset++;
1349
1350     NO_MORE_DATA_CHECK(len);
1351
1352     SHORT_DATA_CHECK(len - (curr_offset - offset), 4);
1353
1354     do
1355     {
1356         oct = tvb_get_guint8(tvb, curr_offset);
1357
1358         proto_tree_add_text(tree, tvb, curr_offset, 1,
1359             "Walsh Code Channel Index: %u",
1360             oct);
1361
1362         curr_offset++;
1363
1364         oct = tvb_get_guint8(tvb, curr_offset);
1365
1366         other_decode_bitfield_value(a_bigbuf, oct, 0xff, 8);
1367         proto_tree_add_text(tree, tvb, curr_offset, 1,
1368             "%s :  Pilot PN Code (LSB)",
1369             a_bigbuf);
1370
1371         curr_offset++;
1372
1373         value = oct;
1374         oct = tvb_get_guint8(tvb, curr_offset);
1375         value |= ((guint32) (oct & 0x80)) << 1;
1376
1377         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
1378         proto_tree_add_text(tree, tvb, curr_offset, 1,
1379             "%s :  Pilot PN Code (MSB): %u",
1380             a_bigbuf,
1381             value);
1382
1383         other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
1384         proto_tree_add_text(tree, tvb, curr_offset, 1,
1385             "%s :  Power Combined",
1386             a_bigbuf);
1387
1388         other_decode_bitfield_value(a_bigbuf, oct, 0x20, 8);
1389         proto_tree_add_text(tree, tvb, curr_offset, 1,
1390             "%s :  Frequency Included",
1391             a_bigbuf);
1392
1393         other_decode_bitfield_value(a_bigbuf, oct, 0x18, 8);
1394         proto_tree_add_text(tree, tvb, curr_offset, 1,
1395             "%s :  Reserved",
1396             a_bigbuf);
1397
1398         value = tvb_get_guint8(tvb, curr_offset + 1) | ((oct & 0x07) << 8);
1399
1400         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
1401         proto_tree_add_text(tree, tvb, curr_offset, 1,
1402             "%s :  ARFCN (MSB): %u",
1403             a_bigbuf,
1404             value);
1405
1406         curr_offset++;
1407
1408         other_decode_bitfield_value(a_bigbuf, value & 0x00ff, 0xff, 8);
1409         proto_tree_add_text(tree, tvb, curr_offset, 1,
1410             "%s :  ARFCN (LSB)",
1411             a_bigbuf);
1412
1413         if (add_string[0] == '\0')
1414         {
1415             g_snprintf(add_string, string_len, " - (ARFCN: %u)", value);
1416         }
1417
1418         curr_offset++;
1419     }
1420     while ((len - (curr_offset - offset)) >= 4);
1421
1422     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
1423
1424     return(curr_offset - offset);
1425 }
1426
1427 /*
1428  * IOS 6.2.2.11
1429  * UNUSED
1430  */
1431
1432 /*
1433  * IOS 6.2.2.12
1434  */
1435 static guint8
1436 elem_enc_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
1437 {
1438     guint8      oct;
1439     guint8      oct_len;
1440     guint32     curr_offset;
1441     const gchar *str;
1442     guint8      num_recs;
1443     proto_tree  *subtree;
1444     proto_item  *item;
1445
1446     curr_offset = offset;
1447
1448     num_recs = 0;
1449
1450     while ((len - (curr_offset - offset)) >= 2)
1451     {
1452         num_recs++;
1453
1454         oct = tvb_get_guint8(tvb, curr_offset);
1455
1456         switch ((oct & 0x7c) >> 2)
1457         {
1458         case 0: str = "Not Used - Invalid value"; break;
1459         case 1: str = "SME Key: Signaling Message Encryption Key"; break;
1460         case 2: str = "Reserved (VPM: Voice Privacy Mask)"; break;
1461         case 3: str = "Reserved"; break;
1462         case 4: str = "Private Longcode"; break;
1463         case 5: str = "Data Key (ORYX)"; break;
1464         case 6: str = "Initial RAND"; break;
1465         default:
1466             str = "Reserved";
1467             break;
1468         }
1469
1470         item =
1471             proto_tree_add_text(tree,
1472                 tvb, curr_offset, 1,
1473                 "Encryption Info [%u]: (%u) %s",
1474                 num_recs,
1475                 (oct & 0x7c) >> 2,
1476                 str);
1477
1478         subtree = proto_item_add_subtree(item, ett_ansi_enc_info);
1479
1480         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
1481         proto_tree_add_text(subtree, tvb, curr_offset, 1,
1482             "%s :  Extension",
1483             a_bigbuf);
1484
1485         other_decode_bitfield_value(a_bigbuf, oct, 0x7c, 8);
1486         proto_tree_add_text(subtree, tvb, curr_offset, 1,
1487             "%s :  Encryption Parameter Identifier: (%u) %s",
1488             a_bigbuf,
1489             (oct & 0x7c) >> 2,
1490             str);
1491
1492         other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
1493         proto_tree_add_text(subtree, tvb, curr_offset, 1,
1494             "%s :  Status: %s",
1495             a_bigbuf,
1496             (oct & 0x02) ? "active" : "inactive");
1497
1498         other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
1499         proto_tree_add_text(subtree, tvb, curr_offset, 1,
1500             "%s :  Available: algorithm is %savailable",
1501             a_bigbuf,
1502             (oct & 0x01) ? "" : "not ");
1503
1504         curr_offset++;
1505
1506         oct_len = tvb_get_guint8(tvb, curr_offset);
1507
1508         proto_tree_add_uint(subtree, hf_ansi_a_length, tvb,
1509             curr_offset, 1, oct_len);
1510
1511         curr_offset++;
1512
1513         if (oct_len > 0)
1514         {
1515             SHORT_DATA_CHECK(len - (curr_offset - offset), oct_len);
1516
1517             proto_tree_add_text(subtree, tvb, curr_offset, oct_len,
1518                 "Encryption Parameter value");
1519
1520             curr_offset += oct_len;
1521         }
1522     }
1523
1524     g_snprintf(add_string, string_len, " - %u record%s",
1525         num_recs, plurality(num_recs, "", "s"));
1526
1527     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
1528
1529     return(curr_offset - offset);
1530 }
1531
1532 /*
1533  * IOS 6.2.2.13
1534  * NO ASSOCIATED DATA
1535  */
1536
1537 /*
1538  * IOS 6.2.2.14
1539  * A3/A7
1540  */
1541
1542 /*
1543  * IOS 6.2.2.15
1544  */
1545 static guint8
1546 elem_cm_info_type_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
1547 {
1548     guint8      oct, oct2;
1549     guint8      num_bands, band_class_count;
1550     guint32     curr_offset;
1551     gint        band_class;
1552     proto_tree  *subtree;
1553     proto_item  *item;
1554     const gchar *str;
1555
1556     curr_offset = offset;
1557
1558     oct = tvb_get_guint8(tvb, curr_offset);
1559
1560     other_decode_bitfield_value(a_bigbuf, oct, 0xe0, 8);
1561     proto_tree_add_text(tree, tvb, curr_offset, 1,
1562         "%s :  Mobile P_REV: %u",
1563         a_bigbuf,
1564         (oct & 0xe0) >> 5);
1565
1566     g_snprintf(add_string, string_len, " - P_REV (%u)", (oct & 0xe0) >> 5);
1567
1568     other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
1569     proto_tree_add_text(tree, tvb, curr_offset, 1,
1570         "%s :  Reserved",
1571         a_bigbuf);
1572
1573     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
1574     proto_tree_add_text(tree, tvb, curr_offset, 1,
1575         "%s :  See List of Entries",
1576         a_bigbuf);
1577
1578     switch (oct & 0x07)
1579     {
1580     case 0: str = "Class 1, vehicle and portable"; break;
1581     case 1: str = "Class 2, portable"; break;
1582     case 2: str = "Class 3, handheld"; break;
1583     case 3: str = "Class 4, handheld"; break;
1584     case 4: str = "Class 5, handheld"; break;
1585     case 5: str = "Class 6, handheld"; break;
1586     case 6: str = "Class 7, handheld"; break;
1587     default:
1588         str = "Class 8, handheld";
1589         break;
1590     }
1591
1592     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
1593     proto_tree_add_text(tree, tvb, curr_offset, 1,
1594         "%s :  RF Power Capability: %s",
1595         a_bigbuf,
1596         str);
1597
1598     curr_offset++;
1599
1600     proto_tree_add_text(tree, tvb, curr_offset, 1,
1601         "Reserved");
1602
1603     curr_offset++;
1604
1605     oct = tvb_get_guint8(tvb, curr_offset);
1606
1607     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
1608     proto_tree_add_text(tree, tvb, curr_offset, 1,
1609         "%s :  NAR_AN_CAP: N-AMPS %ssupported",
1610         a_bigbuf,
1611         (oct & 0x80) ? "" : "not ");
1612
1613     other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
1614     proto_tree_add_text(tree, tvb, curr_offset, 1,
1615         "%s :  IS-95: %ssupported",
1616         a_bigbuf,
1617         (oct & 0x40) ? "" : "not ");
1618
1619     other_decode_bitfield_value(a_bigbuf, oct, 0x20, 8);
1620     proto_tree_add_text(tree, tvb, curr_offset, 1,
1621         "%s :  Slotted: mobile is %sin slotted mode",
1622         a_bigbuf,
1623         (oct & 0x20) ? "" : "not ");
1624
1625     other_decode_bitfield_value(a_bigbuf, oct, 0x18, 8);
1626     proto_tree_add_text(tree, tvb, curr_offset, 1,
1627         "%s :  Reserved",
1628         a_bigbuf);
1629
1630     other_decode_bitfield_value(a_bigbuf, oct, 0x04, 8);
1631     proto_tree_add_text(tree, tvb, curr_offset, 1,
1632         "%s :  DTX: mobile is %scapable of DTX",
1633         a_bigbuf,
1634         (oct & 0x04) ? "" : "not ");
1635
1636     other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
1637     proto_tree_add_text(tree, tvb, curr_offset, 1,
1638         "%s :  Mobile Term: mobile is %scapable of receiving incoming calls",
1639         a_bigbuf,
1640         (oct & 0x02) ? "" : "not ");
1641
1642     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
1643     proto_tree_add_text(tree, tvb, curr_offset, 1,
1644         "%s :  Reserved",
1645         a_bigbuf);
1646
1647     curr_offset++;
1648
1649     NO_MORE_DATA_CHECK(len);
1650
1651     proto_tree_add_text(tree, tvb, curr_offset, 1,
1652         "Reserved");
1653
1654     curr_offset++;
1655
1656     NO_MORE_DATA_CHECK(len);
1657
1658     oct = tvb_get_guint8(tvb, curr_offset);
1659
1660     other_decode_bitfield_value(a_bigbuf, oct, 0xfc, 8);
1661     proto_tree_add_text(tree, tvb, curr_offset, 1,
1662         "%s :  Reserved",
1663         a_bigbuf);
1664
1665     other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
1666     proto_tree_add_text(tree, tvb, curr_offset, 1,
1667         "%s :  Mobile Term: mobile is %scapable of receiving incoming calls",
1668         a_bigbuf,
1669         (oct & 0x02) ? "" : "not ");
1670
1671     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
1672     proto_tree_add_text(tree, tvb, curr_offset, 1,
1673         "%s :  PACA Supported Indicator (PSI): mobile station %s PACA",
1674         a_bigbuf,
1675         (oct & 0x01) ? "supports" : "does not support");
1676
1677     curr_offset++;
1678
1679     NO_MORE_DATA_CHECK(len);
1680
1681     oct = tvb_get_guint8(tvb, curr_offset);
1682
1683     proto_tree_add_text(tree, tvb, curr_offset, 1,
1684         "SCM Length: %u",
1685         oct);
1686
1687     curr_offset++;
1688
1689     oct = tvb_get_guint8(tvb, curr_offset);
1690
1691     item =
1692         proto_tree_add_text(tree, tvb, curr_offset, 1,
1693             "Station Class Mark: %u",
1694             oct);
1695
1696     /*
1697      * following SCM decode is from:
1698      *  3GPP2 C.S0005-0 section 2.3.3
1699      *  3GPP2 C.S0072-0 section 2.1.2
1700      */
1701     subtree = proto_item_add_subtree(item, ett_scm);
1702
1703     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
1704     proto_tree_add_text(subtree, tvb, curr_offset, 1,
1705         "%s :  Extended SCM Indicator: %s",
1706         a_bigbuf,
1707         (oct & 0x80) ? "Band Classes 1,4" : "Other bands");
1708
1709     other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
1710     proto_tree_add_text(subtree, tvb, curr_offset, 1,
1711         "%s :  %s",
1712         a_bigbuf,
1713         (oct & 0x40) ? "Dual Mode" : "CDMA Only");
1714
1715     other_decode_bitfield_value(a_bigbuf, oct, 0x20, 8);
1716     proto_tree_add_text(subtree, tvb, curr_offset, 1,
1717         "%s :  %s",
1718         a_bigbuf,
1719         (oct & 0x20) ? "Slotted" : "Non-Slotted");
1720
1721     if (oct & 0x10)
1722     {
1723         str = "";
1724         g_strlcat(add_string, " (MEID configured)", string_len);
1725         a_meid_configured = TRUE;
1726     }
1727     else
1728     {
1729         str = "not ";
1730     }
1731
1732     other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
1733     proto_tree_add_boolean_format(subtree, hf_ansi_a_meid_configured, tvb,
1734         curr_offset, 1, a_meid_configured,
1735         "%s :  MEID %sconfigured",
1736         a_bigbuf,
1737         str);
1738
1739     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
1740     proto_tree_add_text(subtree, tvb, curr_offset, 1,
1741         "%s :  25 MHz Bandwidth",
1742         a_bigbuf);
1743
1744     other_decode_bitfield_value(a_bigbuf, oct, 0x04, 8);
1745     proto_tree_add_text(subtree, tvb, curr_offset, 1,
1746         "%s :  %s Transmission",
1747         a_bigbuf,
1748         (oct & 0x04) ? "Discontinuous" : "Continuous");
1749
1750     switch (oct & 0x03)
1751     {
1752     case 0x00: str = "Class I"; break;
1753     case 0x01: str = "Class II"; break;
1754     case 0x02: str = "Class III"; break;
1755     case 0x03: str = "Reserved"; break;
1756     }
1757
1758     other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
1759     proto_tree_add_text(subtree, tvb, curr_offset, 1,
1760         "%s :  Power Class for Band Class 0 Analog Operation: %s",
1761         a_bigbuf,
1762         str);
1763
1764     curr_offset++;
1765
1766     NO_MORE_DATA_CHECK(len);
1767
1768     band_class_count = tvb_get_guint8(tvb, curr_offset);
1769
1770     proto_tree_add_text(tree, tvb, curr_offset, 1,
1771         "Count of Band Class Entries: %u",
1772         band_class_count);
1773
1774     curr_offset++;
1775
1776     oct = tvb_get_guint8(tvb, curr_offset);
1777
1778     proto_tree_add_text(tree, tvb, curr_offset, 1,
1779         "Band Class Entry Length: %u",
1780         oct);
1781
1782     curr_offset++;
1783
1784     NO_MORE_DATA_CHECK(len);
1785
1786     if (oct > 0)
1787     {
1788         SHORT_DATA_CHECK(len - (curr_offset - offset), 3);
1789
1790         num_bands = 0;
1791         do
1792         {
1793             item =
1794                 proto_tree_add_text(tree, tvb, curr_offset, 3,
1795                     "Band Class Entry [%u]",
1796                     num_bands + 1);
1797
1798             subtree = proto_item_add_subtree(item, ett_cm2_band_class);
1799
1800             oct = tvb_get_guint8(tvb, curr_offset);
1801
1802             other_decode_bitfield_value(a_bigbuf, oct, 0xe0, 8);
1803             proto_tree_add_text(subtree,
1804                 tvb, curr_offset, 1,
1805                 "%s :  Reserved",
1806                 a_bigbuf);
1807
1808             band_class = oct & 0x1f;
1809             if ((band_class < 0) || (band_class >= (gint) NUM_BAND_CLASS_STR))
1810             {
1811                 str = "Reserved";
1812             }
1813             else
1814             {
1815                 str = band_class_str[band_class];
1816             }
1817
1818             other_decode_bitfield_value(a_bigbuf, oct, 0x1f, 8);
1819             proto_tree_add_text(subtree,
1820                 tvb, curr_offset, 1,
1821                 "%s :  Band Class: %s",
1822                 a_bigbuf,
1823                 str);
1824
1825             curr_offset++;
1826
1827             oct2 = tvb_get_guint8(tvb, curr_offset);
1828             oct = tvb_get_guint8(tvb, curr_offset+1);
1829
1830             if (oct < 4)
1831             {
1832                 other_decode_bitfield_value(a_bigbuf, oct2, 0x80, 8);
1833                 proto_tree_add_text(subtree,
1834                     tvb, curr_offset, 1,
1835                     "%s :  Band Class Air Interfaces OP_MODE0 (CDMA mode in Band Class 1 and Band Class 4)",
1836                     a_bigbuf);
1837
1838                 other_decode_bitfield_value(a_bigbuf, oct2, 0x40, 8);
1839                 proto_tree_add_text(subtree,
1840                     tvb, curr_offset, 1,
1841                     "%s :  Band Class Air Interfaces OP_MODE1 (CDMA mode in Band Class 0 and Band Class 3)",
1842                     a_bigbuf);
1843
1844                 other_decode_bitfield_value(a_bigbuf, oct2, 0x20, 8);
1845                 proto_tree_add_text(subtree,
1846                     tvb, curr_offset, 1,
1847                     "%s :  Band Class Air Interfaces OP_MODE2 (Analog mode)",
1848                     a_bigbuf);
1849
1850                 other_decode_bitfield_value(a_bigbuf, oct2, 0x10, 8);
1851                 proto_tree_add_text(subtree,
1852                     tvb, curr_offset, 1,
1853                     "%s :  Band Class Air Interfaces OP_MODE3 (Wide analog mode)",
1854                     a_bigbuf);
1855
1856                 other_decode_bitfield_value(a_bigbuf, oct2, 0x08, 8);
1857                 proto_tree_add_text(subtree,
1858                     tvb, curr_offset, 1,
1859                     "%s :  Band Class Air Interfaces OP_MODE4 (Narrow analog mode)",
1860                     a_bigbuf);
1861             }
1862             else
1863             {
1864                 other_decode_bitfield_value(a_bigbuf, oct2, 0x80, 8);
1865                 proto_tree_add_text(subtree,
1866                     tvb, curr_offset, 1,
1867                     "%s :  Band Class Air Interfaces OP_MODE0 (CDMA mode)",
1868                     a_bigbuf);
1869
1870                 other_decode_bitfield_value(a_bigbuf, oct2, 0x40, 8);
1871                 proto_tree_add_text(subtree,
1872                     tvb, curr_offset, 1,
1873                     "%s :  Band Class Air Interfaces OP_MODE1 (CDMA mode)",
1874                     a_bigbuf);
1875
1876                 other_decode_bitfield_value(a_bigbuf, oct2, 0x20, 8);
1877                 proto_tree_add_text(subtree,
1878                     tvb, curr_offset, 1,
1879                     "%s :  Band Class Air Interfaces OP_MODE2 (Analog mode)",
1880                     a_bigbuf);
1881
1882                 other_decode_bitfield_value(a_bigbuf, oct2, 0x10, 8);
1883                 proto_tree_add_text(subtree,
1884                     tvb, curr_offset, 1,
1885                     "%s :  Band Class Air Interfaces OP_MODE3 (Wide analog mode)",
1886                     a_bigbuf);
1887
1888                 other_decode_bitfield_value(a_bigbuf, oct2, 0x08, 8);
1889                 proto_tree_add_text(subtree,
1890                     tvb, curr_offset, 1,
1891                     "%s :  Band Class Air Interfaces OP_MODE4 (Narrow analog mode)",
1892                     a_bigbuf);
1893             }
1894
1895             other_decode_bitfield_value(a_bigbuf, oct2, 0x07, 8);
1896             proto_tree_add_text(subtree,
1897                 tvb, curr_offset, 1,
1898                 "%s :  Reserved",
1899                 a_bigbuf);
1900
1901             curr_offset++;
1902
1903             proto_tree_add_text(subtree,
1904                 tvb, curr_offset, 1,
1905                 "Band Class MS Protocol Level: %u",
1906                 oct);
1907
1908             curr_offset++;
1909
1910             proto_item_append_text(item, ": (%d)", band_class);
1911
1912             num_bands++;
1913         }
1914         while (((len - (curr_offset - offset)) >= 3) &&
1915             (num_bands < band_class_count));
1916     }
1917
1918     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
1919
1920     return(curr_offset - offset);
1921 }
1922
1923 /*
1924  * IOS 6.2.2.16
1925  */
1926 static guint8
1927 elem_mid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
1928 {
1929     guint8      oct;
1930     guint8      *poctets;
1931     guint32     value;
1932     guint32     curr_offset;
1933     const gchar *str;
1934
1935     curr_offset = offset;
1936
1937     oct = tvb_get_guint8(tvb, curr_offset);
1938
1939     switch (oct & 0x07)
1940     {
1941     case 1:
1942         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
1943         proto_tree_add_text(tree,
1944             tvb, curr_offset, 1,
1945             "%s :  MEID Hex Digit 1: %X",
1946             a_bigbuf,
1947             (oct & 0xf0) >> 4);
1948
1949         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
1950         proto_tree_add_text(tree,
1951             tvb, curr_offset, 1,
1952             "%s :  Odd/Even Indicator: %s",
1953             a_bigbuf,
1954             (oct & 0x08) ? "ODD" : "EVEN");
1955
1956         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
1957         proto_tree_add_text(tree,
1958             tvb, curr_offset, 1,
1959             "%s :  Type of Identity: MEID",
1960             a_bigbuf);
1961
1962         a_bigbuf[0] = Dgt_meid.out[(oct & 0xf0) >> 4];
1963         curr_offset++;
1964
1965         poctets = tvb_get_ephemeral_string(tvb, curr_offset, len - (curr_offset - offset));
1966
1967         my_dgt_tbcd_unpack(&a_bigbuf[1], poctets, len - (curr_offset - offset),
1968             &Dgt_meid);
1969
1970         curr_offset += len - (curr_offset - offset);
1971
1972         proto_tree_add_string_format(tree,
1973             hf_ansi_a_meid,
1974             tvb, offset + 1, len - 1,
1975             a_bigbuf,
1976             "MEID: %s",
1977             a_bigbuf);
1978
1979         g_snprintf(add_string, string_len, " - %s (%s)",
1980             "MEID",
1981             a_bigbuf);
1982         break;
1983
1984     case 2:
1985         other_decode_bitfield_value(a_bigbuf, oct, 0xf8, 8);
1986         proto_tree_add_text(tree,
1987             tvb, curr_offset, 1,
1988             "%s :  Reserved",
1989             a_bigbuf);
1990
1991         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
1992         proto_tree_add_text(tree,
1993             tvb, curr_offset, 1,
1994             "%s :  Type of Identity: Broadcast",
1995             a_bigbuf);
1996
1997         curr_offset++;
1998
1999         oct = tvb_get_guint8(tvb, curr_offset);
2000
2001         switch ((oct & 0xc0) >> 6)
2002         {
2003         case 0: str = "Normal"; break;
2004         case 1: str = "Interactive"; break;
2005         case 2: str = "Urgent"; break;
2006         default:
2007             str = "Emergency";
2008             break;
2009         }
2010
2011         other_decode_bitfield_value(a_bigbuf, oct, 0xc0, 8);
2012         proto_tree_add_text(tree,
2013             tvb, curr_offset, 1,
2014             "%s :  Priority: %s",
2015             a_bigbuf,
2016             str);
2017
2018         other_decode_bitfield_value(a_bigbuf, oct, 0x3f, 8);
2019         proto_tree_add_text(tree,
2020             tvb, curr_offset, 1,
2021             "%s :  Message ID: %u",
2022             a_bigbuf,
2023             oct & 0x3f);
2024
2025         curr_offset++;
2026
2027         oct = tvb_get_guint8(tvb, curr_offset);
2028
2029         proto_tree_add_text(tree,
2030             tvb, curr_offset, 1,
2031             "Zone ID: %u",
2032             oct);
2033
2034         g_snprintf(add_string, string_len, " - Broadcast (Zone ID: %u)", oct);
2035
2036         curr_offset++;
2037
2038         value = tvb_get_ntohs(tvb, curr_offset);
2039
2040         switch (value)
2041         {
2042         case 0x0000: str = "Unknown or unspecified"; break;
2043         case 0x0001: str = "Emergency Broadcasts"; break;
2044         case 0x0002: str = "Administrative"; break;
2045         case 0x0003: str = "Maintenance"; break;
2046         case 0x0004: str = "General News - Local"; break;
2047         case 0x0005: str = "General News - Regional"; break;
2048         case 0x0006: str = "General News - National"; break;
2049         case 0x0007: str = "General News - International"; break;
2050         case 0x0008: str = "Business/Financial News - Local"; break;
2051         case 0x0009: str = "Business/Financial News - Regional"; break;
2052         case 0x000A: str = "Business/Financial News - National"; break;
2053         case 0x000B: str = "Business/Financial News - International"; break;
2054         case 0x000C: str = "Sports News - Local"; break;
2055         case 0x000D: str = "Sports News - Regional"; break;
2056         case 0x000E: str = "Sports News - National"; break;
2057         case 0x000F: str = "Sports News - International"; break;
2058         case 0x0010: str = "Entertainment News - Local"; break;
2059         case 0x0011: str = "Entertainment News - Regional"; break;
2060         case 0x0012: str = "Entertainment News - National"; break;
2061         case 0x0013: str = "Entertainment News - International"; break;
2062         case 0x0014: str = "Local Weather"; break;
2063         case 0x0015: str = "Area Traffic Reports"; break;
2064         case 0x0016: str = "Local Airport Flight Schedules"; break;
2065         case 0x0017: str = "Restaurants"; break;
2066         case 0x0018: str = "Lodgings"; break;
2067         case 0x0019: str = "Retail Directory"; break;
2068         case 0x001A: str = "Advertisements"; break;
2069         case 0x001B: str = "Stock Quotes"; break;
2070         case 0x001C: str = "Employment Opportunities"; break;
2071         case 0x001D: str = "Medical/Health/Hospitals"; break;
2072         case 0x001E: str = "Technology News"; break;
2073         case 0x001F: str = "Multi-category"; break;
2074         default:
2075             if ((value >= 0x0020) && (value <= 0x8000)) { str = "Reserved for standard service categories"; }
2076             else { str = "Reserved for proprietary service categories"; }
2077             break;
2078         }
2079
2080         proto_tree_add_text(tree,
2081             tvb, curr_offset, 2,
2082             "Service: (%u) %s",
2083             value,
2084             str);
2085
2086         curr_offset += 2;
2087
2088         oct = tvb_get_guint8(tvb, curr_offset);
2089
2090         switch (oct)
2091         {
2092         case 0: str = "Unknown or unspecified"; break;
2093         case 1: str = "English"; break;
2094         case 2: str = "French"; break;
2095         case 3: str = "Spanish"; break;
2096         case 4: str = "Japanese"; break;
2097         case 5: str = "Korean"; break;
2098         case 6: str = "Chinese"; break;
2099         case 7: str = "Hebrew"; break;
2100         default:
2101             str = "Reserved";
2102             break;
2103         }
2104
2105         proto_tree_add_text(tree,
2106             tvb, curr_offset, 1,
2107             "Language: (%u) %s",
2108             oct,
2109             str);
2110
2111         curr_offset++;
2112         break;
2113
2114     case 0:
2115         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
2116         proto_tree_add_text(tree,
2117             tvb, curr_offset, 1,
2118             "%s :  Unused",
2119             a_bigbuf);
2120
2121         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
2122         proto_tree_add_text(tree,
2123             tvb, curr_offset, 1,
2124             "%s :  Odd/Even Indicator: %s",
2125             a_bigbuf,
2126             (oct & 0x08) ? "ODD" : "EVEN");
2127
2128         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
2129         proto_tree_add_text(tree,
2130             tvb, curr_offset, 1,
2131             "%s :  Type of Identity: No Identity Code",
2132             a_bigbuf);
2133
2134         g_snprintf(add_string, string_len, " - No Identity Code");
2135
2136         curr_offset++;
2137
2138         if (len > 1)
2139         {
2140             proto_tree_add_text(tree, tvb, curr_offset, len - 1,
2141                 "Format not supported");
2142         }
2143
2144         curr_offset += len - 1;
2145         break;
2146
2147     case 6:
2148         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
2149         proto_tree_add_text(tree,
2150             tvb, curr_offset, 1,
2151             "%s :  Identity Digit 1: %c",
2152             a_bigbuf,
2153             Dgt_msid.out[(oct & 0xf0) >> 4]);
2154
2155         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
2156         proto_tree_add_text(tree,
2157             tvb, curr_offset, 1,
2158             "%s :  Odd/Even Indicator: %s",
2159             a_bigbuf,
2160             (oct & 0x08) ? "ODD" : "EVEN");
2161
2162         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
2163         proto_tree_add_text(tree,
2164             tvb, curr_offset, 1,
2165             "%s :  Type of Identity: %s",
2166             a_bigbuf,
2167             ((oct & 0x07) == 1) ? "MIN" : "IMSI");
2168
2169         a_bigbuf[0] = Dgt_msid.out[(oct & 0xf0) >> 4];
2170         curr_offset++;
2171
2172         poctets = tvb_get_ephemeral_string(tvb, curr_offset, len - (curr_offset - offset));
2173
2174         my_dgt_tbcd_unpack(&a_bigbuf[1], poctets, len - (curr_offset - offset),
2175             &Dgt_msid);
2176
2177         proto_tree_add_string_format(tree,
2178             ((oct & 0x07) == 1) ? hf_ansi_a_min : hf_ansi_a_imsi,
2179             tvb, curr_offset, len - (curr_offset - offset),
2180             a_bigbuf,
2181             "BCD Digits: %s",
2182             a_bigbuf);
2183
2184         g_snprintf(add_string, string_len, " - %s (%s)",
2185             ((oct & 0x07) == 1) ? "MIN" : "IMSI",
2186             a_bigbuf);
2187
2188         curr_offset += len - (curr_offset - offset);
2189         break;
2190
2191     case 3:
2192         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
2193         proto_tree_add_text(tree,
2194             tvb, curr_offset, 1,
2195             "%s :  Unused",
2196             a_bigbuf);
2197
2198         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
2199         proto_tree_add_text(tree,
2200             tvb, curr_offset, 1,
2201             "%s :  Odd/Even Indicator: %s",
2202             a_bigbuf,
2203             (oct & 0x08) ? "ODD" : "EVEN");
2204
2205         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
2206         proto_tree_add_text(tree,
2207             tvb, curr_offset, 1,
2208             "%s :  Type of Identity: Interface Directory Number",
2209             a_bigbuf);
2210
2211         g_snprintf(add_string, string_len, " - Interface Directory Number");
2212
2213         curr_offset++;
2214
2215         if (len > 1)
2216         {
2217             proto_tree_add_text(tree, tvb, curr_offset, len - 1,
2218                 "Format not supported");
2219         }
2220
2221         curr_offset += len - 1;
2222         break;
2223
2224     case 4:
2225         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
2226         proto_tree_add_text(tree,
2227             tvb, curr_offset, 1,
2228             "%s :  Unused",
2229             a_bigbuf);
2230
2231         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
2232         proto_tree_add_text(tree,
2233             tvb, curr_offset, 1,
2234             "%s :  Odd/Even Indicator: %s",
2235             a_bigbuf,
2236             (oct & 0x08) ? "ODD" : "EVEN");
2237
2238         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
2239         proto_tree_add_text(tree,
2240             tvb, curr_offset, 1,
2241             "%s :  Type of Identity: TMSI",
2242             a_bigbuf);
2243
2244         g_snprintf(add_string, string_len, " - TMSI");
2245
2246         curr_offset++;
2247
2248         if (len > 1)
2249         {
2250             proto_tree_add_text(tree, tvb, curr_offset, len - 1,
2251                 "Format not supported");
2252         }
2253
2254         curr_offset += len - 1;
2255         break;
2256
2257     case 5:
2258         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
2259         proto_tree_add_text(tree,
2260             tvb, curr_offset, 1,
2261             "%s :  Unused",
2262             a_bigbuf);
2263
2264         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
2265         proto_tree_add_text(tree,
2266             tvb, curr_offset, 1,
2267             "%s :  Odd/Even Indicator: %s",
2268             a_bigbuf,
2269             (oct & 0x08) ? "ODD" : "EVEN");
2270
2271         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
2272         proto_tree_add_text(tree,
2273             tvb, curr_offset, 1,
2274             "%s :  Type of Identity: ESN",
2275             a_bigbuf);
2276
2277         curr_offset++;
2278
2279         value = tvb_get_ntohl(tvb, curr_offset);
2280
2281         proto_tree_add_uint(tree, hf_ansi_a_esn,
2282             tvb, curr_offset, 4,
2283             value);
2284
2285         g_snprintf(add_string, string_len, " - %sESN (0x%04x)",
2286             a_meid_configured ? "p" : "",
2287             value);
2288
2289         curr_offset += 4;
2290         break;
2291
2292     default:
2293         proto_tree_add_text(tree, tvb, curr_offset, len,
2294             "Format Unknown");
2295
2296         g_snprintf(add_string, string_len, " - Format Unknown");
2297
2298         curr_offset += len;
2299         break;
2300     }
2301
2302     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2303
2304     return(curr_offset - offset);
2305 }
2306
2307 /*
2308  * IOS 6.2.2.17
2309  */
2310 static guint8
2311 elem_sci(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string, int string_len)
2312 {
2313     guint8      oct;
2314     guint32     curr_offset;
2315
2316     curr_offset = offset;
2317
2318     oct = tvb_get_guint8(tvb, curr_offset);
2319
2320     other_decode_bitfield_value(a_bigbuf, oct, 0xf8, 8);
2321     proto_tree_add_text(tree,
2322         tvb, curr_offset, 1,
2323         "%s :  Reserved",
2324         a_bigbuf);
2325
2326     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
2327     proto_tree_add_text(tree,
2328         tvb, curr_offset, 1,
2329         "%s :  Slot Cycle Index: %u",
2330         a_bigbuf,
2331         oct & 0x07);
2332
2333     g_snprintf(add_string, string_len, " - (%u)", oct & 0x07);
2334
2335     curr_offset++;
2336
2337     /* no length check possible */
2338
2339     return(curr_offset - offset);
2340 }
2341
2342 /*
2343  * IOS 6.2.2.18
2344  */
2345 static guint8
2346 elem_prio(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
2347 {
2348     guint8      oct;
2349     guint32     curr_offset;
2350
2351     curr_offset = offset;
2352
2353     oct = tvb_get_guint8(tvb, curr_offset);
2354
2355     other_decode_bitfield_value(a_bigbuf, oct, 0xc0, 8);
2356     proto_tree_add_text(tree,
2357         tvb, curr_offset, 1,
2358         "%s :  Reserved",
2359         a_bigbuf);
2360
2361     other_decode_bitfield_value(a_bigbuf, oct, 0x3c, 8);
2362     proto_tree_add_text(tree,
2363         tvb, curr_offset, 1,
2364         "%s :  Call Priority Level: %u",
2365         a_bigbuf,
2366         (oct & 0x3c) >> 2);
2367
2368     other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
2369     proto_tree_add_text(tree,
2370         tvb, curr_offset, 1,
2371         "%s :  Queuing %sallowed",
2372         a_bigbuf,
2373         (oct & 0x02) ? "" : "not ");
2374
2375     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
2376     proto_tree_add_text(tree,
2377         tvb, curr_offset, 1,
2378         "%s :  Preemption %sallowed",
2379         a_bigbuf,
2380         (oct & 0x01) ? "" : "not ");
2381
2382     g_snprintf(add_string, string_len, " - (%u)", (oct & 0x3c) >> 2);
2383
2384     curr_offset++;
2385
2386     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2387
2388     return(curr_offset - offset);
2389 }
2390
2391 /*
2392  * IOS 5 4.2.79
2393  */
2394 static guint8
2395 elem_p_rev(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
2396 {
2397     guint8      oct;
2398     guint32     curr_offset;
2399
2400     curr_offset = offset;
2401
2402     oct = tvb_get_guint8(tvb, curr_offset);
2403
2404     proto_tree_add_text(tree, tvb, curr_offset, 1,
2405         "MOB_P_REV");
2406
2407     g_snprintf(add_string, string_len, " - (%u)", oct);
2408
2409     curr_offset++;
2410
2411     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2412
2413     return(curr_offset - offset);
2414 }
2415
2416 /*
2417  * IOS 6.2.2.19
2418  */
2419 static guint8
2420 elem_cause(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
2421 {
2422     guint8      oct;
2423     guint32     value;
2424     guint32     curr_offset;
2425     const gchar *str = NULL;
2426
2427     curr_offset = offset;
2428
2429     oct = tvb_get_guint8(tvb, curr_offset);
2430
2431     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
2432     proto_tree_add_text(tree,
2433         tvb, curr_offset, 1,
2434         "%s :  Extension",
2435         a_bigbuf);
2436
2437     if (oct & 0x80)
2438     {
2439         /* 2 octet cause */
2440
2441         if ((oct & 0x0f) == 0x00)
2442         {
2443             /* national cause */
2444             switch ((oct & 0x70) >> 4)
2445             {
2446             case 0: str = "Normal Event"; break;
2447             case 1: str = "Normal Event"; break;
2448             case 2: str = "Resource Unavailable"; break;
2449             case 3: str = "Service or option not available"; break;
2450             case 4: str = "Service or option not implemented"; break;
2451             case 5: str = "Invalid message (e.g., parameter out of range)"; break;
2452             case 6: str = "Protocol error"; break;
2453             default:
2454                 str = "Interworking";
2455                 break;
2456             }
2457
2458             other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
2459             proto_tree_add_text(tree,
2460                 tvb, curr_offset, 1,
2461                 "%s :  Cause Class: %s",
2462                 a_bigbuf,
2463                 str);
2464
2465             other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
2466             proto_tree_add_text(tree,
2467                 tvb, curr_offset, 1,
2468                 "%s :  National Cause",
2469                 a_bigbuf);
2470
2471             curr_offset++;
2472
2473             value = tvb_get_guint8(tvb, curr_offset);
2474
2475             proto_tree_add_uint_format(tree, hf_ansi_a_cause_2, tvb,
2476                 curr_offset, 1,
2477                 ((oct & 0x7f) << 8) | value,
2478                 "Cause Value");
2479
2480             curr_offset++;
2481
2482             g_snprintf(add_string, string_len, " - (National Cause)");
2483         }
2484         else
2485         {
2486             value = tvb_get_guint8(tvb, curr_offset + 1);
2487
2488             other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
2489
2490             proto_tree_add_uint_format(tree, hf_ansi_a_cause_2, tvb,
2491                 curr_offset, 1,
2492                 ((oct & 0x7f) << 8) | value,
2493                 "%s :  Cause (MSB): %u",
2494                 a_bigbuf,
2495                 ((oct & 0x7f) << 8) | value);
2496
2497             curr_offset++;
2498
2499             other_decode_bitfield_value(a_bigbuf, value, 0xff, 8);
2500             proto_tree_add_text(tree, tvb, curr_offset, 1,
2501                 "%s :  Cause (LSB)",
2502                 a_bigbuf);
2503
2504             curr_offset++;
2505         }
2506     }
2507     else
2508     {
2509         switch (oct)
2510         {
2511         case 0x00: str = "Radio interface message failure"; break;
2512         case 0x01: str = "Radio interface failure"; break;
2513         case 0x02: str = "Uplink Quality"; break;
2514         case 0x03: str = "Uplink strength"; break;
2515         case 0x04: str = "Downlink quality"; break;
2516         case 0x05: str = "Downlink strength"; break;
2517         case 0x06: str = "Distance"; break;
2518         case 0x07: str = "OAM&P intervention"; break;
2519         case 0x08: str = "MS busy"; break;
2520         case 0x09: str = "Call processing"; break;
2521         case 0x0A: str = "Reversion to old channel"; break;
2522         case 0x0B: str = "Handoff successful"; break;
2523         case 0x0C: str = "No response from MS"; break;
2524         case 0x0D: str = "Timer expired"; break;
2525         case 0x0E: str = "Better cell (power budget)"; break;
2526         case 0x0F: str = "Interference"; break;
2527         case 0x10: str = "Packet call going dormant"; break;
2528         case 0x11: str = "Service option not available"; break;
2529
2530         case 0x12: str = "Invalid Call"; break;
2531         case 0x13: str = "Successful operation"; break;
2532         case 0x14: str = "Normal call release"; break;
2533
2534         /* IOS 5 */
2535         case 0x15: str = "Short data burst authentication failure"; break;
2536         case 0x17: str = "Time critical relocation/handoff"; break;
2537         case 0x18: str = "Network optimization"; break;
2538         case 0x19: str = "Power down from dormant state"; break;
2539         case 0x1A: str = "Authentication failure"; break;
2540
2541         case 0x1B: str = "Inter-BS Soft Handoff Drop Target"; break;
2542         case 0x1D: str = "Intra-BS Soft Handoff Drop Target"; break;
2543
2544         /* IOS 5 */
2545         case 0x1E: str = "Autonomous Registration by the Network"; break;
2546
2547         case 0x20: str = "Equipment failure"; break;
2548         case 0x21: str = "No radio resource available"; break;
2549         case 0x22: str = "Requested terrestrial resource unavailable"; break;
2550
2551         /* IOS 5 */
2552         case 0x23: str = "A2p RTP Payload Type not available"; break;
2553         case 0x24: str = "A2p Bearer Format Address Type not available"; break;
2554
2555         case 0x25: str = "BS not equipped"; break;
2556         case 0x26: str = "MS not equipped (or incapable)"; break;
2557
2558         /* IOS 5 */
2559         case 0x27: str = "2G only sector"; break;
2560         case 0x28: str = "3G only sector"; break;
2561
2562         case 0x29: str = "PACA Call Queued"; break;
2563
2564         /* IOS 5 */
2565         case 0x2A: str = "Handoff Blocked"; break;
2566
2567         case 0x2B: str = "Alternate signaling type reject"; break;
2568
2569         /* IOS 5 */
2570         case 0x2C: str = "A2p Resource not available"; break;
2571
2572         case 0x2D: str = "PACA Queue Overflow"; break;
2573         case 0x2E: str = "PACA Cancel Request Rejected"; break;
2574         case 0x30: str = "Requested transcoding/rate adaptation unavailable"; break;
2575         case 0x31: str = "Lower priority radio resources not available"; break;
2576         case 0x32: str = "PCF resources not available"; break;  /* IOS 4 */
2577         case 0x33: str = "TFO Control request Failed"; break;
2578
2579         /* IOS 5 */
2580         case 0x34: str = "MS rejected order"; break;
2581
2582         case 0x40: str = "Ciphering algorithm not supported"; break;
2583         case 0x41: str = "Private Long Code not available or not supported."; break;
2584         case 0x42: str = "Requested MUX option or rates not available."; break;
2585         case 0x43: str = "Requested Privacy Configuration unavailable"; break;
2586
2587         /* IOS 5 */
2588         case 0x45: str = "PDS-related capability not available or not supported"; break;
2589
2590         case 0x50: str = "Terrestrial circuit already allocated"; break;
2591         case 0x60: str = "Protocol Error between BS and MSC"; break;
2592         case 0x71: str = "ADDS message too long for delivery on the paging channel"; break;
2593         case 0x72: str = "MS-to-IWF TCP connection failure"; break;
2594         case 0x73: str = "ATH0 (Modem hang up) Command"; break;
2595         case 0x74: str = "+FSH/+FHNG (Fax session ended) Command"; break;
2596         case 0x75: str = "No carrier"; break;
2597         case 0x76: str = "PPP protocol failure"; break;
2598         case 0x77: str = "PPP session closed by the MS"; break;
2599         case 0x78: str = "Do not notify MS"; break;
2600         case 0x79: str = "PCF (or PDSN) resources are not available"; break;
2601         case 0x7A: str = "Data ready to send"; break;
2602
2603         /* IOS 5 */
2604         case 0x7B: str = "Concurrent authentication"; break;
2605
2606         case 0x7F: str = "Handoff procedure time-out"; break;
2607         default:
2608             str = "Reserved for future use";
2609             break;
2610         }
2611
2612         other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
2613         proto_tree_add_uint_format(tree, hf_ansi_a_cause_1, tvb,
2614             curr_offset, 1, oct,
2615             "%s :  Cause: (%u) %s",
2616             a_bigbuf,
2617             oct & 0x7f,
2618             str);
2619
2620         curr_offset++;
2621
2622         g_snprintf(add_string, string_len, " - (%u) %s", oct & 0x7f, str);
2623     }
2624
2625     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2626
2627     return(curr_offset - offset);
2628 }
2629
2630 /*
2631  * IOS 6.2.2.20
2632  * Formats everything after the discriminator, shared function.
2633  */
2634 static guint8
2635 elem_cell_id_aux(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len, guint8 disc)
2636 {
2637     guint32     value;
2638     guint32     market_id;
2639     guint32     switch_num;
2640     guint32     curr_offset;
2641
2642     curr_offset = offset;
2643
2644     switch (disc)
2645     {
2646     case 0x02:
2647         value = tvb_get_ntohs(tvb, curr_offset);
2648
2649         proto_tree_add_uint(tree, hf_ansi_a_cell_ci, tvb,
2650             curr_offset, 2, value);
2651
2652         curr_offset += 2;
2653
2654         g_snprintf(add_string, string_len, " - CI (%u)", value);
2655         break;
2656
2657     case 0x05:
2658         value = tvb_get_ntohs(tvb, curr_offset);
2659
2660         proto_tree_add_uint(tree, hf_ansi_a_cell_lac, tvb,
2661             curr_offset, 2, value);
2662
2663         curr_offset += 2;
2664
2665         g_snprintf(add_string, string_len, " - LAC (%u)", value);
2666         break;
2667
2668     case 0x07:
2669         market_id = tvb_get_ntohs(tvb, curr_offset);
2670         switch_num = tvb_get_guint8(tvb, curr_offset + 2);
2671
2672         value = tvb_get_ntoh24(tvb, curr_offset);
2673
2674         proto_tree_add_uint_format(tree, hf_ansi_a_cell_mscid, tvb,
2675             curr_offset, 3, value,
2676             "Market ID %u  Switch Number %u",
2677             market_id, switch_num);
2678
2679         curr_offset += 3;
2680
2681         value = tvb_get_ntohs(tvb, curr_offset);
2682
2683         proto_tree_add_uint(tree, hf_ansi_a_cell_ci, tvb,
2684             curr_offset, 2, value);
2685
2686         curr_offset += 2;
2687
2688         g_snprintf(add_string, string_len, " - Market ID (%u) Switch Number (%u) CI (%u)",
2689             market_id,
2690             switch_num,
2691             value);
2692         break;
2693
2694     default:
2695         proto_tree_add_text(tree, tvb, curr_offset, len,
2696             "Cell ID - Non IOS format");
2697
2698         curr_offset += len;
2699         break;
2700     }
2701
2702     return(curr_offset - offset);
2703 }
2704
2705 static guint8
2706 elem_cell_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
2707 {
2708     guint8      oct;
2709     guint32     curr_offset;
2710     const gchar *str = NULL;
2711
2712     curr_offset = offset;
2713
2714     oct = tvb_get_guint8(tvb, curr_offset);
2715
2716     if (oct >= (gint) NUM_CELL_DISC_STR)
2717     {
2718         str = "Unknown";
2719     }
2720     else
2721     {
2722         str = cell_disc_str[oct];
2723     }
2724
2725     proto_tree_add_text(tree,
2726         tvb, curr_offset, 1,
2727         "Cell Identification Discriminator: (%u) %s",
2728         oct,
2729         str);
2730
2731     curr_offset++;
2732
2733     curr_offset +=
2734         elem_cell_id_aux(tvb, tree, curr_offset, len - (curr_offset - offset), add_string, string_len, oct);
2735
2736     /* no length check possible */
2737
2738     return(curr_offset - offset);
2739 }
2740
2741 /*
2742  * IOS 6.2.2.21
2743  */
2744 static guint8
2745 elem_cell_id_list(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
2746 {
2747     guint8      oct;
2748     guint16     consumed;
2749     guint8      num_cells;
2750     guint32     curr_offset;
2751     proto_item  *item = NULL;
2752     proto_tree  *subtree = NULL;
2753     const gchar *str = NULL;
2754
2755     curr_offset = offset;
2756
2757     oct = tvb_get_guint8(tvb, curr_offset);
2758
2759     if (oct >= (gint) NUM_CELL_DISC_STR)
2760     {
2761         str = "Unknown";
2762     }
2763     else
2764     {
2765         str = cell_disc_str[oct];
2766     }
2767
2768     proto_tree_add_text(tree,
2769         tvb, curr_offset, 1,
2770         "Cell Identification Discriminator: (%u) %s",
2771         oct,
2772         str);
2773
2774     curr_offset++;
2775
2776     NO_MORE_DATA_CHECK(len);
2777
2778     num_cells = 0;
2779     do
2780     {
2781         item =
2782             proto_tree_add_text(tree,
2783                 tvb, curr_offset, -1,
2784                 "Cell [%u]",
2785                 num_cells + 1);
2786
2787         subtree = proto_item_add_subtree(item, ett_cell_list);
2788
2789         add_string[0] = '\0';
2790         consumed =
2791             elem_cell_id_aux(tvb, subtree, curr_offset, len - (curr_offset - offset), add_string, string_len, oct);
2792
2793         if (add_string[0] != '\0')
2794         {
2795             proto_item_append_text(item, "%s", add_string);
2796         }
2797
2798         proto_item_set_len(item, consumed);
2799
2800         curr_offset += consumed;
2801
2802         num_cells++;
2803     }
2804     while ((len - (curr_offset - offset)) > 0);
2805
2806     g_snprintf(add_string, string_len, " - %u cell%s",
2807         num_cells, plurality(num_cells, "", "s"));
2808
2809     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2810
2811     return(curr_offset - offset);
2812 }
2813
2814 /*
2815  * IOS 6.2.2.22
2816  */
2817 static guint8
2818 elem_cic(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string, int string_len)
2819 {
2820     guint32     value;
2821     guint32     curr_offset;
2822
2823     curr_offset = offset;
2824
2825     value = tvb_get_ntohs(tvb, curr_offset);
2826
2827     other_decode_bitfield_value(a_bigbuf, value, 0xffe0, 16);
2828     proto_tree_add_text(tree,
2829         tvb, curr_offset, 2,
2830         "%s :  PCM Multiplexer: %u",
2831         a_bigbuf,
2832         (value & 0xffe0) >> 5);
2833
2834     other_decode_bitfield_value(a_bigbuf, value, 0x001f, 16);
2835     proto_tree_add_text(tree,
2836         tvb, curr_offset, 2,
2837         "%s :  Timeslot: %u",
2838         a_bigbuf,
2839         value & 0x001f);
2840
2841     curr_offset += 2;
2842
2843     g_snprintf(add_string, string_len, " - (%u) (0x%04x)", value, value);
2844
2845     /* no length check possible */
2846
2847     return(curr_offset - offset);
2848 }
2849
2850 /*
2851  * IOS 6.2.2.23
2852  */
2853 static guint8
2854 elem_cic_ext(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string, int string_len)
2855 {
2856     guint8      oct;
2857     guint32     value;
2858     guint32     curr_offset;
2859     const gchar *str;
2860
2861     curr_offset = offset;
2862
2863     value = tvb_get_ntohs(tvb, curr_offset);
2864
2865     other_decode_bitfield_value(a_bigbuf, value, 0xffe0, 16);
2866     proto_tree_add_text(tree,
2867         tvb, curr_offset, 2,
2868         "%s :  PCM Multiplexer: %u",
2869         a_bigbuf,
2870         (value & 0xffe0) >> 5);
2871
2872     other_decode_bitfield_value(a_bigbuf, value, 0x001f, 16);
2873     proto_tree_add_text(tree,
2874         tvb, curr_offset, 2,
2875         "%s :  Timeslot: %u",
2876         a_bigbuf,
2877         value & 0x001f);
2878
2879     curr_offset += 2;
2880
2881     g_snprintf(add_string, string_len, " - (%u) (0x%04x)", value, value);
2882
2883     oct = tvb_get_guint8(tvb, curr_offset);
2884
2885     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
2886     proto_tree_add_text(tree,
2887         tvb, curr_offset, 1,
2888         "%s :  Reserved",
2889         a_bigbuf);
2890
2891     switch (oct & 0x0f)
2892     {
2893     case 0x00: str = "Full-rate"; break;
2894     default:
2895         str = "Reserved";
2896         break;
2897     }
2898
2899     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
2900     proto_tree_add_text(tree,
2901         tvb, curr_offset, 1,
2902         "%s :  Circuit Mode: %s",
2903         a_bigbuf,
2904         str);
2905
2906     curr_offset++;
2907
2908     /* no length check possible */
2909
2910     return(curr_offset - offset);
2911 }
2912
2913 /*
2914  * IOS 5 4.2.21
2915  */
2916 static guint8
2917 elem_ssci(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2918 {
2919     guint8      oct;
2920     guint32     curr_offset;
2921
2922     curr_offset = offset;
2923
2924     oct = tvb_get_guint8(tvb, curr_offset);
2925
2926     other_decode_bitfield_value(a_bigbuf, oct, 0xfc, 8);
2927     proto_tree_add_text(tree,
2928         tvb, curr_offset, 1,
2929         "%s :  Reserved",
2930         a_bigbuf);
2931
2932     other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
2933     proto_tree_add_text(tree,
2934         tvb, curr_offset, 1,
2935         "%s :  Mobile Originated Position Determination",
2936         a_bigbuf);
2937
2938     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
2939     proto_tree_add_text(tree,
2940         tvb, curr_offset, 1,
2941         "%s :  Global Emergency Call Indication",
2942         a_bigbuf);
2943
2944     curr_offset++;
2945
2946     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2947
2948     return(curr_offset - offset);
2949 }
2950
2951 /*
2952  * IOS 6.2.2.24
2953  * UNUSED
2954  */
2955
2956 #define ANSI_A_CELL_ID_LEN(_disc) ((_disc == 7) ? 5 : 2)
2957
2958 /*
2959  * IOS 6.2.2.25
2960  * Formats everything no length check
2961  */
2962 static guint8
2963 elem_downlink_re_aux(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
2964 {
2965     guint8      oct;
2966     guint8      disc;
2967     guint16     consumed;
2968     guint8      num_cells;
2969     guint8      curr_cell;
2970     guint32     value;
2971     guint32     curr_offset;
2972     proto_item  *item = NULL;
2973     proto_tree  *subtree = NULL;
2974     const gchar *str;
2975
2976     curr_offset = offset;
2977
2978     num_cells = tvb_get_guint8(tvb, curr_offset);
2979
2980     proto_tree_add_text(tree, tvb, curr_offset, 1,
2981         "Number of Cells: %u",
2982         num_cells);
2983
2984     curr_offset++;
2985
2986     NO_MORE_DATA_CHECK(len);
2987
2988     disc = tvb_get_guint8(tvb, curr_offset);
2989
2990     if (disc >= (gint) NUM_CELL_DISC_STR)
2991     {
2992         str = "Unknown";
2993     }
2994     else
2995     {
2996         str = cell_disc_str[disc];
2997     }
2998
2999     proto_tree_add_text(tree,
3000         tvb, curr_offset, 1,
3001         "Cell Identification Discriminator: (%u) %s",
3002         disc,
3003         str);
3004
3005     curr_offset++;
3006
3007     NO_MORE_DATA_CHECK(len);
3008
3009     SHORT_DATA_CHECK(len - (curr_offset - offset), (guint32) 3 + ANSI_A_CELL_ID_LEN(disc));
3010
3011     curr_cell = 0;
3012
3013     do
3014     {
3015         curr_cell++;
3016
3017         item =
3018             proto_tree_add_text(tree,
3019                 tvb, curr_offset, -1,
3020                 "Cell [%u]",
3021                 curr_cell);
3022
3023         subtree = proto_item_add_subtree(item, ett_cell_list);
3024
3025         add_string[0] = '\0';
3026         consumed =
3027             elem_cell_id_aux(tvb, subtree, curr_offset,
3028                 len - (curr_offset - offset), add_string, string_len, disc);
3029
3030         if (add_string[0] != '\0')
3031         {
3032             proto_item_append_text(item, "%s", add_string);
3033         }
3034
3035         proto_item_set_len(item, consumed);
3036
3037         curr_offset += consumed;
3038
3039         oct = tvb_get_guint8(tvb, curr_offset);
3040
3041         other_decode_bitfield_value(a_bigbuf, oct, 0xc0, 8);
3042         proto_tree_add_text(tree, tvb, curr_offset, 1,
3043             "%s :  Reserved",
3044             a_bigbuf);
3045
3046         other_decode_bitfield_value(a_bigbuf, oct, 0x3f, 8);
3047         proto_tree_add_text(tree, tvb, curr_offset, 1,
3048             "%s :  Downlink Signal Strength Raw: %u",
3049             a_bigbuf,
3050             oct & 0x3f);
3051
3052         curr_offset++;
3053
3054         value = tvb_get_ntohs(tvb, curr_offset);
3055
3056         proto_tree_add_text(tree,
3057             tvb, curr_offset, 2,
3058             "CDMA Target One Way Delay: %u",
3059             value);
3060
3061         curr_offset += 2;
3062     }
3063     while (curr_cell < num_cells);
3064
3065     g_snprintf(add_string, string_len, " - %u cell%s",
3066         num_cells, plurality(num_cells, "", "s"));
3067
3068     return(curr_offset - offset);
3069 }
3070
3071 /*
3072  * IOS 6.2.2.25
3073  */
3074 static guint8
3075 elem_downlink_re(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
3076 {
3077     guint32     curr_offset;
3078
3079     curr_offset = offset;
3080
3081     curr_offset +=
3082         elem_downlink_re_aux(tvb, tree, offset, len, add_string, string_len);
3083
3084     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3085
3086     return(curr_offset - offset);
3087 }
3088
3089 /*
3090  * IOS 6.2.2.140
3091  */
3092 static guint8
3093 elem_downlink_re_list(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
3094 {
3095     guint16     consumed;
3096     guint8      num_envs;
3097     guint8      oct_len;
3098     guint32     curr_offset;
3099     proto_item  *item = NULL;
3100     proto_tree  *subtree = NULL;
3101
3102     curr_offset = offset;
3103
3104     num_envs = 0;
3105
3106     while ((len - (curr_offset - offset)) > 0)
3107     {
3108         num_envs++;
3109
3110         item =
3111             proto_tree_add_text(tree,
3112                 tvb, curr_offset, -1,
3113                 "Environment [%u]",
3114                 num_envs);
3115
3116         subtree = proto_item_add_subtree(item, ett_re_list);
3117
3118         oct_len = tvb_get_guint8(tvb, curr_offset);
3119
3120         proto_tree_add_text(subtree,
3121             tvb, curr_offset, 1,
3122             "Environment Length: %u",
3123             oct_len);
3124
3125         curr_offset++;
3126
3127         add_string[0] = '\0';
3128         consumed =
3129             elem_downlink_re_aux(tvb, subtree, curr_offset, len - (curr_offset - offset), add_string, string_len);
3130
3131         if (add_string[0] != '\0')
3132         {
3133             proto_item_append_text(item, "%s", add_string);
3134         }
3135
3136         /*
3137          * +1 is for environment length
3138          */
3139         proto_item_set_len(item, consumed + 1);
3140
3141         curr_offset += consumed;
3142     }
3143
3144     g_snprintf(add_string, string_len, " - %u environment%s",
3145         num_envs, plurality(num_envs, "", "s"));
3146
3147     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3148
3149     return(curr_offset - offset);
3150 }
3151
3152 /*
3153  * IOS 6.2.2.26
3154  * UNUSED
3155  */
3156
3157 /*
3158  * IOS 6.2.2.27
3159  * UNUSED
3160  */
3161
3162 /*
3163  * IOS 6.2.2.28
3164  * UNUSED
3165  */
3166
3167 /*
3168  * IOS 6.2.2.29
3169  * UNUSED
3170  */
3171
3172 /*
3173  * IOS 6.2.2.30
3174  */
3175 static guint8
3176 elem_pdsn_ip_addr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
3177 {
3178     guint32     curr_offset;
3179
3180     curr_offset = offset;
3181
3182     proto_tree_add_item(tree, hf_ansi_a_pdsn_ip_addr, tvb, curr_offset, len, ENC_BIG_ENDIAN);
3183
3184     curr_offset += len;
3185
3186     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3187
3188     return(curr_offset - offset);
3189 }
3190
3191 /*
3192  * IOS 5 4.2.24
3193  */
3194 static guint8
3195 elem_s_pdsn_ip_addr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
3196 {
3197     guint32     curr_offset;
3198
3199     curr_offset = offset;
3200
3201     proto_tree_add_item(tree, hf_ansi_a_s_pdsn_ip_addr, tvb, curr_offset, len, ENC_BIG_ENDIAN);
3202
3203     curr_offset += len;
3204
3205     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3206
3207     return(curr_offset - offset);
3208 }
3209
3210 /*
3211  * IOS 6.2.2.31
3212  */
3213 static guint8
3214 elem_ho_pow_lev(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
3215 {
3216     guint8      oct;
3217     guint16     consumed;
3218     guint8      num_cells;
3219     proto_item  *item = NULL;
3220     proto_tree  *subtree = NULL;
3221     guint32     curr_offset;
3222
3223     curr_offset = offset;
3224
3225     oct = tvb_get_guint8(tvb, curr_offset);
3226
3227     proto_tree_add_text(tree, tvb, curr_offset, 1,
3228         "Number of Cells: %u",
3229         oct);
3230
3231     curr_offset++;
3232
3233     SHORT_DATA_CHECK(len - (curr_offset - offset), (guint32) 6);
3234
3235     oct = tvb_get_guint8(tvb, curr_offset);
3236
3237     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
3238     proto_tree_add_text(tree, tvb, curr_offset, 1,
3239         "%s :  Reserved",
3240         a_bigbuf);
3241
3242     other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
3243     proto_tree_add_text(tree, tvb, curr_offset, 1,
3244         "%s :  ID Type: %u",
3245         a_bigbuf,
3246         (oct & 0x60) >> 5);
3247
3248     other_decode_bitfield_value(a_bigbuf, oct, 0x1f, 8);
3249     proto_tree_add_text(tree, tvb, curr_offset, 1,
3250         "%s :  Handoff Power Level: %u",
3251         a_bigbuf,
3252         oct & 0x1f);
3253
3254     curr_offset++;
3255
3256     item =
3257         proto_tree_add_text(tree,
3258             tvb, curr_offset, -1,
3259             "Cell [1]");
3260
3261     subtree = proto_item_add_subtree(item, ett_cell_list);
3262
3263     add_string[0] = '\0';
3264     consumed =
3265         elem_cell_id_aux(tvb, subtree, curr_offset,
3266             len - (curr_offset - offset), add_string, string_len, 0x7);
3267
3268     if (add_string[0] != '\0')
3269     {
3270         proto_item_append_text(item, "%s", add_string);
3271     }
3272
3273     proto_item_set_len(item, consumed);
3274
3275     curr_offset += consumed;
3276
3277     num_cells = 1;
3278
3279     while ((len - (curr_offset - offset)) >= 3)
3280     {
3281         num_cells++;
3282
3283         oct = tvb_get_guint8(tvb, curr_offset);
3284
3285         other_decode_bitfield_value(a_bigbuf, oct, 0xe0, 8);
3286         proto_tree_add_text(tree, tvb, curr_offset, 1,
3287             "%s :  Reserved",
3288             a_bigbuf);
3289
3290         other_decode_bitfield_value(a_bigbuf, oct, 0x1f, 8);
3291         proto_tree_add_text(tree, tvb, curr_offset, 1,
3292             "%s :  Handoff Power Level: %u",
3293             a_bigbuf,
3294             oct & 0x1f);
3295
3296         curr_offset++;
3297
3298         item =
3299             proto_tree_add_text(tree,
3300                 tvb, curr_offset, -1,
3301                 "Cell [%u]",
3302                 num_cells);
3303
3304         subtree = proto_item_add_subtree(item, ett_cell_list);
3305
3306         add_string[0] = '\0';
3307         consumed =
3308             elem_cell_id_aux(tvb, subtree, curr_offset,
3309                 len - (curr_offset - offset), add_string, string_len, 0x2);
3310
3311         if (add_string[0] != '\0')
3312         {
3313             proto_item_append_text(item, "%s", add_string);
3314         }
3315
3316         proto_item_set_len(item, consumed);
3317
3318         curr_offset += consumed;
3319     }
3320
3321     g_snprintf(add_string, string_len, " - %u cell%s",
3322         num_cells, plurality(num_cells, "", "s"));
3323
3324     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3325
3326     return(curr_offset - offset);
3327 }
3328
3329 /*
3330  * IOS 6.2.2.32
3331  */
3332 static guint8
3333 elem_uz_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
3334 {
3335     guint32     value;
3336     guint32     curr_offset;
3337
3338     curr_offset = offset;
3339
3340     value = tvb_get_ntohs(tvb, curr_offset);
3341
3342     proto_tree_add_text(tree, tvb, curr_offset, 2,
3343         "UZID: %u",
3344         value);
3345
3346     curr_offset += 2;
3347
3348     g_snprintf(add_string, string_len, " - (%u)", value);
3349
3350     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3351
3352     return(curr_offset - offset);
3353 }
3354
3355 /*
3356  * IOS 6.2.2.33
3357  * UNUSED
3358  */
3359
3360 /*
3361  * IOS 5 4.2.77
3362  */
3363 static guint8
3364 elem_info_rec_req(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
3365 {
3366     guint8      rec_type;
3367     guint8      num_recs;
3368     guint32     curr_offset;
3369     const gchar *str;
3370     gint        idx;
3371
3372     curr_offset = offset;
3373
3374     num_recs = 0;
3375
3376     while ((len - (curr_offset - offset)) > 0)
3377     {
3378         num_recs++;
3379
3380         rec_type = tvb_get_guint8(tvb, curr_offset);
3381
3382         str = match_strval_idx((guint32) rec_type, ansi_rev_ms_info_rec_str, &idx);
3383
3384         if (str == NULL)
3385         {
3386             str = "Reserved";
3387         }
3388
3389         proto_tree_add_text(tree,
3390             tvb, curr_offset, 1,
3391             "Information Record Type - %u: (%u) %s",
3392             num_recs,
3393             rec_type,
3394             str);
3395
3396         curr_offset++;
3397     }
3398
3399     g_snprintf(add_string, string_len, " - %u request%s",
3400         num_recs, plurality(num_recs, "", "s"));
3401
3402     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3403
3404     return(curr_offset - offset);
3405 }
3406
3407 /*
3408  * IOS 6.2.2.34
3409  */
3410 static guint8
3411 elem_is2000_chan_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
3412 {
3413     guint8      oct;
3414     guint8      num_chan;
3415     guint32     value;
3416     guint32     curr_offset;
3417     const gchar *str;
3418
3419     curr_offset = offset;
3420
3421     oct = tvb_get_guint8(tvb, curr_offset);
3422
3423     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
3424     proto_tree_add_text(tree, tvb, curr_offset, 1,
3425         "%s :  OTD: Mobile will %sbe using OTD",
3426         a_bigbuf,
3427         (oct & 0x80) ? "" : "not ");
3428
3429     num_chan = (oct & 0x70) >> 4;
3430
3431     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
3432     proto_tree_add_text(tree, tvb, curr_offset, 1,
3433         "%s :  Channel Count: %u",
3434         a_bigbuf,
3435         num_chan);
3436
3437     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
3438     proto_tree_add_text(tree, tvb, curr_offset, 1,
3439         "%s :  Frame Offset: (%u), %.2f ms",
3440         a_bigbuf,
3441         oct & 0x0f,
3442         (oct & 0x0f) * 1.25);
3443
3444     curr_offset++;
3445
3446     NO_MORE_DATA_CHECK(len);
3447
3448     SHORT_DATA_CHECK(len - (curr_offset - offset), 6);
3449
3450     do
3451     {
3452         oct = tvb_get_guint8(tvb, curr_offset);
3453
3454         switch (oct)
3455         {
3456         case 0x01: str = "Fundamental Channel (FCH) TIA/EIA/IS-2000"; break;
3457         case 0x02: str = "Dedicated Control Channel (DCCH) TIA/EIA/IS-2000"; break;
3458         case 0x03: str = "Supplemental Channel (SCH) TIA/EIA/IS-2000"; break;
3459         default:
3460             if ((oct >= 0x80) && (oct <= 0x9f)) { str = "Reserved for UMTS"; }
3461             else { str = "Reserved"; }
3462             break;
3463         }
3464
3465         proto_tree_add_text(tree, tvb, curr_offset, 1,
3466             "Physical Channel Type: %s",
3467             str);
3468
3469         curr_offset++;
3470
3471         oct = tvb_get_guint8(tvb, curr_offset);
3472
3473         switch (global_a_variant)
3474         {
3475         case A_VARIANT_IOS401:
3476             other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
3477             proto_tree_add_text(tree, tvb, curr_offset, 1,
3478                 "%s :  Reserved",
3479                 a_bigbuf);
3480             break;
3481
3482         case A_VARIANT_IOS501:
3483             other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
3484             proto_tree_add_text(tree, tvb, curr_offset, 1,
3485                 "%s :  Rev_FCH_Gating",
3486                 a_bigbuf);
3487             break;
3488         }
3489
3490         switch ((oct & 0x60) >> 5)
3491         {
3492         case 0: str = "Gating rate 1"; break;
3493         case 1: str = "Gating rate 1/2"; break;
3494         case 2: str = "Gating rate 1/4"; break;
3495         default:
3496             str = "Reserved";
3497             break;
3498         }
3499
3500         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
3501         proto_tree_add_text(tree, tvb, curr_offset, 1,
3502             "%s :  Pilot Gating Rate: %s",
3503             a_bigbuf,
3504             str);
3505
3506         other_decode_bitfield_value(a_bigbuf, oct, 0x18, 8);
3507         proto_tree_add_text(tree, tvb, curr_offset, 1,
3508             "%s :  QOF Mask",
3509             a_bigbuf);
3510
3511         value = tvb_get_guint8(tvb, curr_offset + 1);
3512
3513         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
3514         proto_tree_add_text(tree, tvb, curr_offset, 1,
3515             "%s :  Walsh Code Channel Index (MSB): %u",
3516             a_bigbuf,
3517             ((guint32) (oct & 0x07) << 8) | value);
3518
3519         curr_offset++;
3520
3521         other_decode_bitfield_value(a_bigbuf, value, 0xff, 8);
3522         proto_tree_add_text(tree, tvb, curr_offset, 1,
3523             "%s :  Walsh Code Channel Index (LSB)",
3524             a_bigbuf);
3525
3526         curr_offset++;
3527
3528         oct = tvb_get_guint8(tvb, curr_offset);
3529
3530         other_decode_bitfield_value(a_bigbuf, oct, 0xff, 8);
3531         proto_tree_add_text(tree, tvb, curr_offset, 1,
3532             "%s :  Pilot PN Code (LSB)",
3533             a_bigbuf);
3534
3535         curr_offset++;
3536
3537         value = oct;
3538         oct = tvb_get_guint8(tvb, curr_offset);
3539         value |= ((guint32) (oct & 0x80)) << 1;
3540
3541         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
3542         proto_tree_add_text(tree, tvb, curr_offset, 1,
3543             "%s :  Pilot PN Code (MSB): %u",
3544             a_bigbuf,
3545             value);
3546
3547         switch (global_a_variant)
3548         {
3549         case A_VARIANT_IOS401:
3550             other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
3551             proto_tree_add_text(tree, tvb, curr_offset, 1,
3552                 "%s :  Reserved",
3553                 a_bigbuf);
3554             break;
3555
3556         case A_VARIANT_IOS501:
3557             other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
3558             proto_tree_add_text(tree, tvb, curr_offset, 1,
3559                 "%s :  Reserved",
3560                 a_bigbuf);
3561
3562             other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
3563             proto_tree_add_text(tree, tvb, curr_offset, 1,
3564                 "%s :  Power Combined",
3565                 a_bigbuf);
3566             break;
3567         }
3568
3569         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
3570         proto_tree_add_text(tree, tvb, curr_offset, 1,
3571             "%s :  Frequency Included",
3572             a_bigbuf);
3573
3574         value = tvb_get_guint8(tvb, curr_offset + 1) | ((oct & 0x07) << 8);
3575
3576         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
3577         proto_tree_add_text(tree, tvb, curr_offset, 1,
3578             "%s :  ARFCN (MSB): %u",
3579             a_bigbuf,
3580             value);
3581
3582         curr_offset++;
3583
3584         other_decode_bitfield_value(a_bigbuf, value & 0x00ff, 0xff, 8);
3585         proto_tree_add_text(tree, tvb, curr_offset, 1,
3586             "%s :  ARFCN (LSB)",
3587             a_bigbuf);
3588
3589         curr_offset++;
3590     }
3591     while ((len - (curr_offset - offset)) >= 6);
3592
3593     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3594
3595     return(curr_offset - offset);
3596 }
3597
3598 /*
3599  * IOS 6.2.2.35
3600  * NO ASSOCIATED DATA
3601  */
3602
3603 /*
3604  * IOS 6.2.2.36
3605  */
3606 static guint8
3607 elem_is95_ms_meas_chan_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
3608 {
3609     guint8      oct;
3610     guint32     value;
3611     gint        temp_int;
3612     guint32     curr_offset;
3613     const gchar *str;
3614
3615     curr_offset = offset;
3616
3617     oct = tvb_get_guint8(tvb, curr_offset);
3618
3619     temp_int = (oct & 0xf8) >> 3;
3620     if ((temp_int < 0) || (temp_int >= (gint) NUM_BAND_CLASS_STR))
3621     {
3622         str = "Reserved";
3623     }
3624     else
3625     {
3626         str = band_class_str[temp_int];
3627     }
3628
3629     other_decode_bitfield_value(a_bigbuf, oct, 0xf8, 8);
3630     proto_tree_add_text(tree,
3631         tvb, curr_offset, 1,
3632         "%s :  Band Class: %s",
3633         a_bigbuf,
3634         str);
3635
3636     value = tvb_get_guint8(tvb, curr_offset + 1) | ((oct & 0x07) << 8);
3637
3638     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
3639     proto_tree_add_text(tree, tvb, curr_offset, 1,
3640         "%s :  ARFCN (MSB): %u",
3641         a_bigbuf,
3642         value);
3643
3644     curr_offset++;
3645
3646     other_decode_bitfield_value(a_bigbuf, value & 0x00ff, 0xff, 8);
3647     proto_tree_add_text(tree, tvb, curr_offset, 1,
3648         "%s :  ARFCN (LSB)",
3649         a_bigbuf);
3650
3651     g_snprintf(add_string, string_len, " - (ARFCN: %u)", value);
3652
3653     curr_offset++;
3654
3655     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3656
3657     return(curr_offset - offset);
3658 }
3659
3660 /*
3661  * IOS 6.2.2.37
3662  */
3663 static guint8
3664 elem_clg_party_ascii_num(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
3665 {
3666     guint8      oct;
3667     guint32     curr_offset;
3668     guint8      *poctets;
3669     const gchar *str;
3670
3671     curr_offset = offset;
3672
3673     oct = tvb_get_guint8(tvb, curr_offset);
3674
3675     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
3676     proto_tree_add_text(tree, tvb, curr_offset, 1,
3677         "%s :  Extension: %s",
3678         a_bigbuf,
3679         (oct & 0x80) ? "Not extended" : "Extended");
3680
3681     switch ((oct & 0x70) >> 4)
3682     {
3683     case 0: str = "Unknown"; break;
3684     case 1: str = "International number"; break;
3685     case 2: str = "National number"; break;
3686     case 3: str = "Network-specific number"; break;
3687     case 4: str = "Dedicated PAD access, short code"; break;
3688     case 5: str = "Reserved"; break;
3689     case 6: str = "Reserved"; break;
3690     default:
3691         str = "Reserved for extension";
3692         break;
3693     }
3694
3695     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
3696     proto_tree_add_text(tree, tvb, curr_offset, 1,
3697         "%s :  Type of Number: %s",
3698         a_bigbuf,
3699         str);
3700
3701     switch (oct & 0x0f)
3702     {
3703     case 0x00: str = "Unknown"; break;
3704     case 0x01: str = "ISDN/Telephony Numbering (ITU recommendation E.164/E.163)"; break;
3705     case 0x03: str = "Data Numbering (ITU-T Rec. X.121)"; break;
3706     case 0x04: str = "Telex Numbering (ITU-T Rec. F.69)"; break;
3707     case 0x07: str = "Reserved for extension"; break;
3708     case 0x08: str = "National Numbering"; break;
3709     case 0x09: str = "Private Numbering"; break;
3710     default:
3711         str = "Reserved";
3712         break;
3713     }
3714
3715     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
3716     proto_tree_add_text(tree, tvb, curr_offset, 1,
3717         "%s :  Number Plan Identification: %s",
3718         a_bigbuf,
3719         str);
3720
3721     curr_offset++;
3722
3723     if (!(oct & 0x80))
3724     {
3725         /* octet 3a */
3726
3727         oct = tvb_get_guint8(tvb, curr_offset);
3728
3729         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
3730         proto_tree_add_text(tree, tvb, curr_offset, 1,
3731             "%s :  Extension",
3732             a_bigbuf);
3733
3734         switch ((oct & 0x60) >> 5)
3735         {
3736         case 0: str = "Presentation allowed"; break;
3737         case 1: str = "Presentation restricted"; break;
3738         case 2: str = "Number not available due to interworking"; break;
3739         default:
3740             str = "Reserved";
3741             break;
3742         }
3743
3744         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
3745         proto_tree_add_text(tree, tvb, curr_offset, 1,
3746             "%s :  Presentation Indicator: %s",
3747             a_bigbuf,
3748             str);
3749
3750         switch (oct & 0x03)
3751         {
3752         case 0: str = "User-provided, not screened"; break;
3753         case 1: str = "User-provided, verified and passed"; break;
3754         case 2: str = "User-provided, verified and failed"; break;
3755         default:
3756             str = "Network-provided";
3757             break;
3758         }
3759
3760         other_decode_bitfield_value(a_bigbuf, oct, 0x1c, 8);
3761         proto_tree_add_text(tree, tvb, curr_offset, 1,
3762             "%s :  Reserved",
3763             a_bigbuf);
3764
3765         other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
3766         proto_tree_add_text(tree, tvb, curr_offset, 1,
3767             "%s :  Screening Indicator: %s",
3768             a_bigbuf,
3769             str);
3770
3771         curr_offset++;
3772     }
3773
3774     poctets = tvb_get_ephemeral_string(tvb, curr_offset, len - (curr_offset - offset));
3775
3776     proto_tree_add_string_format(tree, hf_ansi_a_clg_party_ascii_num,
3777         tvb, curr_offset, len - (curr_offset - offset),
3778         (gchar *) poctets,
3779         "Digits: %s",
3780         (gchar *) format_text(poctets, len - (curr_offset - offset)));
3781
3782     curr_offset += len - (curr_offset - offset);
3783
3784     g_snprintf(add_string, string_len, " - (%s)", poctets);
3785
3786     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3787
3788     return(curr_offset - offset);
3789 }
3790
3791 /*
3792  * IOS 6.2.2.38
3793  */
3794 static guint8
3795 elem_l3_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
3796 {
3797     guint32     curr_offset;
3798     tvbuff_t    *l3_tvb;
3799
3800     curr_offset = offset;
3801
3802     proto_tree_add_text(tree, tvb, curr_offset, len,
3803         "Layer 3 Information");
3804
3805     /*
3806      * dissect the embedded DTAP message
3807      */
3808     l3_tvb = tvb_new_subset(tvb, curr_offset, len, len);
3809
3810     call_dissector(dtap_handle, l3_tvb, pinfo, g_tree);
3811
3812     curr_offset += len;
3813
3814     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3815
3816     return(curr_offset - offset);
3817 }
3818
3819 /*
3820  * IOS 6.2.2.39
3821  * Protocol Discriminator
3822  */
3823
3824 /*
3825  * IOS 6.2.2.40
3826  * Reserved Octet
3827  */
3828
3829 /*
3830  * IOS 6.2.2.41
3831  * Location Updating Type
3832  * UNUSED in SPEC!
3833  */
3834
3835 /*
3836  * IOS 6.2.2.42
3837  * Simple data no decode required
3838  */
3839
3840 /*
3841  * IOS 6.2.2.43
3842  */
3843 static guint8
3844 elem_lai(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3845 {
3846     guint8      oct;
3847     guint16     value;
3848     guint32     curr_offset;
3849     gchar       mcc[4];
3850     gchar       mnc[4];
3851
3852     curr_offset = offset;
3853
3854     oct = tvb_get_guint8(tvb, curr_offset);
3855
3856     mcc[0] = Dgt_tbcd.out[oct & 0x0f];
3857     mcc[1] = Dgt_tbcd.out[(oct & 0xf0) >> 4];
3858
3859     oct = tvb_get_guint8(tvb, curr_offset+1);
3860
3861     mcc[2] = Dgt_tbcd.out[(oct & 0x0f)];
3862     mcc[3] = '\0';
3863
3864     mnc[2] = Dgt_tbcd.out[(oct & 0xf0) >> 4];
3865
3866     oct = tvb_get_guint8(tvb, curr_offset+2);
3867
3868     mnc[0] = Dgt_tbcd.out[(oct & 0x0f)];
3869     mnc[1] = Dgt_tbcd.out[(oct & 0xf0) >> 4];
3870     mnc[3] = '\0';
3871
3872     proto_tree_add_text(tree,
3873         tvb, curr_offset, 3,
3874         "Mobile Country Code (MCC): %s, Mobile Network Code (MNC): %s",
3875         mcc,
3876         mnc);
3877
3878     curr_offset += 3;
3879
3880     value = tvb_get_ntohs(tvb, curr_offset);
3881
3882     proto_tree_add_text(tree,
3883         tvb, curr_offset, 2,
3884         "Location Area Code (LAC): 0x%04x (%u)",
3885         value,
3886         value);
3887
3888     curr_offset += 2;
3889
3890     /* no length check possible */
3891
3892     return(curr_offset - offset);
3893 }
3894
3895 /*
3896  * IOS 6.2.2.44
3897  */
3898 static guint8
3899 elem_rej_cause(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string, int string_len)
3900 {
3901     guint8      oct;
3902     guint32     curr_offset;
3903     const gchar *str;
3904
3905     curr_offset = offset;
3906
3907     oct = tvb_get_guint8(tvb, curr_offset);
3908
3909     switch (oct)
3910     {
3911     case 0x01: str = "Reserved"; break;
3912     case 0x02: str = "MIN/IMSI unknown in HLR"; break;
3913     case 0x03: str = "Illegal MS"; break;
3914     case 0x04: str = "TMSI/IMSI/MIN unknown in VLR"; break;
3915     case 0x05: str = "Reserved"; break;
3916     case 0x0b: str = "Roaming not allowed"; break;
3917     case 0x0c: str = "Location area not allowed"; break;
3918     case 0x20: str = "Service option not supported"; break;
3919     case 0x21: str = "Requested service option not subscribed"; break;
3920     case 0x22: str = "Service option temporarily out of order"; break;
3921     case 0x26: str = "Call cannot be identified"; break;
3922     case 0x51: str = "Network failure"; break;
3923     case 0x56: str = "Congestion"; break;
3924     case 0x62: str = "Message type non-existent or not implemented"; break;
3925     case 0x63: str = "Information element non-existent or not implemented"; break;
3926     case 0x64: str = "Invalid information element contents"; break;
3927     case 0x65: str = "Message not compatible with the call state"; break;
3928     case 0x66: str = "Protocol error, unspecified"; break;
3929     case 0x6e: str = "Invalid message, unspecified"; break;
3930     case 0x6f: str = "Mandatory information element error"; break;
3931     default:
3932         str = "Reserved";
3933         break;
3934     }
3935
3936     proto_tree_add_text(tree,
3937         tvb, curr_offset, 1,
3938         "Reject Cause Value: (%u) %s",
3939         oct,
3940         str);
3941
3942     curr_offset++;
3943
3944     g_snprintf(add_string, string_len, " - (%s)", str);
3945
3946     /* no length check possible */
3947
3948     return(curr_offset - offset);
3949 }
3950
3951 /*
3952  * IOS 5 4.2.78
3953  */
3954 static guint8
3955 elem_anchor_pdsn_addr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
3956 {
3957     guint32     curr_offset;
3958
3959     curr_offset = offset;
3960
3961     proto_tree_add_item(tree, hf_ansi_a_anchor_ip_addr, tvb, curr_offset, len, ENC_BIG_ENDIAN);
3962
3963     curr_offset += len;
3964
3965     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3966
3967     return(curr_offset - offset);
3968 }
3969
3970 /*
3971  * IOS 5 4.2.80
3972  */
3973 static guint8
3974 elem_anchor_pp_addr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
3975 {
3976     guint32     curr_offset;
3977
3978     curr_offset = offset;
3979
3980     proto_tree_add_item(tree, hf_ansi_a_anchor_pp_ip_addr, tvb, curr_offset, len, ENC_BIG_ENDIAN);
3981
3982     curr_offset += len;
3983
3984     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3985
3986     return(curr_offset - offset);
3987 }
3988
3989 /*
3990  * IOS 6.2.2.45
3991  */
3992 static guint8
3993 elem_auth_chlg_param(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
3994 {
3995     guint8      oct;
3996     guint32     curr_offset;
3997     const gchar *str;
3998
3999     curr_offset = offset;
4000
4001     oct = tvb_get_guint8(tvb, curr_offset);
4002
4003     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
4004     proto_tree_add_text(tree,
4005         tvb, curr_offset, 1,
4006         "%s :  Reserved",
4007         a_bigbuf);
4008
4009     switch (oct & 0x0f)
4010     {
4011     case 1: str = "RAND 32 bits"; break;
4012     case 2: str = "RANDU 24 bits"; break;
4013     case 4: str = "RANDSSD 56 bits"; break;
4014     case 8: str = "RANDBS 32 bits"; break;
4015     default:
4016         str = "Reserved";
4017         break;
4018     }
4019
4020     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
4021     proto_tree_add_text(tree,
4022         tvb, curr_offset, 1,
4023         "%s :  Random Number Type: (%u) %s",
4024         a_bigbuf,
4025         oct & 0x0f,
4026         str);
4027
4028     curr_offset++;
4029
4030     proto_tree_add_text(tree,
4031         tvb, curr_offset, len - (curr_offset - offset),
4032         "RAND/RANDU/RANDBS/RANDSSD Value");
4033
4034     g_snprintf(add_string, string_len, " - (%s)", str);
4035
4036     curr_offset += len - (curr_offset - offset);
4037
4038     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
4039
4040     return(curr_offset - offset);
4041 }
4042
4043 /*
4044  * IOS 6.2.2.46
4045  */
4046 static guint8
4047 elem_auth_resp_param(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
4048 {
4049     guint8      oct;
4050     guint32     curr_offset;
4051     const gchar *str;
4052
4053     curr_offset = offset;
4054
4055     oct = tvb_get_guint8(tvb, curr_offset);
4056
4057     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
4058     proto_tree_add_text(tree,
4059         tvb, curr_offset, 1,
4060         "%s :  Reserved",
4061         a_bigbuf);
4062
4063     switch (oct & 0x0f)
4064     {
4065     case 1: str = "AUTHR"; break;
4066     case 2: str = "AUTHU"; break;
4067     case 4: str = "AUTHBS"; break;
4068     default:
4069         str = "Reserved";
4070         break;
4071     }
4072
4073     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
4074     proto_tree_add_text(tree,
4075         tvb, curr_offset, 1,
4076         "%s :  Auth Signature Type: (%u) %s",
4077         a_bigbuf,
4078         oct & 0x0f,
4079         str);
4080
4081     curr_offset++;
4082
4083     proto_tree_add_text(tree,
4084         tvb, curr_offset, len - (curr_offset - offset),
4085         "Auth Signature");
4086
4087     g_snprintf(add_string, string_len, " - (%s)", str);
4088
4089     curr_offset += len - (curr_offset - offset);
4090
4091     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
4092
4093     return(curr_offset - offset);
4094 }
4095
4096 /*
4097  * IOS 6.2.2.47
4098  */
4099 static guint8
4100 elem_auth_param_count(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string, int string_len)
4101 {
4102     guint8      oct;
4103     guint32     curr_offset;
4104
4105     curr_offset = offset;
4106
4107     oct = tvb_get_guint8(tvb, curr_offset);
4108
4109     other_decode_bitfield_value(a_bigbuf, oct, 0xc0, 8);
4110     proto_tree_add_text(tree,
4111         tvb, curr_offset, 1,
4112         "%s :  Reserved",
4113         a_bigbuf);
4114
4115     other_decode_bitfield_value(a_bigbuf, oct, 0x3f, 8);
4116     proto_tree_add_text(tree,
4117         tvb, curr_offset, 1,
4118         "%s :  Count: %u",
4119         a_bigbuf,
4120         oct & 0x3f);
4121
4122     curr_offset++;
4123
4124     g_snprintf(add_string, string_len, " - (%u)", oct & 0x3f);
4125
4126     /* no length check possible */
4127
4128     return(curr_offset - offset);
4129 }
4130
4131 /*
4132  * IOS 6.2.2.48
4133  */
4134 static guint8
4135 elem_mwi(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string, int string_len)
4136 {
4137     guint8      oct;
4138     guint32     curr_offset;
4139
4140     curr_offset = offset;
4141
4142     oct = tvb_get_guint8(tvb, curr_offset);
4143
4144     proto_tree_add_text(tree,
4145         tvb, curr_offset, 1,
4146         "Number of Messages: %u",
4147         oct);
4148
4149     curr_offset++;
4150
4151     g_snprintf(add_string, string_len, " - (%u)", oct);
4152
4153     /* no length check possible */
4154
4155     return(curr_offset - offset);
4156 }
4157
4158 /*
4159  * IOS 6.2.2.49
4160  * Progress
4161  * UNUSED in SPEC and no IEI!
4162  */
4163
4164 /*
4165  * IOS 6.2.2.50
4166  */
4167 static guint8
4168 elem_signal(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string, int string_len)
4169 {
4170     guint8      oct;
4171     guint32     curr_offset;
4172     const gchar *str;
4173
4174     curr_offset = offset;
4175
4176     oct = tvb_get_guint8(tvb, curr_offset);
4177
4178     switch (oct)
4179     {
4180     case 0x00: str = "Dial tone on"; break;
4181     case 0x01: str = "Ring back tone on"; break;
4182     case 0x02: str = "Intercept tone on"; break;
4183     case 0x03: str = "Network congestion (reorder) tone on"; break;
4184     case 0x04: str = "Busy tone on"; break;
4185     case 0x05: str = "Confirm tone on"; break;
4186     case 0x06: str = "Answer tone on"; break;
4187     case 0x07: str = "Call waiting tone on"; break;
4188     case 0x08: str = "Off-hook warning tone on"; break;
4189     case 0x3f: str = "Tones off"; break;
4190     case 0x40: str = "Normal Alerting"; break;
4191     case 0x41: str = "Inter-group Alerting"; break;
4192     case 0x42: str = "Special/Priority Alerting"; break;
4193     case 0x43: str = "Reserved (ISDN Alerting pattern 3)"; break;
4194     case 0x44: str = "Ping Ring (abbreviated alert)"; break;
4195     case 0x45: str = "Reserved (ISDN Alerting pattern 5)"; break;
4196     case 0x46: str = "Reserved (ISDN Alerting pattern 6)"; break;
4197     case 0x47: str = "Reserved (ISDN Alerting pattern 7)"; break;
4198     case 0x63: str = "Abbreviated intercept"; break;
4199     case 0x65: str = "Abbreviated reorder"; break;
4200     case 0x4f: str = "Alerting off"; break;
4201     default:
4202         str = "Unknown";
4203         break;
4204     }
4205
4206     proto_tree_add_text(tree,
4207         tvb, curr_offset, 1,
4208         "Signal Value: (%u) %s",
4209         oct,
4210         str);
4211
4212     g_snprintf(add_string, string_len, " - (%s)", str);
4213
4214     curr_offset++;
4215
4216     oct = tvb_get_guint8(tvb, curr_offset);
4217
4218     other_decode_bitfield_value(a_bigbuf, oct, 0xfc, 8);
4219     proto_tree_add_text(tree,
4220         tvb, curr_offset, 1,
4221         "%s :  Reserved",
4222         a_bigbuf);
4223
4224     switch (oct & 0x03)
4225     {
4226     case 0: str = "Medium pitch (standard alert)"; break;
4227     case 1: str = "High pitch"; break;
4228     case 2: str = "Low pitch"; break;
4229     default:
4230         str = "Reserved";
4231         break;
4232     }
4233
4234     proto_tree_add_text(tree,
4235         tvb, curr_offset, 1,
4236         "%s : Alert Pitch: %s",
4237         a_bigbuf,
4238         str);
4239
4240     curr_offset++;
4241
4242     /* no length check possible */
4243
4244     return(curr_offset - offset);
4245 }
4246
4247 /*
4248  * IOS 6.2.2.51
4249  * CM Service Type
4250  */
4251
4252 /*
4253  * IOS 6.2.2.52
4254  */
4255 static guint8
4256 elem_cld_party_bcd_num(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
4257 {
4258     guint8      oct;
4259     guint8      *poctets;
4260     guint32     curr_offset;
4261     const gchar *str;
4262
4263     curr_offset = offset;
4264
4265     oct = tvb_get_guint8(tvb, curr_offset);
4266
4267     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
4268     proto_tree_add_text(tree,
4269         tvb, curr_offset, 1,
4270         "%s :  Extension",
4271         a_bigbuf);
4272
4273     switch ((oct & 0x70) >> 4)
4274     {
4275     case 0: str = "Unknown"; break;
4276     case 1: str = "International number"; break;
4277     case 2: str = "National number"; break;
4278     case 3: str = "Network specific number"; break;
4279     case 4: str = "Dedicated PAD access, short code"; break;
4280     case 7: str = "Reserved for extension"; break;
4281     default:
4282         str = "Reserved";
4283         break;
4284     }
4285
4286     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
4287     proto_tree_add_text(tree,
4288         tvb, curr_offset, 1,
4289         "%s :  Type of Number: %s",
4290         a_bigbuf,
4291         str);
4292
4293     switch (oct & 0x0f)
4294     {
4295     case 0x00: str = "Unknown"; break;
4296     case 0x01: str = "ISDN/telephony number plan (ITU recommendation E.164/E.163)"; break;
4297     case 0x03: str = "Data number plan (ITU recommendation X.121)"; break;
4298     case 0x04: str = "Telex numbering plan (ITU recommendation F.69)"; break;
4299     case 0x07: str = "Reserved for extension"; break;
4300     case 0x08: str = "National numbering plan"; break;
4301     case 0x09: str = "Private numbering plan"; break;
4302     default:
4303         str = "Reserved";
4304         break;
4305     }
4306
4307     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
4308     proto_tree_add_text(tree,
4309         tvb, curr_offset, 1,
4310         "%s :  Numbering Plan Identification: %s",
4311         a_bigbuf,
4312         str);
4313
4314     curr_offset++;
4315
4316     poctets = tvb_get_ephemeral_string(tvb, curr_offset, len - (curr_offset - offset));
4317
4318     my_dgt_tbcd_unpack(a_bigbuf, poctets, len - (curr_offset - offset),
4319         &Dgt_tbcd);
4320
4321     proto_tree_add_string_format(tree, hf_ansi_a_cld_party_bcd_num,
4322         tvb, curr_offset, len - (curr_offset - offset),
4323         a_bigbuf,
4324         "BCD Digits: %s",
4325         a_bigbuf);
4326
4327     g_snprintf(add_string, string_len, " - (%s)", a_bigbuf);
4328
4329     curr_offset += len - (curr_offset - offset);
4330
4331     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
4332
4333     return(curr_offset - offset);
4334 }
4335
4336 /*
4337  * IOS 6.2.2.53
4338  * UNUSED in SPEC and no IEI!
4339  */
4340 #ifdef MAYBE_USED_FOR_OLDER_CODECS
4341 static guint8
4342 elem_clg_party_bcd_num(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
4343 {
4344     guint8      oct;
4345     guint8      *poctets;
4346     guint32     curr_offset;
4347     const gchar *str;
4348
4349     curr_offset = offset;
4350
4351     oct = tvb_get_guint8(tvb, curr_offset);
4352
4353     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
4354     proto_tree_add_text(tree, tvb, curr_offset, 1,
4355         "%s :  Extension: %s",
4356         a_bigbuf,
4357         (oct & 0x80) ? "Not extended" : "Extended");
4358
4359     switch ((oct & 0x70) >> 4)
4360     {
4361     case 0: str = "Unknown"; break;
4362     case 1: str = "International number"; break;
4363     case 2: str = "National number"; break;
4364     case 3: str = "Network specific number"; break;
4365     case 4: str = "Dedicated PAD access, short code"; break;
4366     case 7: str = "Reserved for extension"; break;
4367     default:
4368         str = "Reserved";
4369         break;
4370     }
4371
4372     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
4373     proto_tree_add_text(tree,
4374         tvb, curr_offset, 1,
4375         "%s :  Type of Number: %s",
4376         a_bigbuf,
4377         str);
4378
4379     switch (oct & 0x0f)
4380     {
4381     case 0x00: str = "Unknown"; break;
4382     case 0x01: str = "ISDN/telephony number plan (ITU recommendation E.164/E.163)"; break;
4383     case 0x03: str = "Data number plan (ITU recommendation X.121)"; break;
4384     case 0x04: str = "Telex numbering plan (ITU recommendation F.69)"; break;
4385     case 0x07: str = "Reserved for extension"; break;
4386     case 0x08: str = "National numbering plan"; break;
4387     case 0x09: str = "Private numbering plan"; break;
4388     default:
4389         str = "Reserved";
4390         break;
4391     }
4392
4393     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
4394     proto_tree_add_text(tree,
4395         tvb, curr_offset, 1,
4396         "%s :  Numbering Plan Identification: %s",
4397         a_bigbuf,
4398         str);
4399
4400     curr_offset++;
4401
4402     if (!(oct & 0x80))
4403     {
4404         /* octet 3a */
4405
4406         oct = tvb_get_guint8(tvb, curr_offset);
4407
4408         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
4409         proto_tree_add_text(tree, tvb, curr_offset, 1,
4410             "%s :  Extension",
4411             a_bigbuf);
4412
4413         switch ((oct & 0x60) >> 5)
4414         {
4415         case 0: str = "Presentation allowed"; break;
4416         case 1: str = "Presentation restricted"; break;
4417         case 2: str = "Number not available due to interworking"; break;
4418         default:
4419             str = "Reserved";
4420             break;
4421         }
4422
4423         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
4424         proto_tree_add_text(tree, tvb, curr_offset, 1,
4425             "%s :  Presentation Indicator: %s",
4426             a_bigbuf,
4427             str);
4428
4429         switch (oct & 0x03)
4430         {
4431         case 0: str = "User-provided, not screened"; break;
4432         case 1: str = "User-provided, verified and passed"; break;
4433         case 2: str = "User-provided, verified and failed"; break;
4434         default:
4435             str = "Network-provided";
4436             break;
4437         }
4438
4439         other_decode_bitfield_value(a_bigbuf, oct, 0x1c, 8);
4440         proto_tree_add_text(tree, tvb, curr_offset, 1,
4441             "%s :  Reserved",
4442             a_bigbuf);
4443
4444         other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
4445         proto_tree_add_text(tree, tvb, curr_offset, 1,
4446             "%s :  Screening Indicator: %s",
4447             a_bigbuf,
4448             str);
4449
4450         curr_offset++;
4451     }
4452
4453     poctets = tvb_get_ephemeral_string(tvb, curr_offset, len - (curr_offset - offset));
4454
4455     my_dgt_tbcd_unpack(a_bigbuf, poctets, len - (curr_offset - offset),
4456         &Dgt_tbcd);
4457
4458     proto_tree_add_string_format(tree, hf_ansi_a_clg_party_bcd_num,
4459         tvb, curr_offset, len - (curr_offset - offset),
4460         a_bigbuf,
4461         "BCD Digits: %s",
4462         a_bigbuf);
4463
4464     g_snprintf(add_string, string_len, " - (%s)", a_bigbuf);
4465
4466     curr_offset += len - (curr_offset - offset);
4467
4468     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
4469
4470     return(curr_offset - offset);
4471 }
4472 #endif
4473
4474 /*
4475  * IOS 6.2.2.54
4476  */
4477 static guint8
4478 elem_qos_params(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
4479 {
4480     guint8      oct;
4481     guint32     curr_offset;
4482
4483     curr_offset = offset;
4484
4485     oct = tvb_get_guint8(tvb, curr_offset);
4486
4487     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
4488     proto_tree_add_text(tree,
4489         tvb, curr_offset, 1,
4490         "%s :  Reserved",
4491         a_bigbuf);
4492
4493     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
4494     proto_tree_add_text(tree,
4495         tvb, curr_offset, 1,
4496         "%s :  Packet Priority: %u",
4497         a_bigbuf,
4498         oct & 0x0f);
4499
4500     g_snprintf(add_string, string_len, " - (%u)", oct & 0x0f);
4501
4502     curr_offset++;
4503
4504     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
4505
4506     return(curr_offset - offset);
4507 }
4508
4509 /*
4510  * IOS 6.2.2.55
4511  */
4512 static guint8
4513 elem_cause_l3(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
4514 {
4515     guint8      oct;
4516     guint32     curr_offset;
4517     const gchar *str = NULL;
4518
4519     curr_offset = offset;
4520
4521     oct = tvb_get_guint8(tvb, curr_offset);
4522
4523     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
4524     proto_tree_add_text(tree,
4525         tvb, curr_offset, 1,
4526         "%s :  Extension",
4527         a_bigbuf);
4528
4529     switch ((oct & 0x60) >> 5)
4530     {
4531     case 0: str = "Standard as described in ITU Recommendation Q.931"; break;
4532     case 1: str = "Reserved for other international standards"; break;
4533     case 2: str = "National standard"; break;
4534     default:
4535         str = "Reserved for other international standards";
4536         break;
4537     }
4538
4539     other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
4540     proto_tree_add_text(tree,
4541         tvb, curr_offset, 1,
4542         "%s :  Coding Standard: %s",
4543         a_bigbuf,
4544         str);
4545
4546     other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
4547     proto_tree_add_text(tree,
4548         tvb, curr_offset, 1,
4549         "%s :  Reserved",
4550         a_bigbuf);
4551
4552     switch (oct & 0x0f)
4553     {
4554     case 0: str = "User"; break;
4555     case 1: str = "Private network serving the local user"; break;
4556     case 2: str = "Public network serving the local user"; break;
4557     case 3: str = "Transit network"; break;
4558     case 4: str = "Public network serving the remote user"; break;
4559     case 5: str = "Private network serving the remote user"; break;
4560     case 7: str = "International network"; break;
4561     case 10: str = "Network beyond interworking point"; break;
4562     default:
4563         str = "Reserved";
4564         break;
4565     }
4566
4567     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
4568     proto_tree_add_text(tree,
4569         tvb, curr_offset, 1,
4570         "%s :  Location: %s",
4571         a_bigbuf,
4572         str);
4573
4574     curr_offset++;
4575
4576     oct = tvb_get_guint8(tvb, curr_offset);
4577
4578     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
4579     proto_tree_add_text(tree,
4580         tvb, curr_offset, 1,
4581         "%s :  Extension",
4582         a_bigbuf);
4583
4584     switch ((oct & 0x70) >> 4)
4585     {
4586     case 0: str = "normal event"; break;
4587     case 1: str = "normal event"; break;
4588     case 2: str = "resource unavailable"; break;
4589     case 3: str = "service or option not available"; break;
4590     case 4: str = "service or option not implemented"; break;
4591     case 5: str = "invalid message (e.g., parameter out of range)"; break;
4592     case 6: str = "protocol error (e.g., unknown message)"; break;
4593     default:
4594         str = "interworking";
4595         break;
4596     }
4597
4598     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
4599     proto_tree_add_text(tree,
4600         tvb, curr_offset, 1,
4601         "%s :  Class: (%u) %s",
4602         a_bigbuf,
4603         (oct & 0x70) >> 4,
4604         str);
4605
4606     switch (oct & 0x7f)
4607     {
4608     case 0x01: str = "Unassigned (unallocated) number"; break;
4609     case 0x03: str = "No route to destination"; break;
4610     case 0x06: str = "Channel unacceptable"; break;
4611     case 0x0F: str = "Procedure failed"; break;
4612     case 0x10: str = "Normal Clearing"; break;
4613     case 0x11: str = "User busy"; break;
4614     case 0x12: str = "No user responding"; break;
4615     case 0x13: str = "User alerting, no answer"; break;
4616     case 0x15: str = "Call rejected"; break;
4617     case 0x16: str = "Number changed New destination"; break;
4618     case 0x1A: str = "Non selected user clearing"; break;
4619     case 0x1B: str = "Destination out of order"; break;
4620     case 0x1C: str = "Invalid number format (incomplete number)"; break;
4621     case 0x1D: str = "Facility rejected"; break;
4622     case 0x1F: str = "Normal, unspecified"; break;
4623     case 0x22: str = "No circuit/channel available"; break;
4624     case 0x26: str = "Network out of order"; break;
4625     case 0x29: str = "Temporary failure"; break;
4626     case 0x2A: str = "Switching equipment congestion"; break;
4627     case 0x2B: str = "Access information discarded information element ids"; break;
4628     case 0x2C: str = "requested circuit/channel not available"; break;
4629     case 0x2F: str = "Resources unavailable, unspecified"; break;
4630     case 0x31: str = "Quality of service unavailable"; break;
4631     case 0x32: str = "Requested facility not subscribed"; break;
4632     case 0x33: str = "Request MUX option or rates unavailable"; break;
4633     case 0x39: str = "Bearer capability not authorized"; break;
4634     case 0x3A: str = "Bearer capability not presently available"; break;
4635     case 0x3B: str = "SSD Update Rejected"; break;
4636     case 0x3F: str = "Service or option not available, unspecified"; break;
4637     case 0x41: str = "Bearer service not implemented"; break;
4638     case 0x45: str = "Requested facility not implement"; break;
4639     case 0x46: str = "Only restricted digital information bearer capability is available"; break;
4640     case 0x4F: str = "Service or option not implemented, unspecified"; break;
4641     case 0x51: str = "Reserved"; break;
4642     case 0x58: str = "Incompatible destination incompatible parameter"; break;
4643     case 0x5B: str = "Invalid transit network selection"; break;
4644     case 0x5F: str = "Invalid message, unspecified"; break;
4645     case 0x60: str = "Mandatory information element error information element identifier(s)"; break;
4646     case 0x61: str = "Message type nonexistent or not implemented message type"; break;
4647     case 0x62: str = "Message not compatible with control state message type or message type nonexistent or not implemented"; break;
4648     case 0x64: str = "Invalid information element contents Information element Identifier(s)"; break;
4649     case 0x65: str = "Message not compatible with call state message type"; break;
4650     case 0x6F: str = "Protocol error, unspecified"; break;
4651     case 0x7F: str = "Interworking, unspecified"; break;
4652     default:
4653         str = "Reserved";
4654         break;
4655     }
4656
4657     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
4658     proto_tree_add_text(tree,
4659         tvb, curr_offset, 1,
4660         "%s :  Value: (%u)",
4661         a_bigbuf,
4662         oct & 0x0f);
4663
4664     g_snprintf(add_string, string_len, " - (%u) %s", oct & 0x7f, str);
4665
4666     curr_offset++;
4667
4668     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
4669
4670     return(curr_offset - offset);
4671 }
4672
4673 /*
4674  * IOS 6.2.2.56
4675  * A3/A7
4676  */
4677
4678 /*
4679  * IOS 6.2.2.57
4680  * A3/A7
4681  */
4682
4683 /*
4684  * IOS 6.2.2.58
4685  */
4686 static guint8
4687 elem_xmode(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
4688 {
4689     guint8      oct;
4690     guint32     curr_offset;
4691
4692     curr_offset = offset;
4693
4694     oct = tvb_get_guint8(tvb, curr_offset);
4695
4696     other_decode_bitfield_value(a_bigbuf, oct, 0xfe, 8);
4697     proto_tree_add_text(tree,
4698         tvb, curr_offset, 1,
4699         "%s :  Reserved",
4700         a_bigbuf);
4701
4702     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
4703     proto_tree_add_text(tree,
4704         tvb, curr_offset, 1,
4705         "%s :  TFO Mode: %s",
4706         a_bigbuf,
4707         (oct & 0x01) ? "TFO" : "tandem");
4708
4709     g_snprintf(add_string, string_len, " - (%s)",
4710         (oct & 0x01) ? "TFO" : "tandem");
4711
4712     curr_offset++;
4713
4714     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
4715
4716     return(curr_offset - offset);
4717 }
4718
4719 /*
4720  * IOS 6.2.2.59
4721  * UNUSED
4722  */
4723
4724 /*
4725  * IOS 6.2.2.60
4726  * NO ASSOCIATED DATA
4727  */
4728
4729 /*
4730  * IOS 6.2.2.61
4731  */
4732 static guint8
4733 elem_reg_type(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string, int string_len)
4734 {
4735     guint8      oct;
4736     guint32     curr_offset;
4737     const gchar *str;
4738
4739     curr_offset = offset;
4740
4741     oct = tvb_get_guint8(tvb, curr_offset);
4742
4743     switch (oct)
4744     {
4745     case 0x00: str = "Timer-based"; break;
4746     case 0x01: str = "Power-up"; break;
4747     case 0x02: str = "Zone-based"; break;
4748     case 0x03: str = "Power-down"; break;
4749     case 0x04: str = "Parameter-change"; break;
4750     case 0x05: str = "Ordered"; break;
4751     case 0x06: str = "Distance-based"; break;
4752     case 0x07: str = "User Zone-based"; break;
4753     case 0x09: str = "BCMC Registration"; break;
4754     default:
4755         str = "Reserved";
4756         break;
4757     }
4758
4759     proto_tree_add_text(tree,
4760         tvb, curr_offset, 1,
4761         "Location Registration Type: %s",
4762         str);
4763
4764     g_snprintf(add_string, string_len, " - (%s)", str);
4765
4766     curr_offset++;
4767
4768     /* no length check possible */
4769
4770     return(curr_offset - offset);
4771 }
4772
4773 /*
4774  * IOS 6.2.2.62
4775  */
4776 static guint8
4777 elem_tag(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string, int string_len)
4778 {
4779     guint32     value;
4780     guint32     curr_offset;
4781
4782     curr_offset = offset;
4783
4784     value = tvb_get_ntohl(tvb, curr_offset);
4785
4786     proto_tree_add_text(tree,
4787         tvb, curr_offset, 4,
4788         "Tag Value: %u",
4789         value);
4790
4791     g_snprintf(add_string, string_len, " - (%u)", value);
4792
4793     curr_offset += 4;
4794
4795     /* no length check possible */
4796
4797     return(curr_offset - offset);
4798 }
4799
4800 /*
4801  * IOS 6.2.2.63
4802  */
4803 static guint8
4804 elem_hho_params(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string, int string_len)
4805 {
4806     guint8      oct;
4807     gint        temp_int;
4808     guint32     curr_offset;
4809     const gchar *str;
4810
4811     curr_offset = offset;
4812
4813     oct = tvb_get_guint8(tvb, curr_offset);
4814
4815     other_decode_bitfield_value(a_bigbuf, oct, 0xe0, 8);
4816     proto_tree_add_text(tree,
4817         tvb, curr_offset, 1,
4818         "%s :  Reserved",
4819         a_bigbuf);
4820
4821     temp_int = oct & 0x1f;
4822     if ((temp_int < 0) || (temp_int >= (gint) NUM_BAND_CLASS_STR))
4823     {
4824         str = "Reserved";
4825     }
4826     else
4827     {
4828         str = band_class_str[temp_int];
4829     }
4830
4831     other_decode_bitfield_value(a_bigbuf, oct, 0x1f, 8);
4832     proto_tree_add_text(tree,
4833         tvb, curr_offset, 1,
4834         "%s :  Band Class: %s",
4835         a_bigbuf,
4836         str);
4837
4838     curr_offset++;
4839
4840     g_snprintf(add_string, string_len, " - (%s)", str);
4841
4842     oct = tvb_get_guint8(tvb, curr_offset);
4843
4844     other_decode_bitfield_value(a_bigbuf, oct, 0xe0, 8);
4845     proto_tree_add_text(tree,
4846         tvb, curr_offset, 1,
4847         "%s :  Number of Preamble Frames: %u",
4848         a_bigbuf,
4849         (oct & 0xe0) >> 5);
4850
4851     other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
4852     proto_tree_add_text(tree,
4853         tvb, curr_offset, 1,
4854         "%s :  Reset L2: %s Layer 2 Acknowledgement",
4855         a_bigbuf,
4856         (oct & 0x10) ? "Reset" : "Do not reset");
4857
4858     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
4859     proto_tree_add_text(tree,
4860         tvb, curr_offset, 1,
4861         "%s :  Reset FPC: %s counters",
4862         a_bigbuf,
4863         (oct & 0x10) ? "Reset" : "Do not reset");
4864
4865     switch ((oct & 0x06) >> 1)
4866     {
4867     case 0: str = "Encryption disabled"; break;
4868     case 1: str = "Encryption enabled"; break;
4869     default:
4870         str = "Unknown";
4871         break;
4872     }
4873
4874     other_decode_bitfield_value(a_bigbuf, oct, 0x06, 8);
4875     proto_tree_add_text(tree,
4876         tvb, curr_offset, 1,
4877         "%s :  Encryption Mode: %s",
4878         a_bigbuf,
4879         str);
4880
4881     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
4882     proto_tree_add_text(tree,
4883         tvb, curr_offset, 1,
4884         "%s :  Private LCM: %s Private Long Code Mask",
4885         a_bigbuf,
4886         (oct & 0x01) ? "Use" : "Do not use");
4887
4888     curr_offset++;
4889
4890     oct = tvb_get_guint8(tvb, curr_offset);
4891
4892     switch (global_a_variant)
4893     {
4894     case A_VARIANT_IOS401:
4895         other_decode_bitfield_value(a_bigbuf, oct, 0xe0, 8);
4896         proto_tree_add_text(tree,
4897             tvb, curr_offset, 1,
4898             "%s :  Reserved",
4899             a_bigbuf);
4900         break;
4901
4902     case A_VARIANT_IOS501:
4903         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
4904         proto_tree_add_text(tree,
4905             tvb, curr_offset, 1,
4906             "%s :  Rev_Pwr_Cntl_Delay_Incl",
4907             a_bigbuf);
4908
4909         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
4910         proto_tree_add_text(tree, tvb, curr_offset, 1,
4911             "%s :  Rev_Pwr_Cntl_Delay",
4912             a_bigbuf);
4913         break;
4914     }
4915
4916     other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
4917     proto_tree_add_text(tree,
4918         tvb, curr_offset, 1,
4919         "%s :  Nom_Pwr_Ext",
4920         a_bigbuf);
4921
4922     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
4923     proto_tree_add_text(tree,
4924         tvb, curr_offset, 1,
4925         "%s :  Nom_Pwr: %u",
4926         a_bigbuf,
4927         oct & 0x0f);
4928
4929     curr_offset++;
4930
4931     oct = tvb_get_guint8(tvb, curr_offset);
4932
4933     other_decode_bitfield_value(a_bigbuf, oct, 0xc0, 8);
4934     proto_tree_add_text(tree,
4935         tvb, curr_offset, 1,
4936         "%s :  Reserved",
4937         a_bigbuf);
4938
4939     other_decode_bitfield_value(a_bigbuf, oct, 0x3e, 8);
4940     proto_tree_add_text(tree,
4941         tvb, curr_offset, 1,
4942         "%s :  FPC Subchannel Information: %u",
4943         a_bigbuf,
4944         (oct & 0x3e) >> 1);
4945
4946     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
4947     proto_tree_add_text(tree,
4948         tvb, curr_offset, 1,
4949         "%s :  FPC Subchannel Information Included",
4950         a_bigbuf);
4951
4952     curr_offset++;
4953
4954     oct = tvb_get_guint8(tvb, curr_offset);
4955
4956     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
4957     proto_tree_add_text(tree,
4958         tvb, curr_offset, 1,
4959         "%s :  Reserved",
4960         a_bigbuf);
4961
4962     other_decode_bitfield_value(a_bigbuf, oct, 0x0e, 8);
4963     proto_tree_add_text(tree,
4964         tvb, curr_offset, 1,
4965         "%s :  Power Control Step: %u",
4966         a_bigbuf,
4967         (oct & 0x0e) >> 1);
4968
4969     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
4970     proto_tree_add_text(tree,
4971         tvb, curr_offset, 1,
4972         "%s :  Power Control Step Included",
4973         a_bigbuf);
4974
4975     curr_offset++;
4976
4977     /* no length check possible */
4978
4979     return(curr_offset - offset);
4980 }
4981
4982 /*
4983  * IOS 6.2.2.64
4984  * UNUSED
4985  */
4986
4987 /*
4988  * IOS 6.2.2.65
4989  */
4990 static guint8
4991 elem_sw_ver(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
4992 {
4993     guint8      major, minor, point;
4994     guint32     curr_offset;
4995
4996     curr_offset = offset;
4997
4998     major = tvb_get_guint8(tvb, curr_offset);
4999
5000     proto_tree_add_text(tree,
5001         tvb, curr_offset, 1,
5002         "IOS Major Revision Level: %u",
5003         major);
5004
5005     curr_offset++;
5006
5007     minor = tvb_get_guint8(tvb, curr_offset);
5008
5009     proto_tree_add_text(tree,
5010         tvb, curr_offset, 1,
5011         "IOS Minor Revision Level: %u",
5012         minor);
5013
5014     curr_offset++;
5015
5016     point = tvb_get_guint8(tvb, curr_offset);
5017
5018     proto_tree_add_text(tree,
5019         tvb, curr_offset, 1,
5020         "IOS Point Revision Level: %u",
5021         point);
5022
5023     curr_offset++;
5024
5025     g_snprintf(add_string, string_len, " - (IOS %u.%u.%u)", major, minor, point);
5026
5027     if (len > 3)
5028     {
5029         proto_tree_add_text(tree, tvb, curr_offset, len - 3,
5030             "Manufacturer/Carrier Software Information");
5031
5032         curr_offset += len - 3;
5033     }
5034
5035     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5036
5037     return(curr_offset - offset);
5038 }
5039
5040 /*
5041  * IOS 6.2.2.66
5042  */
5043 static guint8
5044 elem_so(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string, int string_len)
5045 {
5046     guint16     value;
5047     guint32     curr_offset;
5048
5049     curr_offset = offset;
5050
5051     value = tvb_get_ntohs(tvb, curr_offset);
5052
5053     other_decode_bitfield_value(a_bigbuf, value, 0x8000, 16);
5054     proto_tree_add_text(tree,
5055         tvb, curr_offset, 2,
5056         "%s :  Proprietary Indicator",
5057         a_bigbuf);
5058
5059     other_decode_bitfield_value(a_bigbuf, value, 0x7000, 16);
5060     proto_tree_add_text(tree,
5061         tvb, curr_offset, 2,
5062         "%s :  Service Option Revision",
5063         a_bigbuf);
5064
5065     other_decode_bitfield_value(a_bigbuf, value, 0x0fff, 16);
5066     proto_tree_add_text(tree,
5067         tvb, curr_offset, 2,
5068         "%s :  Base Service Option Number",
5069         a_bigbuf);
5070
5071     g_snprintf(add_string, string_len, " - (%u) (0x%04x)", value, value);
5072
5073     proto_tree_add_uint_format(tree, hf_ansi_a_so, tvb,
5074         curr_offset, 2, value,
5075         "%s %s",
5076         &add_string[3],
5077         ansi_a_so_int_to_str(value));
5078
5079     curr_offset += 2;
5080
5081     /* no length check possible */
5082
5083     return(curr_offset - offset);
5084 }
5085
5086 /*
5087  * IOS 5 4.2.73
5088  */
5089 static guint8
5090 elem_soci(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
5091 {
5092     guint8      oct;
5093     guint32     curr_offset;
5094
5095     curr_offset = offset;
5096
5097     oct = tvb_get_guint8(tvb, curr_offset);
5098
5099     other_decode_bitfield_value(a_bigbuf, oct, 0xf8, 8);
5100     proto_tree_add_text(tree,
5101         tvb, curr_offset, 1,
5102         "%s :  Reserved",
5103         a_bigbuf);
5104
5105     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
5106     proto_tree_add_text(tree,
5107         tvb, curr_offset, 1,
5108         "%s :  SOCI: %u",
5109         a_bigbuf,
5110         oct & 0x07);
5111
5112     g_snprintf(add_string, string_len, " - (%u)", oct);
5113
5114     curr_offset++;
5115
5116     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5117
5118     return(curr_offset - offset);
5119 }
5120
5121 /*
5122  * IOS 5 4.2.74
5123  */
5124 static guint8
5125 elem_so_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
5126 {
5127     guint8      oct;
5128     guint8      num_so;
5129     guint8      inst;
5130     guint32     curr_offset;
5131     proto_item  *item;
5132     proto_tree  *subtree;
5133
5134     curr_offset = offset;
5135
5136     num_so = tvb_get_guint8(tvb, curr_offset);
5137
5138     proto_tree_add_text(tree, tvb, curr_offset, 1,
5139         "Number of Service Option instances: %u",
5140         num_so);
5141
5142     /*
5143      * this is in case we leave the function before the
5144      * loop through the instances
5145      */
5146     g_snprintf(add_string, string_len, " - %u service options", num_so);
5147
5148     curr_offset++;
5149
5150     NO_MORE_DATA_CHECK(len);
5151
5152     SHORT_DATA_CHECK(len - (curr_offset - offset), 3);
5153
5154     inst = 1;
5155
5156     do
5157     {
5158         item =
5159             proto_tree_add_text(tree,
5160                 tvb, curr_offset, 1,
5161                 "Service Option Instance [%u]",
5162                 inst);
5163
5164         subtree = proto_item_add_subtree(item, ett_so_list);
5165
5166         oct = tvb_get_guint8(tvb, curr_offset);
5167
5168         other_decode_bitfield_value(a_bigbuf, oct, 0xc0, 8);
5169         proto_tree_add_text(subtree,
5170             tvb, curr_offset, 1,
5171             "%s :  Reserved",
5172             a_bigbuf);
5173
5174         other_decode_bitfield_value(a_bigbuf, oct, 0x38, 8);
5175         proto_tree_add_text(subtree,
5176             tvb, curr_offset, 1,
5177             "%s :  SR_ID: %u",
5178             a_bigbuf,
5179             (oct & 0x38) >> 3);
5180
5181         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
5182         proto_tree_add_text(subtree,
5183             tvb, curr_offset, 1,
5184             "%s :  SOCI: %u",
5185             a_bigbuf,
5186             oct & 0x07);
5187
5188         curr_offset++;
5189
5190         curr_offset += elem_so(tvb, pinfo, subtree, curr_offset, len, add_string, string_len);
5191         add_string[0] = '\0';
5192
5193         inst++;
5194     }
5195     while ((len - (curr_offset - offset)) >= 3);
5196
5197     /*
5198      * this is because 'add_string' was used by 'elem_so()'
5199      */
5200     g_snprintf(add_string, string_len, " - %u service options", num_so);
5201
5202     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5203
5204     return(curr_offset - offset);
5205 }
5206
5207 /*
5208  * IOS 5 4.2.70
5209  */
5210 static guint8
5211 elem_acc_net_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
5212 {
5213     guint32     value;
5214     guint32     sid, nid, pzid;
5215     guint32     curr_offset;
5216
5217     curr_offset = offset;
5218
5219     value = tvb_get_ntohs(tvb, curr_offset);
5220     sid = value & 0x7fff;
5221
5222     other_decode_bitfield_value(a_bigbuf, value >> 8, 0x80, 8);
5223     proto_tree_add_text(tree, tvb, curr_offset, 1,
5224         "%s :  Reserved",
5225         a_bigbuf);
5226
5227     other_decode_bitfield_value(a_bigbuf, value >> 8, 0x7f, 8);
5228     proto_tree_add_text(tree, tvb, curr_offset, 1,
5229         "%s :  SID (MSB), %u",
5230         a_bigbuf,
5231         sid);
5232
5233     other_decode_bitfield_value(a_bigbuf, value & 0x00ff, 0xff, 8);
5234     proto_tree_add_text(tree, tvb, curr_offset + 1, 1,
5235         "%s :  SID (LSB)",
5236         a_bigbuf);
5237
5238     curr_offset += 2;
5239
5240     nid = tvb_get_ntohs(tvb, curr_offset);
5241
5242     proto_tree_add_text(tree,
5243         tvb, curr_offset, 2,
5244         "NID: %u",
5245         nid);
5246
5247     curr_offset += 2;
5248
5249     pzid = tvb_get_ntohs(tvb, curr_offset);
5250
5251     proto_tree_add_text(tree,
5252         tvb, curr_offset, 2,
5253         "PZID: %u",
5254         pzid);
5255
5256     curr_offset += 2;
5257
5258     g_snprintf(add_string, string_len, " - (SID/NID/PZID: %u/%u/%u)", sid, nid, pzid);
5259
5260     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5261
5262     return(curr_offset - offset);
5263 }
5264
5265
5266 #define ADDS_APP_UNKNOWN        0x00
5267 #define ADDS_APP_ADS            0x01
5268 #define ADDS_APP_FAX            0x02
5269 #define ADDS_APP_SMS            0x03
5270 #define ADDS_APP_OTA            0x04
5271 #define ADDS_APP_PDS            0x05            /* aka PLD */
5272 #define ADDS_APP_SDB            0x06
5273 #define ADDS_APP_HRPD           0x07
5274 #define ADDS_APP_EXT_INTL       0x3E
5275 #define ADDS_APP_EXT            0x3F
5276
5277 static const value_string ansi_a_adds_strings[] = {
5278     { ADDS_APP_UNKNOWN,         "UNKNOWN" },
5279     { ADDS_APP_ADS,             "ADS" },
5280     { ADDS_APP_FAX,             "FAX" },
5281     { ADDS_APP_SMS,             "SMS" },
5282     { ADDS_APP_OTA,             "OTA" },
5283     { ADDS_APP_PDS,             "PDS" },
5284     { ADDS_APP_SDB,             "SDB" },
5285     { ADDS_APP_HRPD,            "HRPD" },
5286     { ADDS_APP_EXT_INTL,        "EXT_INTL" },
5287     { ADDS_APP_EXT,             "EXT" },
5288     { 0,                        NULL}
5289 };
5290
5291 /*
5292  * IOS 6.2.2.67
5293  */
5294 static guint8
5295 elem_adds_user_part(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
5296 {
5297     guint8      oct;
5298     guint32     value;
5299     guint8      adds_app;
5300     guint32     curr_offset;
5301     const gchar *str;
5302     tvbuff_t    *adds_tvb;
5303     gint        idx;
5304     proto_tree  *subtree;
5305     proto_item  *item;
5306
5307     curr_offset = offset;
5308     adds_app = 0;
5309
5310     oct = tvb_get_guint8(tvb, curr_offset);
5311
5312     other_decode_bitfield_value(a_bigbuf, oct, 0xc0, 8);
5313     proto_tree_add_text(tree,
5314         tvb, curr_offset, 1,
5315         "%s :  Reserved",
5316         a_bigbuf);
5317
5318     adds_app = oct & 0x3f;
5319
5320     str = match_strval_idx((guint32) adds_app, ansi_a_adds_strings, &idx);
5321     if (str == NULL)
5322     {
5323         str = "Reserved";
5324     }
5325     g_snprintf(add_string, string_len, " - (%s)", str);
5326
5327     other_decode_bitfield_value(a_bigbuf, oct, 0x3f, 8);
5328     proto_tree_add_text(tree,
5329         tvb, curr_offset, 1,
5330         "%s :  Data Burst Type: %s",
5331         a_bigbuf,
5332         str);
5333
5334     curr_offset++;
5335
5336     item =
5337         proto_tree_add_text(tree, tvb, curr_offset, len - 1,
5338             "Application Data Message");
5339
5340     subtree = proto_item_add_subtree(item, ett_adds_user_part);
5341
5342     switch (adds_app)
5343     {
5344     case ADDS_APP_SMS:
5345         adds_tvb = tvb_new_subset(tvb, curr_offset, len - 1, len - 1);
5346
5347         dissector_try_uint(is637_dissector_table,
5348             0, adds_tvb, pinfo, g_tree);
5349
5350         curr_offset += (len - 1);
5351         break;
5352
5353     case ADDS_APP_OTA:
5354         adds_tvb = tvb_new_subset(tvb, curr_offset, len - 1, len - 1);
5355
5356         dissector_try_uint(is683_dissector_table,
5357             (pinfo->p2p_dir == P2P_DIR_RECV), adds_tvb, pinfo, g_tree);
5358
5359         curr_offset += (len - 1);
5360         break;
5361
5362     case ADDS_APP_PDS:
5363         adds_tvb = tvb_new_subset(tvb, curr_offset, len - 1, len - 1);
5364
5365         dissector_try_uint(is801_dissector_table,
5366             (pinfo->p2p_dir == P2P_DIR_RECV), adds_tvb, pinfo, g_tree);
5367
5368         curr_offset += (len - 1);
5369         break;
5370
5371     case ADDS_APP_SDB:
5372         /*
5373          * no SDB dissector, push to GRE/A11 dissector ?
5374          */
5375         curr_offset += (len - 1);
5376         break;
5377
5378     case ADDS_APP_EXT_INTL:
5379         /*
5380          * no generic External International dissector
5381          */
5382         value = tvb_get_ntohs(tvb, curr_offset);
5383
5384         proto_tree_add_text(subtree,
5385             tvb, curr_offset, 2,
5386             "Extended Burst Type - International: 0x%04x", value);
5387
5388         curr_offset += 2;
5389
5390         proto_tree_add_text(tree, tvb, curr_offset, len - (curr_offset - offset),
5391             "Data");
5392
5393         curr_offset += len - (curr_offset - offset);
5394         break;
5395
5396     case ADDS_APP_EXT:
5397         value = tvb_get_ntohs(tvb, curr_offset);
5398
5399         proto_tree_add_text(subtree,
5400             tvb, curr_offset, 2,
5401             "Extended Burst Type: 0x%04x", value);
5402
5403         curr_offset += 2;
5404
5405         proto_tree_add_text(subtree, tvb, curr_offset, len - (curr_offset - offset),
5406             "Data");
5407
5408         curr_offset += len - (curr_offset - offset);
5409         break;
5410
5411     default:
5412         /*
5413          * no sub-dissectors
5414          */
5415         curr_offset += (len - 1);
5416         break;
5417     }
5418
5419     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5420
5421     return(curr_offset - offset);
5422 }
5423
5424 /*
5425  * IOS 5 4.2.75
5426  */
5427 static guint8
5428 elem_amps_hho_param(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
5429 {
5430     guint8      oct;
5431     guint32     curr_offset;
5432
5433     curr_offset = offset;
5434
5435     oct = tvb_get_guint8(tvb, curr_offset);
5436
5437     other_decode_bitfield_value(a_bigbuf, oct, 0xfc, 8);
5438     proto_tree_add_text(tree, tvb, curr_offset, 1,
5439         "%s :  Reserved",
5440         a_bigbuf);
5441
5442     other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
5443     proto_tree_add_text(tree, tvb, curr_offset, 1,
5444         "%s :  Encryption Mode: (%u) %s",
5445         a_bigbuf,
5446         oct & 0x03,
5447         (oct & 0x03) ? "enabled" : "disabled");
5448
5449     curr_offset++;
5450
5451     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5452
5453     return(curr_offset - offset);
5454 }
5455
5456 /*
5457  * IOS 6.2.2.68
5458  */
5459 static guint8
5460 elem_is2000_scr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
5461 {
5462     guint8      oct, num_con_rec, i;
5463     guint8      bit_mask, bit_offset;
5464     guint32     curr_offset, saved_offset;
5465     guint32     value;
5466     guint       is2000_portion_len;
5467     proto_tree  *scr_subtree, *subtree;
5468     proto_item  *item = NULL;
5469     const gchar *str = NULL;
5470
5471     curr_offset = offset;
5472
5473     oct = tvb_get_guint8(tvb, curr_offset);
5474
5475     other_decode_bitfield_value(a_bigbuf, oct, 0xf8, 8);
5476     proto_tree_add_text(tree, tvb, curr_offset, 1,
5477         "%s :  Reserved",
5478         a_bigbuf);
5479
5480     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
5481     proto_tree_add_text(tree, tvb, curr_offset, 1,
5482         "%s :  Bit-Exact Length Fill Bits: %u",
5483         a_bigbuf,
5484         oct & 0x07);
5485
5486     curr_offset++;
5487
5488     is2000_portion_len = len - (curr_offset - offset);
5489
5490     /*
5491      * the following decode was modified from the packet-ansi_map.c version
5492      */
5493
5494     SHORT_DATA_CHECK(is2000_portion_len, 7);
5495
5496     saved_offset = curr_offset;
5497
5498     item =
5499         proto_tree_add_text(tree, tvb, curr_offset,
5500             is2000_portion_len,
5501             "IS-2000 Service Configuration Record Content");
5502
5503     scr_subtree =
5504         proto_item_add_subtree(item, ett_scr);
5505
5506     proto_tree_add_text(scr_subtree, tvb,
5507         curr_offset, 2,
5508         "FOR_MUX_OPTION:  Forward Traffic Channel multiplex option");
5509
5510     curr_offset += 2;
5511
5512     proto_tree_add_text(scr_subtree, tvb,
5513         curr_offset, 2,
5514         "REV_MUX_OPTION:  Reverse Traffic Channel multiplex option");
5515
5516     curr_offset += 2;
5517
5518     proto_tree_add_text(scr_subtree, tvb,
5519         curr_offset, 1,
5520         "FOR_RATES:  Transmission rates of the Forward Fundamental Channel");
5521
5522     curr_offset += 1;
5523
5524     proto_tree_add_text(scr_subtree, tvb,
5525         curr_offset, 1,
5526         "REV_RATES:  Transmission rates of the Reverse Fundamental Channel");
5527
5528     curr_offset += 1;
5529
5530     num_con_rec = tvb_get_guint8(tvb, curr_offset);
5531
5532     proto_tree_add_text(scr_subtree, tvb,
5533         curr_offset, 1,
5534         "NUM_CON_REC:  Number of service option connection records, %u",
5535         num_con_rec);
5536
5537     curr_offset += 1;
5538
5539     for (i=1; i <= num_con_rec; i++)
5540     {
5541         oct = tvb_get_guint8(tvb, curr_offset);
5542
5543         item =
5544             proto_tree_add_text(scr_subtree, tvb,
5545                 curr_offset, oct /* oct already includes the length octet itself */,
5546                 "Service option connection record [%u]",
5547                 i);
5548
5549         subtree =
5550             proto_item_add_subtree(item, ett_srvc_con_rec);
5551
5552         curr_offset += 1;
5553
5554         oct = tvb_get_guint8(tvb, curr_offset);
5555
5556         proto_tree_add_text(subtree, tvb,
5557             curr_offset, 1,
5558             "CON_REF:  Service option connection reference, %u",
5559             oct);
5560
5561         curr_offset += 1;
5562
5563         value = tvb_get_ntohs(tvb, curr_offset);
5564
5565         proto_tree_add_text(subtree, tvb,
5566             curr_offset, 2,
5567             "SERVICE_OPTION:  %s",
5568             ansi_a_so_int_to_str(value));
5569
5570         curr_offset += 2;
5571
5572         oct = tvb_get_guint8(tvb, curr_offset);
5573
5574         switch ((oct & 0xf0) >> 4)
5575         {
5576         case 0x00: str = "The service option connection does not use Forward Traffic Channel traffic."; break;
5577         case 0x01: str = "The service option connection uses primary traffic on the Forward Traffic Channel."; break;
5578         case 0x02: str = "The service option connection uses secondary traffic on the Forward Traffic Channel."; break;
5579         default: str = "Reserved"; break;
5580         }
5581
5582         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
5583         proto_tree_add_text(subtree, tvb,
5584             curr_offset, 1,
5585             "%s :  FOR_TRAFFIC:  Forward Traffic Channel traffic type, %s",
5586             a_bigbuf,
5587             str);
5588
5589         switch (oct & 0x0f)
5590         {
5591         case 0x00: str = "The service option connection does not use Reverse Traffic Channel traffic."; break;
5592         case 0x01: str = "The service option connection uses primary traffic on the Reverse Traffic Channel."; break;
5593         case 0x02: str = "The service option connection uses secondary traffic on the Reverse Traffic Channel."; break;
5594         default: str = "Reserved"; break;
5595         }
5596
5597         other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
5598         proto_tree_add_text(subtree, tvb,
5599             curr_offset, 1,
5600             "%s :  REV_TRAFFIC:  Reverse Traffic Channel traffic type, %s",
5601             a_bigbuf,
5602             str);
5603
5604         curr_offset += 1;
5605
5606         oct = tvb_get_guint8(tvb, curr_offset);
5607
5608         other_decode_bitfield_value(a_bigbuf, oct, 0xe0, 8);
5609         proto_tree_add_text(subtree, tvb,
5610             curr_offset, 1,
5611             "%s :  UI_ENCRYPT_MODE:  Encryption mode indicator for user information privacy",
5612             a_bigbuf);
5613
5614         other_decode_bitfield_value(a_bigbuf, oct, 0x1c, 8);
5615         proto_tree_add_text(subtree, tvb,
5616             curr_offset, 1,
5617             "%s :  SR_ID:  Service reference identifier",
5618             a_bigbuf);
5619
5620         other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
5621         proto_tree_add_text(subtree, tvb,
5622             curr_offset, 1,
5623             "%s :  RLP_INFO_INCL:  RLP information included indicator",
5624             a_bigbuf);
5625
5626         if (oct & 0x02)
5627         {
5628             value = (oct & 0x01) << 3;
5629             other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
5630
5631             curr_offset += 1;
5632
5633             oct = tvb_get_guint8(tvb, curr_offset);
5634
5635             value |= (oct & 0xe0) >> 5;
5636
5637             proto_tree_add_text(subtree, tvb,
5638                 curr_offset - 1, 1,
5639                 "%s :  RLP_BLOB_LEN (MSB), %u",
5640                 a_bigbuf,
5641                 value);
5642
5643             other_decode_bitfield_value(a_bigbuf, oct, 0xe0, 8);
5644             proto_tree_add_text(subtree, tvb,
5645                 curr_offset, 1,
5646                 "%s :  RLP_BLOB_LEN (LSB)",
5647                 a_bigbuf);
5648
5649             other_decode_bitfield_value(a_bigbuf, oct, 0x1f, 8);
5650             proto_tree_add_text(subtree, tvb,
5651                 curr_offset, 1,
5652                 "%s :  RLP_BLOB (MSB)",
5653                 a_bigbuf);
5654
5655             curr_offset += 1;
5656
5657             if (value > 1)
5658             {
5659                 proto_tree_add_text(subtree, tvb,
5660                     curr_offset, value - 1,
5661                     "RLP_BLOB");
5662
5663                 curr_offset += value - 1;
5664             }
5665
5666             oct = tvb_get_guint8(tvb, curr_offset);
5667
5668             other_decode_bitfield_value(a_bigbuf, oct, 0xe0, 8);
5669             proto_tree_add_text(subtree, tvb,
5670                 curr_offset, 1,
5671                 "%s :  RLP_BLOB (LSB)",
5672                 a_bigbuf);
5673
5674             other_decode_bitfield_value(a_bigbuf, oct, 0x1f, 8);
5675             proto_tree_add_text(subtree, tvb,
5676                 curr_offset, 1,
5677                 "%s :  Reserved",
5678                 a_bigbuf);
5679         }
5680         else
5681         {
5682             other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
5683             proto_tree_add_text(subtree, tvb,
5684                 curr_offset, 1,
5685                 "%s :  Reserved",
5686                 a_bigbuf);
5687         }
5688
5689         curr_offset += 1;
5690     }
5691
5692     oct = tvb_get_guint8(tvb, curr_offset);
5693
5694     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
5695     proto_tree_add_text(scr_subtree, tvb,
5696         curr_offset, 1,
5697         "%s :  FCH_CC_INCL:  Channel configuration for the Fundamental Channel included indicator",
5698         a_bigbuf);
5699
5700     if (oct & 0x80)
5701     {
5702         other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
5703         proto_tree_add_text(scr_subtree, tvb,
5704             curr_offset, 1,
5705             "%s :  FCH_FRAME_SIZE:  Fundamental Channel frame size supported indicator",
5706             a_bigbuf);
5707
5708         other_decode_bitfield_value(a_bigbuf, oct, 0x3e, 8);
5709         proto_tree_add_text(scr_subtree, tvb,
5710             curr_offset, 1,
5711             "%s :  FOR_FCH_RC:  Forward Fundamental Channel Radio Configuration, %u",
5712             a_bigbuf,
5713             (oct & 0x3e) >> 1);
5714
5715         other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
5716         value = (oct & 0x01) << 4;
5717
5718         curr_offset += 1;
5719
5720         oct = tvb_get_guint8(tvb, curr_offset);
5721
5722         value |= (oct & 0xf0) >> 4;
5723
5724         proto_tree_add_text(scr_subtree, tvb,
5725             curr_offset - 1, 1,
5726             "%s :  REV_FCH_RC:  Reverse Fundamental Channel Radio Configuration (MSB), %u",
5727             a_bigbuf,
5728             value);
5729
5730         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
5731         proto_tree_add_text(scr_subtree, tvb,
5732             curr_offset, 1,
5733             "%s :  REV_FCH_RC:  (LSB)",
5734             a_bigbuf);
5735
5736         bit_mask = 0x08;
5737         bit_offset = 3;
5738     }
5739     else
5740     {
5741         bit_mask = 0x40;
5742         bit_offset = 6;
5743     }
5744
5745     other_decode_bitfield_value(a_bigbuf, oct, bit_mask, 8);
5746     proto_tree_add_text(scr_subtree, tvb,
5747         curr_offset, 1,
5748         "%s :  DCCH_CC_INCL:  Channel configuration for the Dedicated Control Channel included indicator",
5749         a_bigbuf);
5750
5751     if (oct & bit_mask)
5752     {
5753         /* can't be bothered to do the rest of the decode */
5754
5755         proto_tree_add_text(scr_subtree, tvb,
5756             curr_offset, (is2000_portion_len - (curr_offset - saved_offset)),
5757             "DCCH + ? + Reserved");
5758
5759         curr_offset += (is2000_portion_len - (curr_offset - saved_offset));
5760     }
5761     else
5762     {
5763         bit_mask >>= 1;
5764         bit_offset--;
5765
5766         other_decode_bitfield_value(a_bigbuf, oct, bit_mask, 8);
5767         proto_tree_add_text(scr_subtree, tvb,
5768             curr_offset, 1,
5769             "%s :  FOR_SCH_CC_INCL:  Channel configuration for the Dedicated Control Channel included indicator",
5770             a_bigbuf);
5771
5772         if (oct & bit_mask)
5773         {
5774             /* can't be bothered to do the rest of the decode */
5775
5776             proto_tree_add_text(scr_subtree, tvb,
5777                 curr_offset, (is2000_portion_len - (curr_offset - saved_offset)),
5778                 "FOR_SCH + ? + Reserved");
5779
5780             curr_offset += (is2000_portion_len - (curr_offset - saved_offset));
5781         }
5782         else
5783         {
5784             bit_mask >>= 1;
5785             bit_offset--;
5786
5787             other_decode_bitfield_value(a_bigbuf, oct, bit_mask, 8);
5788             proto_tree_add_text(scr_subtree, tvb,
5789                 curr_offset, 1,
5790                 "%s :  REV_SCH_CC_INCL:  Channel configuration for the Dedicated Control Channel included indicator",
5791                 a_bigbuf);
5792
5793             if (oct & bit_mask)
5794             {
5795                 /* can't be bothered to do the rest of the decode */
5796
5797                 proto_tree_add_text(scr_subtree, tvb,
5798                     curr_offset, (is2000_portion_len - (curr_offset - saved_offset)),
5799                     "REV_SCH + ? + Reserved");
5800
5801                 curr_offset += (is2000_portion_len - (curr_offset - saved_offset));
5802             }
5803             else
5804             {
5805                 bit_mask = (0xff << (8 - bit_offset));
5806                 bit_mask >>= (8 - bit_offset);
5807
5808                 other_decode_bitfield_value(a_bigbuf, oct, bit_mask, 8);
5809                 proto_tree_add_text(scr_subtree, tvb,
5810                     curr_offset, 1,
5811                     "%s :  Reserved",
5812                     a_bigbuf);
5813
5814                 curr_offset += 1;
5815             }
5816         }
5817     }
5818
5819     EXTRANEOUS_DATA_CHECK_EXPERT(len, curr_offset - offset);
5820
5821     return(curr_offset - offset);
5822 }
5823
5824 /*
5825  * IOS 6.2.2.69
5826  */
5827 static guint8
5828 elem_is2000_nn_scr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
5829 {
5830     guint8      oct;
5831     guint32     curr_offset;
5832     guint       is2000_portion_len;
5833
5834     curr_offset = offset;
5835
5836     oct = tvb_get_guint8(tvb, curr_offset);
5837
5838     other_decode_bitfield_value(a_bigbuf, oct, 0xf8, 8);
5839     proto_tree_add_text(tree, tvb, curr_offset, 1,
5840         "%s :  Reserved",
5841         a_bigbuf);
5842
5843     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
5844     proto_tree_add_text(tree, tvb, curr_offset, 1,
5845         "%s :  Bit-Exact Length Fill Bits: %u",
5846         a_bigbuf,
5847         oct & 0x07);
5848
5849     curr_offset++;
5850
5851     is2000_portion_len = len - (curr_offset - offset);
5852
5853 #ifndef MLUM
5854
5855     NO_MORE_DATA_CHECK(len);
5856
5857     if (is2000_portion_len > 0)
5858     {
5859         SHORT_DATA_CHECK(len - (curr_offset - offset), is2000_portion_len);
5860
5861         proto_tree_add_text(tree, tvb, curr_offset, is2000_portion_len,
5862             "IS-2000 Non-Negotiable Service Configuration Record Content");
5863
5864         curr_offset += is2000_portion_len;
5865     }
5866
5867 #else
5868
5869
5870 #endif
5871
5872     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5873
5874     return(curr_offset - offset);
5875 }
5876
5877 /*
5878  * IOS 6.2.2.70
5879  */
5880 static guint8
5881 elem_is2000_mob_cap(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
5882 {
5883     guint8      oct;
5884     guint8      oct_len;
5885     guint32     curr_offset;
5886     proto_tree  *subtree;
5887     proto_item  *item = NULL;
5888     const gchar *str;
5889
5890     curr_offset = offset;
5891
5892     oct = tvb_get_guint8(tvb, curr_offset);
5893
5894     switch (global_a_variant)
5895     {
5896     case A_VARIANT_IOS401:
5897         other_decode_bitfield_value(a_bigbuf, oct, 0xe0, 8);
5898         proto_tree_add_text(tree, tvb, curr_offset, 1,
5899             "%s :  Reserved",
5900             a_bigbuf);
5901         break;
5902
5903     case A_VARIANT_IOS501:
5904         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
5905         proto_tree_add_text(tree, tvb, curr_offset, 1,
5906             "%s :  REV_PDCH Supported: IS-2000 R-PDCH %ssupported",
5907             a_bigbuf,
5908             (oct & 0x80) ? "" : "not ");
5909
5910         other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
5911         proto_tree_add_text(tree, tvb, curr_offset, 1,
5912             "%s :  FOR_PDCH Supported: IS-2000 F-PDCH %ssupported",
5913             a_bigbuf,
5914             (oct & 0x40) ? "" : "not ");
5915
5916         other_decode_bitfield_value(a_bigbuf, oct, 0x20, 8);
5917         proto_tree_add_text(tree, tvb, curr_offset, 1,
5918             "%s :  ERAM Supported: Enhanced Rate Adaptation Mode %ssupported",
5919             a_bigbuf,
5920             (oct & 0x20) ? "" : "not ");
5921         break;
5922     }
5923
5924     other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
5925     proto_tree_add_text(tree, tvb, curr_offset, 1,
5926         "%s :  DCCH Supported: IS-2000 DCCH %ssupported",
5927         a_bigbuf,
5928         (oct & 0x10) ? "" : "not ");
5929
5930     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
5931     proto_tree_add_text(tree, tvb, curr_offset, 1,
5932         "%s :  FCH Supported: IS-2000 FCH %ssupported",
5933         a_bigbuf,
5934         (oct & 0x08) ? "" : "not ");
5935
5936     other_decode_bitfield_value(a_bigbuf, oct, 0x04, 8);
5937     proto_tree_add_text(tree, tvb, curr_offset, 1,
5938         "%s :  OTD Supported: Orthogonal Transmit Diversity %ssupported",
5939         a_bigbuf,
5940         (oct & 0x04) ? "" : "not ");
5941
5942     other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
5943     proto_tree_add_text(tree, tvb, curr_offset, 1,
5944         "%s :  Enhanced RC CFG Supported: Radio configuration in radio class 2 %ssupported",
5945         a_bigbuf,
5946         (oct & 0x02) ? "" : "not ");
5947
5948     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
5949     proto_tree_add_text(tree, tvb, curr_offset, 1,
5950         "%s :  QPCH Supported: Quick Paging Channel %ssupported",
5951         a_bigbuf,
5952         (oct & 0x01) ? "" : "not ");
5953
5954     curr_offset++;
5955
5956     NO_MORE_DATA_CHECK(len);
5957
5958     oct_len = tvb_get_guint8(tvb, curr_offset);
5959
5960     proto_tree_add_text(tree,
5961         tvb, curr_offset, 1,
5962         "FCH Information: Bit-Exact Length Octet Count: %u",
5963         oct_len);
5964
5965     curr_offset++;
5966
5967     NO_MORE_DATA_CHECK(len);
5968
5969     oct = tvb_get_guint8(tvb, curr_offset);
5970
5971     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
5972     proto_tree_add_text(tree, tvb, curr_offset, 1,
5973         "%s :  Reserved",
5974         a_bigbuf);
5975
5976     switch ((oct & 0x70) >> 4)
5977     {
5978     case 0: str = "No mobile assisted geo-location capabilities"; break;
5979     case 1: str = "IS801 capable (Advanced Forward Link Triangulation only (AFLT))"; break;
5980     case 2: str = "IS801 capable (Advanced Forward Link Triangulation and Global Positioning Systems"; break;
5981     case 3: str = "Global Positioning Systems Only"; break;
5982     default:
5983         str = "Reserved";
5984         break;
5985     }
5986
5987     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
5988     proto_tree_add_text(tree, tvb, curr_offset, 1,
5989         "%s :  Geo Location Type: %s",
5990         a_bigbuf,
5991         str);
5992
5993     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
5994     proto_tree_add_text(tree, tvb, curr_offset, 1,
5995         "%s :  Geo Location Included",
5996         a_bigbuf);
5997
5998     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
5999     proto_tree_add_text(tree, tvb, curr_offset, 1,
6000         "%s :  FCH Information: Bit-Exact Length Fill Bits: %u",
6001         a_bigbuf,
6002         oct & 0x07);
6003
6004     curr_offset++;
6005
6006     NO_MORE_DATA_CHECK(len);
6007
6008     if (oct_len > 0)
6009     {
6010         SHORT_DATA_CHECK(len - (curr_offset - offset), oct_len);
6011
6012         proto_tree_add_text(tree, tvb, curr_offset, oct_len,
6013             "FCH Information Content");
6014
6015         curr_offset += oct_len;
6016
6017         NO_MORE_DATA_CHECK(len);
6018     }
6019
6020     /*
6021      * DCCH
6022      */
6023     oct_len = tvb_get_guint8(tvb, curr_offset);
6024
6025     proto_tree_add_text(tree,
6026         tvb, curr_offset, 1,
6027         "DCCH Information: Bit-Exact Length Octet Count: %u",
6028         oct_len);
6029
6030     curr_offset++;
6031
6032     NO_MORE_DATA_CHECK(len);
6033
6034     oct = tvb_get_guint8(tvb, curr_offset);
6035
6036     other_decode_bitfield_value(a_bigbuf, oct, 0xf8, 8);
6037     proto_tree_add_text(tree, tvb, curr_offset, 1,
6038         "%s :  Reserved",
6039         a_bigbuf);
6040
6041     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
6042     proto_tree_add_text(tree, tvb, curr_offset, 1,
6043         "%s :  DCCH Information: Bit-Exact Length Fill Bits: %u",
6044         a_bigbuf,
6045         oct & 0x07);
6046
6047     curr_offset++;
6048
6049     NO_MORE_DATA_CHECK(len);
6050
6051     if (oct_len > 0)
6052     {
6053         SHORT_DATA_CHECK(len - (curr_offset - offset), oct_len);
6054
6055         proto_tree_add_text(tree, tvb, curr_offset, oct_len,
6056             "DCCH Information Content");
6057
6058         curr_offset += oct_len;
6059
6060         NO_MORE_DATA_CHECK(len);
6061     }
6062
6063     /*
6064      * FOR_PDCH
6065      */
6066     oct_len = tvb_get_guint8(tvb, curr_offset);
6067
6068     proto_tree_add_text(tree,
6069         tvb, curr_offset, 1,
6070         "FOR_PDCH Information: Bit-Exact Length Octet Count: %u",
6071         oct_len);
6072
6073     curr_offset++;
6074
6075     NO_MORE_DATA_CHECK(len);
6076
6077     oct = tvb_get_guint8(tvb, curr_offset);
6078
6079     other_decode_bitfield_value(a_bigbuf, oct, 0xf8, 8);
6080     proto_tree_add_text(tree, tvb, curr_offset, 1,
6081         "%s :  Reserved",
6082         a_bigbuf);
6083
6084     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
6085     proto_tree_add_text(tree, tvb, curr_offset, 1,
6086         "%s :  FOR_PDCH Information: Bit-Exact Length Fill Bits: %u",
6087         a_bigbuf,
6088         oct & 0x07);
6089
6090     curr_offset++;
6091
6092     NO_MORE_DATA_CHECK(len);
6093
6094     if (oct_len > 0)
6095     {
6096         SHORT_DATA_CHECK(len - (curr_offset - offset), oct_len);
6097
6098         proto_tree_add_text(tree, tvb, curr_offset, oct_len,
6099             "FOR_PDCH Information Content");
6100
6101         curr_offset += oct_len;
6102
6103         NO_MORE_DATA_CHECK(len);
6104     }
6105
6106     /*
6107      * REV_PDCH
6108      */
6109     oct_len = tvb_get_guint8(tvb, curr_offset);
6110
6111     proto_tree_add_text(tree,
6112         tvb, curr_offset, 1,
6113         "REV_PDCH Information: Bit-Exact Length Octet Count: %u",
6114         oct_len);
6115
6116     curr_offset++;
6117
6118     NO_MORE_DATA_CHECK(len);
6119
6120     oct = tvb_get_guint8(tvb, curr_offset);
6121
6122     other_decode_bitfield_value(a_bigbuf, oct, 0xf8, 8);
6123     proto_tree_add_text(tree, tvb, curr_offset, 1,
6124         "%s :  Reserved",
6125         a_bigbuf);
6126
6127     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
6128     proto_tree_add_text(tree, tvb, curr_offset, 1,
6129         "%s :  REV_PDCH Information: Bit-Exact Length Fill Bits: %u",
6130         a_bigbuf,
6131         oct & 0x07);
6132
6133     curr_offset++;
6134
6135     NO_MORE_DATA_CHECK(len);
6136
6137     if (oct_len > 0)
6138     {
6139         SHORT_DATA_CHECK(len - (curr_offset - offset), oct_len);
6140
6141         proto_tree_add_text(tree, tvb, curr_offset, oct_len,
6142             "REV_PDCH Information Content");
6143
6144         curr_offset += oct_len;
6145
6146         NO_MORE_DATA_CHECK(len);
6147     }
6148
6149     oct = tvb_get_guint8(tvb, curr_offset);
6150
6151     item =
6152         proto_tree_add_text(tree, tvb,
6153             curr_offset, 1,
6154             "VP Algorithms Supported%s",
6155             oct ? "" : ":  No voice privacy supported");
6156
6157     if (oct)
6158     {
6159         subtree =
6160             proto_item_add_subtree(item, ett_vp_algs);
6161
6162         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
6163         proto_tree_add_text(subtree, tvb, curr_offset, 1,
6164             "%s :  %s",
6165             a_bigbuf,
6166             (oct & 0x80) ? "No extension" : "Extended");
6167
6168         other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
6169         proto_tree_add_text(subtree, tvb, curr_offset, 1,
6170             "%s :  A7:  Reserved",
6171             a_bigbuf);
6172
6173         other_decode_bitfield_value(a_bigbuf, oct, 0x20, 8);
6174         proto_tree_add_text(subtree, tvb, curr_offset, 1,
6175             "%s :  A6:  Reserved",
6176             a_bigbuf);
6177
6178         other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
6179         proto_tree_add_text(subtree, tvb, curr_offset, 1,
6180             "%s :  A5:  Reserved",
6181             a_bigbuf);
6182
6183         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
6184         proto_tree_add_text(subtree, tvb, curr_offset, 1,
6185             "%s :  A4:  Reserved",
6186             a_bigbuf);
6187
6188         other_decode_bitfield_value(a_bigbuf, oct, 0x04, 8);
6189         proto_tree_add_text(subtree, tvb, curr_offset, 1,
6190             "%s :  A3:  Reserved",
6191             a_bigbuf);
6192
6193         other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
6194         proto_tree_add_text(subtree, tvb, curr_offset, 1,
6195             "%s :  A2:  Advanced Encryption Standard (AES)",
6196             a_bigbuf);
6197
6198         other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
6199         proto_tree_add_text(subtree, tvb, curr_offset, 1,
6200             "%s :  A1:  Private long code",
6201             a_bigbuf);
6202     }
6203
6204     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
6205
6206     return(curr_offset - offset);
6207 }
6208
6209 /*
6210  * IOS 6.2.2.71
6211  */
6212 static guint8
6213 elem_ptype(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
6214 {
6215     guint32     value;
6216     guint32     curr_offset;
6217     const gchar *str;
6218
6219     curr_offset = offset;
6220
6221     value = tvb_get_ntohs(tvb, curr_offset);
6222
6223     switch (value)
6224     {
6225     case 0x880b: str = "PPP"; break;
6226     case 0x8881: str = "Unstructured Byte Stream"; break;
6227     default:
6228         str = "Unknown";
6229         break;
6230     }
6231
6232     proto_tree_add_text(tree,
6233         tvb, curr_offset, 2,
6234         "(%u) %s",
6235         value,
6236         str);
6237
6238     g_snprintf(add_string, string_len, " - (%s)", str);
6239
6240     curr_offset += 2;
6241
6242     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
6243
6244     return(curr_offset - offset);
6245 }
6246
6247 /*
6248  * IOS 6.2.2.72
6249  */
6250 static guint8
6251 elem_fwd_ms_info_recs(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
6252 {
6253     guint8      oct;
6254     guint8      oct_len;
6255     guint8      rec_type;
6256     guint8      num_recs;
6257     guint32     value;
6258     guint32     curr_offset;
6259     const gchar *str;
6260     gint        ett_elem_idx, idx, i;
6261     proto_tree  *subtree;
6262     proto_item  *item;
6263
6264     curr_offset = offset;
6265
6266     num_recs = 0;
6267
6268     while ((len - (curr_offset - offset)) >= 2)
6269     {
6270         num_recs++;
6271
6272         rec_type = tvb_get_guint8(tvb, curr_offset);
6273
6274         str = match_strval_idx((guint32) rec_type, ansi_fwd_ms_info_rec_str, &idx);
6275
6276         if (str == NULL)
6277         {
6278             str = "Reserved";
6279             ett_elem_idx = ett_ansi_ms_info_rec_reserved;
6280         }
6281         else
6282         {
6283             ett_elem_idx = ett_ansi_fwd_ms_info_rec[idx];
6284         }
6285
6286         item =
6287             proto_tree_add_text(tree,
6288                 tvb, curr_offset, 1,
6289                 "Information Record Type [%u]: (%u) %s",
6290                 num_recs,
6291                 rec_type,
6292                 str);
6293
6294         subtree = proto_item_add_subtree(item, ett_elem_idx);
6295
6296         curr_offset++;
6297
6298         oct_len = tvb_get_guint8(tvb, curr_offset);
6299
6300         proto_tree_add_uint(subtree, hf_ansi_a_length, tvb,
6301             curr_offset, 1, oct_len);
6302
6303         curr_offset++;
6304
6305         if (oct_len > 0)
6306         {
6307             SHORT_DATA_CHECK(len - (curr_offset - offset), oct_len);
6308
6309             switch (rec_type)
6310             {
6311             case ANSI_FWD_MS_INFO_REC_CLD_PN:
6312                 oct = tvb_get_guint8(tvb, curr_offset);
6313
6314                 switch ((oct & 0xe0) >> 5)
6315                 {
6316                 case 0: str = "Unknown"; break;
6317                 case 1: str = "International number"; break;
6318                 case 2: str = "National number"; break;
6319                 case 3: str = "Network-specific number"; break;
6320                 case 4: str = "Subscriber number"; break;
6321                 case 5: str = "Reserved"; break;
6322                 case 6: str = "Abbreviated number"; break;
6323                 default:
6324                     str = "Reserved for extension";
6325                     break;
6326                 }
6327
6328                 other_decode_bitfield_value(a_bigbuf, oct, 0xe0, 8);
6329                 proto_tree_add_text(subtree, tvb, curr_offset, 1,
6330                     "%s :  Number Type: %s",
6331                     a_bigbuf,
6332                     str);
6333
6334                 switch ((oct & 0x1e) >> 1)
6335                 {
6336                 case 0x00: str = "Unknown"; break;
6337                 case 0x01: str = "ISDN/Telephony Numbering"; break;
6338                 case 0x03: str = "Data Numbering (ITU-T Rec. X.121)"; break;
6339                 case 0x04: str = "Telex Numbering (ITU-T Rec. F.69)"; break;
6340                 case 0x09: str = "Private Numbering"; break;
6341                 case 0x0f: str = "Reserved for extension"; break;
6342                 default:
6343                     str = "Reserved";
6344                     break;
6345                 }
6346
6347                 other_decode_bitfield_value(a_bigbuf, oct, 0x1e, 8);
6348                 proto_tree_add_text(subtree, tvb, curr_offset, 1,
6349                     "%s :  Number Plan: %s",
6350                     a_bigbuf,
6351                     str);
6352
6353                 if (oct_len > 1)
6354                 {
6355                     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
6356                     proto_tree_add_text(subtree, tvb, curr_offset, 1,
6357                         "%s :  MSB of first digit",
6358                         a_bigbuf);
6359
6360                     curr_offset++;
6361
6362                     for (i=0; i < (oct_len - 1); i++)
6363                     {
6364                         a_bigbuf[i] = (oct & 0x01) << 7;
6365
6366                         oct = tvb_get_guint8(tvb, curr_offset + i);
6367
6368                         a_bigbuf[i] |= (oct & 0xfe) >> 1;
6369                     }
6370                     a_bigbuf[i] = '\0';
6371
6372                     proto_tree_add_text(subtree, tvb, curr_offset, oct_len - 1,
6373                         "Digits: %s",
6374                         a_bigbuf);
6375
6376                     curr_offset += (oct_len - 2);
6377                 }
6378
6379                 other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
6380                 proto_tree_add_text(subtree, tvb, curr_offset, 1,
6381                     "%s :  Reserved",
6382                     a_bigbuf);
6383
6384                 curr_offset++;
6385                 break;
6386
6387             case ANSI_FWD_MS_INFO_REC_CLG_PN:
6388                 value = tvb_get_ntohs(tvb, curr_offset);
6389
6390                 oct = (value & 0xff00) >> 8;
6391
6392                 switch ((oct & 0xe0) >> 5)
6393                 {
6394                 case 0: str = "Unknown"; break;
6395                 case 1: str = "International number"; break;
6396                 case 2: str = "National number"; break;
6397                 case 3: str = "Network-specific number"; break;
6398                 case 4: str = "Subscriber number"; break;
6399                 case 5: str = "Reserved"; break;
6400                 case 6: str = "Abbreviated number"; break;
6401                 default:
6402                     str = "Reserved for extension";
6403                     break;
6404                 }
6405
6406                 other_decode_bitfield_value(a_bigbuf, value, 0xe000, 16);
6407                 proto_tree_add_text(subtree, tvb, curr_offset, 2,
6408                     "%s :  Number Type: %s",
6409                     a_bigbuf,
6410                     str);
6411
6412                 switch ((oct & 0x1e) >> 1)
6413                 {
6414                 case 0x00: str = "Unknown"; break;
6415                 case 0x01: str = "ISDN/Telephony Numbering"; break;
6416                 case 0x03: str = "Data Numbering (ITU-T Rec. X.121)"; break;
6417                 case 0x04: str = "Telex Numbering (ITU-T Rec. F.69)"; break;
6418                 case 0x09: str = "Private Numbering"; break;
6419                 case 0x0f: str = "Reserved for extension"; break;
6420                 default:
6421                     str = "Reserved";
6422                     break;
6423                 }
6424
6425                 other_decode_bitfield_value(a_bigbuf, value, 0x1e00, 16);
6426                 proto_tree_add_text(subtree, tvb, curr_offset, 2,
6427                     "%s :  Number Plan: %s",
6428                     a_bigbuf,
6429                     str);
6430
6431                 switch ((value & 0x0180) >> 7)
6432                 {
6433                 case 0: str = "Presentation allowed"; break;
6434                 case 1: str = "Presentation restricted"; break;
6435                 case 2: str = "Number not available"; break;
6436                 default:
6437                     str = "Reserved";
6438                     break;
6439                 }
6440
6441                 other_decode_bitfield_value(a_bigbuf, value, 0x0180, 16);
6442                 proto_tree_add_text(subtree, tvb, curr_offset, 2,
6443                     "%s :  Presentation Indicator (PI): %s",
6444                     a_bigbuf,
6445                     str);
6446
6447                 switch ((value & 0x0060) >> 5)
6448                 {
6449                 case 0: str = "User-provided, not screened"; break;
6450                 case 1: str = "User-provided, verified and passed"; break;
6451                 case 2: str = "User-provided, verified and failed"; break;
6452                 default:
6453                     str = "Network-provided";
6454                     break;
6455                 }
6456
6457                 other_decode_bitfield_value(a_bigbuf, value, 0x0060, 16);
6458                 proto_tree_add_text(subtree, tvb, curr_offset, 2,
6459                     "%s :  Screening Indicator (SI): %s",
6460                     a_bigbuf,
6461                     str);
6462
6463                 if (oct_len > 2)
6464                 {
6465                     oct = (value & 0x00ff);
6466
6467                     other_decode_bitfield_value(a_bigbuf, value, 0x001f, 16);
6468                     proto_tree_add_text(subtree, tvb, curr_offset, 2,
6469                         "%s :  MSB of first digit",
6470                         a_bigbuf);
6471
6472                     curr_offset += 2;
6473
6474                     for (i=0; i < (oct_len - 2); i++)
6475                     {
6476                         a_bigbuf[i] = (oct & 0x1f) << 3;
6477
6478                         oct = tvb_get_guint8(tvb, curr_offset + i);
6479
6480                         a_bigbuf[i] |= (oct & 0xe0) >> 5;
6481                     }
6482                     a_bigbuf[i] = '\0';
6483
6484                     proto_tree_add_text(subtree, tvb, curr_offset, oct_len - 2,
6485                         "Digits: %s",
6486                         a_bigbuf);
6487
6488                     curr_offset += (oct_len - 3);
6489
6490                     other_decode_bitfield_value(a_bigbuf, oct, 0x1f, 8);
6491                     proto_tree_add_text(subtree, tvb, curr_offset, 1,
6492                         "%s :  Reserved",
6493                         a_bigbuf);
6494
6495                     curr_offset++;
6496                 }
6497                 else
6498                 {
6499                     other_decode_bitfield_value(a_bigbuf, value, 0x001f, 16);
6500                     proto_tree_add_text(subtree, tvb, curr_offset, 2,
6501                         "%s :  Reserved",
6502                         a_bigbuf);
6503
6504                     curr_offset += 2;
6505                 }
6506                 break;
6507
6508             case ANSI_FWD_MS_INFO_REC_MW:
6509                 oct = tvb_get_guint8(tvb, curr_offset);
6510
6511                 proto_tree_add_text(subtree, tvb, curr_offset, 1,
6512                     "Number of messages waiting: %u",
6513                     oct);
6514
6515                 curr_offset++;
6516                 break;
6517
6518             default:
6519                 proto_tree_add_text(subtree,
6520                     tvb, curr_offset, oct_len,
6521                     "Record Content");
6522
6523                 curr_offset += oct_len;
6524                 break;
6525             }
6526         }
6527     }
6528
6529     g_snprintf(add_string, string_len, " - %u record%s",
6530         num_recs, plurality(num_recs, "", "s"));
6531
6532     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
6533
6534     return(curr_offset - offset);
6535 }
6536
6537 /*
6538  * IOS 6.2.2.72
6539  */
6540 static guint8
6541 elem_rev_ms_info_recs(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
6542 {
6543     guint8      oct;
6544     guint8      oct_len;
6545     guint8      rec_type;
6546     guint8      num_recs;
6547     guint32     value;
6548     guint32     curr_offset, saved_offset;
6549     const gchar *str;
6550     gint        ett_elem_idx, idx, i;
6551     proto_tree  *subtree, *subtree2;
6552     proto_item  *item;
6553     guint8      *poctets;
6554
6555     curr_offset = offset;
6556
6557     num_recs = 0;
6558
6559     while ((len - (curr_offset - offset)) >= 2)
6560     {
6561         num_recs++;
6562
6563         rec_type = tvb_get_guint8(tvb, curr_offset);
6564
6565         str = match_strval_idx((guint32) rec_type, ansi_rev_ms_info_rec_str, &idx);
6566
6567         if (str == NULL)
6568         {
6569             str = "Reserved";
6570             ett_elem_idx = ett_ansi_ms_info_rec_reserved;
6571         }
6572         else
6573         {
6574             ett_elem_idx = ett_ansi_rev_ms_info_rec[idx];
6575         }
6576
6577         item =
6578             proto_tree_add_text(tree,
6579                 tvb, curr_offset, 1,
6580                 "Information Record Type [%u]: (%u) %s",
6581                 num_recs,
6582                 rec_type,
6583                 str);
6584
6585         subtree = proto_item_add_subtree(item, ett_elem_idx);
6586
6587         curr_offset++;
6588
6589         oct_len = tvb_get_guint8(tvb, curr_offset);
6590
6591         proto_tree_add_uint(subtree, hf_ansi_a_length, tvb,
6592             curr_offset, 1, oct_len);
6593
6594         curr_offset++;
6595
6596         if (oct_len > 0)
6597         {
6598             SHORT_DATA_CHECK(len - (curr_offset - offset), oct_len);
6599
6600             switch (rec_type)
6601             {
6602             case ANSI_REV_MS_INFO_REC_KEYPAD_FAC:
6603                 poctets = tvb_get_ephemeral_string(tvb, curr_offset, oct_len);
6604
6605                 proto_tree_add_string_format(subtree, hf_ansi_a_cld_party_ascii_num,
6606                     tvb, curr_offset, oct_len,
6607                     (gchar *) poctets,
6608                     "Digits: %s",
6609                     (gchar *) format_text(poctets, oct_len));
6610
6611                 curr_offset += oct_len;
6612                 break;
6613
6614             case ANSI_REV_MS_INFO_REC_CLD_PN:
6615                 oct = tvb_get_guint8(tvb, curr_offset);
6616
6617                 switch ((oct & 0xe0) >> 5)
6618                 {
6619                 case 0: str = "Unknown"; break;
6620                 case 1: str = "International number"; break;
6621                 case 2: str = "National number"; break;
6622                 case 3: str = "Network-specific number"; break;
6623                 case 4: str = "Subscriber number"; break;
6624                 case 5: str = "Reserved"; break;
6625                 case 6: str = "Abbreviated number"; break;
6626                 default:
6627                     str = "Reserved for extension";
6628                     break;
6629                 }
6630
6631                 other_decode_bitfield_value(a_bigbuf, oct, 0xe0, 8);
6632                 proto_tree_add_text(subtree, tvb, curr_offset, 1,
6633                     "%s :  Number Type: %s",
6634                     a_bigbuf,
6635                     str);
6636
6637                 switch ((oct & 0x1e) >> 1)
6638                 {
6639                 case 0x00: str = "Unknown"; break;
6640                 case 0x01: str = "ISDN/Telephony Numbering"; break;
6641                 case 0x03: str = "Data Numbering (ITU-T Rec. X.121)"; break;
6642                 case 0x04: str = "Telex Numbering (ITU-T Rec. F.69)"; break;
6643                 case 0x09: str = "Private Numbering"; break;
6644                 case 0x0f: str = "Reserved for extension"; break;
6645                 default:
6646                     str = "Reserved";
6647                     break;
6648                 }
6649
6650                 other_decode_bitfield_value(a_bigbuf, oct, 0x1e, 8);
6651                 proto_tree_add_text(subtree, tvb, curr_offset, 1,
6652                     "%s :  Number Plan: %s",
6653                     a_bigbuf,
6654                     str);
6655
6656                 if (oct_len > 1)
6657                 {
6658                     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
6659                     proto_tree_add_text(subtree, tvb, curr_offset, 1,
6660                         "%s :  MSB of first digit",
6661                         a_bigbuf);
6662
6663                     curr_offset++;
6664
6665                     for (i=0; i < (oct_len - 1); i++)
6666                     {
6667                         a_bigbuf[i] = (oct & 0x01) << 7;
6668
6669                         oct = tvb_get_guint8(tvb, curr_offset + i);
6670
6671                         a_bigbuf[i] |= (oct & 0xfe) >> 1;
6672                     }
6673                     a_bigbuf[i] = '\0';
6674
6675                     proto_tree_add_text(subtree, tvb, curr_offset, oct_len - 1,
6676                         "Digits: %s",
6677                         a_bigbuf);
6678
6679                     curr_offset += (oct_len - 2);
6680                 }
6681
6682                 other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
6683                 proto_tree_add_text(subtree, tvb, curr_offset, 1,
6684                     "%s :  Reserved",
6685                     a_bigbuf);
6686
6687                 curr_offset++;
6688                 break;
6689
6690             case ANSI_REV_MS_INFO_REC_CLG_PN:
6691                 value = tvb_get_ntohs(tvb, curr_offset);
6692
6693                 oct = (value & 0xff00) >> 8;
6694
6695                 switch ((oct & 0xe0) >> 5)
6696                 {
6697                 case 0: str = "Unknown"; break;
6698                 case 1: str = "International number"; break;
6699                 case 2: str = "National number"; break;
6700                 case 3: str = "Network-specific number"; break;
6701                 case 4: str = "Subscriber number"; break;
6702                 case 5: str = "Reserved"; break;
6703                 case 6: str = "Abbreviated number"; break;
6704                 default:
6705                     str = "Reserved for extension";
6706                     break;
6707                 }
6708
6709                 other_decode_bitfield_value(a_bigbuf, value, 0xe000, 16);
6710                 proto_tree_add_text(subtree, tvb, curr_offset, 2,
6711                     "%s :  Number Type: %s",
6712                     a_bigbuf,
6713                     str);
6714
6715                 switch ((oct & 0x1e) >> 1)
6716                 {
6717                 case 0x00: str = "Unknown"; break;
6718                 case 0x01: str = "ISDN/Telephony Numbering"; break;
6719                 case 0x03: str = "Data Numbering (ITU-T Rec. X.121)"; break;
6720                 case 0x04: str = "Telex Numbering (ITU-T Rec. F.69)"; break;
6721                 case 0x09: str = "Private Numbering"; break;
6722                 case 0x0f: str = "Reserved for extension"; break;
6723                 default:
6724                     str = "Reserved";
6725                     break;
6726                 }
6727
6728                 other_decode_bitfield_value(a_bigbuf, value, 0x1e00, 16);
6729                 proto_tree_add_text(subtree, tvb, curr_offset, 2,
6730                     "%s :  Number Plan: %s",
6731                     a_bigbuf,
6732                     str);
6733
6734                 switch ((value & 0x0180) >> 7)
6735                 {
6736                 case 0: str = "Presentation allowed"; break;
6737                 case 1: str = "Presentation restricted"; break;
6738                 case 2: str = "Number not available"; break;
6739                 default:
6740                     str = "Reserved";
6741                     break;
6742                 }
6743
6744                 other_decode_bitfield_value(a_bigbuf, value, 0x0180, 16);
6745                 proto_tree_add_text(subtree, tvb, curr_offset, 2,
6746                     "%s :  Presentation Indicator (PI): %s",
6747                     a_bigbuf,
6748                     str);
6749
6750                 switch ((value & 0x0060) >> 5)
6751                 {
6752                 case 0: str = "User-provided, not screened"; break;
6753                 case 1: str = "User-provided, verified and passed"; break;
6754                 case 2: str = "User-provided, verified and failed"; break;
6755                 default:
6756                     str = "Network-provided";
6757                     break;
6758                 }
6759
6760                 other_decode_bitfield_value(a_bigbuf, value, 0x0060, 16);
6761                 proto_tree_add_text(subtree, tvb, curr_offset, 2,
6762                     "%s :  Screening Indicator (SI): %s",
6763                     a_bigbuf,
6764                     str);
6765
6766                 if (oct_len > 2)
6767                 {
6768                     oct = (value & 0x00ff);
6769
6770                     other_decode_bitfield_value(a_bigbuf, value, 0x001f, 16);
6771                     proto_tree_add_text(subtree, tvb, curr_offset, 2,
6772                         "%s :  MSB of first digit",
6773                         a_bigbuf);
6774
6775                     curr_offset += 2;
6776
6777                     for (i=0; i < (oct_len - 2); i++)
6778                     {
6779                         a_bigbuf[i] = (oct & 0x1f) << 3;
6780
6781                         oct = tvb_get_guint8(tvb, curr_offset + i);
6782
6783                         a_bigbuf[i] |= (oct & 0xe0) >> 5;
6784                     }
6785                     a_bigbuf[i] = '\0';
6786
6787                     proto_tree_add_text(subtree, tvb, curr_offset, oct_len - 2,
6788                         "Digits: %s",
6789                         a_bigbuf);
6790
6791                     curr_offset += (oct_len - 3);
6792
6793                     other_decode_bitfield_value(a_bigbuf, oct, 0x1f, 8);
6794                     proto_tree_add_text(subtree, tvb, curr_offset, 1,
6795                         "%s :  Reserved",
6796                         a_bigbuf);
6797
6798                     curr_offset++;
6799                 }
6800                 else
6801                 {
6802                     other_decode_bitfield_value(a_bigbuf, value, 0x001f, 16);
6803                     proto_tree_add_text(subtree, tvb, curr_offset, 2,
6804                         "%s :  Reserved",
6805                         a_bigbuf);
6806
6807                     curr_offset += 2;
6808                 }
6809                 break;
6810
6811             case ANSI_REV_MS_INFO_REC_SO_INFO:
6812                 i = 0;
6813                 saved_offset = curr_offset;
6814
6815                 while ((oct_len - (curr_offset - saved_offset)) > 2)
6816                 {
6817                     item =
6818                         proto_tree_add_text(subtree,
6819                             tvb, curr_offset, 3,
6820                             "Service Option [%u]",
6821                             i + 1);
6822
6823                     subtree2 = proto_item_add_subtree(item, ett_so_list);
6824
6825                     oct = tvb_get_guint8(tvb, curr_offset);
6826
6827                     other_decode_bitfield_value(a_bigbuf, oct, 0xfc, 8);
6828                     proto_tree_add_text(subtree2, tvb, curr_offset, 1,
6829                         "%s :  Reserved",
6830                         a_bigbuf);
6831
6832                     other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
6833                     proto_tree_add_text(subtree2, tvb, curr_offset, 1,
6834                         "%s :  Forward Support: %s",
6835                         a_bigbuf,
6836                         (oct & 0x02) ? "TRUE" : "FALSE");
6837
6838                     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
6839                     proto_tree_add_text(subtree2, tvb, curr_offset, 1,
6840                         "%s :  Reverse Support: %s",
6841                         a_bigbuf,
6842                         (oct & 0x01) ? "TRUE" : "FALSE");
6843
6844                     curr_offset++;
6845
6846                     value = tvb_get_ntohs(tvb, curr_offset);
6847
6848                     str = ansi_a_so_int_to_str(value);
6849                     proto_tree_add_text(subtree2, tvb, curr_offset, 2,
6850                         "Service Option:  %s (%u)",
6851                         str,
6852                         value);
6853
6854                     proto_item_append_text(item, " - (%u) %s", value, str);
6855
6856                     i++;
6857                     curr_offset += 2;
6858                 }
6859                 break;
6860
6861             default:
6862                 proto_tree_add_text(subtree,
6863                     tvb, curr_offset, oct_len,
6864                     "Record Content");
6865
6866                 curr_offset += oct_len;
6867                 break;
6868             }
6869         }
6870     }
6871
6872     g_snprintf(add_string, string_len, " - %u record%s",
6873         num_recs, plurality(num_recs, "", "s"));
6874
6875     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
6876
6877     return(curr_offset - offset);
6878 }
6879
6880 /*
6881  * IOS 6.2.2.73
6882  */
6883 static guint8
6884 elem_ext_ho_dir_params(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
6885 {
6886     guint8      oct;
6887     guint32     value;
6888     guint32     curr_offset;
6889     const gchar *str;
6890
6891     curr_offset = offset;
6892
6893     oct = tvb_get_guint8(tvb, curr_offset);
6894
6895     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
6896     proto_tree_add_text(tree, tvb, curr_offset, 1,
6897         "%s :  Search Window A Size (Srch_Win_A): %u",
6898         a_bigbuf,
6899         (oct & 0xf0) >> 4);
6900
6901     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
6902     proto_tree_add_text(tree, tvb, curr_offset, 1,
6903         "%s :  Search Window N Size (Srch_Win_N): %u",
6904         a_bigbuf,
6905         oct & 0x0f);
6906
6907     curr_offset++;
6908
6909     NO_MORE_DATA_CHECK(len);
6910
6911     oct = tvb_get_guint8(tvb, curr_offset);
6912
6913     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
6914     proto_tree_add_text(tree, tvb, curr_offset, 1,
6915         "%s :  Search Window R Size (Srch_Win_R): %u",
6916         a_bigbuf,
6917         (oct & 0xf0) >> 4);
6918
6919     value = tvb_get_guint8(tvb, curr_offset + 1);
6920
6921     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
6922     proto_tree_add_text(tree, tvb, curr_offset, 1,
6923         "%s :  Add Pilot Threshold (T_Add) (MSB): %u",
6924         a_bigbuf,
6925         (oct & 0x0f) << 2 | (value & 0xc0) >> 6);
6926
6927     curr_offset++;
6928
6929     oct = value;
6930
6931     other_decode_bitfield_value(a_bigbuf, oct, 0xc0, 8);
6932     proto_tree_add_text(tree, tvb, curr_offset, 1,
6933         "%s :  Add Pilot Threshold (T_Add) (LSB)",
6934         a_bigbuf);
6935
6936     other_decode_bitfield_value(a_bigbuf, oct, 0x3f, 8);
6937     proto_tree_add_text(tree, tvb, curr_offset, 1,
6938         "%s :  Drop Pilot Threshold (T_Drop): %u",
6939         a_bigbuf,
6940         oct & 0x3f);
6941
6942     curr_offset++;
6943
6944     NO_MORE_DATA_CHECK(len);
6945
6946     oct = tvb_get_guint8(tvb, curr_offset);
6947
6948     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
6949     proto_tree_add_text(tree, tvb, curr_offset, 1,
6950         "%s :  Compare Threshold (T_Comp): %u",
6951         a_bigbuf,
6952         (oct & 0xf0) >> 4);
6953
6954     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
6955     proto_tree_add_text(tree, tvb, curr_offset, 1,
6956         "%s :  Drop Timer Value (T_TDrop): %u",
6957         a_bigbuf,
6958         oct & 0x0f);
6959
6960     curr_offset++;
6961
6962     NO_MORE_DATA_CHECK(len);
6963
6964     oct = tvb_get_guint8(tvb, curr_offset);
6965
6966     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
6967     proto_tree_add_text(tree, tvb, curr_offset, 1,
6968         "%s :  Neighbor Max Age (Nghbor_Max_AGE): %u",
6969         a_bigbuf,
6970         (oct & 0xf0) >> 4);
6971
6972     switch (global_a_variant)
6973     {
6974     case A_VARIANT_IOS401:
6975         other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
6976         proto_tree_add_text(tree, tvb, curr_offset, 1,
6977             "%s :  Reserved",
6978             a_bigbuf);
6979         break;
6980
6981     case A_VARIANT_IOS501:
6982         other_decode_bitfield_value(a_bigbuf, oct, 0x0c, 8);
6983         proto_tree_add_text(tree, tvb, curr_offset, 1,
6984             "%s :  Reserved",
6985             a_bigbuf);
6986
6987         switch (oct & 0x03)
6988         {
6989         case 0: str = "Only Search Window A Size is valid"; break;
6990         case 1: str = "Subset is valid"; break;
6991         case 2: str = "All fields valid"; break;
6992         default:
6993             str = "Reserved";
6994             break;
6995         }
6996
6997         other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
6998         proto_tree_add_text(tree, tvb, curr_offset, 1,
6999             "%s :  Target BS Values Included: %s",
7000             a_bigbuf,
7001             str);
7002         break;
7003     }
7004
7005     curr_offset++;
7006
7007     NO_MORE_DATA_CHECK(len);
7008
7009     oct = tvb_get_guint8(tvb, curr_offset);
7010
7011     other_decode_bitfield_value(a_bigbuf, oct, 0xc0, 8);
7012     proto_tree_add_text(tree, tvb, curr_offset, 1,
7013         "%s :  Reserved",
7014         a_bigbuf);
7015
7016     other_decode_bitfield_value(a_bigbuf, oct, 0x3f, 8);
7017     proto_tree_add_text(tree, tvb, curr_offset, 1,
7018         "%s :  SOFT_SLOPE: %u",
7019         a_bigbuf,
7020         oct & 0x3f);
7021
7022     curr_offset++;
7023
7024     NO_MORE_DATA_CHECK(len);
7025
7026     oct = tvb_get_guint8(tvb, curr_offset);
7027
7028     other_decode_bitfield_value(a_bigbuf, oct, 0xc0, 8);
7029     proto_tree_add_text(tree, tvb, curr_offset, 1,
7030         "%s :  Reserved",
7031         a_bigbuf);
7032
7033     other_decode_bitfield_value(a_bigbuf, oct, 0x3f, 8);
7034     proto_tree_add_text(tree, tvb, curr_offset, 1,
7035         "%s :  ADD_INTERCEPT: %u",
7036         a_bigbuf,
7037         oct & 0x3f);
7038
7039     curr_offset++;
7040
7041     NO_MORE_DATA_CHECK(len);
7042
7043     oct = tvb_get_guint8(tvb, curr_offset);
7044
7045     other_decode_bitfield_value(a_bigbuf, oct, 0xc0, 8);
7046     proto_tree_add_text(tree, tvb, curr_offset, 1,
7047         "%s :  Reserved",
7048         a_bigbuf);
7049
7050     other_decode_bitfield_value(a_bigbuf, oct, 0x3f, 8);
7051     proto_tree_add_text(tree, tvb, curr_offset, 1,
7052         "%s :  DROP_INTERCEPT: %u",
7053         a_bigbuf,
7054         oct & 0x3f);
7055
7056     curr_offset++;
7057
7058     NO_MORE_DATA_CHECK(len);
7059
7060     oct = tvb_get_guint8(tvb, curr_offset);
7061
7062     proto_tree_add_text(tree, tvb, curr_offset, 1,
7063         "Target BS P_REV: %u",
7064         oct);
7065
7066     curr_offset++;
7067
7068     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
7069
7070     return(curr_offset - offset);
7071 }
7072
7073 /*
7074  * IOS 6.2.2.74
7075  * UNUSED in SPEC and no IEI!
7076  */
7077
7078 /*
7079  * IOS 6.2.2.75
7080  * UNUSED in SPEC and no IEI!
7081  */
7082
7083 /*
7084  * IOS 6.2.2.76
7085  * UNUSED
7086  */
7087
7088 /*
7089  * IOS 6.2.2.77
7090  * UNUSED in SPEC and no IEI!
7091  */
7092
7093 /*
7094  * IOS 6.2.2.78
7095  * UNUSED in SPEC and no IEI!
7096  */
7097
7098 /*
7099  * IOS 6.2.2.79
7100  */
7101 static guint8
7102 elem_cdma_sowd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
7103 {
7104     guint8      oct;
7105     guint32     value;
7106     guint32     curr_offset;
7107     const gchar *str = NULL;
7108
7109     curr_offset = offset;
7110
7111     curr_offset += elem_cell_id(tvb, pinfo, tree, offset, len, add_string, string_len);
7112     add_string[0] = '\0';
7113
7114     value = tvb_get_ntohs(tvb, curr_offset);
7115
7116     proto_tree_add_text(tree,
7117         tvb, curr_offset, 2,
7118         "CDMA Serving One Way Delay: %u",
7119         value);
7120
7121     curr_offset += 2;
7122
7123     oct = tvb_get_guint8(tvb, curr_offset);
7124
7125     other_decode_bitfield_value(a_bigbuf, oct, 0xfc, 8);
7126     proto_tree_add_text(tree,
7127         tvb, curr_offset, 1,
7128         "%s :  Reserved",
7129         a_bigbuf);
7130
7131     switch (oct & 0x03)
7132     {
7133     case 0: str = "100 nsec"; break;
7134     case 1: str = "50 nsec"; break;
7135     case 2: str = "1/16 CDMA PN Chip"; break;
7136     case 3: str = "Reserved"; break;
7137     }
7138
7139     other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
7140     proto_tree_add_text(tree,
7141         tvb, curr_offset, 1,
7142         "%s :  Resolution: %s",
7143         a_bigbuf,
7144         str);
7145
7146     curr_offset++;
7147
7148     if ((len - (curr_offset - offset)) > 1)
7149     {
7150         proto_tree_add_text(tree,
7151             tvb, curr_offset, 2,
7152             "Timestamp");
7153
7154         curr_offset += 2;
7155     }
7156
7157     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
7158
7159     return(curr_offset - offset);
7160 }
7161
7162 /*
7163  * IOS 6.2.2.80
7164  * UNUSED
7165  */
7166
7167 /*
7168  * IOS 6.2.2.81
7169  * UNUSED
7170  */
7171
7172 /*
7173  * IOS 6.2.2.82
7174  */
7175 static guint8
7176 elem_re_res(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
7177 {
7178     guint8      oct;
7179     guint32     curr_offset;
7180     const gchar *str;
7181
7182     curr_offset = offset;
7183
7184     oct = tvb_get_guint8(tvb, curr_offset);
7185
7186     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
7187     proto_tree_add_text(tree,
7188         tvb, curr_offset, 1,
7189         "%s :  Reserved",
7190         a_bigbuf);
7191
7192     other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
7193     proto_tree_add_text(tree,
7194         tvb, curr_offset, 1,
7195         "%s :  Include Priority: MSC %s include priority in Assignment Request",
7196         a_bigbuf,
7197         (oct & 0x40) ? "should" : "does not need to");
7198
7199     switch ((oct & 0x30) >> 4)
7200     {
7201     case 0: str = "Not reported"; break;
7202     case 1: str = "radio environment is acceptable"; break;
7203     case 2: str = "radio environment is marginally acceptable"; break;
7204     default:
7205         str = "radio environment is poor";
7206         break;
7207     }
7208
7209     other_decode_bitfield_value(a_bigbuf, oct, 0x30, 8);
7210     proto_tree_add_text(tree,
7211         tvb, curr_offset, 1,
7212         "%s :  Forward: %s",
7213         a_bigbuf,
7214         str);
7215
7216     switch ((oct & 0x0c) >> 2)
7217     {
7218     case 0: str = "Not reported"; break;
7219     case 1: str = "radio environment is acceptable"; break;
7220     case 2: str = "radio environment is marginally acceptable"; break;
7221     default:
7222         str = "radio environment is poor";
7223         break;
7224     }
7225
7226     other_decode_bitfield_value(a_bigbuf, oct, 0x0c, 8);
7227     proto_tree_add_text(tree,
7228         tvb, curr_offset, 1,
7229         "%s :  Reverse: %s",
7230         a_bigbuf,
7231         str);
7232
7233     other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
7234     proto_tree_add_text(tree,
7235         tvb, curr_offset, 1,
7236         "%s :  Alloc: resources are %sallocated",
7237         a_bigbuf,
7238         (oct & 0x02) ? "" : "not ");
7239
7240     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
7241     proto_tree_add_text(tree,
7242         tvb, curr_offset, 1,
7243         "%s :  Avail: resources are %savailable",
7244         a_bigbuf,
7245         (oct & 0x01) ? "" : "not ");
7246
7247     curr_offset++;
7248
7249     /* no length check possible */
7250
7251     return(curr_offset - offset);
7252 }
7253
7254 /*
7255  * IOS 6.2.2.83
7256  * UNUSED in SPEC and no IEI!
7257  */
7258
7259 /*
7260  * IOS 6.2.2.84
7261  * UNUSED
7262  */
7263
7264 /*
7265  * IOS 6.2.2.85
7266  * UNUSED
7267  */
7268
7269 /*
7270  * IOS 6.2.2.86
7271  * UNUSED
7272  */
7273
7274 /*
7275  * IOS 6.2.2.87
7276  * UNUSED
7277  */
7278
7279 /*
7280  * IOS 6.2.2.88
7281  * UNUSED
7282  */
7283
7284 /*
7285  * IOS 6.2.2.89
7286  * A3/A7
7287  */
7288
7289 /*
7290  * IOS 6.2.2.90
7291  * UNUSED in SPEC and no IEI!
7292  */
7293
7294 /*
7295  * IOS 6.2.2.91
7296  * A3/A7
7297  */
7298
7299 /*
7300  * IOS 6.2.2.92
7301  * UNUSED
7302  */
7303
7304 /*
7305  * IOS 6.2.2.93
7306  * UNUSED
7307  */
7308
7309 /*
7310  * IOS 6.2.2.94
7311  * UNUSED
7312  */
7313
7314 /*
7315  * IOS 6.2.2.95
7316  * UNUSED
7317  */
7318
7319 /*
7320  * IOS 6.2.2.96
7321  * A3/A7
7322  */
7323
7324 /*
7325  * IOS 6.2.2.97
7326  * A3/A7
7327  */
7328
7329 /*
7330  * IOS 6.2.2.98
7331  * A3/A7
7332  */
7333
7334 /*
7335  * IOS 6.2.2.99
7336  * A3/A7
7337  */
7338
7339 /*
7340  * IOS 6.2.2.100
7341  * UNUSED
7342  */
7343
7344 /*
7345  * IOS 6.2.2.101
7346  * UNUSED
7347  */
7348
7349 /*
7350  * IOS 6.2.2.102
7351  * UNUSED
7352  */
7353
7354 /*
7355  * IOS 6.2.2.103
7356  * UNUSED
7357  */
7358
7359 /*
7360  * IOS 6.2.2.104
7361  * UNUSED
7362  */
7363
7364 /*
7365  * IOS 6.2.2.105
7366  */
7367 static guint8
7368 elem_cld_party_ascii_num(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
7369 {
7370     guint8      oct;
7371     guint32     curr_offset;
7372     guint8      *poctets;
7373     const gchar *str;
7374
7375     curr_offset = offset;
7376
7377     oct = tvb_get_guint8(tvb, curr_offset);
7378
7379     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
7380     proto_tree_add_text(tree, tvb, curr_offset, 1,
7381         "%s :  Extension",
7382         a_bigbuf);
7383
7384     switch ((oct & 0x70) >> 4)
7385     {
7386     case 0: str = "Unknown"; break;
7387     case 1: str = "International number"; break;
7388     case 2: str = "National number"; break;
7389     case 3: str = "Network specific number"; break;
7390     case 4: str = "Dedicated PAD access, short code"; break;
7391     case 7: str = "Reserved for extension"; break;
7392     default:
7393         str = "Reserved";
7394         break;
7395     }
7396
7397     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
7398     proto_tree_add_text(tree,
7399         tvb, curr_offset, 1,
7400         "%s :  Type of Number: %s",
7401         a_bigbuf,
7402         str);
7403
7404     switch (oct & 0x0f)
7405     {
7406     case 0x00: str = "Unknown"; break;
7407     case 0x01: str = "ISDN/telephony number plan (ITU recommendation E.164/E.163)"; break;
7408     case 0x03: str = "Data number plan (ITU recommendation X.121)"; break;
7409     case 0x04: str = "Telex numbering plan (ITU recommendation F.69)"; break;
7410     case 0x07: str = "Reserved for extension"; break;
7411     case 0x08: str = "National numbering plan"; break;
7412     case 0x09: str = "Private numbering plan"; break;
7413     default:
7414         str = "Reserved";
7415         break;
7416     }
7417
7418     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
7419     proto_tree_add_text(tree,
7420         tvb, curr_offset, 1,
7421         "%s :  Numbering Plan Identification: %s",
7422         a_bigbuf,
7423         str);
7424
7425     curr_offset++;
7426
7427     poctets = tvb_get_ephemeral_string(tvb, curr_offset, len - (curr_offset - offset));
7428
7429     proto_tree_add_string_format(tree, hf_ansi_a_cld_party_ascii_num,
7430         tvb, curr_offset, len - (curr_offset - offset),
7431         (gchar *) poctets,
7432         "Digits: %s",
7433         (gchar *) format_text(poctets, len - (curr_offset - offset)));
7434
7435     curr_offset += len - (curr_offset - offset);
7436
7437     g_snprintf(add_string, string_len, " - (%s)", poctets);
7438
7439     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
7440
7441     return(curr_offset - offset);
7442 }
7443
7444 /*
7445  * IOS 6.2.2.106
7446  */
7447 static guint8
7448 elem_band_class(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
7449 {
7450     guint8      oct;
7451     guint32     curr_offset;
7452     gint        temp_int;
7453     const gchar *str;
7454
7455     curr_offset = offset;
7456
7457     oct = tvb_get_guint8(tvb, curr_offset);
7458
7459     other_decode_bitfield_value(a_bigbuf, oct, 0xe0, 8);
7460     proto_tree_add_text(tree,
7461         tvb, curr_offset, 1,
7462         "%s :  Reserved",
7463         a_bigbuf);
7464
7465     temp_int = oct & 0x1f;
7466     if ((temp_int < 0) || (temp_int >= (gint) NUM_BAND_CLASS_STR))
7467     {
7468         str = "Reserved";
7469     }
7470     else
7471     {
7472         str = band_class_str[temp_int];
7473     }
7474
7475     other_decode_bitfield_value(a_bigbuf, oct, 0x1f, 8);
7476     proto_tree_add_text(tree,
7477         tvb, curr_offset, 1,
7478         "%s :  Band Class: %s",
7479         a_bigbuf,
7480         str);
7481
7482     curr_offset++;
7483
7484     g_snprintf(add_string, string_len, " - (%s)", str);
7485
7486     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
7487
7488     return(curr_offset - offset);
7489 }
7490
7491 /*
7492  * IOS 6.2.2.107
7493  * UNUSED
7494  */
7495
7496 /*
7497  * IOS 6.2.2.108
7498  * A3/A7
7499  */
7500
7501 /*
7502  * IOS 6.2.2.109
7503  * A3/A7
7504  */
7505
7506 /*
7507  * IOS 6.2.2.110
7508  */
7509 static guint8
7510 elem_is2000_cause(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
7511 {
7512     guint32     curr_offset;
7513
7514     curr_offset = offset;
7515
7516     proto_tree_add_text(tree, tvb, curr_offset, len, "IS-95/IS-2000 Cause Information");
7517
7518     curr_offset += len;
7519
7520     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
7521
7522     return(curr_offset - offset);
7523 }
7524
7525 /*
7526  * IOS 6.2.2.111
7527  * UNUSED
7528  */
7529
7530 /*
7531  * IOS 6.2.2.112
7532  * UNUSED
7533  */
7534
7535 /*
7536  * IOS 6.2.2.113
7537  * UNUSED
7538  */
7539
7540 /*
7541  * IOS 6.2.2.114
7542  */
7543 static guint8
7544 elem_auth_event(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
7545 {
7546     guint8      oct;
7547     guint32     curr_offset;
7548     const gchar *str;
7549
7550     curr_offset = offset;
7551
7552     if (len == 1)
7553     {
7554         oct = tvb_get_guint8(tvb, curr_offset);
7555
7556         switch (oct)
7557         {
7558         case 0x01: str = "Event: Authentication parameters were NOT received from mobile"; break;
7559         case 0x02: str = "Event: RANDC mis-match"; break;
7560         case 0x03: str = "Event: Recently requested"; break;
7561         case 0x04: str = "Event: Direct channel assignment"; break;
7562         default:
7563             str = "Event";
7564             break;
7565         }
7566
7567         proto_tree_add_text(tree, tvb, curr_offset, len,
7568             "%s", str);
7569     }
7570     else
7571     {
7572         proto_tree_add_text(tree, tvb, curr_offset, len, "Event");
7573     }
7574
7575     curr_offset += len;
7576
7577     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
7578
7579     return(curr_offset - offset);
7580 }
7581
7582 /*
7583  * IOS 6.2.2.115
7584  * UNUSED
7585  */
7586
7587 /*
7588  * IOS 6.2.2.116
7589  * UNUSED
7590  */
7591
7592 /*
7593  * IOS 6.2.2.117
7594  * UNUSED
7595  */
7596
7597 /*
7598  * IOS 6.2.2.118
7599  * UNUSED
7600  */
7601
7602 /*
7603  * IOS 6.2.2.119
7604  * A3/A7
7605  */
7606
7607 /*
7608  * IOS 6.2.2.120
7609  * A3/A7
7610  */
7611
7612 /*
7613  * IOS 6.2.2.121
7614  * A3/A7
7615  */
7616
7617 /*
7618  * IOS 6.2.2.122
7619  * UNUSED
7620  */
7621
7622 /*
7623  * IOS 6.2.2.123
7624  * UNUSED
7625  */
7626
7627 /*
7628  * IOS 6.2.2.124
7629  * UNUSED
7630  */
7631
7632 /*
7633  * IOS 6.2.2.125
7634  * A3/A7
7635  */
7636
7637 /*
7638  * IOS 6.2.2.126
7639  * UNUSED
7640  */
7641
7642 /*
7643  * IOS 6.2.2.127
7644  * UNUSED
7645  */
7646
7647 /*
7648  * IOS 6.2.2.128
7649  * A3/A7
7650  */
7651
7652 /*
7653  * IOS 6.2.2.129
7654  * UNUSED
7655  */
7656
7657 /*
7658  * IOS 6.2.2.130
7659  * UNUSED
7660  */
7661
7662 /*
7663  * IOS 6.2.2.131
7664  * UNUSED
7665  */
7666
7667 /*
7668  * IOS 6.2.2.132
7669  * A3/A7
7670  */
7671
7672 /*
7673  * IOS 6.2.2.133
7674  * UNUSED
7675  */
7676
7677 /*
7678  * IOS 6.2.2.134
7679  * A3/A7
7680  */
7681
7682 /*
7683  * IOS 6.2.2.135
7684  * UNUSED
7685  */
7686
7687 /*
7688  * IOS 6.2.2.136
7689  * UNUSED
7690  */
7691
7692 /*
7693  * IOS 6.2.2.137
7694  * Generic decode is good enough
7695  */
7696
7697 /*
7698  * IOS 6.2.2.138
7699  */
7700 static guint8
7701 elem_psmm_count(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
7702 {
7703     guint8      oct;
7704     guint32     curr_offset;
7705
7706     curr_offset = offset;
7707
7708     oct = tvb_get_guint8(tvb, curr_offset);
7709
7710     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
7711     proto_tree_add_text(tree,
7712         tvb, curr_offset, 1,
7713         "%s :  Reserved",
7714         a_bigbuf);
7715
7716     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
7717     proto_tree_add_text(tree,
7718         tvb, curr_offset, 1,
7719         "%s :  PSMM Count: %u",
7720         a_bigbuf,
7721         oct & 0x0f);
7722
7723     curr_offset++;
7724
7725     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
7726
7727     return(curr_offset - offset);
7728 }
7729
7730 /*
7731  * IOS 6.2.2.139
7732  */
7733 static guint8
7734 elem_geo_loc(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
7735 {
7736     guint32     curr_offset;
7737
7738     curr_offset = offset;
7739
7740     proto_tree_add_text(tree, tvb, curr_offset, len, "Calling Geodetic Location");
7741
7742     curr_offset += len;
7743
7744     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
7745
7746     return(curr_offset - offset);
7747 }
7748
7749 /*
7750  * IOS 6.2.2.140
7751  * UNUSED
7752  */
7753
7754 /*
7755  * IOS 6.2.2.141
7756  * A3/A7
7757  */
7758
7759 /*
7760  * IOS 6.2.2.142
7761  * A3/A7
7762  */
7763
7764 /*
7765  * IOS 6.2.2.143
7766  * A3/A7
7767  */
7768
7769 /*
7770  * IOS 6.2.2.144
7771  * A3/A7
7772  */
7773
7774 /*
7775  * IOS 6.2.2.145
7776  * A3/A7
7777  */
7778
7779 /*
7780  * IOS 6.2.2.146
7781  * A3/A7
7782  */
7783
7784 /*
7785  * IOS 6.2.2.147
7786  * A3/A7
7787  */
7788
7789 /*
7790  * IOS 6.2.2.148
7791  */
7792 static guint8
7793 elem_cct_group(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
7794 {
7795     guint8      oct;
7796     guint32     value;
7797     guint32     curr_offset;
7798
7799     curr_offset = offset;
7800
7801     oct = tvb_get_guint8(tvb, curr_offset);
7802
7803     other_decode_bitfield_value(a_bigbuf, oct, 0xfc, 8);
7804     proto_tree_add_text(tree,
7805         tvb, curr_offset, 1,
7806         "%s :  Reserved",
7807         a_bigbuf);
7808
7809     other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
7810     proto_tree_add_text(tree,
7811         tvb, curr_offset, 1,
7812         "%s :  All Circuits",
7813         a_bigbuf);
7814
7815     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
7816     proto_tree_add_text(tree,
7817         tvb, curr_offset, 1,
7818         "%s :  Inclusive",
7819         a_bigbuf);
7820
7821     curr_offset++;
7822
7823     NO_MORE_DATA_CHECK(len);
7824
7825     oct = tvb_get_guint8(tvb, curr_offset);
7826
7827     proto_tree_add_text(tree,
7828         tvb, curr_offset, 1,
7829         "Count: %u circuit%s",
7830         oct, plurality(oct, "", "s"));
7831
7832     g_snprintf(add_string, string_len, " - %u circuit%s",
7833         oct, plurality(oct, "", "s"));
7834
7835     curr_offset++;
7836
7837     value = tvb_get_ntohs(tvb, curr_offset);
7838
7839     other_decode_bitfield_value(a_bigbuf, value, 0xffe0, 16);
7840     proto_tree_add_text(tree,
7841         tvb, curr_offset, 2,
7842         "%s :  PCM Multiplexer: %u",
7843         a_bigbuf,
7844         (value & 0xffe0) >> 5);
7845
7846     other_decode_bitfield_value(a_bigbuf, value, 0x001f, 16);
7847     proto_tree_add_text(tree,
7848         tvb, curr_offset, 2,
7849         "%s :  Timeslot: %u",
7850         a_bigbuf,
7851         value & 0x001f);
7852
7853     curr_offset += 2;
7854
7855     NO_MORE_DATA_CHECK(len);
7856
7857     proto_tree_add_text(tree,
7858         tvb, curr_offset, len - (curr_offset - offset),
7859         "Circuit Bitmap");
7860
7861     curr_offset += len - (curr_offset - offset);
7862
7863     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
7864
7865     return(curr_offset - offset);
7866 }
7867
7868 /*
7869  * IOS 6.2.2.149
7870  */
7871 static guint8
7872 elem_paca_ts(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
7873 {
7874     guint32     curr_offset;
7875
7876     curr_offset = offset;
7877
7878     proto_tree_add_text(tree, tvb, curr_offset, len, "PACA Queuing Time");
7879
7880     curr_offset += len;
7881
7882     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
7883
7884     return(curr_offset - offset);
7885 }
7886
7887 /*
7888  * IOS 6.2.2.150
7889  */
7890 static guint8
7891 elem_paca_order(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
7892 {
7893     guint8      oct;
7894     guint32     curr_offset;
7895     const gchar *str;
7896
7897     curr_offset = offset;
7898
7899     oct = tvb_get_guint8(tvb, curr_offset);
7900
7901     other_decode_bitfield_value(a_bigbuf, oct, 0xf8, 8);
7902     proto_tree_add_text(tree,
7903         tvb, curr_offset, 1,
7904         "%s :  Reserved",
7905         a_bigbuf);
7906
7907     switch (oct & 0x07)
7908     {
7909     case 0: str = "Reserved"; break;
7910     case 1: str = "Update Queue Position and notify MS"; break;
7911     case 2: str = "Remove MS from the queue and release MS"; break;
7912     case 3: str = "Remove MS from the queue"; break;
7913     case 4: str = "MS Requested PACA Cancel"; break;
7914     case 5: str = "BS Requested PACA Cancel"; break;
7915     default:
7916         str = "Reserved";
7917         break;
7918     }
7919
7920     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
7921     proto_tree_add_text(tree,
7922         tvb, curr_offset, 1,
7923         "%s :  PACA Action Required: %s",
7924         a_bigbuf,
7925         str);
7926
7927     curr_offset++;
7928
7929     g_snprintf(add_string, string_len, " - (%s)", str);
7930
7931     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
7932
7933     return(curr_offset - offset);
7934 }
7935
7936 /*
7937  * IOS 6.2.2.151
7938  */
7939 static guint8
7940 elem_paca_reoi(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
7941 {
7942     guint8      oct;
7943     guint32     curr_offset;
7944
7945     curr_offset = offset;
7946
7947     oct = tvb_get_guint8(tvb, curr_offset);
7948
7949     other_decode_bitfield_value(a_bigbuf, oct, 0xfe, 8);
7950     proto_tree_add_text(tree,
7951         tvb, curr_offset, 1,
7952         "%s :  Reserved",
7953         a_bigbuf);
7954
7955     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
7956     proto_tree_add_text(tree,
7957         tvb, curr_offset, 1,
7958         "%s :  PACA Reorigination Indicator (PRI)",
7959         a_bigbuf);
7960
7961     curr_offset++;
7962
7963     g_snprintf(add_string, string_len, " - (%sReorigination)", (oct & 0x01) ? "" : "Not ");
7964
7965     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
7966
7967     return(curr_offset - offset);
7968 }
7969
7970 /*
7971  * IOS 5 4.2.89
7972  */
7973 static guint8
7974 elem_a2p_bearer_session(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
7975 {
7976     guint8      oct;
7977     guint32     curr_offset;
7978
7979     curr_offset = offset;
7980
7981     oct = tvb_get_guint8(tvb, curr_offset);
7982
7983     other_decode_bitfield_value(a_bigbuf, oct, 0xc0, 8);
7984     proto_tree_add_text(tree,
7985         tvb, curr_offset, 1,
7986         "%s :  Reserved",
7987         a_bigbuf);
7988
7989     other_decode_bitfield_value(a_bigbuf, oct, 0x38, 8);
7990     proto_tree_add_text(tree,
7991         tvb, curr_offset, 1,
7992         "%s :  Max Frames: %u",
7993         a_bigbuf,
7994         (oct & 0x38) >> 3);
7995
7996     other_decode_bitfield_value(a_bigbuf, oct, 0x06, 8);
7997     proto_tree_add_text(tree,
7998         tvb, curr_offset, 1,
7999         "%s :  Session IP Address Type: Internet Protocol IPv%s",
8000         a_bigbuf,
8001         ((oct & 0x06) >> 1) ? "6" : "4");
8002
8003     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
8004     proto_tree_add_text(tree,
8005         tvb, curr_offset, 1,
8006         "%s :  Session Address Flag",
8007         a_bigbuf);
8008
8009     curr_offset++;
8010
8011     if (oct & 0x01)
8012     {
8013         /* session address included */
8014
8015         if ((oct & 0x06) >> 1)
8016         {
8017             SHORT_DATA_CHECK(len - (curr_offset - offset), 18);
8018
8019             proto_tree_add_item(tree, hf_ansi_a_a2p_bearer_ipv6_addr,
8020                 tvb, curr_offset, 16, ENC_NA);
8021
8022             rtp_src_addr.type = AT_IPv6;
8023             rtp_src_addr.len = 16;
8024             rtp_src_addr.data = (guint8 *) &rtp_ipv6_addr;
8025
8026             tvb_get_ipv6(tvb, curr_offset, &rtp_ipv6_addr);
8027
8028             curr_offset += 16;
8029         }
8030         else
8031         {
8032             SHORT_DATA_CHECK(len - (curr_offset - offset), 6);
8033
8034             proto_tree_add_item(tree, hf_ansi_a_a2p_bearer_ipv4_addr,
8035                 tvb, curr_offset, 4, ENC_BIG_ENDIAN);
8036
8037             rtp_src_addr.type = AT_IPv4;
8038             rtp_src_addr.len = 4;
8039             rtp_src_addr.data = (guint8 *) &rtp_ipv4_addr;
8040
8041             rtp_ipv4_addr = tvb_get_ipv4(tvb, curr_offset);
8042
8043             curr_offset += 4;
8044         }
8045
8046         proto_tree_add_item(tree, hf_ansi_a_a2p_bearer_udp_port,
8047             tvb, curr_offset, 2, ENC_BIG_ENDIAN);
8048
8049         rtp_port = tvb_get_ntohs(tvb, curr_offset);
8050
8051         curr_offset += 2;
8052     }
8053
8054     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
8055
8056     return(curr_offset - offset);
8057 }
8058
8059 static void
8060 free_encoding_name_str(void *ptr)
8061 {
8062     encoding_name_and_rate_t    *encoding_name_and_rate = (encoding_name_and_rate_t *) ptr;
8063
8064     if (encoding_name_and_rate->encoding_name)
8065     {
8066         g_free(encoding_name_and_rate->encoding_name);
8067     }
8068 }
8069
8070 /*
8071  * IOS 5 4.2.90
8072  */
8073 static guint8
8074 elem_a2p_bearer_format(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
8075 {
8076     guint8                              oct;
8077     proto_item                          *item;
8078     proto_tree                          *subtree;
8079     guint8                              num_bearers;
8080     guint32                             curr_offset, orig_offset;
8081     guint8                              ip_addr_type;
8082     gboolean                            ext;
8083     guint8                              ext_len;
8084     const gchar                         *str;
8085     const gchar                         *mime_type;
8086     int                                 sample_rate;
8087     gboolean                            format_assigned;
8088     gboolean                            in_band_format_assigned;
8089     gboolean                            first_assigned_found;
8090     gboolean                            rtp_dyn_payload_used;
8091     guint8                              rtp_payload_type;
8092     GHashTable                          *rtp_dyn_payload;
8093     gint                                *key;
8094     encoding_name_and_rate_t            *encoding_name_and_rate;
8095
8096     rtp_dyn_payload = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, free_encoding_name_str);
8097     rtp_dyn_payload_used = FALSE;
8098
8099     first_assigned_found = FALSE;
8100
8101     curr_offset = offset;
8102
8103     oct = tvb_get_guint8(tvb, curr_offset);
8104
8105     other_decode_bitfield_value(a_bigbuf, oct, 0xfc, 8);
8106     proto_tree_add_text(tree,
8107         tvb, curr_offset, 1,
8108         "%s :  Number of Bearer Formats: %u",
8109         a_bigbuf,
8110         (oct & 0xfc) >> 2);
8111
8112     other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
8113     proto_tree_add_text(tree,
8114         tvb, curr_offset, 1,
8115         "%s :  Session IP Address Type: Internet Protocol IPv%s",
8116         a_bigbuf,
8117         (oct & 0x03) ? "6" : "4");
8118
8119     ip_addr_type = (oct & 0x03);
8120
8121     curr_offset++;
8122
8123     num_bearers = 0;
8124
8125     while ((len - (curr_offset - offset)) > 0)
8126     {
8127         orig_offset = curr_offset;
8128
8129         item =
8130             proto_tree_add_text(tree,
8131                 tvb, curr_offset, -1,
8132                 "Bearer Format [%u]",
8133                 num_bearers + 1);
8134
8135         subtree = proto_item_add_subtree(item, ett_bearer_list);
8136
8137         oct = tvb_get_guint8(tvb, curr_offset);
8138
8139         proto_tree_add_text(subtree, tvb, curr_offset, 1,
8140             "Bearer Format Length: %u",
8141             oct);
8142
8143         curr_offset++;
8144
8145         NO_MORE_DATA_CHECK(len);
8146
8147         oct = tvb_get_guint8(tvb, curr_offset);
8148
8149         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
8150         proto_tree_add_text(subtree, tvb, curr_offset, 1,
8151             "%s :  Extension",
8152             a_bigbuf);
8153
8154         ext = (oct & 0x80) ? TRUE : FALSE;
8155
8156         format_assigned = FALSE;
8157         in_band_format_assigned = FALSE;
8158
8159         switch ((oct & 0x70) >> 4)
8160         {
8161         case 0: str = "Unknown"; break;
8162         case 1:
8163             str = "In-band signaling";
8164             in_band_format_assigned = TRUE;
8165             break;
8166         case 2:
8167             str = "Assigned";
8168             format_assigned = TRUE;
8169             break;
8170         case 3: str = "Unassigned"; break;
8171         case 4: str = "Transcoded"; break;
8172         default:
8173             str = "Reserved";
8174             break;
8175         }
8176
8177         other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
8178         proto_tree_add_text(subtree, tvb, curr_offset, 1,
8179             "%s :  Bearer Format Tag Type: %s",
8180             a_bigbuf,
8181             str);
8182
8183         /*
8184          * assuming default sampling rate of 8000Hz
8185          */
8186         sample_rate = 8000;
8187
8188         switch (oct & 0x0f)
8189         {
8190         case 0: mime_type = str = "PCMU"; break;
8191         case 1: mime_type = str = "PCMA"; break;
8192         case 2:
8193             str = "13K Vocoder";
8194             mime_type = "QCELP";
8195             break;
8196         case 3: mime_type = str = "EVRC"; break;
8197         case 4: mime_type = str = "EVRC0"; break;
8198         case 5: mime_type = str = "SMV"; break;
8199         case 6: mime_type = str = "SMV0"; break;
8200         case 7: mime_type = str = "telephone-event"; break;
8201         case 8: mime_type = str = "EVRCB"; break;
8202         case 9: mime_type = str = "EVRCB0"; break;
8203         case 10: mime_type = str = "EVRCWB"; sample_rate = 16000; break;
8204         case 11: mime_type = str = "EVRCWB0"; sample_rate = 16000; break;
8205         case 12: mime_type = str = "EVRCNW"; sample_rate = 16000; break;
8206         case 13: mime_type = str = "EVRCNW0"; sample_rate = 16000; break;
8207         default:
8208             mime_type = str = "Reserved";
8209             break;
8210         }
8211
8212         other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
8213         proto_tree_add_text(subtree, tvb, curr_offset, 1,
8214             "%s :  Bearer Format ID: %s",
8215             a_bigbuf,
8216             str);
8217
8218         proto_item_append_text(item, " - (%s)", str);
8219
8220         curr_offset++;
8221
8222         NO_MORE_DATA_CHECK(len);
8223
8224         oct = tvb_get_guint8(tvb, curr_offset);
8225
8226         rtp_payload_type = (oct & 0xfe) >> 1;
8227
8228         other_decode_bitfield_value(a_bigbuf, oct, 0xfe, 8);
8229         proto_tree_add_text(subtree, tvb, curr_offset, 1,
8230             "%s :  RTP Payload Type: %u",
8231             a_bigbuf,
8232             rtp_payload_type);
8233
8234         other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
8235         proto_tree_add_text(subtree, tvb, curr_offset, 1,
8236             "%s :  Bearer Address Flag",
8237             a_bigbuf);
8238
8239         curr_offset++;
8240
8241         if (oct & 0x01)
8242         {
8243             /* bearer address included */
8244
8245             if (ip_addr_type != 0)
8246             {
8247                 SHORT_DATA_CHECK(len - (curr_offset - offset), 18);
8248
8249                 proto_tree_add_item(subtree, hf_ansi_a_a2p_bearer_ipv6_addr,
8250                     tvb, curr_offset, 16, ENC_NA);
8251
8252                 if (format_assigned)
8253                 {
8254                     rtp_src_addr.type = AT_IPv6;
8255                     rtp_src_addr.len = 16;
8256                     rtp_src_addr.data = (guint8 *) &rtp_ipv6_addr;
8257
8258                     tvb_get_ipv6(tvb, curr_offset, &rtp_ipv6_addr);
8259                 }
8260
8261                 curr_offset += 16;
8262             }
8263             else
8264             {
8265                 SHORT_DATA_CHECK(len - (curr_offset - offset), 6);
8266
8267                 proto_tree_add_item(subtree, hf_ansi_a_a2p_bearer_ipv4_addr,
8268                     tvb, curr_offset, 4, ENC_BIG_ENDIAN);
8269
8270                 if (format_assigned)
8271                 {
8272                     rtp_src_addr.type = AT_IPv4;
8273                     rtp_src_addr.len = 4;
8274                     rtp_src_addr.data = (guint8 *) &rtp_ipv4_addr;
8275
8276                     rtp_ipv4_addr = tvb_get_ipv4(tvb, curr_offset);
8277                 }
8278
8279                 curr_offset += 4;
8280             }
8281
8282             proto_tree_add_item(subtree, hf_ansi_a_a2p_bearer_udp_port,
8283                 tvb, curr_offset, 2, ENC_BIG_ENDIAN);
8284
8285             if (format_assigned)
8286             {
8287                 rtp_port = tvb_get_ntohs(tvb, curr_offset);
8288             }
8289
8290             curr_offset += 2;
8291         }
8292
8293         if (ext)
8294         {
8295             SHORT_DATA_CHECK(len - (curr_offset - offset), 1);
8296
8297             oct = tvb_get_guint8(tvb, curr_offset);
8298
8299             ext_len = (oct & 0xf0) >> 4;
8300
8301             other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
8302             proto_tree_add_text(subtree, tvb, curr_offset, 1,
8303                 "%s :  Extension Length: %u",
8304                 a_bigbuf,
8305                 ext_len);
8306
8307             other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
8308             proto_tree_add_text(subtree, tvb, curr_offset, 1,
8309                 "%s :  Extension ID: %u",
8310                 a_bigbuf,
8311                 (oct & 0x0f));
8312
8313             curr_offset++;
8314
8315             if (ext_len > 0)
8316             {
8317                 SHORT_DATA_CHECK(len - (curr_offset - offset), ext_len);
8318
8319                 proto_tree_add_text(subtree, tvb, curr_offset, ext_len,
8320                     "Extension Parameter value");
8321
8322                 curr_offset += ext_len;
8323             }
8324         }
8325
8326         proto_item_set_len(item, curr_offset - orig_offset);
8327
8328         if (rtp_handle &&
8329             format_assigned &&
8330             (first_assigned_found == FALSE))
8331         {
8332             key = (gint *) g_malloc(sizeof(gint));
8333             *key = rtp_payload_type;
8334
8335             encoding_name_and_rate = g_malloc(sizeof(encoding_name_and_rate_t));
8336             encoding_name_and_rate->encoding_name = g_strdup(mime_type);
8337             encoding_name_and_rate->sample_rate = sample_rate;
8338
8339             g_hash_table_insert(rtp_dyn_payload, key, encoding_name_and_rate);
8340             rtp_dyn_payload_used = TRUE;
8341
8342             first_assigned_found = TRUE;
8343             rtp_add_address(pinfo, &rtp_src_addr, rtp_port, 0, "IOS5",
8344                 pinfo->fd->num, FALSE, rtp_dyn_payload);
8345         }
8346
8347         if (in_band_format_assigned)
8348         {
8349             key = (gint *) g_malloc(sizeof(gint));
8350             *key = rtp_payload_type;
8351
8352             encoding_name_and_rate = g_malloc(sizeof(encoding_name_and_rate_t));
8353             encoding_name_and_rate->encoding_name = g_strdup("telephone-event");
8354             encoding_name_and_rate->sample_rate = sample_rate;
8355
8356             g_hash_table_insert(rtp_dyn_payload, key, encoding_name_and_rate);
8357             rtp_dyn_payload_used = TRUE;
8358         }
8359
8360         num_bearers++;
8361     }
8362
8363     if (rtp_dyn_payload_used == FALSE)
8364     {
8365         rtp_free_hash_dyn_payload(rtp_dyn_payload);
8366     }
8367
8368     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
8369
8370     return(curr_offset - offset);
8371 }
8372
8373 /*
8374  * IOS 5 4.2.88
8375  */
8376 static guint8
8377 elem_ms_des_freq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len)
8378 {
8379     guint8      oct;
8380     guint32     value;
8381     gint        temp_int;
8382     guint32     curr_offset;
8383     const gchar *str;
8384
8385     curr_offset = offset;
8386
8387     oct = tvb_get_guint8(tvb, curr_offset);
8388
8389     temp_int = (oct & 0xf8) >> 3;
8390     if ((temp_int < 0) || (temp_int >= (gint) NUM_BAND_CLASS_STR))
8391     {
8392         str = "Reserved";
8393     }
8394     else
8395     {
8396         str = band_class_str[temp_int];
8397     }
8398
8399     other_decode_bitfield_value(a_bigbuf, oct, 0xf8, 8);
8400     proto_tree_add_text(tree,
8401         tvb, curr_offset, 1,
8402         "%s :  Band Class: %s",
8403         a_bigbuf,
8404         str);
8405
8406     value = tvb_get_guint8(tvb, curr_offset + 1) | ((oct & 0x07) << 8);
8407
8408     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
8409     proto_tree_add_text(tree, tvb, curr_offset, 1,
8410         "%s :  CDMA Channel (MSB): %u",
8411         a_bigbuf,
8412         value);
8413
8414     curr_offset++;
8415
8416     other_decode_bitfield_value(a_bigbuf, value & 0x00ff, 0xff, 8);
8417     proto_tree_add_text(tree, tvb, curr_offset, 1,
8418         "%s :  CDMA Channel (LSB)",
8419         a_bigbuf);
8420
8421     g_snprintf(add_string, string_len, " - (CDMA Channel: %u)", value);
8422
8423     curr_offset++;
8424
8425     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
8426
8427     return(curr_offset - offset);
8428 }
8429
8430 /*
8431  * IOS 5 4.2.87
8432  */
8433 static guint8
8434 elem_plcm_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
8435 {
8436     guint8      oct;
8437     guint32     curr_offset;
8438     const gchar *str;
8439
8440     curr_offset = offset;
8441
8442     oct = tvb_get_guint8(tvb, curr_offset);
8443
8444     /*
8445      * from C.S0005-D v1.0 L3 Table 3.7.2.3.2.21-5
8446      */
8447     switch ((oct & 0xf0) >> 4)
8448     {
8449     case 0x00: str = "PLCM derived from ESN or MEID"; break;
8450     case 0x01: str = "PLCM specified by the base station"; break;
8451     case 0x02: str = "PLCM derived from IMSI_O_S when IMSI_O is derived from IMSI_M"; break;
8452     case 0x03: str = "PLCM derived from IMSI_O_S when IMSI_O is derived from IMSI_T"; break;
8453     default:
8454         str = "Reserved";
8455         break;
8456     }
8457
8458     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
8459     proto_tree_add_text(tree,
8460         tvb, curr_offset, 1,
8461         "%s :  PLCM_TYPE: %s",
8462         a_bigbuf,
8463         str);
8464
8465     other_decode_bitfield_value(a_bigbuf, oct, 0x0c, 8);
8466     proto_tree_add_text(tree,
8467         tvb, curr_offset, 1,
8468         "%s :  Reserved",
8469         a_bigbuf);
8470
8471     other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
8472     proto_tree_add_text(tree, tvb, curr_offset, 1,
8473         "%s :  PLCM_42 (MSB)",
8474         a_bigbuf);
8475
8476     curr_offset++;
8477
8478     proto_tree_add_text(tree, tvb, curr_offset, 5, "PLCM_42");
8479
8480     curr_offset += 5;
8481
8482     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
8483
8484     return(curr_offset - offset);
8485 }
8486
8487 /*
8488  * IOS 6.2.2.152
8489  * A3/A7
8490  */
8491
8492 /*
8493  * IOS 6.2.2.153
8494  * A3/A7
8495  */
8496
8497 /*
8498  * ORDER MUST BE MAINTAINED
8499  *
8500  * The value of this enum is used as an index into
8501  * elem_1_fcn[]
8502  *
8503  */
8504 typedef enum
8505 {
8506     ANSI_A_E_ACC_NET_ID,            /* Access Network Identifiers */
8507     ANSI_A_E_ADDS_USER_PART,        /* ADDS User Part */
8508     ANSI_A_E_AMPS_HHO_PARAM,        /* AMPS Hard Handoff Parameters */
8509     ANSI_A_E_ANCH_PDSN_ADDR,        /* Anchor PDSN Address */
8510     ANSI_A_E_ANCH_PP_ADDR,          /* Anchor P-P Address */
8511     ANSI_A_E_AUTH_CHLG_PARAM,       /* Authentication Challenge Parameter */
8512     ANSI_A_E_AUTH_CNF_PARAM,        /* Authentication Confirmation Parameter (RANDC) */
8513     ANSI_A_E_AUTH_DATA,             /* Authentication Data */
8514     ANSI_A_E_AUTH_EVENT,            /* Authentication Event */
8515     ANSI_A_E_AUTH_PARAM_COUNT,      /* Authentication Parameter COUNT */
8516     ANSI_A_E_AUTH_RESP_PARAM,       /* Authentication Response Parameter */
8517     ANSI_A_E_BAND_CLASS,            /* Band Class */
8518     ANSI_A_E_CLD_PARTY_ASCII_NUM,   /* Called Party ASCII Number */
8519     ANSI_A_E_CLD_PARTY_BCD_NUM,     /* Called Party BCD Number */
8520     ANSI_A_E_CLG_PARTY_ASCII_NUM,   /* Calling Party ASCII Number */
8521     ANSI_A_E_CAUSE,                 /* Cause */
8522     ANSI_A_E_CAUSE_L3,              /* Cause Layer 3 */
8523     ANSI_A_E_CDMA_SOWD,             /* CDMA Serving One Way Delay */
8524     ANSI_A_E_CELL_ID,               /* Cell Identifier */
8525     ANSI_A_E_CELL_ID_LIST,          /* Cell Identifier List */
8526     ANSI_A_E_CHAN_NUM,              /* Channel Number */
8527     ANSI_A_E_CHAN_TYPE,             /* Channel Type */
8528     ANSI_A_E_CCT_GROUP,             /* Circuit Group */
8529     ANSI_A_E_CIC,                   /* Circuit Identity Code */
8530     ANSI_A_E_CIC_EXT,               /* Circuit Identity Code Extension */
8531     ANSI_A_E_CM_INFO_TYPE_2,        /* Classmark Information Type 2 */
8532     ANSI_A_E_DOWNLINK_RE,           /* Downlink Radio Environment */
8533     ANSI_A_E_DOWNLINK_RE_LIST,      /* Downlink Radio Environment List */
8534     ANSI_A_E_ENC_INFO,              /* Encryption Information */
8535     ANSI_A_E_EXT_HO_DIR_PARAMS,     /* Extended Handoff Direction Parameters */
8536     ANSI_A_E_GEO_LOC,               /* Geographic Location */
8537     ANSI_A_E_SSCI,                  /* Special Service Call Indicator */
8538     ANSI_A_E_HO_POW_LEV,            /* Handoff Power Level */
8539     ANSI_A_E_HHO_PARAMS,            /* Hard Handoff Parameters */
8540     ANSI_A_E_IE_REQD,               /* Information Element Requested */
8541     ANSI_A_E_IS2000_CHAN_ID,        /* IS-2000 Channel Identity */
8542     ANSI_A_E_IS2000_CHAN_ID_3X,     /* IS-2000 Channel Identity 3X */
8543     ANSI_A_E_IS2000_MOB_CAP,        /* IS-2000 Mobile Capabilities */
8544     ANSI_A_E_IS2000_NN_SCR,         /* IS-2000 Non-Negotiable Service Configuration Record */
8545     ANSI_A_E_IS2000_SCR,            /* IS-2000 Service Configuration Record */
8546     ANSI_A_E_IS2000_CAUSE,          /* IS-95/IS-2000 Cause Value */
8547     ANSI_A_E_IS2000_RED_RECORD,     /* IS-2000 Redirection Record */
8548     ANSI_A_E_IS95_CHAN_ID,          /* IS-95 Channel Identity */
8549     ANSI_A_E_IS95_MS_MEAS_CHAN_ID,  /* IS-95 MS Measured Channel Identity */
8550     ANSI_A_E_L3_INFO,               /* Layer 3 Information */
8551     ANSI_A_E_LAI,                   /* Location Area Information */
8552     ANSI_A_E_MWI,                   /* Message Waiting Indication */
8553     ANSI_A_E_MID,                   /* Mobile Identity */
8554     ANSI_A_E_FWD_MS_INFO_RECS,      /* (Forward) MS Information Records */
8555     ANSI_A_E_ORIG_CI,               /* Origination Continuation Indicator */
8556     ANSI_A_E_PACA_ORDER,            /* PACA Order */
8557     ANSI_A_E_PACA_REOI,             /* PACA Reorigination Indicator */
8558     ANSI_A_E_PACA_TS,               /* PACA Timestamp */
8559     ANSI_A_E_PSP,                   /* Packet Session Parameters */
8560     ANSI_A_E_PDSN_IP_ADDR,          /* PDSN IP Address */
8561     ANSI_A_E_PDI,                   /* Power Down Indicator */
8562     ANSI_A_E_PRIO,                  /* Priority */
8563     ANSI_A_E_P_REV,                 /* Protocol Revision */
8564     ANSI_A_E_PTYPE,                 /* Protocol Type */
8565     ANSI_A_E_PSMM_COUNT,            /* PSMM Count */
8566     ANSI_A_E_QOS_PARAMS,            /* Quality of Service Parameters */
8567     ANSI_A_E_RE_RES,                /* Radio Environment and Resources */
8568     ANSI_A_E_REG_TYPE,              /* Registration Type */
8569     ANSI_A_E_REJ_CAUSE,             /* Reject Cause */
8570     ANSI_A_E_RESP_REQ,              /* Response Request */
8571     ANSI_A_E_RETURN_CAUSE,          /* Return Cause */
8572     ANSI_A_E_RF_CHAN_ID,            /* RF Channel Identity */
8573     ANSI_A_E_SO,                    /* Service Option */
8574     ANSI_A_E_SOCI,                  /* Service Option Connection Identifier (SOCI) */
8575     ANSI_A_E_SO_LIST,               /* Service Option List */
8576     ANSI_A_E_S_RED_INFO,            /* Service Redirection Info */
8577     ANSI_A_E_SR_ID,                 /* Service Reference Identifier (SR_ID) */
8578     ANSI_A_E_SID,                   /* SID */
8579     ANSI_A_E_SIGNAL,                /* Signal */
8580     ANSI_A_E_SCI,                   /* Slot Cycle Index */
8581     ANSI_A_E_SW_VER,                /* Software Version */
8582     ANSI_A_E_SRNC_TRNC_TC,          /* Source RNC to Target RNC Transparent Container */
8583     ANSI_A_E_S_PDSN_ADDR,           /* Source PDSN Address */
8584     ANSI_A_E_TAG,                   /* Tag */
8585     ANSI_A_E_TRNC_SRNC_TC,          /* Target RNC to Source RNC Transparent Container */
8586     ANSI_A_E_XMODE,                 /* Transcoder Mode */
8587     ANSI_A_E_UZ_ID,                 /* User Zone ID */
8588     ANSI_A_E_VP_REQ,                /* Voice Privacy Request */
8589     ANSI_A_E_A2P_BEARER_SESSION,    /* A2p Bearer Session-Level Parameters */
8590     ANSI_A_E_A2P_BEARER_FORMAT,     /* A2p Bearer Format-Specific Parameters */
8591     ANSI_A_E_MS_DES_FREQ,           /* MS Designated Frequency */
8592     ANSI_A_E_MOB_SUB_INFO,          /* Mobile Subscription Information */
8593     ANSI_A_E_PLCM_ID,               /* Public Long Code Mask Identifier */
8594     ANSI_A_E_REV_MS_INFO_RECS,      /* (Reverse) MS Information Records */
8595     ANSI_A_E_NONE        /* NONE */
8596 }
8597 elem_idx_t;
8598 static elem_idx_t ansi_a_elem_1_max = 0;
8599
8600 #define MAX_IOS401_NUM_ELEM_1 (sizeof(ansi_a_ios401_elem_1_strings)/sizeof(ext_value_string_t))
8601 #define MAX_IOS501_NUM_ELEM_1 (sizeof(ansi_a_ios501_elem_1_strings)/sizeof(ext_value_string_t))
8602 static gint ett_ansi_elem_1[MAX(MAX_IOS401_NUM_ELEM_1, MAX_IOS501_NUM_ELEM_1)];
8603 static guint8 (*elem_1_fcn[])(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len, gchar *add_string, int string_len) =
8604 {
8605     elem_acc_net_id,                /* Access Network Identifiers */
8606     elem_adds_user_part,            /* ADDS User Part */
8607     elem_amps_hho_param,            /* AMPS Hard Handoff Parameters */
8608     elem_anchor_pdsn_addr,          /* Anchor PDSN Address */
8609     elem_anchor_pp_addr,            /* Anchor P-P Address */
8610     elem_auth_chlg_param,           /* Authentication Challenge Parameter */
8611     NULL /* no decode required */,  /* Authentication Confirmation Parameter (RANDC) */
8612     NULL /* no decode required */,  /* Authentication Data */
8613     elem_auth_event,                /* Authentication Event */
8614     elem_auth_param_count,          /* Authentication Parameter COUNT */
8615     elem_auth_resp_param,           /* Authentication Response Parameter */
8616     elem_band_class,                /* Band Class */
8617     elem_cld_party_ascii_num,       /* Called Party ASCII Number */
8618     elem_cld_party_bcd_num,         /* Called Party BCD Number */
8619     elem_clg_party_ascii_num,       /* Calling Party ASCII Number */
8620     elem_cause,                     /* Cause */
8621     elem_cause_l3,                  /* Cause Layer 3 */
8622     elem_cdma_sowd,                 /* CDMA Serving One Way Delay */
8623     elem_cell_id,                   /* Cell Identifier */
8624     elem_cell_id_list,              /* Cell Identifier List */
8625     elem_chan_num,                  /* Channel Number */
8626     elem_chan_type,                 /* Channel Type */
8627     elem_cct_group,                 /* Circuit Group */
8628     elem_cic,                       /* Circuit Identity Code */
8629     elem_cic_ext,                   /* Circuit Identity Code Extension */
8630     elem_cm_info_type_2,            /* Classmark Information Type 2 */
8631     elem_downlink_re,               /* Downlink Radio Environment */
8632     elem_downlink_re_list,          /* Downlink Radio Environment List */
8633     elem_enc_info,                  /* Encryption Information */
8634     elem_ext_ho_dir_params,         /* Extended Handoff Direction Parameters */
8635     elem_geo_loc,                   /* Geographic Location */
8636     elem_ssci,                      /* Special Service Call Indicator */
8637     elem_ho_pow_lev,                /* Handoff Power Level */
8638     elem_hho_params,                /* Hard Handoff Parameters */
8639     elem_info_rec_req,              /* Information Element Requested */
8640     elem_is2000_chan_id,            /* IS-2000 Channel Identity */
8641     NULL,                           /* IS-2000 Channel Identity 3X */
8642     elem_is2000_mob_cap,            /* IS-2000 Mobile Capabilities */
8643     elem_is2000_nn_scr,             /* IS-2000 Non-Negotiable Service Configuration Record */
8644     elem_is2000_scr,                /* IS-2000 Service Configuration Record */
8645     elem_is2000_cause,              /* IS-95/IS-2000 Cause Value */
8646     NULL,                           /* IS-2000 Redirection Record */
8647     elem_is95_chan_id,              /* IS-95 Channel Identity */
8648     elem_is95_ms_meas_chan_id,      /* IS-95 MS Measured Channel Identity */
8649     elem_l3_info,                   /* Layer 3 Information */
8650     elem_lai,                       /* Location Area Information */
8651     elem_mwi,                       /* Message Waiting Indication */
8652     elem_mid,                       /* Mobile Identity */
8653     elem_fwd_ms_info_recs,          /* (Forward) MS Information Records */
8654     NULL /* no associated data */,  /* Origination Continuation Indicator */
8655     elem_paca_order,                /* PACA Order */
8656     elem_paca_reoi,                 /* PACA Reorigination Indicator */
8657     elem_paca_ts,                   /* PACA Timestamp */
8658     NULL,                           /* Packet Session Parameters */
8659     elem_pdsn_ip_addr,              /* PDSN IP Address */
8660     NULL /* no associated data */,  /* Power Down Indicator */
8661     elem_prio,                      /* Priority */
8662     elem_p_rev,                     /* Protocol Revision */
8663     elem_ptype,                     /* Protocol Type */
8664     elem_psmm_count,                /* PSMM Count */
8665     elem_qos_params,                /* Quality of Service Parameters */
8666     elem_re_res,                    /* Radio Environment and Resources */
8667     elem_reg_type,                  /* Registration Type */
8668     elem_rej_cause,                 /* Reject Cause */
8669     NULL /* no associated data */,  /* Response Request */
8670     elem_return_cause,              /* Return Cause */
8671     elem_rf_chan_id,                /* RF Channel Identity */
8672     elem_so,                        /* Service Option */
8673     elem_soci,                      /* Service Option Connection Identifier (SOCI) */
8674     elem_so_list,                   /* Service Option List */
8675     NULL,                           /* Service Redirection Info */
8676     elem_sr_id,                     /* Service Reference Identifier (SR_ID) */
8677     elem_sid,                       /* SID */
8678     elem_signal,                    /* Signal */
8679     elem_sci,                       /* Slot Cycle Index */
8680     elem_sw_ver,                    /* Software Version */
8681     NULL /* transparent */,         /* Source RNC to Target RNC Transparent Container */
8682     elem_s_pdsn_ip_addr,            /* Source PDSN Address */
8683     elem_tag,                       /* Tag */
8684     NULL /* transparent */,         /* Target RNC to Source RNC Transparent Container */
8685     elem_xmode,                     /* Transcoder Mode */
8686     elem_uz_id,                     /* User Zone ID */
8687     NULL /* no associated data */,  /* Voice Privacy Request */
8688     elem_a2p_bearer_session,        /* A2p Bearer Session-Level Parameters */
8689     elem_a2p_bearer_format,         /* A2p Bearer Format-Specific Parameters */
8690     elem_ms_des_freq,               /* MS Designated Frequency */
8691     NULL,                           /* Mobile Subscription Information */
8692     elem_plcm_id,                   /* Public Long Code Mask Identification */
8693     elem_rev_ms_info_recs,          /* (Reverse) MS Information Records */
8694     NULL,        /* NONE */
8695 };
8696
8697 /* MESSAGE FUNCTIONS */
8698
8699 /*
8700  * Type Length Value (TLV) element dissector
8701  */
8702 static guint16
8703 elem_tlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, elem_idx_t idx, guint32 offset, guint len _U_, const gchar *name_add)
8704 {
8705     guint8      oct, parm_len;
8706     guint16     consumed;
8707     guint32     curr_offset;
8708     proto_tree  *subtree;
8709     proto_item  *item;
8710     gint        dec_idx;
8711
8712     curr_offset = offset;
8713     consumed = 0;
8714
8715     if ((int)idx < 0 || idx >= ansi_a_elem_1_max-1)
8716     {
8717         /* Unknown index, skip the element */
8718         return tvb_length_remaining(tvb, offset) ;
8719     }
8720
8721     oct = tvb_get_guint8(tvb, curr_offset);
8722
8723     if (oct == (guint8) ansi_a_elem_1_strings[idx].value)
8724     {
8725         dec_idx = ansi_a_elem_1_strings[idx].dec_index;
8726
8727         parm_len = tvb_get_guint8(tvb, curr_offset + 1);
8728
8729         item =
8730             proto_tree_add_text(tree,
8731                 tvb, curr_offset, parm_len + 2,
8732                 "%s%s",
8733                 ansi_a_elem_1_strings[idx].strptr,
8734                 (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
8735
8736         subtree = proto_item_add_subtree(item, ett_ansi_elem_1[idx]);
8737
8738         proto_tree_add_uint_format(subtree, hf_ansi_a_elem_id, tvb,
8739             curr_offset, 1, oct,
8740             "Element ID");
8741
8742         proto_tree_add_uint(subtree, hf_ansi_a_length, tvb,
8743             curr_offset + 1, 1, parm_len);
8744
8745         if (parm_len > 0)
8746         {
8747             if (elem_1_fcn[dec_idx] == NULL)
8748             {
8749                 proto_tree_add_text(subtree,
8750                     tvb, curr_offset + 2, parm_len,
8751                     "Element Value");
8752
8753                 consumed = parm_len;
8754             }
8755             else
8756             {
8757                 gchar *a_add_string;
8758
8759                 a_add_string = (gchar *) ep_alloc(1024);
8760                 a_add_string[0] = '\0';
8761                 consumed =
8762                     (*elem_1_fcn[dec_idx])(tvb, pinfo, subtree, curr_offset + 2,
8763                         parm_len, a_add_string, 1024);
8764
8765                 if (a_add_string[0] != '\0')
8766                 {
8767                     proto_item_append_text(item, "%s", a_add_string);
8768                 }
8769             }
8770         }
8771
8772         consumed += 2;
8773     }
8774
8775     return(consumed);
8776 }
8777
8778 /*
8779  * Type Value (TV) element dissector
8780  *
8781  * Length cannot be used in these functions, big problem if a element dissector
8782  * is not defined for these.
8783  */
8784 static guint16
8785 elem_tv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, elem_idx_t idx, guint32 offset, const gchar *name_add)
8786 {
8787     guint8      oct;
8788     guint16     consumed;
8789     guint32     curr_offset;
8790     proto_tree  *subtree;
8791     proto_item  *item;
8792     gint        dec_idx;
8793
8794
8795     curr_offset = offset;
8796     consumed = 0;
8797
8798     if ((int)idx < 0 || idx >= ansi_a_elem_1_max-1)
8799     {
8800         /* Unknown index, skip the element */
8801         return tvb_length_remaining(tvb, offset) ;
8802     }
8803
8804     oct = tvb_get_guint8(tvb, curr_offset);
8805
8806     if (oct == (guint8) ansi_a_elem_1_strings[idx].value)
8807     {
8808         dec_idx = ansi_a_elem_1_strings[idx].dec_index;
8809
8810         item =
8811             proto_tree_add_text(tree,
8812                 tvb, curr_offset, -1,
8813                 "%s%s",
8814                 ansi_a_elem_1_strings[idx].strptr,
8815                 (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
8816
8817         subtree = proto_item_add_subtree(item, ett_ansi_elem_1[idx]);
8818
8819         proto_tree_add_uint_format(subtree, hf_ansi_a_elem_id, tvb,
8820             curr_offset, 1, oct,
8821             "Element ID");
8822
8823         if (elem_1_fcn[dec_idx] == NULL)
8824         {
8825             /* BAD THING, CANNOT DETERMINE LENGTH */
8826
8827             proto_tree_add_text(subtree,
8828                 tvb, curr_offset + 1, 1,
8829                 "No element dissector, rest of dissection may be incorrect");
8830
8831             consumed = 1;
8832         }
8833         else
8834         {
8835             gchar *a_add_string;
8836
8837             a_add_string = (gchar *) ep_alloc(1024);
8838             a_add_string[0] = '\0';
8839             consumed = (*elem_1_fcn[dec_idx])(tvb, pinfo, subtree, curr_offset + 1, -1, a_add_string, 1024);
8840
8841             if (a_add_string[0] != '\0')
8842             {
8843                 proto_item_append_text(item, "%s", a_add_string);
8844             }
8845         }
8846
8847         consumed++;
8848
8849         proto_item_set_len(item, consumed);
8850     }
8851
8852     return(consumed);
8853 }
8854
8855 /*
8856  * Type (T) element dissector
8857  *
8858  * Length cannot be used in these functions, big problem if a element dissector
8859  * is not defined for these.
8860  */
8861 static guint16
8862 elem_t(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, elem_idx_t idx, guint32 offset, const gchar *name_add)
8863 {
8864     guint8      oct;
8865     guint32     curr_offset;
8866     guint16     consumed;
8867
8868
8869     curr_offset = offset;
8870     consumed = 0;
8871
8872     if ((int)idx < 0 || idx >= ansi_a_elem_1_max-1)
8873     {
8874         /* Unknown index, skip the element */
8875         return tvb_length_remaining(tvb, offset) ;
8876     }
8877
8878     oct = tvb_get_guint8(tvb, curr_offset);
8879
8880     if (oct == (guint8) ansi_a_elem_1_strings[idx].value)
8881     {
8882         proto_tree_add_uint_format(tree, hf_ansi_a_elem_id, tvb, curr_offset, 1, oct,
8883             "%s%s",
8884             ansi_a_elem_1_strings[idx].strptr,
8885             (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
8886
8887         consumed = 1;
8888     }
8889
8890     return(consumed);
8891 }
8892
8893 /*
8894  * Length Value (LV) element dissector
8895  */
8896 static guint16
8897 elem_lv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, elem_idx_t idx, guint32 offset, guint len _U_, const gchar *name_add)
8898 {
8899     guint8      parm_len;
8900     guint16     consumed;
8901     guint32     curr_offset;
8902     proto_tree  *subtree;
8903     proto_item  *item;
8904     gint        dec_idx;
8905
8906
8907     curr_offset = offset;
8908     consumed = 0;
8909
8910     if ((int)idx < 0 || idx >= ansi_a_elem_1_max-1)
8911     {
8912         /* Unknown index, skip the element */
8913         return tvb_length_remaining(tvb, offset) ;
8914     }
8915
8916     dec_idx = ansi_a_elem_1_strings[idx].dec_index;
8917
8918     parm_len = tvb_get_guint8(tvb, curr_offset);
8919
8920     item =
8921         proto_tree_add_text(tree,
8922             tvb, curr_offset, parm_len + 1,
8923             "%s%s",
8924             ansi_a_elem_1_strings[idx].strptr,
8925             (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
8926
8927     subtree = proto_item_add_subtree(item, ett_ansi_elem_1[idx]);
8928
8929     proto_tree_add_uint(subtree, hf_ansi_a_length, tvb,
8930         curr_offset, 1, parm_len);
8931
8932     if (parm_len > 0)
8933     {
8934         if (elem_1_fcn[dec_idx] == NULL)
8935         {
8936             proto_tree_add_text(subtree,
8937                 tvb, curr_offset + 1, parm_len,
8938                 "Element Value");
8939
8940             consumed = parm_len;
8941         }
8942         else
8943         {
8944             gchar *a_add_string;
8945
8946             a_add_string = (gchar *) ep_alloc(1024);
8947             a_add_string[0] = '\0';
8948             consumed =
8949                 (*elem_1_fcn[dec_idx])(tvb, pinfo, subtree, curr_offset + 1,
8950                     parm_len, a_add_string, 1024);
8951
8952             if (a_add_string[0] != '\0')
8953             {
8954                 proto_item_append_text(item, "%s", a_add_string);
8955             }
8956         }
8957     }
8958
8959     return(consumed + 1);
8960 }
8961
8962 /*
8963  * Value (V) element dissector
8964  *
8965  * Length cannot be used in these functions, big problem if a element dissector
8966  * is not defined for these.
8967  */
8968 static guint16
8969 elem_v(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, elem_idx_t idx, guint32 offset)
8970 {
8971     guint16     consumed;
8972     guint32     curr_offset;
8973     gint        dec_idx;
8974
8975     curr_offset = offset;
8976     consumed = 0;
8977
8978     if ((int)idx < 0 || idx >= ansi_a_elem_1_max-1)
8979     {
8980         /* Unknown index, skip the element */
8981         return tvb_length_remaining(tvb, offset) ;
8982     }
8983
8984     dec_idx = ansi_a_elem_1_strings[idx].dec_index;
8985
8986     if (elem_1_fcn[dec_idx] == NULL)
8987     {
8988         /* BAD THING, CANNOT DETERMINE LENGTH */
8989
8990         proto_tree_add_text(tree,
8991             tvb, curr_offset, 1,
8992             "No element dissector, rest of dissection may be incorrect");
8993
8994         consumed = 1;
8995     }
8996     else
8997     {
8998         gchar *a_add_string;
8999
9000         a_add_string = (gchar *) ep_alloc(1024);
9001         a_add_string[0] = '\0';
9002         consumed = (*elem_1_fcn[dec_idx])(tvb, pinfo, tree, curr_offset, -1, a_add_string, 1024);
9003     }
9004
9005     return(consumed);
9006 }
9007
9008
9009 #define ELEM_MAND_TLV(elem_idx, elem_name_addition) \
9010 {\
9011     if ((consumed = elem_tlv(tvb, pinfo, tree, elem_idx, curr_offset, curr_len, elem_name_addition)) > 0) \
9012     { \
9013         curr_offset += consumed; \
9014         curr_len -= consumed; \
9015     } \
9016     else \
9017     { \
9018         proto_tree_add_text(tree, \
9019             tvb, curr_offset, 0, \
9020             "Missing Mandatory element (0x%02x) %s%s, rest of dissection is suspect", \
9021                 ansi_a_elem_1_strings[elem_idx].value, \
9022                 ansi_a_elem_1_strings[elem_idx].strptr, \
9023                 (elem_name_addition == NULL) || (elem_name_addition[0] == '\0') ? "" : elem_name_addition \
9024             ); \
9025     } \
9026     if (curr_len <= 0) return; \
9027 }
9028
9029 #define ELEM_OPT_TLV(elem_idx, elem_name_addition) \
9030 {\
9031     if ((consumed = elem_tlv(tvb, pinfo, tree, elem_idx, curr_offset, curr_len, elem_name_addition)) > 0) \
9032     { \
9033         curr_offset += consumed; \
9034         curr_len -= consumed; \
9035     } \
9036     if (curr_len <= 0) return; \
9037 }
9038
9039 #define ELEM_MAND_TV(elem_idx, elem_name_addition) \
9040 {\
9041     if ((consumed = elem_tv(tvb, pinfo, tree, elem_idx, curr_offset, elem_name_addition)) > 0) \
9042     { \
9043         curr_offset += consumed; \
9044         curr_len -= consumed; \
9045     } \
9046     else \
9047     { \
9048         proto_tree_add_text(tree, \
9049             tvb, curr_offset, 0, \
9050             "Missing Mandatory element (0x%02x) %s%s, rest of dissection is suspect", \
9051                 ansi_a_elem_1_strings[elem_idx].value, \
9052                 ansi_a_elem_1_strings[elem_idx].strptr, \
9053                 (elem_name_addition == NULL) || (elem_name_addition[0] == '\0') ? "" : elem_name_addition \
9054             ); \
9055     } \
9056     if (curr_len <= 0) return; \
9057 }
9058
9059 #define ELEM_OPT_TV(elem_idx, elem_name_addition) \
9060 {\
9061     if ((consumed = elem_tv(tvb, pinfo, tree, elem_idx, curr_offset, elem_name_addition)) > 0) \
9062     { \
9063         curr_offset += consumed; \
9064         curr_len -= consumed; \
9065     } \
9066     if (curr_len <= 0) return; \
9067 }
9068
9069 #define ELEM_OPT_T(elem_idx, elem_name_addition) \
9070 {\
9071     if ((consumed = elem_t(tvb, pinfo, tree, elem_idx, curr_offset, elem_name_addition)) > 0) \
9072     { \
9073         curr_offset += consumed; \
9074         curr_len -= consumed; \
9075     } \
9076     if (curr_len <= 0) return; \
9077 }
9078
9079 #define ELEM_MAND_LV(elem_idx, elem_name_addition) \
9080 {\
9081     if ((consumed = elem_lv(tvb, pinfo, tree, elem_idx, curr_offset, curr_len, elem_name_addition)) > 0) \
9082     { \
9083         curr_offset += consumed; \
9084         curr_len -= consumed; \
9085     } \
9086     else \
9087     { \
9088         /* Mandatory, but nothing we can do */ \
9089     } \
9090     if (curr_len <= 0) return; \
9091 }
9092
9093 #define ELEM_MAND_V(elem_idx) \
9094 {\
9095     if ((consumed = elem_v(tvb, pinfo, tree, elem_idx, curr_offset)) > 0) \
9096     { \
9097         curr_offset += consumed; \
9098         curr_len -= consumed; \
9099     } \
9100     else \
9101     { \
9102         /* Mandatory, but nothing we can do */ \
9103     } \
9104     if (curr_len <= 0) return; \
9105 }
9106
9107
9108 /*
9109  * IOS 6.1.2.1
9110  */
9111 static void
9112 bsmap_cl3_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9113 {
9114     guint16      consumed;
9115     guint32     curr_offset;
9116     guint       curr_len;
9117
9118     curr_offset = offset;
9119     curr_len = len;
9120
9121     ELEM_MAND_TLV(ANSI_A_E_CELL_ID, "");
9122
9123     ELEM_MAND_TLV(ANSI_A_E_L3_INFO, "");
9124
9125     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9126 }
9127
9128 /*
9129  * IOS 6.1.2.2
9130  */
9131 static void
9132 dtap_cm_srvc_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9133 {
9134     guint32     curr_offset;
9135     guint32     consumed;
9136     guint       curr_len;
9137     guint8      oct;
9138     proto_tree  *subtree;
9139     proto_item  *item;
9140     const gchar *str;
9141
9142     curr_offset = offset;
9143     curr_len = len;
9144
9145     /*
9146      * special dissection for CM Service Type
9147      */
9148     oct = tvb_get_guint8(tvb, curr_offset);
9149
9150     switch (oct & 0x0f)
9151     {
9152     case 0x01: str = "Mobile Originating Call"; break;
9153     default:
9154         str = "Unknown";
9155         break;
9156     }
9157
9158     item =
9159         proto_tree_add_text(tree,
9160             tvb, curr_offset, 1,
9161             "CM Service Type: %s",
9162             str);
9163
9164     subtree = proto_item_add_subtree(item, ett_cm_srvc_type);
9165
9166     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
9167     proto_tree_add_text(subtree,
9168         tvb, curr_offset, 1,
9169         "%s :  Element ID",
9170         a_bigbuf);
9171
9172     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
9173     proto_tree_add_text(subtree,
9174         tvb, curr_offset, 1,
9175         "%s :  Service Type: (%u) %s",
9176         a_bigbuf,
9177         oct & 0x0f,
9178         str);
9179
9180     curr_offset++;
9181     curr_len--;
9182
9183     ELEM_MAND_LV(ANSI_A_E_CM_INFO_TYPE_2, "");
9184
9185     ELEM_MAND_LV(ANSI_A_E_MID, "");
9186
9187     ELEM_OPT_TLV(ANSI_A_E_CLD_PARTY_BCD_NUM, "");
9188
9189     ELEM_OPT_TLV(ANSI_A_E_MID, "");
9190
9191     ELEM_OPT_TV(ANSI_A_E_SCI, "");
9192
9193     ELEM_OPT_TLV(ANSI_A_E_AUTH_RESP_PARAM, "");
9194
9195     ELEM_OPT_TV(ANSI_A_E_AUTH_CNF_PARAM, "");
9196
9197     ELEM_OPT_TV(ANSI_A_E_AUTH_PARAM_COUNT, "");
9198
9199     ELEM_OPT_TLV(ANSI_A_E_AUTH_CHLG_PARAM, "");
9200
9201     ELEM_OPT_TV(ANSI_A_E_SO, "");
9202
9203     ELEM_OPT_T(ANSI_A_E_VP_REQ, "");
9204
9205     ELEM_OPT_TV(ANSI_A_E_RE_RES, "");
9206
9207     ELEM_OPT_TLV(ANSI_A_E_CLD_PARTY_ASCII_NUM, "");
9208
9209     ELEM_OPT_TV(ANSI_A_E_CIC, "");
9210
9211     ELEM_OPT_TLV(ANSI_A_E_AUTH_EVENT, "");
9212
9213     ELEM_OPT_TLV(ANSI_A_E_AUTH_DATA, "");
9214
9215     ELEM_OPT_TLV(ANSI_A_E_PACA_REOI, "");
9216
9217     ELEM_OPT_TLV(ANSI_A_E_UZ_ID, "");
9218
9219     ELEM_OPT_TLV(ANSI_A_E_IS2000_MOB_CAP, "");
9220
9221     ELEM_OPT_TLV(ANSI_A_E_CDMA_SOWD, "");
9222
9223     switch (global_a_variant)
9224     {
9225     case A_VARIANT_IOS501:
9226         ELEM_OPT_TLV(ANSI_A_E_SSCI, "");
9227
9228         ELEM_OPT_TLV(ANSI_A_E_SOCI, "");
9229
9230         ELEM_OPT_T(ANSI_A_E_ORIG_CI, "");
9231
9232         ELEM_OPT_TV(ANSI_A_E_RETURN_CAUSE, "");
9233
9234         ELEM_OPT_TLV(ANSI_A_E_MID, "");
9235
9236         ELEM_OPT_TLV(ANSI_A_E_A2P_BEARER_SESSION, "");
9237
9238         ELEM_OPT_TLV(ANSI_A_E_A2P_BEARER_FORMAT, "");
9239
9240         ELEM_OPT_TLV(ANSI_A_E_MOB_SUB_INFO, "");
9241         break;
9242     }
9243
9244     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9245 }
9246
9247 /*
9248  * IOS 5 3.1.3
9249  */
9250 static void
9251 dtap_cm_srvc_req_cont(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9252 {
9253     guint32     curr_offset;
9254     guint32     consumed;
9255     guint       curr_len;
9256
9257     curr_offset = offset;
9258     curr_len = len;
9259
9260     ELEM_OPT_TLV(ANSI_A_E_CLD_PARTY_BCD_NUM, "");
9261
9262     ELEM_OPT_TLV(ANSI_A_E_CLD_PARTY_ASCII_NUM, "");
9263
9264     ELEM_OPT_TLV(ANSI_A_E_REV_MS_INFO_RECS, "");
9265
9266     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9267 }
9268
9269 /*
9270  * IOS 6.1.2.3
9271  */
9272 static void
9273 bsmap_page_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9274 {
9275     guint32     curr_offset;
9276     guint32     consumed;
9277     guint       curr_len;
9278
9279     curr_offset = offset;
9280     curr_len = len;
9281
9282     ELEM_MAND_TLV(ANSI_A_E_MID, "");
9283
9284     ELEM_OPT_TV(ANSI_A_E_TAG, "");
9285
9286     ELEM_OPT_TLV(ANSI_A_E_CELL_ID_LIST, "");
9287
9288     ELEM_OPT_TV(ANSI_A_E_SCI, "");
9289
9290     ELEM_OPT_TV(ANSI_A_E_SO, "");
9291
9292     ELEM_OPT_TLV(ANSI_A_E_IS2000_MOB_CAP, "");
9293
9294     switch (global_a_variant)
9295     {
9296     case A_VARIANT_IOS501:
9297         ELEM_OPT_TLV(ANSI_A_E_P_REV, "");
9298
9299         ELEM_OPT_TLV(ANSI_A_E_MS_DES_FREQ, "");
9300
9301         ELEM_OPT_TLV(ANSI_A_E_A2P_BEARER_FORMAT, "");
9302
9303         ELEM_OPT_TLV(ANSI_A_E_MID, "");
9304
9305         ELEM_OPT_TLV(ANSI_A_E_MOB_SUB_INFO, "");
9306         break;
9307     }
9308
9309     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9310 }
9311
9312 /*
9313  * IOS 6.1.2.4
9314  */
9315 static void
9316 dtap_page_resp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9317 {
9318     guint32     curr_offset;
9319     guint32     consumed;
9320     guint       curr_len;
9321
9322     curr_offset = offset;
9323     curr_len = len;
9324
9325     ELEM_MAND_LV(ANSI_A_E_CM_INFO_TYPE_2, "");
9326
9327     ELEM_MAND_LV(ANSI_A_E_MID, "");
9328
9329     ELEM_OPT_TV(ANSI_A_E_TAG, "");
9330
9331     ELEM_OPT_TLV(ANSI_A_E_MID, "");
9332
9333     ELEM_OPT_TV(ANSI_A_E_SCI, "");
9334
9335     ELEM_OPT_TLV(ANSI_A_E_AUTH_RESP_PARAM, "");
9336
9337     ELEM_OPT_TV(ANSI_A_E_AUTH_CNF_PARAM, "");
9338
9339     ELEM_OPT_TV(ANSI_A_E_AUTH_PARAM_COUNT, "");
9340
9341     ELEM_OPT_TLV(ANSI_A_E_AUTH_CHLG_PARAM, "");
9342
9343     ELEM_OPT_TV(ANSI_A_E_SO, "");
9344
9345     ELEM_OPT_T(ANSI_A_E_VP_REQ, "");
9346
9347     ELEM_OPT_TV(ANSI_A_E_CIC, "");
9348
9349     ELEM_OPT_TLV(ANSI_A_E_AUTH_EVENT, "");
9350
9351     ELEM_OPT_TV(ANSI_A_E_RE_RES, "");
9352
9353     ELEM_OPT_TLV(ANSI_A_E_UZ_ID, "");
9354
9355     ELEM_OPT_TLV(ANSI_A_E_IS2000_MOB_CAP, "");
9356
9357     ELEM_OPT_TLV(ANSI_A_E_CDMA_SOWD, "");
9358
9359     switch (global_a_variant)
9360     {
9361     case A_VARIANT_IOS501:
9362         ELEM_OPT_TLV(ANSI_A_E_SOCI, "");
9363
9364         ELEM_OPT_TLV(ANSI_A_E_MID, "");
9365
9366         ELEM_OPT_TLV(ANSI_A_E_A2P_BEARER_SESSION, "");
9367
9368         ELEM_OPT_TLV(ANSI_A_E_A2P_BEARER_FORMAT, "");
9369         break;
9370     }
9371
9372     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9373 }
9374
9375 /*
9376  * IOS 6.1.2.12
9377  */
9378 static void
9379 dtap_progress(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9380 {
9381     guint32     curr_offset;
9382     guint32     consumed;
9383     guint       curr_len;
9384
9385     curr_offset = offset;
9386     curr_len = len;
9387
9388     ELEM_OPT_TV(ANSI_A_E_SIGNAL, "");
9389
9390     ELEM_OPT_TLV(ANSI_A_E_FWD_MS_INFO_RECS, "");
9391
9392     ELEM_OPT_TLV(ANSI_A_E_SOCI, "");
9393
9394     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9395 }
9396
9397 /*
9398  * IOS 5 3.8.1
9399  */
9400 static void
9401 dtap_srvc_redirection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9402 {
9403     guint32     curr_offset;
9404     guint32     consumed;
9405     guint       curr_len;
9406
9407     curr_offset = offset;
9408     curr_len = len;
9409
9410     ELEM_MAND_TLV(ANSI_A_E_IS2000_RED_RECORD, "");
9411
9412     ELEM_MAND_TLV(ANSI_A_E_S_RED_INFO, "");
9413
9414     ELEM_MAND_TLV(ANSI_A_E_MID, "");
9415
9416     ELEM_OPT_TLV(ANSI_A_E_MID, "");
9417
9418     ELEM_OPT_TLV(ANSI_A_E_P_REV, "");
9419
9420     ELEM_OPT_TLV(ANSI_A_E_MID, "");
9421
9422     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9423 }
9424
9425 /*
9426  * IOS 5 3.1.11
9427  */
9428 static void
9429 dtap_srvc_release(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9430 {
9431     guint32     curr_offset;
9432     guint32     consumed;
9433     guint       curr_len;
9434
9435     curr_offset = offset;
9436     curr_len = len;
9437
9438     ELEM_MAND_TLV(ANSI_A_E_SOCI, "");
9439
9440     ELEM_MAND_TLV(ANSI_A_E_CAUSE, "");
9441
9442     ELEM_OPT_TLV(ANSI_A_E_CAUSE_L3, "");
9443
9444     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9445 }
9446
9447 /*
9448  * IOS 5 3.1.12
9449  */
9450 static void
9451 dtap_srvc_release_complete(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9452 {
9453     guint32     curr_offset;
9454     guint32     consumed;
9455     guint       curr_len;
9456
9457     curr_offset = offset;
9458     curr_len = len;
9459
9460     ELEM_MAND_TLV(ANSI_A_E_SOCI, "");
9461
9462     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9463 }
9464
9465 /*
9466  * IOS 6.1.2.15
9467  */
9468 static void
9469 bsmap_ass_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9470 {
9471     guint16      consumed;
9472     guint32     curr_offset;
9473     guint       curr_len;
9474
9475     curr_offset = offset;
9476     curr_len = len;
9477
9478     ELEM_MAND_TLV(ANSI_A_E_CHAN_TYPE, "");
9479
9480     ELEM_OPT_TV(ANSI_A_E_CIC, "");
9481
9482     ELEM_OPT_TLV(ANSI_A_E_ENC_INFO, "");
9483
9484     ELEM_OPT_TV(ANSI_A_E_SO, "");
9485
9486     ELEM_OPT_TV(ANSI_A_E_SIGNAL, "");
9487
9488     ELEM_OPT_TLV(ANSI_A_E_CLG_PARTY_ASCII_NUM, "");
9489
9490     ELEM_OPT_TLV(ANSI_A_E_FWD_MS_INFO_RECS, "");
9491
9492     ELEM_OPT_TLV(ANSI_A_E_PRIO, "");
9493
9494     ELEM_OPT_TLV(ANSI_A_E_PACA_TS, "");
9495
9496     ELEM_OPT_TLV(ANSI_A_E_QOS_PARAMS, "");
9497
9498     switch (global_a_variant)
9499     {
9500     case A_VARIANT_IOS501:
9501         ELEM_OPT_TLV(ANSI_A_E_SOCI, "");
9502
9503         ELEM_OPT_TLV(ANSI_A_E_SR_ID, "");
9504
9505         ELEM_OPT_TLV(ANSI_A_E_A2P_BEARER_SESSION, "");
9506
9507         ELEM_OPT_TLV(ANSI_A_E_A2P_BEARER_FORMAT, "");
9508
9509         ELEM_OPT_TLV(ANSI_A_E_MID, "");
9510
9511         ELEM_OPT_TLV(ANSI_A_E_MOB_SUB_INFO, "");
9512         break;
9513     }
9514
9515     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9516 }
9517
9518 /*
9519  * IOS 6.1.2.16
9520  */
9521 static void
9522 bsmap_ass_complete(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9523 {
9524     guint16     consumed;
9525     guint32     curr_offset;
9526     guint       curr_len;
9527
9528     curr_offset = offset;
9529     curr_len = len;
9530
9531     ELEM_MAND_TV(ANSI_A_E_CHAN_NUM, "");
9532
9533     ELEM_OPT_TLV(ANSI_A_E_ENC_INFO, "");
9534
9535     ELEM_OPT_TV(ANSI_A_E_SO, "");
9536
9537     switch (global_a_variant)
9538     {
9539     case A_VARIANT_IOS501:
9540         ELEM_OPT_TLV(ANSI_A_E_SOCI, "");
9541
9542         ELEM_OPT_TLV(ANSI_A_E_A2P_BEARER_SESSION, "");
9543
9544         ELEM_OPT_TLV(ANSI_A_E_A2P_BEARER_FORMAT, "");
9545
9546         ELEM_OPT_TLV(ANSI_A_E_MID, "");
9547         break;
9548     }
9549
9550     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9551 }
9552
9553 /*
9554  * IOS 6.1.2.17
9555  */
9556 static void
9557 bsmap_ass_failure(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9558 {
9559     guint16     consumed;
9560     guint32     curr_offset;
9561     guint       curr_len;
9562
9563     curr_offset = offset;
9564     curr_len = len;
9565
9566     ELEM_MAND_TLV(ANSI_A_E_CAUSE, "");
9567
9568     ELEM_OPT_TLV(ANSI_A_E_SOCI, "");
9569
9570     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9571 }
9572
9573 /*
9574  * IOS 6.1.2.20
9575  */
9576 static void
9577 bsmap_clr_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9578 {
9579     guint16     consumed;
9580     guint32     curr_offset;
9581     guint       curr_len;
9582
9583     curr_offset = offset;
9584     curr_len = len;
9585
9586     ELEM_MAND_TLV(ANSI_A_E_CAUSE, "");
9587
9588     ELEM_OPT_TLV(ANSI_A_E_CAUSE_L3, "");
9589
9590     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9591 }
9592
9593 /*
9594  * IOS 6.1.2.21
9595  */
9596 static void
9597 bsmap_clr_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9598 {
9599     guint16     consumed;
9600     guint32     curr_offset;
9601     guint       curr_len;
9602
9603     curr_offset = offset;
9604     curr_len = len;
9605
9606     ELEM_MAND_TLV(ANSI_A_E_CAUSE, "");
9607
9608     ELEM_OPT_TLV(ANSI_A_E_CAUSE_L3, "");
9609
9610     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9611 }
9612
9613 /*
9614  * IOS 6.1.2.22
9615  */
9616 static void
9617 bsmap_clr_complete(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9618 {
9619     guint16     consumed;
9620     guint32     curr_offset;
9621     guint       curr_len;
9622
9623     curr_offset = offset;
9624     curr_len = len;
9625
9626     ELEM_OPT_T(ANSI_A_E_PDI, "");
9627
9628     ELEM_OPT_TLV(ANSI_A_E_MOB_SUB_INFO, "");
9629
9630     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9631 }
9632
9633 /*
9634  * IOS 6.1.2.24
9635  */
9636 static void
9637 dtap_alert_with_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9638 {
9639     guint32     curr_offset;
9640     guint32     consumed;
9641     guint       curr_len;
9642
9643     curr_offset = offset;
9644     curr_len = len;
9645
9646     ELEM_OPT_TLV(ANSI_A_E_FWD_MS_INFO_RECS, "");
9647
9648     ELEM_OPT_TLV(ANSI_A_E_SOCI, "");
9649
9650     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9651 }
9652
9653 /*
9654  * IOS 6.1.2.28
9655  */
9656 static void
9657 bsmap_bs_srvc_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9658 {
9659     guint32     curr_offset;
9660     guint32     consumed;
9661     guint       curr_len;
9662
9663     curr_offset = offset;
9664     curr_len = len;
9665
9666     ELEM_MAND_TLV(ANSI_A_E_MID, "");
9667
9668     ELEM_OPT_TLV(ANSI_A_E_MID, "");
9669
9670     ELEM_OPT_TV(ANSI_A_E_SO, "");
9671
9672     ELEM_OPT_TV(ANSI_A_E_TAG, "");
9673
9674     ELEM_OPT_TLV(ANSI_A_E_ADDS_USER_PART, "");
9675
9676     ELEM_OPT_TLV(ANSI_A_E_SR_ID, "");
9677
9678     ELEM_OPT_TLV(ANSI_A_E_MID, "");
9679
9680     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9681 }
9682
9683 /*
9684  * IOS 6.1.2.29
9685  */
9686 static void
9687 bsmap_bs_srvc_resp(tvbuff_t *tvb, packet_info *pinfo, 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     ELEM_MAND_TLV(ANSI_A_E_MID, "");
9697
9698     ELEM_OPT_TLV(ANSI_A_E_MID, "");
9699
9700     ELEM_OPT_TV(ANSI_A_E_TAG, "");
9701
9702     ELEM_OPT_TLV(ANSI_A_E_CAUSE, "");
9703
9704     ELEM_OPT_TLV(ANSI_A_E_MID, "");
9705
9706     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9707 }
9708
9709 /*
9710  * IOS 5 3.1.19
9711  */
9712 static void
9713 bsmap_add_srvc_noti(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9714 {
9715     guint32     curr_offset;
9716     guint32     consumed;
9717     guint       curr_len;
9718
9719     curr_offset = offset;
9720     curr_len = len;
9721
9722     ELEM_MAND_TLV(ANSI_A_E_MID, "");
9723
9724     ELEM_MAND_TV(ANSI_A_E_SO, "");
9725
9726     ELEM_OPT_TLV(ANSI_A_E_A2P_BEARER_SESSION, "");
9727
9728     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9729 }
9730
9731 /*
9732  * IOS 5 3.1.20
9733  */
9734 static void
9735 dtap_add_srvc_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9736 {
9737     guint32     curr_offset;
9738     guint32     consumed;
9739     guint       curr_len;
9740
9741     curr_offset = offset;
9742     curr_len = len;
9743
9744     ELEM_MAND_TLV(ANSI_A_E_SOCI, "");
9745
9746     ELEM_OPT_TLV(ANSI_A_E_CLD_PARTY_BCD_NUM, "");
9747
9748     ELEM_MAND_TV(ANSI_A_E_SO, "");
9749
9750     ELEM_OPT_T(ANSI_A_E_VP_REQ, "");
9751
9752     ELEM_OPT_TLV(ANSI_A_E_CLD_PARTY_ASCII_NUM, "");
9753
9754     ELEM_OPT_TV(ANSI_A_E_CIC, "");
9755
9756     ELEM_OPT_TLV(ANSI_A_E_SSCI, "");
9757
9758     ELEM_OPT_TLV(ANSI_A_E_A2P_BEARER_SESSION, "");
9759
9760     ELEM_OPT_TLV(ANSI_A_E_A2P_BEARER_FORMAT, "");
9761
9762     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9763 }
9764
9765 /*
9766  * IOS 5 3.1.10
9767  */
9768 static void
9769 dtap_connect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9770 {
9771     guint32     curr_offset;
9772     guint32     consumed;
9773     guint       curr_len;
9774
9775     curr_offset = offset;
9776     curr_len = len;
9777
9778     ELEM_OPT_TLV(ANSI_A_E_SOCI, "");
9779
9780     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9781 }
9782
9783 /*
9784  * IOS 6.1.3.7
9785  */
9786 static void
9787 dtap_flash_with_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9788 {
9789     guint32     curr_offset;
9790     guint32     consumed;
9791     guint       curr_len;
9792
9793     curr_offset = offset;
9794     curr_len = len;
9795
9796     ELEM_OPT_TLV(ANSI_A_E_CLD_PARTY_BCD_NUM, "");
9797
9798     ELEM_OPT_TV(ANSI_A_E_SIGNAL, "");
9799
9800     ELEM_OPT_TV(ANSI_A_E_MWI, "");
9801
9802     ELEM_OPT_TLV(ANSI_A_E_CLG_PARTY_ASCII_NUM, "");
9803
9804     ELEM_OPT_TV(ANSI_A_E_TAG, "");
9805
9806     if (pinfo->p2p_dir == P2P_DIR_RECV)
9807     {
9808         ELEM_OPT_TLV(ANSI_A_E_REV_MS_INFO_RECS, "");
9809     }
9810     else
9811     {
9812         ELEM_OPT_TLV(ANSI_A_E_FWD_MS_INFO_RECS, "");
9813     }
9814
9815     ELEM_OPT_TLV(ANSI_A_E_SSCI, "");
9816
9817     ELEM_OPT_TLV(ANSI_A_E_SOCI, "");
9818
9819     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9820 }
9821
9822 /*
9823  * IOS 6.1.3.8
9824  */
9825 static void
9826 dtap_flash_with_info_ack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9827 {
9828     guint32     curr_offset;
9829     guint32     consumed;
9830     guint       curr_len;
9831
9832     curr_offset = offset;
9833     curr_len = len;
9834
9835     ELEM_OPT_TV(ANSI_A_E_TAG, "");
9836
9837     ELEM_OPT_TLV(ANSI_A_E_SOCI, "");
9838
9839     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9840 }
9841
9842 /*
9843  * IOS 6.1.3.9
9844  */
9845 static void
9846 bsmap_feat_noti(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9847 {
9848     guint32     curr_offset;
9849     guint32     consumed;
9850     guint       curr_len;
9851
9852     curr_offset = offset;
9853     curr_len = len;
9854
9855     ELEM_MAND_TLV(ANSI_A_E_MID, "");
9856
9857     ELEM_OPT_TV(ANSI_A_E_TAG, "");
9858
9859     ELEM_OPT_TLV(ANSI_A_E_CELL_ID_LIST, "");
9860
9861     ELEM_OPT_TV(ANSI_A_E_SCI, "");
9862
9863     ELEM_OPT_TV(ANSI_A_E_SIGNAL, "");
9864
9865     ELEM_OPT_TV(ANSI_A_E_MWI, "");
9866
9867     ELEM_OPT_TLV(ANSI_A_E_CLG_PARTY_ASCII_NUM, "");
9868
9869     ELEM_OPT_TLV(ANSI_A_E_FWD_MS_INFO_RECS, "");
9870
9871     ELEM_OPT_TLV(ANSI_A_E_IS2000_MOB_CAP, "");
9872
9873     ELEM_OPT_TLV(ANSI_A_E_P_REV, "");
9874
9875     ELEM_OPT_TLV(ANSI_A_E_MS_DES_FREQ, "");
9876
9877     ELEM_OPT_TLV(ANSI_A_E_MOB_SUB_INFO, "");
9878
9879     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9880 }
9881
9882 /*
9883  * IOS 6.1.3.10
9884  */
9885 static void
9886 bsmap_feat_noti_ack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9887 {
9888     guint32     curr_offset;
9889     guint32     consumed;
9890     guint       curr_len;
9891
9892     curr_offset = offset;
9893     curr_len = len;
9894
9895     ELEM_MAND_TLV(ANSI_A_E_MID, "");
9896
9897     ELEM_OPT_TV(ANSI_A_E_TAG, "");
9898
9899     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9900 }
9901
9902 /*
9903  * IOS 6.1.3.11
9904  */
9905 static void
9906 bsmap_paca_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9907 {
9908     guint32     curr_offset;
9909     guint32     consumed;
9910     guint       curr_len;
9911
9912     curr_offset = offset;
9913     curr_len = len;
9914
9915     ELEM_OPT_TLV(ANSI_A_E_PRIO, "");
9916
9917     ELEM_OPT_TLV(ANSI_A_E_PACA_TS, "");
9918
9919     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9920 }
9921
9922 /*
9923  * IOS 6.1.3.12
9924  */
9925 static void
9926 bsmap_paca_command_ack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9927 {
9928     guint32     curr_offset;
9929     guint32     consumed;
9930     guint       curr_len;
9931
9932     curr_offset = offset;
9933     curr_len = len;
9934
9935     ELEM_OPT_TLV(ANSI_A_E_CAUSE, "");
9936
9937     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9938 }
9939
9940 /*
9941  * IOS 6.1.3.13
9942  */
9943 static void
9944 bsmap_paca_update(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9945 {
9946     guint32     curr_offset;
9947     guint32     consumed;
9948     guint       curr_len;
9949
9950     curr_offset = offset;
9951     curr_len = len;
9952
9953     ELEM_OPT_TLV(ANSI_A_E_MID, "");
9954
9955     ELEM_OPT_TLV(ANSI_A_E_MID, "");
9956
9957     ELEM_OPT_TLV(ANSI_A_E_PACA_ORDER, "");
9958
9959     ELEM_OPT_TLV(ANSI_A_E_PRIO, "");
9960
9961     ELEM_OPT_TLV(ANSI_A_E_AUTH_RESP_PARAM, "");
9962
9963     ELEM_OPT_TV(ANSI_A_E_AUTH_CNF_PARAM, "");
9964
9965     ELEM_OPT_TV(ANSI_A_E_AUTH_PARAM_COUNT, "");
9966
9967     ELEM_OPT_TLV(ANSI_A_E_AUTH_CHLG_PARAM, "");
9968
9969     ELEM_OPT_TLV(ANSI_A_E_AUTH_EVENT, "");
9970
9971     ELEM_OPT_TLV(ANSI_A_E_MID, "");
9972
9973     ELEM_OPT_TLV(ANSI_A_E_MS_DES_FREQ, "");
9974
9975     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9976 }
9977
9978 /*
9979  * IOS 6.1.3.14
9980  */
9981 static void
9982 bsmap_paca_update_ack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
9983 {
9984     guint32     curr_offset;
9985     guint32     consumed;
9986     guint       curr_len;
9987
9988     curr_offset = offset;
9989     curr_len = len;
9990
9991     ELEM_OPT_TLV(ANSI_A_E_MID, "");
9992
9993     ELEM_OPT_TLV(ANSI_A_E_PRIO, "");
9994
9995     ELEM_OPT_TLV(ANSI_A_E_CAUSE, "");
9996
9997     EXTRANEOUS_DATA_CHECK(curr_len, 0);
9998 }
9999
10000 /*
10001  * IOS 5 3.2.9
10002  */
10003 static void
10004 bsmap_rm_pos_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10005 {
10006     guint32     curr_offset;
10007     guint32     consumed;
10008     guint       curr_len;
10009
10010     curr_offset = offset;
10011     curr_len = len;
10012
10013     ELEM_MAND_TLV(ANSI_A_E_PSMM_COUNT, "");
10014
10015     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10016 }
10017
10018 /*
10019  * IOS 5 3.2.10
10020  */
10021 static void
10022 bsmap_rm_pos_resp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10023 {
10024     guint32     curr_offset;
10025     guint32     consumed;
10026     guint       curr_len;
10027
10028     curr_offset = offset;
10029     curr_len = len;
10030
10031     ELEM_OPT_TLV(ANSI_A_E_CDMA_SOWD, "");
10032
10033     ELEM_OPT_TLV(ANSI_A_E_CAUSE, "");
10034
10035     ELEM_OPT_TLV(ANSI_A_E_DOWNLINK_RE_LIST, "");
10036
10037     ELEM_OPT_TLV(ANSI_A_E_GEO_LOC, "");
10038
10039     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10040 }
10041
10042 /*
10043  * IOS 6.1.4.1
10044  */
10045 static void
10046 bsmap_auth_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10047 {
10048     guint32     curr_offset;
10049     guint32     consumed;
10050     guint       curr_len;
10051
10052     curr_offset = offset;
10053     curr_len = len;
10054
10055     ELEM_MAND_TLV(ANSI_A_E_AUTH_CHLG_PARAM, "");
10056
10057     ELEM_OPT_TLV(ANSI_A_E_MID, "");
10058
10059     ELEM_OPT_TV(ANSI_A_E_TAG, "");
10060
10061     ELEM_OPT_TLV(ANSI_A_E_CELL_ID_LIST, "");
10062
10063     ELEM_OPT_TV(ANSI_A_E_SCI, "");
10064
10065     ELEM_OPT_TLV(ANSI_A_E_IS2000_MOB_CAP, "");
10066
10067     ELEM_OPT_TLV(ANSI_A_E_P_REV, "");
10068
10069     ELEM_OPT_TLV(ANSI_A_E_MS_DES_FREQ, "");
10070
10071     ELEM_OPT_TLV(ANSI_A_E_MOB_SUB_INFO, "");
10072
10073     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10074 }
10075
10076 static void
10077 dtap_auth_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10078 {
10079     guint32     curr_offset;
10080     guint32     consumed;
10081     guint       curr_len;
10082
10083     curr_offset = offset;
10084     curr_len = len;
10085
10086     ELEM_MAND_LV(ANSI_A_E_AUTH_CHLG_PARAM, "");
10087
10088     ELEM_OPT_TLV(ANSI_A_E_IS2000_MOB_CAP, "");
10089
10090     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10091 }
10092
10093 /*
10094  * IOS 6.1.4.2
10095  */
10096 static void
10097 bsmap_auth_resp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10098 {
10099     guint32     curr_offset;
10100     guint32     consumed;
10101     guint       curr_len;
10102
10103     curr_offset = offset;
10104     curr_len = len;
10105
10106     ELEM_MAND_TLV(ANSI_A_E_AUTH_RESP_PARAM, "");
10107
10108     ELEM_MAND_TLV(ANSI_A_E_MID, "");
10109
10110     ELEM_MAND_TV(ANSI_A_E_TAG, "");
10111
10112     ELEM_OPT_TLV(ANSI_A_E_MID, "");
10113
10114     ELEM_OPT_TLV(ANSI_A_E_MID, "");
10115
10116     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10117 }
10118
10119 /*
10120  * IOS 5
10121  * Section 3.1.21
10122  */
10123 static void
10124 bsmap_bearer_upd_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10125 {
10126     guint32     curr_offset;
10127     guint32     consumed;
10128     guint       curr_len;
10129
10130     curr_offset = offset;
10131     curr_len = len;
10132
10133     ELEM_OPT_TLV(ANSI_A_E_A2P_BEARER_SESSION, "");
10134
10135     ELEM_OPT_TLV(ANSI_A_E_A2P_BEARER_FORMAT, "");
10136
10137     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10138 }
10139
10140 /*
10141  * IOS 5
10142  * Section 3.1.22
10143  */
10144 static void
10145 bsmap_bearer_upd_resp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10146 {
10147     guint32     curr_offset;
10148     guint32     consumed;
10149     guint       curr_len;
10150
10151     curr_offset = offset;
10152     curr_len = len;
10153
10154     ELEM_OPT_TLV(ANSI_A_E_CAUSE, "");
10155
10156     ELEM_OPT_TLV(ANSI_A_E_A2P_BEARER_SESSION, "");
10157
10158     ELEM_OPT_TLV(ANSI_A_E_A2P_BEARER_FORMAT, "");
10159
10160     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10161 }
10162
10163 /*
10164  * IOS 5
10165  * Section 3.1.23
10166  */
10167 static void
10168 bsmap_bearer_upd_reqd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10169 {
10170     guint32     curr_offset;
10171     guint32     consumed;
10172     guint       curr_len;
10173
10174     curr_offset = offset;
10175     curr_len = len;
10176
10177     ELEM_OPT_TLV(ANSI_A_E_CAUSE, "");
10178
10179     ELEM_OPT_TLV(ANSI_A_E_A2P_BEARER_SESSION, "");
10180
10181     ELEM_OPT_TLV(ANSI_A_E_A2P_BEARER_FORMAT, "");
10182
10183     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10184 }
10185
10186 static void
10187 dtap_auth_resp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10188 {
10189     guint32     curr_offset;
10190     guint32     consumed;
10191     guint       curr_len;
10192
10193     curr_offset = offset;
10194     curr_len = len;
10195
10196     ELEM_MAND_LV(ANSI_A_E_AUTH_RESP_PARAM, "");
10197
10198     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10199 }
10200
10201 /*
10202  * IOS 6.1.4.3
10203  */
10204 static void
10205 bsmap_user_zone_update(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10206 {
10207     guint32     curr_offset;
10208     guint32     consumed;
10209     guint       curr_len;
10210
10211     curr_offset = offset;
10212     curr_len = len;
10213
10214     ELEM_OPT_TLV(ANSI_A_E_UZ_ID, "");
10215
10216     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10217 }
10218
10219 /*
10220  * IOS 5 3.3.16
10221  */
10222 static void
10223 dtap_user_zone_update_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10224 {
10225     guint32     curr_offset;
10226     guint32     consumed;
10227     guint       curr_len;
10228
10229     curr_offset = offset;
10230     curr_len = len;
10231
10232     ELEM_MAND_TLV(ANSI_A_E_UZ_ID, "");
10233
10234     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10235 }
10236
10237 /*
10238  * IOS 5 3.3.17
10239  */
10240 static void
10241 dtap_user_zone_update(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10242 {
10243     guint32     curr_offset;
10244     guint32     consumed;
10245     guint       curr_len;
10246
10247     curr_offset = offset;
10248     curr_len = len;
10249
10250     ELEM_MAND_TLV(ANSI_A_E_UZ_ID, "");
10251
10252     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10253 }
10254
10255 /*
10256  * IOS 5 3.3.18
10257  */
10258 static void
10259 bsmap_user_zone_reject(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10260 {
10261     guint32     curr_offset;
10262     guint32     consumed;
10263     guint       curr_len;
10264
10265     curr_offset = offset;
10266     curr_len = len;
10267
10268     ELEM_OPT_TLV(ANSI_A_E_UZ_ID, "");
10269
10270     ELEM_MAND_TLV(ANSI_A_E_MID, "");
10271
10272     ELEM_OPT_TLV(ANSI_A_E_CELL_ID_LIST, "");
10273
10274     ELEM_OPT_TV(ANSI_A_E_SCI, "");
10275
10276     ELEM_OPT_TLV(ANSI_A_E_IS2000_MOB_CAP, "");
10277
10278     ELEM_OPT_TLV(ANSI_A_E_P_REV, "");
10279
10280     ELEM_OPT_TLV(ANSI_A_E_MS_DES_FREQ, "");
10281
10282     ELEM_OPT_TLV(ANSI_A_E_MOB_SUB_INFO, "");
10283
10284     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10285 }
10286
10287 /*
10288  * IOS 5 3.3.18
10289  */
10290 static void
10291 dtap_user_zone_reject(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10292 {
10293     guint32     curr_offset;
10294     guint32     consumed;
10295     guint       curr_len;
10296
10297     curr_offset = offset;
10298     curr_len = len;
10299
10300     ELEM_OPT_TLV(ANSI_A_E_UZ_ID, "");
10301
10302     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10303 }
10304
10305 /*
10306  * IOS 5 3.3.19
10307  */
10308 static void
10309 bsmap_reg_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10310 {
10311     guint32     curr_offset;
10312     guint32     consumed;
10313     guint       curr_len;
10314
10315     curr_offset = offset;
10316     curr_len = len;
10317
10318     ELEM_MAND_TLV(ANSI_A_E_MID, "");
10319
10320     ELEM_OPT_TLV(ANSI_A_E_CELL_ID_LIST, "");
10321
10322     ELEM_OPT_TV(ANSI_A_E_SCI, "");
10323
10324     ELEM_OPT_TLV(ANSI_A_E_P_REV, "");
10325
10326     ELEM_OPT_TLV(ANSI_A_E_IS2000_MOB_CAP, "");
10327
10328     ELEM_OPT_TLV(ANSI_A_E_MS_DES_FREQ, "");
10329
10330     ELEM_OPT_TLV(ANSI_A_E_MOB_SUB_INFO, "");
10331
10332     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10333 }
10334
10335 /*
10336  * IOS 5 3.3.20
10337  */
10338 static void
10339 bsmap_ms_reg_noti(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10340 {
10341     guint32     curr_offset;
10342     guint32     consumed;
10343     guint       curr_len;
10344
10345     curr_offset = offset;
10346     curr_len = len;
10347
10348     ELEM_MAND_TLV(ANSI_A_E_CAUSE, "");
10349
10350     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10351 }
10352
10353 /*
10354  * IOS 5 3.3.21
10355  */
10356 static void
10357 bsmap_bs_auth_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10358 {
10359     guint32     curr_offset;
10360     guint32     consumed;
10361     guint       curr_len;
10362
10363     curr_offset = offset;
10364     curr_len = len;
10365
10366     ELEM_MAND_TLV(ANSI_A_E_MID, "");
10367
10368     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10369 }
10370
10371 /*
10372  * IOS 5 3.3.22
10373  */
10374 static void
10375 bsmap_bs_auth_req_ack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10376 {
10377     guint32     curr_offset;
10378     guint32     consumed;
10379     guint       curr_len;
10380
10381     curr_offset = offset;
10382     curr_len = len;
10383
10384     ELEM_MAND_TLV(ANSI_A_E_MID, "");
10385
10386     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10387 }
10388
10389 /*
10390  * IOS 6.1.4.4
10391  */
10392 static void
10393 dtap_ssd_update_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10394 {
10395     guint32     curr_offset;
10396     guint32     consumed;
10397     guint       curr_len;
10398
10399     curr_offset = offset;
10400     curr_len = len;
10401
10402     ELEM_MAND_LV(ANSI_A_E_AUTH_CHLG_PARAM, "");
10403
10404     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10405 }
10406
10407 /*
10408  * IOS 6.1.4.5
10409  */
10410 static void
10411 dtap_bs_challenge(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10412 {
10413     guint32     curr_offset;
10414     guint32     consumed;
10415     guint       curr_len;
10416
10417     curr_offset = offset;
10418     curr_len = len;
10419
10420     ELEM_MAND_LV(ANSI_A_E_AUTH_CHLG_PARAM, "");
10421
10422     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10423 }
10424
10425 /*
10426  * IOS 6.1.4.6
10427  */
10428 static void
10429 dtap_bs_challenge_resp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10430 {
10431     guint32     curr_offset;
10432     guint32     consumed;
10433     guint       curr_len;
10434
10435     curr_offset = offset;
10436     curr_len = len;
10437
10438     ELEM_MAND_LV(ANSI_A_E_AUTH_RESP_PARAM, "");
10439
10440     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10441 }
10442
10443 /*
10444  * IOS 6.1.4.7
10445  */
10446 static void
10447 dtap_ssd_update_resp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10448 {
10449     guint32     curr_offset;
10450     guint32     consumed;
10451     guint       curr_len;
10452
10453     curr_offset = offset;
10454     curr_len = len;
10455
10456     ELEM_OPT_TLV(ANSI_A_E_CAUSE_L3, "");
10457
10458     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10459 }
10460
10461 /*
10462  * IOS 6.1.4.8
10463  */
10464 static void
10465 dtap_lu_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10466 {
10467     guint32     curr_offset;
10468     guint32     consumed;
10469     guint       curr_len;
10470
10471     curr_offset = offset;
10472     curr_len = len;
10473
10474     ELEM_MAND_LV(ANSI_A_E_MID, "");
10475
10476     ELEM_OPT_TV(ANSI_A_E_LAI, "");
10477
10478     ELEM_OPT_TLV(ANSI_A_E_CM_INFO_TYPE_2, "");
10479
10480     ELEM_OPT_TV(ANSI_A_E_REG_TYPE, "");
10481
10482     ELEM_OPT_TLV(ANSI_A_E_MID, "");
10483
10484     ELEM_OPT_TV(ANSI_A_E_SCI, "");
10485
10486     ELEM_OPT_TLV(ANSI_A_E_AUTH_RESP_PARAM, "");
10487
10488     ELEM_OPT_TV(ANSI_A_E_AUTH_CNF_PARAM, "");
10489
10490     ELEM_OPT_TV(ANSI_A_E_AUTH_PARAM_COUNT, "");
10491
10492     ELEM_OPT_TLV(ANSI_A_E_AUTH_CHLG_PARAM, "");
10493
10494     ELEM_OPT_TLV(ANSI_A_E_AUTH_EVENT, "");
10495
10496     ELEM_OPT_TLV(ANSI_A_E_UZ_ID, "");
10497
10498     ELEM_OPT_TLV(ANSI_A_E_IS2000_MOB_CAP, "");
10499
10500     ELEM_OPT_TV(ANSI_A_E_RETURN_CAUSE, "");
10501
10502     ELEM_OPT_TLV(ANSI_A_E_MS_DES_FREQ, "");
10503
10504     ELEM_OPT_TLV(ANSI_A_E_MID, "");
10505
10506     ELEM_OPT_TLV(ANSI_A_E_MOB_SUB_INFO, "");
10507
10508     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10509 }
10510
10511 /*
10512  * IOS 6.1.4.9
10513  */
10514 static void
10515 dtap_lu_accept(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10516 {
10517     guint32     curr_offset;
10518     guint32     consumed;
10519     guint       curr_len;
10520
10521     curr_offset = offset;
10522     curr_len = len;
10523
10524     switch (global_a_variant)
10525     {
10526     case A_VARIANT_IOS401:
10527         ELEM_OPT_TV(ANSI_A_E_LAI, "");
10528         break;
10529
10530     case A_VARIANT_IOS501:
10531         ELEM_OPT_TLV(ANSI_A_E_CAUSE, "");
10532
10533         ELEM_OPT_TLV(ANSI_A_E_P_REV, "");
10534
10535         ELEM_OPT_TLV(ANSI_A_E_MS_DES_FREQ, "");
10536         break;
10537     }
10538
10539     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10540 }
10541
10542 /*
10543  * IOS 6.1.4.10
10544  */
10545 static void
10546 dtap_lu_reject(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10547 {
10548     guint32     curr_offset;
10549     guint32     consumed;
10550     guint       curr_len;
10551
10552     curr_offset = offset;
10553     curr_len = len;
10554
10555     ELEM_MAND_V(ANSI_A_E_REJ_CAUSE);
10556
10557     switch (global_a_variant)
10558     {
10559     case A_VARIANT_IOS501:
10560         ELEM_OPT_TLV(ANSI_A_E_P_REV, "");
10561
10562         ELEM_OPT_TLV(ANSI_A_E_MS_DES_FREQ, "");
10563         break;
10564     }
10565
10566     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10567 }
10568
10569 /*
10570  * IOS 6.1.4.18
10571  */
10572 static void
10573 bsmap_priv_mode_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10574 {
10575     guint32     curr_offset;
10576     guint32     consumed;
10577     guint       curr_len;
10578
10579     curr_offset = offset;
10580     curr_len = len;
10581
10582     ELEM_MAND_TLV(ANSI_A_E_ENC_INFO, "");
10583
10584     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10585 }
10586
10587 /*
10588  * IOS 6.1.4.19
10589  */
10590 static void
10591 bsmap_priv_mode_complete(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10592 {
10593     guint32     curr_offset;
10594     guint32     consumed;
10595     guint       curr_len;
10596
10597     curr_offset = offset;
10598     curr_len = len;
10599
10600     ELEM_OPT_TLV(ANSI_A_E_ENC_INFO, "");
10601
10602     ELEM_OPT_T(ANSI_A_E_VP_REQ, "");
10603
10604     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10605 }
10606
10607 /*
10608  * IOS 5 3.3.14
10609  */
10610 static void
10611 bsmap_status_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10612 {
10613     guint32     curr_offset;
10614     guint32     consumed;
10615     guint       curr_len;
10616
10617     curr_offset = offset;
10618     curr_len = len;
10619
10620     ELEM_MAND_TLV(ANSI_A_E_IE_REQD, "");
10621
10622     ELEM_OPT_TLV(ANSI_A_E_MID, "");
10623
10624     ELEM_OPT_TLV(ANSI_A_E_MID, "");
10625
10626     ELEM_OPT_TV(ANSI_A_E_SCI, "");
10627
10628     ELEM_OPT_TLV(ANSI_A_E_CELL_ID_LIST, "");
10629
10630     ELEM_OPT_TLV(ANSI_A_E_IS2000_MOB_CAP, "");
10631
10632     ELEM_OPT_TLV(ANSI_A_E_P_REV, "");
10633
10634     ELEM_OPT_TLV(ANSI_A_E_MS_DES_FREQ, "");
10635
10636     ELEM_OPT_TLV(ANSI_A_E_MID, "");
10637
10638     ELEM_OPT_TV(ANSI_A_E_TAG, "");
10639
10640     ELEM_OPT_TLV(ANSI_A_E_MOB_SUB_INFO, "");
10641
10642     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10643 }
10644
10645 /*
10646  * IOS 5 3.3.14
10647  */
10648 static void
10649 dtap_status_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10650 {
10651     guint32     curr_offset;
10652     guint32     consumed;
10653     guint       curr_len;
10654
10655     curr_offset = offset;
10656     curr_len = len;
10657
10658     ELEM_MAND_LV(ANSI_A_E_IE_REQD, "");
10659
10660     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10661 }
10662
10663
10664 /*
10665  * IOS 5 3.3.15
10666  */
10667 static void
10668 bsmap_status_resp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10669 {
10670     guint32     curr_offset;
10671     guint32     consumed;
10672     guint       curr_len;
10673
10674     curr_offset = offset;
10675     curr_len = len;
10676
10677     ELEM_MAND_TLV(ANSI_A_E_REV_MS_INFO_RECS, "");
10678
10679     ELEM_OPT_TLV(ANSI_A_E_MID, "");
10680
10681     ELEM_OPT_TLV(ANSI_A_E_MID, "");
10682
10683     ELEM_OPT_TLV(ANSI_A_E_MID, "");
10684
10685     ELEM_OPT_TV(ANSI_A_E_TAG, "");
10686
10687     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10688 }
10689
10690 /*
10691  * IOS 5 3.3.15
10692  */
10693 static void
10694 dtap_status_resp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10695 {
10696     guint32     curr_offset;
10697     guint32     consumed;
10698     guint       curr_len;
10699
10700     curr_offset = offset;
10701     curr_len = len;
10702
10703     ELEM_MAND_LV(ANSI_A_E_REV_MS_INFO_RECS, "");
10704
10705     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10706 }
10707
10708 /*
10709  * IOS 6.1.5.4
10710  */
10711 static void
10712 bsmap_ho_reqd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10713 {
10714     guint32     curr_offset;
10715     guint32     consumed;
10716     guint       curr_len;
10717
10718     curr_offset = offset;
10719     curr_len = len;
10720
10721     ELEM_MAND_TLV(ANSI_A_E_CAUSE, "");
10722
10723     ELEM_MAND_TLV(ANSI_A_E_CELL_ID_LIST, " (Target)");
10724
10725     ELEM_OPT_TLV(ANSI_A_E_CM_INFO_TYPE_2, "");
10726
10727     ELEM_OPT_T(ANSI_A_E_RESP_REQ, "");
10728
10729     ELEM_OPT_TLV(ANSI_A_E_ENC_INFO, "");
10730
10731     ELEM_OPT_TLV(ANSI_A_E_IS95_CHAN_ID, "");
10732
10733     ELEM_OPT_TLV(ANSI_A_E_MID, "");
10734
10735     ELEM_OPT_TLV(ANSI_A_E_DOWNLINK_RE, "");
10736
10737     ELEM_OPT_TV(ANSI_A_E_SO, "");
10738
10739     ELEM_OPT_TLV(ANSI_A_E_CDMA_SOWD, "");
10740
10741     ELEM_OPT_TLV(ANSI_A_E_IS95_MS_MEAS_CHAN_ID, "");
10742
10743     ELEM_OPT_TLV(ANSI_A_E_IS2000_CHAN_ID, "");
10744
10745     ELEM_OPT_TLV(ANSI_A_E_QOS_PARAMS, "");
10746
10747     ELEM_OPT_TLV(ANSI_A_E_IS2000_MOB_CAP, "");
10748
10749     ELEM_OPT_TLV(ANSI_A_E_IS2000_SCR, "");
10750
10751     switch (global_a_variant)
10752     {
10753     case A_VARIANT_IOS401:
10754         ELEM_OPT_TLV(ANSI_A_E_PDSN_IP_ADDR, "");
10755         break;
10756
10757     case A_VARIANT_IOS501:
10758         ELEM_OPT_TLV(ANSI_A_E_S_PDSN_ADDR, "");
10759         break;
10760     }
10761
10762     ELEM_OPT_TLV(ANSI_A_E_PTYPE, "");
10763
10764     ELEM_OPT_TLV(ANSI_A_E_SRNC_TRNC_TC, "");
10765
10766     ELEM_OPT_TV(ANSI_A_E_SCI, "");
10767
10768     ELEM_OPT_TV(ANSI_A_E_ACC_NET_ID, "");
10769
10770     ELEM_OPT_TLV(ANSI_A_E_SO_LIST, "");
10771
10772     ELEM_OPT_TLV(ANSI_A_E_IS2000_CHAN_ID_3X, "");
10773
10774     ELEM_OPT_TLV(ANSI_A_E_IS2000_NN_SCR, "");
10775
10776     ELEM_OPT_TLV(ANSI_A_E_ANCH_PDSN_ADDR, "");
10777
10778     ELEM_OPT_TLV(ANSI_A_E_ANCH_PP_ADDR, "");
10779
10780     ELEM_OPT_TLV(ANSI_A_E_PSP, "");
10781
10782     ELEM_OPT_TLV(ANSI_A_E_PLCM_ID, "");
10783
10784     ELEM_OPT_TLV(ANSI_A_E_MID, "");
10785
10786     ELEM_OPT_TLV(ANSI_A_E_MOB_SUB_INFO, "");
10787
10788     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10789 }
10790
10791 /*
10792  * IOS 6.1.5.5
10793  */
10794 static void
10795 bsmap_ho_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10796 {
10797     guint32     curr_offset;
10798     guint32     consumed;
10799     guint       curr_len;
10800
10801     curr_offset = offset;
10802     curr_len = len;
10803
10804     ELEM_MAND_TLV(ANSI_A_E_CHAN_TYPE, "");
10805
10806     ELEM_MAND_TLV(ANSI_A_E_ENC_INFO, "");
10807
10808     ELEM_MAND_TLV(ANSI_A_E_CM_INFO_TYPE_2, "");
10809
10810     ELEM_MAND_TLV(ANSI_A_E_CELL_ID_LIST, "(Target)");
10811
10812     ELEM_OPT_TLV(ANSI_A_E_CIC_EXT, "");
10813
10814     ELEM_OPT_TLV(ANSI_A_E_IS95_CHAN_ID, "");
10815
10816     ELEM_OPT_TLV(ANSI_A_E_MID, "");
10817
10818     ELEM_OPT_TLV(ANSI_A_E_MID, "");
10819
10820     ELEM_OPT_TLV(ANSI_A_E_DOWNLINK_RE, "");
10821
10822     ELEM_OPT_TV(ANSI_A_E_SO, "");
10823
10824     ELEM_OPT_TLV(ANSI_A_E_CDMA_SOWD, "");
10825
10826     ELEM_OPT_TLV(ANSI_A_E_IS95_MS_MEAS_CHAN_ID, "");
10827
10828     ELEM_OPT_TLV(ANSI_A_E_IS2000_CHAN_ID, "");
10829
10830     ELEM_OPT_TLV(ANSI_A_E_QOS_PARAMS, "");
10831
10832     ELEM_OPT_TLV(ANSI_A_E_IS2000_MOB_CAP, "");
10833
10834     ELEM_OPT_TLV(ANSI_A_E_IS2000_SCR, "");
10835
10836     switch (global_a_variant)
10837     {
10838     case A_VARIANT_IOS401:
10839         ELEM_OPT_TLV(ANSI_A_E_PDSN_IP_ADDR, "");
10840         break;
10841
10842     case A_VARIANT_IOS501:
10843         ELEM_OPT_TLV(ANSI_A_E_S_PDSN_ADDR, "");
10844         break;
10845     }
10846
10847     ELEM_OPT_TLV(ANSI_A_E_PTYPE, "");
10848
10849     switch (global_a_variant)
10850     {
10851     case A_VARIANT_IOS501:
10852         ELEM_OPT_TLV(ANSI_A_E_SRNC_TRNC_TC, "");
10853
10854         ELEM_OPT_TV(ANSI_A_E_SCI, "");
10855
10856         ELEM_OPT_TV(ANSI_A_E_ACC_NET_ID, "");
10857
10858         ELEM_OPT_TLV(ANSI_A_E_SO_LIST, "");
10859
10860         ELEM_OPT_TLV(ANSI_A_E_IS2000_CHAN_ID_3X, "");
10861
10862         ELEM_OPT_TLV(ANSI_A_E_IS2000_NN_SCR, "");
10863
10864         ELEM_OPT_TLV(ANSI_A_E_ANCH_PDSN_ADDR, "");
10865
10866         ELEM_OPT_TLV(ANSI_A_E_ANCH_PP_ADDR, "");
10867
10868         ELEM_OPT_TLV(ANSI_A_E_PSP, "");
10869
10870         ELEM_OPT_TLV(ANSI_A_E_PLCM_ID, "");
10871
10872         ELEM_OPT_TLV(ANSI_A_E_A2P_BEARER_SESSION, "");
10873
10874         ELEM_OPT_TLV(ANSI_A_E_A2P_BEARER_FORMAT, "");
10875
10876         ELEM_OPT_TLV(ANSI_A_E_MID, "");
10877
10878         ELEM_OPT_TLV(ANSI_A_E_MOB_SUB_INFO, "");
10879         break;
10880     }
10881
10882     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10883 }
10884
10885 /*
10886  * IOS 6.1.5.6
10887  */
10888 static void
10889 bsmap_ho_req_ack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10890 {
10891     guint32     curr_offset;
10892     guint32     consumed;
10893     guint       curr_len;
10894
10895     curr_offset = offset;
10896     curr_len = len;
10897
10898     ELEM_OPT_TLV(ANSI_A_E_IS95_CHAN_ID, "");
10899
10900     ELEM_OPT_TLV(ANSI_A_E_CELL_ID_LIST, "");
10901
10902     ELEM_OPT_TLV(ANSI_A_E_EXT_HO_DIR_PARAMS, "");
10903
10904     ELEM_OPT_TV(ANSI_A_E_HHO_PARAMS, "");
10905
10906     ELEM_OPT_TLV(ANSI_A_E_IS2000_CHAN_ID, "");
10907
10908     ELEM_OPT_TLV(ANSI_A_E_IS2000_SCR, "");
10909
10910     ELEM_OPT_TLV(ANSI_A_E_IS2000_NN_SCR, "");
10911
10912     switch (global_a_variant)
10913     {
10914     case A_VARIANT_IOS501:
10915         ELEM_OPT_TLV(ANSI_A_E_TRNC_SRNC_TC, "");
10916
10917         ELEM_OPT_TLV(ANSI_A_E_SO_LIST, "");
10918
10919         ELEM_OPT_TLV(ANSI_A_E_CAUSE, "");
10920
10921         ELEM_OPT_TLV(ANSI_A_E_IS2000_CHAN_ID_3X, "");
10922
10923         ELEM_OPT_TLV(ANSI_A_E_PLCM_ID, "");
10924
10925         ELEM_OPT_TLV(ANSI_A_E_A2P_BEARER_SESSION, "");
10926
10927         ELEM_OPT_TLV(ANSI_A_E_A2P_BEARER_FORMAT, "");
10928         break;
10929     }
10930
10931     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10932 }
10933
10934 /*
10935  * IOS 6.1.5.7
10936  */
10937 static void
10938 bsmap_ho_failure(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10939 {
10940     guint32     curr_offset;
10941     guint32     consumed;
10942     guint       curr_len;
10943
10944     curr_offset = offset;
10945     curr_len = len;
10946
10947     ELEM_MAND_TLV(ANSI_A_E_CAUSE, "");
10948
10949     EXTRANEOUS_DATA_CHECK(curr_len, 0);
10950 }
10951
10952 /*
10953  * IOS 6.1.5.8
10954  */
10955 static void
10956 bsmap_ho_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
10957 {
10958     guint32     curr_offset;
10959     guint32     consumed;
10960     guint       curr_len;
10961
10962     curr_offset = offset;
10963     curr_len = len;
10964
10965     ELEM_OPT_TV(ANSI_A_E_RF_CHAN_ID, "");
10966
10967     ELEM_OPT_TLV(ANSI_A_E_IS95_CHAN_ID, "");
10968
10969     ELEM_OPT_TLV(ANSI_A_E_CELL_ID_LIST, "");
10970
10971     ELEM_OPT_TLV(ANSI_A_E_HO_POW_LEV, "");
10972
10973     ELEM_OPT_TV(ANSI_A_E_SID, "");
10974
10975     ELEM_OPT_TLV(ANSI_A_E_EXT_HO_DIR_PARAMS, "");
10976
10977     ELEM_OPT_TV(ANSI_A_E_HHO_PARAMS, "");
10978
10979     ELEM_OPT_TLV(ANSI_A_E_IS2000_CHAN_ID, "");
10980
10981     ELEM_OPT_TLV(ANSI_A_E_IS2000_SCR, "");
10982
10983     ELEM_OPT_TLV(ANSI_A_E_IS2000_NN_SCR, "");
10984
10985     switch (global_a_variant)
10986     {
10987     case A_VARIANT_IOS501:
10988         ELEM_OPT_TLV(ANSI_A_E_TRNC_SRNC_TC, "");
10989
10990         ELEM_OPT_TLV(ANSI_A_E_SO_LIST, "");
10991
10992         ELEM_OPT_TLV(ANSI_A_E_CAUSE, "");
10993
10994         ELEM_OPT_TLV(ANSI_A_E_AMPS_HHO_PARAM, "");
10995
10996         ELEM_OPT_TLV(ANSI_A_E_IS2000_CHAN_ID_3X, "");
10997
10998         ELEM_OPT_TLV(ANSI_A_E_PLCM_ID, "");
10999         break;
11000     }
11001
11002     EXTRANEOUS_DATA_CHECK(curr_len, 0);
11003 }
11004
11005 /*
11006  * IOS 5 3.4.6
11007  */
11008 static void
11009 bsmap_ho_complete(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
11010 {
11011     guint32     curr_offset;
11012     guint32     consumed;
11013     guint       curr_len;
11014
11015     curr_offset = offset;
11016     curr_len = len;
11017
11018     ELEM_OPT_TV(ANSI_A_E_SO, "");
11019
11020     EXTRANEOUS_DATA_CHECK(curr_len, 0);
11021 }
11022
11023 /*
11024  * IOS 6.1.5.9
11025  */
11026 static void
11027 bsmap_ho_reqd_rej(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
11028 {
11029     guint32     curr_offset;
11030     guint32     consumed;
11031     guint       curr_len;
11032
11033     curr_offset = offset;
11034     curr_len = len;
11035
11036     ELEM_MAND_TLV(ANSI_A_E_CAUSE, "");
11037
11038     EXTRANEOUS_DATA_CHECK(curr_len, 0);
11039 }
11040
11041 /*
11042  * IOS 6.1.5.12
11043  */
11044 static void
11045 bsmap_ho_performed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
11046 {
11047     guint32     curr_offset;
11048     guint32     consumed;
11049     guint       curr_len;
11050
11051     curr_offset = offset;
11052     curr_len = len;
11053
11054     ELEM_MAND_TLV(ANSI_A_E_CAUSE, "");
11055
11056     ELEM_OPT_TLV(ANSI_A_E_CELL_ID_LIST, "");
11057
11058     ELEM_OPT_TV(ANSI_A_E_CHAN_NUM, "");
11059
11060     ELEM_OPT_TLV(ANSI_A_E_BAND_CLASS, "");
11061
11062     ELEM_OPT_TLV(ANSI_A_E_MOB_SUB_INFO, "");
11063
11064     EXTRANEOUS_DATA_CHECK(curr_len, 0);
11065 }
11066
11067 /*
11068  * IOS 6.1.6.2
11069  */
11070 static void
11071 bsmap_block(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
11072 {
11073     guint32     curr_offset;
11074     guint32     consumed;
11075     guint       curr_len;
11076
11077     curr_offset = offset;
11078     curr_len = len;
11079
11080     ELEM_MAND_TV(ANSI_A_E_CIC, "");
11081
11082     ELEM_MAND_TLV(ANSI_A_E_CAUSE, "");
11083
11084     ELEM_OPT_TLV(ANSI_A_E_CCT_GROUP, "");
11085
11086     EXTRANEOUS_DATA_CHECK(curr_len, 0);
11087 }
11088
11089 /*
11090  * IOS 6.1.6.3
11091  */
11092 static void
11093 bsmap_block_ack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
11094 {
11095     guint32     curr_offset;
11096     guint32     consumed;
11097     guint       curr_len;
11098
11099     curr_offset = offset;
11100     curr_len = len;
11101
11102     ELEM_MAND_TV(ANSI_A_E_CIC, "");
11103
11104     EXTRANEOUS_DATA_CHECK(curr_len, 0);
11105 }
11106
11107 /*
11108  * IOS 6.1.6.4
11109  */
11110 static void
11111 bsmap_unblock(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
11112 {
11113     guint32     curr_offset;
11114     guint32     consumed;
11115     guint       curr_len;
11116
11117     curr_offset = offset;
11118     curr_len = len;
11119
11120     ELEM_MAND_TV(ANSI_A_E_CIC, "");
11121
11122     ELEM_OPT_TLV(ANSI_A_E_CCT_GROUP, "");
11123
11124     EXTRANEOUS_DATA_CHECK(curr_len, 0);
11125 }
11126
11127 /*
11128  * IOS 6.1.6.5
11129  */
11130 static void
11131 bsmap_unblock_ack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
11132 {
11133     guint32     curr_offset;
11134     guint32     consumed;
11135     guint       curr_len;
11136
11137     curr_offset = offset;
11138     curr_len = len;
11139
11140     ELEM_MAND_TV(ANSI_A_E_CIC, "");
11141
11142     EXTRANEOUS_DATA_CHECK(curr_len, 0);
11143 }
11144
11145 /*
11146  * IOS 6.1.6.6
11147  */
11148 static void
11149 bsmap_reset(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
11150 {
11151     guint32     curr_offset;
11152     guint32     consumed;
11153     guint       curr_len;
11154
11155     curr_offset = offset;
11156     curr_len = len;
11157
11158     ELEM_MAND_TLV(ANSI_A_E_CAUSE, "");
11159
11160     ELEM_OPT_TLV(ANSI_A_E_SW_VER, "");
11161
11162     EXTRANEOUS_DATA_CHECK(curr_len, 0);
11163 }
11164
11165 /*
11166  * IOS 6.1.6.7
11167  */
11168 static void
11169 bsmap_reset_ack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
11170 {
11171     guint32     curr_offset;
11172     guint32     consumed;
11173     guint       curr_len;
11174
11175     curr_offset = offset;
11176     curr_len = len;
11177
11178     ELEM_OPT_TLV(ANSI_A_E_SW_VER, "");
11179
11180     EXTRANEOUS_DATA_CHECK(curr_len, 0);
11181 }
11182
11183 /*
11184  * IOS 6.1.6.8
11185  */
11186 static void
11187 bsmap_reset_cct(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
11188 {
11189     guint32     curr_offset;
11190     guint32     consumed;
11191     guint       curr_len;
11192
11193     curr_offset = offset;
11194     curr_len = len;
11195
11196     ELEM_MAND_TV(ANSI_A_E_CIC, "");
11197
11198     ELEM_MAND_TLV(ANSI_A_E_CAUSE, "");
11199
11200     ELEM_OPT_TLV(ANSI_A_E_CCT_GROUP, "");
11201
11202     EXTRANEOUS_DATA_CHECK(curr_len, 0);
11203 }
11204
11205 /*
11206  * IOS 6.1.6.9
11207  */
11208 static void
11209 bsmap_reset_cct_ack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
11210 {
11211     guint32     curr_offset;
11212     guint32     consumed;
11213     guint       curr_len;
11214
11215     curr_offset = offset;
11216     curr_len = len;
11217
11218     ELEM_MAND_TV(ANSI_A_E_CIC, "");
11219
11220     EXTRANEOUS_DATA_CHECK(curr_len, 0);
11221 }
11222
11223 /*
11224  * IOS 6.1.6.10
11225  */
11226 static void
11227 bsmap_xmode_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
11228 {
11229     guint32     curr_offset;
11230     guint32     consumed;
11231     guint       curr_len;
11232
11233     curr_offset = offset;
11234     curr_len = len;
11235
11236     ELEM_MAND_TLV(ANSI_A_E_XMODE, "");
11237
11238     EXTRANEOUS_DATA_CHECK(curr_len, 0);
11239 }
11240
11241 /*
11242  * IOS 6.1.6.11
11243  */
11244 static void
11245 bsmap_xmode_ack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
11246 {
11247     guint32     curr_offset;
11248     guint32     consumed;
11249     guint       curr_len;
11250
11251     curr_offset = offset;
11252     curr_len = len;
11253
11254     ELEM_MAND_TLV(ANSI_A_E_CAUSE, "");
11255
11256     EXTRANEOUS_DATA_CHECK(curr_len, 0);
11257 }
11258
11259 /*
11260  * IOS 6.1.7.1
11261  */
11262 static void
11263 bsmap_adds_page(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
11264 {
11265     guint32     curr_offset;
11266     guint32     consumed;
11267     guint       curr_len;
11268
11269     curr_offset = offset;
11270     curr_len = len;
11271
11272     ELEM_MAND_TLV(ANSI_A_E_MID, "");
11273
11274     ELEM_MAND_TLV(ANSI_A_E_ADDS_USER_PART, "");
11275
11276     ELEM_OPT_TV(ANSI_A_E_TAG, "");
11277
11278     ELEM_OPT_TLV(ANSI_A_E_CELL_ID_LIST, "");
11279
11280     ELEM_OPT_TV(ANSI_A_E_SCI, "");
11281
11282     ELEM_OPT_TLV(ANSI_A_E_IS2000_MOB_CAP, "");
11283
11284     ELEM_OPT_TLV(ANSI_A_E_P_REV, "");
11285
11286     ELEM_OPT_TLV(ANSI_A_E_MS_DES_FREQ, "");
11287
11288     ELEM_OPT_TLV(ANSI_A_E_MOB_SUB_INFO, "");
11289
11290     EXTRANEOUS_DATA_CHECK(curr_len, 0);
11291 }
11292
11293 /*
11294  * IOS 6.1.7.2
11295  */
11296 static void
11297 bsmap_adds_transfer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
11298 {
11299     guint32     curr_offset;
11300     guint32     consumed;
11301     guint       curr_len;
11302
11303     curr_offset = offset;
11304     curr_len = len;
11305
11306     ELEM_MAND_TLV(ANSI_A_E_MID, "");
11307
11308     ELEM_MAND_TLV(ANSI_A_E_ADDS_USER_PART, "");
11309
11310     ELEM_OPT_TLV(ANSI_A_E_MID, "");
11311
11312     ELEM_OPT_TLV(ANSI_A_E_AUTH_RESP_PARAM, "");
11313
11314     ELEM_OPT_TV(ANSI_A_E_AUTH_CNF_PARAM, "");
11315
11316     ELEM_OPT_TV(ANSI_A_E_AUTH_PARAM_COUNT, "");
11317
11318     ELEM_OPT_TLV(ANSI_A_E_AUTH_CHLG_PARAM, "");
11319
11320     ELEM_OPT_TLV(ANSI_A_E_AUTH_EVENT, "");
11321
11322     ELEM_OPT_TLV(ANSI_A_E_CELL_ID, "");
11323
11324     ELEM_OPT_TLV(ANSI_A_E_CDMA_SOWD, "");
11325
11326     ELEM_OPT_TLV(ANSI_A_E_AUTH_DATA, "");
11327
11328     ELEM_OPT_TV(ANSI_A_E_TAG, "");
11329
11330     ELEM_OPT_TLV(ANSI_A_E_CM_INFO_TYPE_2, "");
11331
11332     ELEM_OPT_TV(ANSI_A_E_SCI, "");
11333
11334     ELEM_OPT_TV(ANSI_A_E_SO, "");
11335
11336     ELEM_OPT_TLV(ANSI_A_E_UZ_ID, "");
11337
11338     ELEM_OPT_TLV(ANSI_A_E_IS2000_MOB_CAP, "");
11339
11340     ELEM_OPT_TLV(ANSI_A_E_MID, "");
11341
11342     ELEM_OPT_TLV(ANSI_A_E_MOB_SUB_INFO, "");
11343
11344     EXTRANEOUS_DATA_CHECK(curr_len, 0);
11345 }
11346
11347 /*
11348  * IOS 5 3.6.4
11349  */
11350 static void
11351 bsmap_adds_transfer_ack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
11352 {
11353     guint32     curr_offset;
11354     guint32     consumed;
11355     guint       curr_len;
11356
11357     curr_offset = offset;
11358     curr_len = len;
11359
11360     ELEM_MAND_TLV(ANSI_A_E_MID, "");
11361
11362     ELEM_OPT_TV(ANSI_A_E_TAG, "");
11363
11364     ELEM_OPT_TLV(ANSI_A_E_CAUSE, "");
11365
11366     EXTRANEOUS_DATA_CHECK(curr_len, 0);
11367 }
11368
11369 /*
11370  * IOS 6.1.7.3
11371  */
11372 static void
11373 dtap_adds_deliver(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
11374 {
11375     guint32     curr_offset;
11376     guint32     consumed;
11377     guint       curr_len;
11378
11379     curr_offset = offset;
11380     curr_len = len;
11381
11382     ELEM_MAND_LV(ANSI_A_E_ADDS_USER_PART, "");
11383
11384     ELEM_OPT_TV(ANSI_A_E_TAG, "");
11385
11386     ELEM_OPT_TLV(ANSI_A_E_CDMA_SOWD, "");
11387
11388     EXTRANEOUS_DATA_CHECK(curr_len, 0);
11389 }
11390
11391 /*
11392  * IOS 6.1.7.4
11393  */
11394 static void
11395 bsmap_adds_page_ack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
11396 {
11397     guint32     curr_offset;
11398     guint32     consumed;
11399     guint       curr_len;
11400
11401     curr_offset = offset;
11402     curr_len = len;
11403
11404     ELEM_MAND_TLV(ANSI_A_E_MID, "");
11405
11406     ELEM_OPT_TV(ANSI_A_E_TAG, "");
11407
11408     ELEM_OPT_TLV(ANSI_A_E_MID, "");
11409
11410     ELEM_OPT_TLV(ANSI_A_E_CAUSE, "");
11411
11412     ELEM_OPT_TLV(ANSI_A_E_CELL_ID, "");
11413
11414     ELEM_OPT_TLV(ANSI_A_E_MID, "");
11415
11416     EXTRANEOUS_DATA_CHECK(curr_len, 0);
11417 }
11418
11419 /*
11420  * IOS 6.1.7.5
11421  */
11422 static void
11423 dtap_adds_deliver_ack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
11424 {
11425     guint32     curr_offset;
11426     guint32     consumed;
11427     guint       curr_len;
11428
11429     curr_offset = offset;
11430     curr_len = len;
11431
11432     ELEM_OPT_TV(ANSI_A_E_TAG, "");
11433
11434     ELEM_OPT_TLV(ANSI_A_E_CAUSE, "");
11435
11436     EXTRANEOUS_DATA_CHECK(curr_len, 0);
11437 }
11438
11439 /*
11440  * IOS 6.1.8.1
11441  */
11442 static void
11443 bsmap_rejection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
11444 {
11445     guint32     curr_offset;
11446     guint32     consumed;
11447     guint       curr_len;
11448
11449     curr_offset = offset;
11450     curr_len = len;
11451
11452     ELEM_OPT_TLV(ANSI_A_E_MID, "");
11453
11454     ELEM_OPT_TLV(ANSI_A_E_MID, "");
11455
11456     ELEM_OPT_TLV(ANSI_A_E_IS2000_CAUSE, "");
11457
11458     ELEM_OPT_TLV(ANSI_A_E_MID, "");
11459
11460     EXTRANEOUS_DATA_CHECK(curr_len, 0);
11461 }
11462
11463 static void
11464 dtap_rejection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
11465 {
11466     guint32     curr_offset;
11467     guint32     consumed;
11468     guint       curr_len;
11469
11470     curr_offset = offset;
11471     curr_len = len;
11472
11473     ELEM_OPT_TLV(ANSI_A_E_MID, "");
11474
11475     ELEM_OPT_TLV(ANSI_A_E_IS2000_CAUSE, "");
11476
11477     ELEM_OPT_TLV(ANSI_A_E_SOCI, "");
11478
11479     ELEM_OPT_TLV(ANSI_A_E_MID, "");
11480
11481     EXTRANEOUS_DATA_CHECK(curr_len, 0);
11482 }
11483
11484 #define ANSI_A_IOS401_BSMAP_NUM_MSG (sizeof(ansi_a_ios401_bsmap_strings)/sizeof(ext_value_string_t))
11485 #define ANSI_A_IOS501_BSMAP_NUM_MSG (sizeof(ansi_a_ios501_bsmap_strings)/sizeof(ext_value_string_t))
11486 static gint ett_bsmap_msg[MAX(ANSI_A_IOS401_BSMAP_NUM_MSG, ANSI_A_IOS501_BSMAP_NUM_MSG)];
11487 static void (*bsmap_msg_fcn[])(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len) =
11488 {
11489     bsmap_add_srvc_noti,            /* Additional Service Notification */
11490     bsmap_adds_page,                /* ADDS Page */
11491     bsmap_adds_page_ack,            /* ADDS Page Ack */
11492     bsmap_adds_transfer,            /* ADDS Transfer */
11493     bsmap_adds_transfer_ack,        /* ADDS Transfer Ack */
11494     bsmap_ass_complete,             /* Assignment Complete */
11495     bsmap_ass_failure,              /* Assignment Failure */
11496     bsmap_ass_req,                  /* Assignment Request */
11497     bsmap_auth_req,                 /* Authentication Request */
11498     bsmap_auth_resp,                /* Authentication Response */
11499     NULL /* no BSMAP definition */, /* Base Station Challenge */
11500     NULL /* no BSMAP definition */, /* Base Station Challenge Response */
11501     bsmap_block,                    /* Block */
11502     bsmap_block_ack,                /* Block Acknowledge */
11503     bsmap_bs_srvc_req,              /* BS Service Request */
11504     bsmap_bs_srvc_resp,             /* BS Service Response */
11505     bsmap_clr_command,              /* Clear Command */
11506     bsmap_clr_complete,             /* Clear Complete */
11507     bsmap_clr_req,                  /* Clear Request */
11508     bsmap_cl3_info,                 /* Complete Layer 3 Information */
11509     bsmap_feat_noti,                /* Feature Notification */
11510     bsmap_feat_noti_ack,            /* Feature Notification Ack */
11511     bsmap_ho_command,               /* Handoff Command */
11512     NULL /* no associated data */,  /* Handoff Commenced */
11513     bsmap_ho_complete,              /* Handoff Complete */
11514     bsmap_ho_failure,               /* Handoff Failure */
11515     bsmap_ho_performed,             /* Handoff Performed */
11516     bsmap_ho_req,                   /* Handoff Request */
11517     bsmap_ho_req_ack,               /* Handoff Request Acknowledge */
11518     bsmap_ho_reqd,                  /* Handoff Required */
11519     bsmap_ho_reqd_rej,              /* Handoff Required Reject */
11520     bsmap_paca_command,             /* PACA Command */
11521     bsmap_paca_command_ack,         /* PACA Command Ack */
11522     bsmap_paca_update,              /* PACA Update */
11523     bsmap_paca_update_ack,          /* PACA Update Ack */
11524     bsmap_page_req,                 /* Paging Request */
11525     bsmap_priv_mode_command,        /* Privacy Mode Command */
11526     bsmap_priv_mode_complete,       /* Privacy Mode Complete */
11527     bsmap_rm_pos_req,               /* Radio Measurements for Position Request */
11528     bsmap_rm_pos_resp,              /* Radio Measurements for Position Response */
11529     bsmap_rejection,                /* Rejection */
11530     bsmap_reg_req,                  /* Registration Request */
11531     bsmap_reset,                    /* Reset */
11532     bsmap_reset_ack,                /* Reset Acknowledge */
11533     bsmap_reset_cct,                /* Reset Circuit */
11534     bsmap_reset_cct_ack,            /* Reset Circuit Acknowledge */
11535     NULL /* no BSMAP definition */, /* SSD Update Request */
11536     NULL /* no BSMAP definition */, /* SSD Update Response */
11537     bsmap_status_req,               /* Status Request */
11538     bsmap_status_resp,              /* Status Response */
11539     bsmap_xmode_ack,                /* Transcoder Control Acknowledge */
11540     bsmap_xmode_req,                /* Transcoder Control Request */
11541     bsmap_unblock,                  /* Unblock */
11542     bsmap_unblock_ack,              /* Unblock Acknowledge */
11543     bsmap_user_zone_reject,         /* User Zone Reject */
11544     bsmap_user_zone_update,         /* User Zone Update */
11545     bsmap_bearer_upd_req,           /* Bearer Update Request *//* IOS 5.0.1 */
11546     bsmap_bearer_upd_resp,          /* Bearer Update Response *//* IOS 5.0.1 */
11547     bsmap_bearer_upd_reqd,          /* Bearer Update Required *//* IOS 5.0.1 */
11548     bsmap_ms_reg_noti,              /* Mobile Station Registered Notification *//* IOS 5.0.1 */
11549     bsmap_bs_auth_req,              /* BS Authentication Request *//* IOS 5.0.1 */
11550     bsmap_bs_auth_req_ack,          /* BS Authentication Request Ack *//* IOS 5.0.1 */
11551     NULL,        /* NONE */
11552 };
11553
11554 #define ANSI_A_IOS401_DTAP_NUM_MSG (sizeof(ansi_a_ios401_dtap_strings)/sizeof(ext_value_string_t))
11555 #define ANSI_A_IOS501_DTAP_NUM_MSG (sizeof(ansi_a_ios501_dtap_strings)/sizeof(ext_value_string_t))
11556 static gint ett_dtap_msg[MAX(ANSI_A_IOS401_DTAP_NUM_MSG, ANSI_A_IOS501_DTAP_NUM_MSG)];
11557 static void (*dtap_msg_fcn[])(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint len) =
11558 {
11559     dtap_add_srvc_req,              /* Additional Service Request */
11560     dtap_adds_deliver,              /* ADDS Deliver */
11561     dtap_adds_deliver_ack,          /* ADDS Deliver Ack */
11562     dtap_alert_with_info,           /* Alert With Information */
11563     dtap_auth_req,                  /* Authentication Request */
11564     dtap_auth_resp,                 /* Authentication Response */
11565     dtap_bs_challenge,              /* Base Station Challenge */
11566     dtap_bs_challenge_resp,         /* Base Station Challenge Response */
11567     dtap_cm_srvc_req,               /* CM Service Request */
11568     dtap_cm_srvc_req_cont,          /* CM Service Request Continuation */
11569     dtap_connect,                   /* Connect */
11570     dtap_flash_with_info,           /* Flash with Information */
11571     dtap_flash_with_info_ack,       /* Flash with Information Ack */
11572     dtap_lu_accept,                 /* Location Updating Accept */
11573     dtap_lu_reject,                 /* Location Updating Reject */
11574     dtap_lu_req,                    /* Location Updating Request */
11575     dtap_page_resp,                 /* Paging Response */
11576     NULL /* no associated data */,  /* Parameter Update Confirm */
11577     NULL /* no associated data */,  /* Parameter Update Request */
11578     dtap_rejection,                 /* Rejection */
11579     dtap_progress,                  /* Progress */
11580     dtap_srvc_redirection,          /* Service Redirection */
11581     dtap_srvc_release,              /* Service Release */
11582     dtap_srvc_release_complete,     /* Service Release Complete */
11583     dtap_ssd_update_req,            /* SSD Update Request */
11584     dtap_ssd_update_resp,           /* SSD Update Response */
11585     dtap_status_req,                /* Status Request */
11586     dtap_status_resp,               /* Status Response */
11587     dtap_user_zone_reject,          /* User Zone Reject */
11588     dtap_user_zone_update,          /* User Zone Update */
11589     dtap_user_zone_update_req,      /* User Zone Update Request */
11590     NULL,       /* NONE */
11591 };
11592
11593 /* Utillity function to dissect CDMA200 A1 elements in ANSI MAP messages */
11594 void
11595 dissect_cdma2000_a1_elements(tvbuff_t *tvb, _U_ packet_info *pinfo, proto_tree *tree, guint32 offset, guint len)
11596 {
11597     guint32     curr_offset;
11598     guint32     consumed;
11599     guint       curr_len;
11600     elem_idx_t  idx;
11601     guint8      oct;
11602
11603     curr_offset = offset;
11604     curr_len = len;
11605
11606     /*
11607      * require at least 2 octets for T(ype) and L(ength)
11608      */
11609     while (curr_len > 1)
11610     {
11611         /*
11612          * peeking at T(ype)
11613          */
11614         oct = tvb_get_guint8(tvb, curr_offset);
11615
11616         for (idx=0; idx < ansi_a_elem_1_max; idx++)
11617         {
11618             if (oct == (guint8) ansi_a_elem_1_strings[idx].value)
11619             {
11620                 ELEM_OPT_TLV(idx, "");
11621                 break;
11622             }
11623         }
11624
11625         if (idx == ansi_a_elem_1_max)
11626         {
11627             /*
11628              * didn't recognize the T(ype)
11629              * assuming it is in TLV form, step over
11630              */
11631             consumed = 2 + tvb_get_guint8(tvb, curr_offset + 1);
11632             curr_offset += consumed;
11633             curr_len -= consumed;
11634         }
11635     }
11636
11637     EXTRANEOUS_DATA_CHECK_EXPERT(curr_len, 0);
11638 }
11639
11640 /* GENERIC DISSECTOR FUNCTIONS */
11641
11642 static void
11643 dissect_bsmap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
11644 {
11645     static ansi_a_tap_rec_t     tap_rec[16];
11646     static ansi_a_tap_rec_t     *tap_p;
11647     static int                  tap_current=0;
11648     guint8                      oct;
11649     guint32                     offset, saved_offset;
11650     guint32                     len;
11651     gint                        idx, dec_idx;
11652     proto_item                  *bsmap_item = NULL;
11653     proto_tree                  *bsmap_tree = NULL;
11654     const gchar                 *msg_str;
11655
11656
11657     col_append_str(pinfo->cinfo, COL_INFO, "(BSMAP) ");
11658
11659     /*
11660      * set tap record pointer
11661      */
11662     tap_current++;
11663     if (tap_current == array_length(tap_rec))
11664     {
11665         tap_current = 0;
11666     }
11667     tap_p = &tap_rec[tap_current];
11668
11669
11670     offset = 0;
11671     saved_offset = offset;
11672
11673     g_tree = tree;
11674
11675     len = tvb_length(tvb);
11676
11677     /*
11678      * add BSMAP message name
11679      */
11680     oct = tvb_get_guint8(tvb, offset++);
11681
11682     msg_str = my_match_strval_idx((guint32) oct, ansi_a_bsmap_strings, &idx, &dec_idx);
11683
11684     /*
11685      * create the a protocol tree
11686      */
11687     if (msg_str == NULL)
11688     {
11689         bsmap_item =
11690             proto_tree_add_protocol_format(tree, proto_a_bsmap, tvb, 0, len,
11691                 "ANSI A-I/F BSMAP - Unknown BSMAP Message Type (%u)",
11692                 oct);
11693
11694         bsmap_tree = proto_item_add_subtree(bsmap_item, ett_bsmap);
11695     }
11696     else
11697     {
11698         bsmap_item =
11699             proto_tree_add_protocol_format(tree, proto_a_bsmap, tvb, 0, -1,
11700                 "ANSI A-I/F BSMAP - %s",
11701                 msg_str);
11702
11703         bsmap_tree = proto_item_add_subtree(bsmap_item, ett_bsmap_msg[dec_idx]);
11704
11705         col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", msg_str);
11706     }
11707
11708     /*
11709      * add BSMAP message name
11710      */
11711     proto_tree_add_uint_format(bsmap_tree, hf_ansi_a_bsmap_msgtype,
11712         tvb, saved_offset, 1, oct, "Message Type");
11713
11714     tap_p->pdu_type = BSSAP_PDU_TYPE_BSMAP;
11715     tap_p->message_type = oct;
11716
11717     tap_queue_packet(ansi_a_tap, pinfo, tap_p);
11718
11719     if (msg_str == NULL) return;
11720
11721     if ((len - offset) <= 0) return;
11722
11723     a_meid_configured = FALSE;
11724
11725     /*
11726      * decode elements
11727      */
11728     if (bsmap_msg_fcn[dec_idx] == NULL)
11729     {
11730         proto_tree_add_text(bsmap_tree,
11731             tvb, offset, len - offset,
11732             "Message Elements");
11733     }
11734     else
11735     {
11736         (*bsmap_msg_fcn[dec_idx])(tvb, pinfo, bsmap_tree, offset, len - offset);
11737     }
11738 }
11739
11740 static void
11741 dissect_dtap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
11742 {
11743     static ansi_a_tap_rec_t     tap_rec[16];
11744     static ansi_a_tap_rec_t     *tap_p;
11745     static int                  tap_current=0;
11746     guint8                      oct;
11747     guint32                     offset, saved_offset;
11748     guint32                     len;
11749     guint32                     oct_1, oct_2;
11750     gint                        idx, dec_idx;
11751     proto_item                  *dtap_item = NULL;
11752     proto_tree                  *dtap_tree = NULL;
11753     proto_item                  *oct_1_item = NULL;
11754     proto_tree                  *oct_1_tree = NULL;
11755     const gchar                 *msg_str;
11756     const gchar                 *str;
11757
11758
11759     len = tvb_length(tvb);
11760
11761     if (len < 3)
11762     {
11763         /*
11764          * too short to be DTAP
11765          */
11766         call_dissector(data_handle, tvb, pinfo, tree);
11767         return;
11768     }
11769
11770     col_append_str(pinfo->cinfo, COL_INFO, "(DTAP) ");
11771
11772     /*
11773      * set tap record pointer
11774      */
11775     tap_current++;
11776     if (tap_current == array_length(tap_rec))
11777     {
11778         tap_current = 0;
11779     }
11780     tap_p = &tap_rec[tap_current];
11781
11782
11783     offset = 0;
11784     saved_offset = offset;
11785
11786     g_tree = tree;
11787
11788     /*
11789      * get protocol discriminator
11790      */
11791     oct_1 = tvb_get_guint8(tvb, offset++);
11792     oct_2 = tvb_get_guint8(tvb, offset++);
11793
11794     /*
11795      * add DTAP message name
11796      */
11797     saved_offset = offset;
11798     oct = tvb_get_guint8(tvb, offset++);
11799
11800     msg_str = my_match_strval_idx((guint32) oct, ansi_a_dtap_strings, &idx, &dec_idx);
11801
11802     /*
11803      * create the a protocol tree
11804      */
11805     if (msg_str == NULL)
11806     {
11807         dtap_item =
11808             proto_tree_add_protocol_format(tree, proto_a_dtap, tvb, 0, len,
11809                 "ANSI A-I/F DTAP - Unknown DTAP Message Type (%u)",
11810                 oct);
11811
11812         dtap_tree = proto_item_add_subtree(dtap_item, ett_dtap);
11813     }
11814     else
11815     {
11816         dtap_item =
11817             proto_tree_add_protocol_format(tree, proto_a_dtap, tvb, 0, -1,
11818                 "ANSI A-I/F DTAP - %s",
11819                 msg_str);
11820
11821         dtap_tree = proto_item_add_subtree(dtap_item, ett_dtap_msg[dec_idx]);
11822
11823         col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", msg_str);
11824     }
11825
11826     /*
11827      * octet 1
11828      */
11829     switch (oct_1 & 0x0f)
11830     {
11831     case 3: str = "Call Control, call related SS"; break;
11832     case 5: str = "Mobility Management"; break;
11833     case 6: str = "Radio Resource Management"; break;
11834     case 9: str = "Facility Management"; break;
11835     case 11: str = "Other Signaling Procedures"; break;
11836     case 15: str = "Reserved for tests"; break;
11837     default:
11838         str = "Unknown";
11839         break;
11840     }
11841
11842     oct_1_item =
11843         proto_tree_add_text(dtap_tree,
11844             tvb, 0, 1,
11845             "Protocol Discriminator: %s",
11846             str);
11847
11848     oct_1_tree = proto_item_add_subtree(oct_1_item, ett_dtap_oct_1);
11849
11850     other_decode_bitfield_value(a_bigbuf, oct_1, 0xf0, 8);
11851     proto_tree_add_text(oct_1_tree,
11852         tvb, 0, 1,
11853         "%s :  Reserved",
11854         a_bigbuf);
11855
11856     other_decode_bitfield_value(a_bigbuf, oct_1, 0x0f, 8);
11857     proto_tree_add_text(oct_1_tree,
11858         tvb, 0, 1,
11859         "%s :  Protocol Discriminator: %u",
11860         a_bigbuf,
11861         oct_1 & 0x0f);
11862
11863     /*
11864      * octet 2
11865      */
11866     switch (global_a_variant)
11867     {
11868     case A_VARIANT_IS634:
11869         other_decode_bitfield_value(a_bigbuf, oct_2, 0x80, 8);
11870         proto_tree_add_text(dtap_tree,
11871             tvb, 1, 1,
11872             "%s :  Transaction Identifier (TI) Flag: %s",
11873             a_bigbuf,
11874             ((oct_2 & 0x80) ?  "allocated by receiver" : "allocated by sender"));
11875
11876         other_decode_bitfield_value(a_bigbuf, oct_2, 0x70, 8);
11877         proto_tree_add_text(dtap_tree,
11878             tvb, 1, 1,
11879             "%s :  Transaction Identifier (TI): %u",
11880             a_bigbuf,
11881             (oct_2 & 0x70) >> 4);
11882
11883         other_decode_bitfield_value(a_bigbuf, oct_2, 0x0f, 8);
11884         proto_tree_add_text(dtap_tree,
11885             tvb, 1, 1,
11886             "%s :  Reserved",
11887             a_bigbuf);
11888         break;
11889
11890     default:
11891         proto_tree_add_text(dtap_tree,
11892             tvb, 1, 1,
11893             "Reserved Octet");
11894         break;
11895     }
11896
11897     /*
11898      * add DTAP message name
11899      */
11900     proto_tree_add_uint_format(dtap_tree, hf_ansi_a_dtap_msgtype,
11901         tvb, saved_offset, 1, oct,
11902         "Message Type");
11903
11904     tap_p->pdu_type = BSSAP_PDU_TYPE_DTAP;
11905     tap_p->message_type = oct;
11906
11907     tap_queue_packet(ansi_a_tap, pinfo, tap_p);
11908
11909     if (msg_str == NULL) return;
11910
11911     if ((len - offset) <= 0) return;
11912
11913     a_meid_configured = FALSE;
11914
11915     /*
11916      * decode elements
11917      */
11918     if (dtap_msg_fcn[dec_idx] == NULL)
11919     {
11920         proto_tree_add_text(dtap_tree,
11921             tvb, offset, len - offset,
11922             "Message Elements");
11923     }
11924     else
11925     {
11926         (*dtap_msg_fcn[dec_idx])(tvb, pinfo, dtap_tree, offset, len - offset);
11927     }
11928 }
11929
11930
11931 /* Register the protocol with Wireshark */
11932 void
11933 proto_register_ansi_a(void)
11934 {
11935     module_t            *ansi_a_module;
11936     guint               i;
11937     gint                last_offset;
11938
11939     /* Setup list of header fields */
11940
11941     static hf_register_info hf[] =
11942     {
11943         { &hf_ansi_a_bsmap_msgtype,
11944             { "BSMAP Message Type",     "ansi_a_bsmap.msgtype",
11945             FT_UINT8, BASE_HEX, NULL, 0x0,
11946             NULL, HFILL }
11947         },
11948         { &hf_ansi_a_dtap_msgtype,
11949             { "DTAP Message Type",      "ansi_a_bsmap.dtap_msgtype",
11950             FT_UINT8, BASE_HEX, NULL, 0x0,
11951             NULL, HFILL }
11952         },
11953         { &hf_ansi_a_elem_id,
11954             { "Element ID",     "ansi_a_bsmap.elem_id",
11955             FT_UINT8, BASE_DEC, NULL, 0,
11956             NULL, HFILL }
11957         },
11958         { &hf_ansi_a_length,
11959             { "Length",         "ansi_a_bsmap.len",
11960             FT_UINT8, BASE_DEC, NULL, 0,
11961             NULL, HFILL }
11962         },
11963         { &hf_ansi_a_none,
11964             { "Sub tree",       "ansi_a_bsmap.none",
11965             FT_NONE, BASE_NONE, 0, 0,
11966             NULL, HFILL }
11967         },
11968         { &hf_ansi_a_esn,
11969             { "ESN",    "ansi_a_bsmap.esn",
11970             FT_UINT32, BASE_HEX, 0, 0x0,
11971             NULL, HFILL }
11972         },
11973         { &hf_ansi_a_imsi,
11974             { "IMSI",   "ansi_a_bsmap.imsi",
11975             FT_STRING, BASE_NONE, 0, 0,
11976             NULL, HFILL }
11977         },
11978         { &hf_ansi_a_min,
11979             { "MIN",    "ansi_a_bsmap.min",
11980             FT_STRING, BASE_NONE, 0, 0,
11981             NULL, HFILL }
11982         },
11983         { &hf_ansi_a_meid,
11984             { "MEID",   "ansi_a_bsmap.meid",
11985             FT_STRING, BASE_NONE, 0, 0,
11986             NULL, HFILL }
11987         },
11988         { &hf_ansi_a_cld_party_bcd_num,
11989             { "Called Party BCD Number",        "ansi_a_bsmap.cld_party_bcd_num",
11990             FT_STRING, BASE_NONE, 0, 0,
11991             NULL, HFILL }
11992         },
11993         { &hf_ansi_a_clg_party_bcd_num,
11994             { "Calling Party BCD Number",       "ansi_a_bsmap.clg_party_bcd_num",
11995             FT_STRING, BASE_NONE, 0, 0,
11996             NULL, HFILL }
11997         },
11998         { &hf_ansi_a_cld_party_ascii_num,
11999             { "Called Party ASCII Number",      "ansi_a_bsmap.cld_party_ascii_num",
12000             FT_STRING, BASE_NONE, 0, 0,
12001             NULL, HFILL }
12002         },
12003         { &hf_ansi_a_clg_party_ascii_num,
12004             { "Calling Party ASCII Number",     "ansi_a_bsmap.clg_party_ascii_num",
12005             FT_STRING, BASE_NONE, 0, 0,
12006             NULL, HFILL }
12007         },
12008         { &hf_ansi_a_cell_ci,
12009             { "Cell CI",        "ansi_a_bsmap.cell_ci",
12010             FT_UINT16, BASE_HEX, 0, 0x0,
12011             NULL, HFILL }
12012         },
12013         { &hf_ansi_a_cell_lac,
12014             { "Cell LAC",       "ansi_a_bsmap.cell_lac",
12015             FT_UINT16, BASE_HEX, 0, 0x0,
12016             NULL, HFILL }
12017         },
12018         { &hf_ansi_a_cell_mscid,
12019             { "Cell MSCID",     "ansi_a_bsmap.cell_mscid",
12020             FT_UINT24, BASE_HEX, 0, 0x0,
12021             NULL, HFILL }
12022         },
12023         { &hf_ansi_a_pdsn_ip_addr,
12024             { "PDSN IP Address", "ansi_a_bsmap.pdsn_ip_addr",
12025             FT_IPv4, BASE_NONE, NULL, 0,
12026             "IP Address", HFILL }
12027         },
12028         { &hf_ansi_a_s_pdsn_ip_addr,
12029             { "Source PDSN Address", "ansi_a_bsmap.s_pdsn_ip_addr",
12030             FT_IPv4, BASE_NONE, NULL, 0,
12031             "IP Address", HFILL }
12032         },
12033         { &hf_ansi_a_anchor_ip_addr,
12034             { "Anchor PDSN Address", "ansi_a_bsmap.anchor_pdsn_ip_addr",
12035             FT_IPv4, BASE_NONE, NULL, 0,
12036             "IP Address", HFILL }
12037         },
12038         { &hf_ansi_a_anchor_pp_ip_addr,
12039             { "Anchor P-P Address", "ansi_a_bsmap.anchor_pp_ip_addr",
12040             FT_IPv4, BASE_NONE, NULL, 0,
12041             "IP Address", HFILL }
12042         },
12043         { &hf_ansi_a_a2p_bearer_ipv4_addr,
12044             { "A2p Bearer IP Address", "ansi_a_bsmap.a2p_bearer_ipv4_addr",
12045             FT_IPv4, BASE_NONE, NULL, 0,
12046             NULL, HFILL }
12047         },
12048         { &hf_ansi_a_a2p_bearer_ipv6_addr,
12049             { "A2p Bearer IP Address", "ansi_a_bsmap.a2p_bearer_ipv6_addr",
12050             FT_IPv6, BASE_NONE, NULL, 0,
12051             NULL, HFILL }
12052         },
12053         { &hf_ansi_a_a2p_bearer_udp_port,
12054             { "A2p Bearer UDP Port", "ansi_a_bsmap.a2p_bearer_udp_port",
12055             FT_UINT16, BASE_DEC, NULL, 0,
12056             NULL, HFILL }
12057         },
12058         { &hf_ansi_a_so,
12059             { "Service Option", "ansi_a_bsmap.so",
12060             FT_UINT16, BASE_DEC, NULL, 0,
12061             NULL, HFILL }
12062         },
12063         { &hf_ansi_a_cause_1,
12064             { "Cause",  "ansi_a_bsmap.cause_1",
12065             FT_UINT8, BASE_DEC, NULL, 0,
12066             NULL, HFILL }
12067         },
12068         { &hf_ansi_a_cause_2,
12069             { "Cause",  "ansi_a_bsmap.cause_2",
12070             FT_UINT16, BASE_DEC, NULL, 0,
12071             NULL, HFILL }
12072         },
12073         { &hf_ansi_a_meid_configured,
12074             { "Is MEID configured",  "ansi_a_bsmap.meid_configured",
12075             FT_BOOLEAN, BASE_NONE, NULL, 0x0,
12076             NULL, HFILL }
12077         }
12078     };
12079
12080     static enum_val_t a_variant_options[] = {
12081             { "is-634-rev0",    "IS-634 rev. 0",        A_VARIANT_IS634 },
12082             { "tsb-80",         "TSB-80",               A_VARIANT_TSB80 },
12083             { "is-634-a",       "IS-634-A",             A_VARIANT_IS634A },
12084             { "ios-2.x",        "IOS 2.x",              A_VARIANT_IOS2 },
12085             { "ios-3.x",        "IOS 3.x",              A_VARIANT_IOS3 },
12086             { "ios-4.0.1",      "IOS 4.0.1",            A_VARIANT_IOS401 },
12087             { "ios-5.0.1",      "IOS 5.0.1",            A_VARIANT_IOS501 },
12088             { NULL,             NULL,                   0 }
12089
12090     };
12091
12092     /* Setup protocol subtree array */
12093 #define MAX_NUM_DTAP_MSG        MAX(ANSI_A_IOS401_DTAP_NUM_MSG, ANSI_A_IOS501_DTAP_NUM_MSG)
12094 #define MAX_NUM_BSMAP_MSG       MAX(ANSI_A_IOS401_BSMAP_NUM_MSG, ANSI_A_IOS501_BSMAP_NUM_MSG)
12095 #define MAX_NUM_ELEM_1          MAX(MAX_IOS401_NUM_ELEM_1, MAX_IOS501_NUM_ELEM_1)
12096 #define NUM_INDIVIDUAL_ELEMS    18
12097     gint **ett;
12098     gint ett_len = (NUM_INDIVIDUAL_ELEMS+MAX_NUM_DTAP_MSG+MAX_NUM_BSMAP_MSG+MAX_NUM_ELEM_1+NUM_FWD_MS_INFO_REC+NUM_REV_MS_INFO_REC) * sizeof(gint *);
12099
12100     /*
12101      * XXX - at least one version of the HP C compiler apparently doesn't
12102      * recognize constant expressions using the "?" operator as being
12103      * constant expressions, so you can't use the expression that
12104      * initializes "ett_let" as an array size.  Therefore, we dynamically
12105      * allocate the array instead.
12106      */
12107     ett = (gint **) g_malloc(ett_len);
12108
12109     memset((void *) ett_dtap_msg, -1, sizeof(ett_dtap_msg));
12110     memset((void *) ett_bsmap_msg, -1, sizeof(ett_bsmap_msg));
12111     memset((void *) ett_ansi_elem_1, -1, sizeof(ett_ansi_elem_1));
12112     memset((void *) ett_ansi_fwd_ms_info_rec, -1, sizeof(gint) * NUM_FWD_MS_INFO_REC);
12113     memset((void *) ett_ansi_rev_ms_info_rec, -1, sizeof(gint) * NUM_REV_MS_INFO_REC);
12114
12115     ett[0] = &ett_bsmap;
12116     ett[1] = &ett_dtap;
12117     ett[2] = &ett_elems;
12118     ett[3] = &ett_elem;
12119     ett[4] = &ett_dtap_oct_1;
12120     ett[5] = &ett_cm_srvc_type;
12121     ett[6] = &ett_ansi_ms_info_rec_reserved;
12122     ett[7] = &ett_ansi_enc_info;
12123     ett[8] = &ett_cell_list;
12124     ett[9] = &ett_bearer_list;
12125     ett[10] = &ett_re_list;
12126     ett[11] = &ett_so_list;
12127     ett[12] = &ett_scm;
12128     ett[13] = &ett_adds_user_part;
12129     ett[14] = &ett_scr;
12130     ett[15] = &ett_srvc_con_rec;
12131     ett[16] = &ett_cm2_band_class;
12132     ett[17] = &ett_vp_algs;
12133
12134     last_offset = NUM_INDIVIDUAL_ELEMS;
12135
12136     for (i=0; i < MAX_NUM_DTAP_MSG; i++, last_offset++)
12137     {
12138         ett[last_offset] = &ett_dtap_msg[i];
12139     }
12140
12141     for (i=0; i < MAX_NUM_BSMAP_MSG; i++, last_offset++)
12142     {
12143         ett[last_offset] = &ett_bsmap_msg[i];
12144     }
12145
12146     for (i=0; i < MAX_NUM_ELEM_1; i++, last_offset++)
12147     {
12148         ett[last_offset] = &ett_ansi_elem_1[i];
12149     }
12150
12151     for (i=0; i < NUM_FWD_MS_INFO_REC; i++, last_offset++)
12152     {
12153         ett[last_offset] = &ett_ansi_fwd_ms_info_rec[i];
12154     }
12155
12156     for (i=0; i < NUM_REV_MS_INFO_REC; i++, last_offset++)
12157     {
12158         ett[last_offset] = &ett_ansi_rev_ms_info_rec[i];
12159     }
12160
12161     /* Register the protocol name and description */
12162
12163     proto_a_bsmap =
12164         proto_register_protocol("ANSI A-I/F BSMAP", "ANSI BSMAP", "ansi_a_bsmap");
12165
12166     proto_register_field_array(proto_a_bsmap, hf, array_length(hf));
12167
12168     proto_a_dtap =
12169         proto_register_protocol("ANSI A-I/F DTAP", "ANSI DTAP", "ansi_a_dtap");
12170
12171     is637_dissector_table =
12172         register_dissector_table("ansi_a.sms", "IS-637-A (SMS)",
12173         FT_UINT8, BASE_DEC);
12174
12175     is683_dissector_table =
12176         register_dissector_table("ansi_a.ota", "IS-683-A (OTA)",
12177         FT_UINT8, BASE_DEC);
12178
12179     is801_dissector_table =
12180         register_dissector_table("ansi_a.pld", "IS-801 (PLD)",
12181         FT_UINT8, BASE_DEC);
12182
12183     proto_register_subtree_array(ett, ett_len / (int)sizeof(gint *));
12184
12185     ansi_a_tap = register_tap("ansi_a");
12186
12187     /*
12188      * setup for preferences
12189      */
12190     ansi_a_module = prefs_register_protocol(proto_a_bsmap, proto_reg_handoff_ansi_a);
12191
12192     prefs_register_enum_preference(ansi_a_module,
12193         "global_variant",
12194         "Dissect PDU as",
12195         "(if other than the default of IOS 4.0.1)",
12196         &global_a_variant,
12197         a_variant_options,
12198         FALSE);
12199
12200     g_free(ett);
12201 }
12202
12203
12204 void
12205 proto_reg_handoff_ansi_a(void)
12206 {
12207     static gboolean ansi_a_prefs_initialized = FALSE;
12208
12209     if (!ansi_a_prefs_initialized)
12210     {
12211         dissector_handle_t bsmap_handle;
12212         bsmap_handle = create_dissector_handle(dissect_bsmap, proto_a_bsmap);
12213         dtap_handle = create_dissector_handle(dissect_dtap, proto_a_dtap);
12214         data_handle = find_dissector("data");
12215         rtp_handle = find_dissector("rtp");
12216
12217         dissector_add_uint("bsap.pdu_type",  BSSAP_PDU_TYPE_BSMAP, bsmap_handle);
12218         dissector_add_uint("bsap.pdu_type",  BSSAP_PDU_TYPE_DTAP, dtap_handle);
12219
12220         ansi_a_prefs_initialized = TRUE;
12221     }
12222
12223     switch (global_a_variant)
12224     {
12225     case A_VARIANT_IOS501:
12226         ansi_a_bsmap_strings = ansi_a_ios501_bsmap_strings;
12227         ansi_a_dtap_strings = ansi_a_ios501_dtap_strings;
12228         ansi_a_elem_1_strings = ansi_a_ios501_elem_1_strings;
12229         ansi_a_elem_1_max = MAX_IOS501_NUM_ELEM_1;
12230         break;
12231
12232     default:
12233         ansi_a_bsmap_strings = ansi_a_ios401_bsmap_strings;
12234         ansi_a_dtap_strings = ansi_a_ios401_dtap_strings;
12235         ansi_a_elem_1_strings = ansi_a_ios401_elem_1_strings;
12236         ansi_a_elem_1_max = MAX_IOS401_NUM_ELEM_1;
12237         break;
12238     }
12239 }