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