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