From Michael Lum:
[metze/wireshark/wip.git] / 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  *
7  * Title                3GPP2                   Other
8  *
9  *   Inter-operability Specification (IOS) for CDMA
10  *   2000 Access Network Interfaces
11  *                      3GPP2 A.S0001-1         TIA/EIA-2001
12  *
13  * $Id: packet-ansi_a.c,v 1.16 2004/03/27 11:32:28 guy Exp $
14  *
15  * Ethereal - Network traffic analyzer
16  * By Gerald Combs <gerald@ethereal.com>
17  * Copyright 1998 Gerald Combs
18  *
19  * This program is free software; you can redistribute it and/or
20  * modify it under the terms of the GNU General Public License
21  * as published by the Free Software Foundation; either version 2
22  * of the License, or (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program; if not, write to the Free Software
31  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32  */
33
34 #ifdef HAVE_CONFIG_H
35 # include "config.h"
36 #endif
37
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41
42 #include "epan/packet.h"
43 #include "prefs.h"
44 #include "tap.h"
45
46 #include "packet-bssap.h"
47 #include "packet-ansi_a.h"
48
49
50 /* PROTOTYPES/FORWARDS */
51
52 void proto_reg_handoff_ansi_a(void);
53
54 #define ANSI_A_MAX(x,y) (((x) < (y)) ? (y) : (x))
55
56 #define ANSI_A_MIN(x,y) (((x) < (y)) ? (x) : (y))
57
58 const value_string ansi_a_ios401_bsmap_strings[] = {
59     { 0x69,     "Additional Service Notification" },
60     { 0x65,     "ADDS Page" },
61     { 0x66,     "ADDS Page Ack" },
62     { 0x67,     "ADDS Transfer" },
63     { 0x68,     "ADDS Transfer Ack" },
64     { 0x02,     "Assignment Complete" },
65     { 0x03,     "Assignment Failure" },
66     { 0x01,     "Assignment Request" },
67     { 0x45,     "Authentication Request" },
68     { 0x46,     "Authentication Response" },
69     { 0x48,     "Base Station Challenge" },
70     { 0x49,     "Base Station Challenge Response" },
71     { 0x40,     "Block" },
72     { 0x41,     "Block Acknowledge" },
73     { 0x09,     "BS Service Request" },
74     { 0x0A,     "BS Service Response" },
75     { 0x20,     "Clear Command" },
76     { 0x21,     "Clear Complete" },
77     { 0x22,     "Clear Request" },
78     { 0x57,     "Complete Layer 3 Information" },
79     { 0x60,     "Feature Notification" },
80     { 0x61,     "Feature Notification Ack" },
81     { 0x13,     "Handoff Command" },
82     { 0x15,     "Handoff Commenced" },
83     { 0x14,     "Handoff Complete" },
84     { 0x16,     "Handoff Failure" },
85     { 0x17,     "Handoff Performed" },
86     { 0x10,     "Handoff Request" },
87     { 0x12,     "Handoff Request Acknowledge" },
88     { 0x11,     "Handoff Required" },
89     { 0x1A,     "Handoff Required Reject" },
90     { 0x6C,     "PACA Command" },
91     { 0x6D,     "PACA Command Ack" },
92     { 0x6E,     "PACA Update" },
93     { 0x6F,     "PACA Update Ack" },
94     { 0x52,     "Paging Request" },
95     { 0x53,     "Privacy Mode Command" },
96     { 0x55,     "Privacy Mode Complete" },
97     { 0x23,     "Radio Measurements for Position Request" },
98     { 0x25,     "Radio Measurements for Position Response" },
99     { 0x56,     "Rejection" },
100     { 0x05,     "Registration Request" },
101     { 0x30,     "Reset" },
102     { 0x31,     "Reset Acknowledge" },
103     { 0x34,     "Reset Circuit" },
104     { 0x35,     "Reset Circuit Acknowledge" },
105     { 0x47,     "SSD Update Request" },
106     { 0x4A,     "SSD Update Response" },
107     { 0x6A,     "Status Request" },
108     { 0x6B,     "Status Response" },
109     { 0x39,     "Transcoder Control Acknowledge" },
110     { 0x38,     "Transcoder Control Request" },
111     { 0x42,     "Unblock" },
112     { 0x43,     "Unblock Acknowledge" },
113     { 0x0B,     "User Zone Reject" },
114     { 0x04,     "User Zone Update" },
115     { 0, NULL },
116 };
117
118 const value_string ansi_a_ios401_dtap_strings[] = {
119     { 0x62,     "Additional Service Request" },
120     { 0x53,     "ADDS Deliver" },
121     { 0x54,     "ADDS Deliver Ack" },
122     { 0x26,     "Alert With Information" },
123     { 0x45,     "Authentication Request" },
124     { 0x46,     "Authentication Response" },
125     { 0x48,     "Base Station Challenge" },
126     { 0x49,     "Base Station Challenge Response" },
127     { 0x24,     "CM Service Request" },
128     { 0x25,     "CM Service Request Continuation" },
129     { 0x07,     "Connect" },
130     { 0x10,     "Flash with Information" },
131     { 0x50,     "Flash with Information Ack" },
132     { 0x02,     "Location Updating Accept" },
133     { 0x04,     "Location Updating Reject" },
134     { 0x08,     "Location Updating Request" },
135     { 0x27,     "Paging Response" },
136     { 0x2B,     "Parameter Update Confirm" },
137     { 0x2C,     "Parameter Update Request" },
138     { 0x56,     "Rejection" },
139     { 0x03,     "Progress" },
140     { 0x70,     "Service Redirection" },
141     { 0x2E,     "Service Release" },
142     { 0x2F,     "Service Release Complete" },
143     { 0x47,     "SSD Update Request" },
144     { 0x4A,     "SSD Update Response" },
145     { 0x6A,     "Status Request" },
146     { 0x6B,     "Status Response" },
147     { 0x0B,     "User Zone Reject" },
148     { 0x0C,     "User Zone Update" },
149     { 0x0D,     "User Zone Update Request" },
150     { 0, NULL },
151 };
152
153 const value_string ansi_a_ios401_elem_1_strings[] = {
154     { 0x20,     "Access Network Identifiers" },
155     { 0x3D,     "ADDS User Part" },
156     { 0x25,     "AMPS Hard Handoff Parameters" },
157     { 0x30,     "Anchor PDSN Address" },
158     { 0x7C,     "Anchor P-P Address" },
159     { 0x41,     "Authentication Challenge Parameter" },
160     { 0x28,     "Authentication Confirmation Parameter (RANDC)" },
161     { 0x59,     "Authentication Data" },
162     { 0x4A,     "Authentication Event" },
163     { 0x40,     "Authentication Parameter COUNT" },
164     { 0x42,     "Authentication Response Parameter" },
165     { 0x37,     "Band Class" },
166     { 0x5B,     "Called Party ASCII Number" },
167     { 0x5E,     "Called Party BCD Number" },
168     { 0x4B,     "Calling Party ASCII Number" },
169     { 0x04,     "Cause" },
170     { 0x08,     "Cause Layer 3" },
171     { 0x0C,     "CDMA Serving One Way Delay" },
172     { 0x05,     "Cell Identifier" },
173     { 0x1A,     "Cell Identifier List" },
174     { 0x23,     "Channel Number" },
175     { 0x0B,     "Channel Type" },
176     { 0x19,     "Circuit Group" },
177     { 0x01,     "Circuit Identity Code" },
178     { 0x24,     "Circuit Identity Code Extension" },
179     { 0x12,     "Classmark Information Type 2" },
180     { 0x29,     "Downlink Radio Environment" },
181     { 0x2B,     "Downlink Radio Environment List" },
182     { 0x0A,     "Encryption Information" },
183     { 0x10,     "Extended Handoff Direction Parameters" },
184     { 0x2C,     "Geographic Location" },
185     { 0x5A,     "Special Service Call Indicator" },
186     { 0x26,     "Handoff Power Level" },
187     { 0x16,     "Hard Handoff Parameters" },
188     { 0x2E,     "Information Element Requested" },
189     { 0x09,     "IS-2000 Channel Identity" },
190     { 0x27,     "IS-2000 Channel Identity 3X" },
191     { 0x11,     "IS-2000 Mobile Capabilities" },
192     { 0x0F,     "IS-2000 Non-Negotiable Service Configuration Record" },
193     { 0x0E,     "IS-2000 Service Configuration Record" },
194     { 0x62,     "IS-95/IS-2000 Cause Value" },
195     { 0x67,     "IS-2000 Redirection Record" },
196     { 0x22,     "IS-95 Channel Identity" },
197     { 0x64,     "IS-95 MS Measured Channel Identity" },
198     { 0x17,     "Layer 3 Information" },
199     { 0x13,     "Location Area Information" },
200     { 0x38,     "Message Waiting Indication" },
201     { 0x0D,     "Mobile Identity" },
202     { 0x15,     "MS Information Records" },
203     { 0xA0,     "Origination Continuation Indicator" },
204     { 0x5F,     "PACA Order" },
205     { 0x60,     "PACA Reorigination Indicator" },
206     { 0x4E,     "PACA Timestamp" },
207     { 0x70,     "Packet Session Parameters" },
208     { 0x14,     "PDSN IP Address" },
209     { 0xA2,     "Power Down Indicator" },
210     { 0x06,     "Priority" },
211     { 0x3B,     "Protocol Revision" },
212     { 0x18,     "Protocol Type" },
213     { 0x2D,     "PSMM Count" },
214     { 0x07,     "Quality of Service Parameters" },
215     { 0x1D,     "Radio Environment and Resources" },
216     { 0x1F,     "Registration Type" },
217     { 0x44,     "Reject Cause" },
218     { 0x1B,     "Response Request" },
219     { 0x68,     "Return Cause" },
220     { 0x21,     "RF Channel Identity" },
221     { 0x03,     "Service Option" },
222     { 0x1E,     "Service Option Connection Identifier (SOCI)" },
223     { 0x2A,     "Service Option List" },
224     { 0x69,     "Service Redirection Info" },
225     { 0x71,     "Session Reference Identifier (SR_ID)" },
226     { 0x32,     "SID" },
227     { 0x34,     "Signal" },
228     { 0x35,     "Slot Cycle Index" },
229     { 0x31,     "Software Version" },
230     { 0x39,     "Source RNC to Target RNC Transparent Container" },
231     { 0x14,     "Source PDSN Address" },
232     { 0x33,     "Tag" },
233     { 0x3A,     "Target RNC to Source RNC Transparent Container" },
234     { 0x36,     "Transcoder Mode" }, /* XXX 0x1C in IOS 4.0.1 */
235     { 0x02,     "User Zone ID" },
236     { 0xA1,     "Voice Privacy Request" },
237     { 0, NULL },
238 };
239
240 #define ANSI_MS_INFO_REC_DISPLAY        0x01
241 #define ANSI_MS_INFO_REC_CLD_PN         0x02
242 #define ANSI_MS_INFO_REC_CLG_PN         0x03
243 #define ANSI_MS_INFO_REC_CONN_N         0x04
244 #define ANSI_MS_INFO_REC_SIGNAL         0x05
245 #define ANSI_MS_INFO_REC_MW             0x06
246 #define ANSI_MS_INFO_REC_SC             0x07
247 #define ANSI_MS_INFO_REC_CLD_PSA        0x08
248 #define ANSI_MS_INFO_REC_CLG_PSA        0x09
249 #define ANSI_MS_INFO_REC_CONN_SA        0x0a
250 #define ANSI_MS_INFO_REC_RED_N          0x0b
251 #define ANSI_MS_INFO_REC_RED_SA         0x0c
252 #define ANSI_MS_INFO_REC_MP             0x0d
253 #define ANSI_MS_INFO_REC_PA             0x0e
254 #define ANSI_MS_INFO_REC_LC             0x0f
255 #define ANSI_MS_INFO_REC_EDISPLAY       0x10
256 #define ANSI_MS_INFO_REC_NNSC           0x13
257 #define ANSI_MS_INFO_REC_MC_EDISPLAY    0x14
258 #define ANSI_MS_INFO_REC_CWI            0x15
259 #define ANSI_MS_INFO_REC_ERTI           0xfe
260
261 static const value_string ansi_ms_info_rec_str[] = {
262     { ANSI_MS_INFO_REC_DISPLAY,         "Display" },
263     { ANSI_MS_INFO_REC_CLD_PN,          "Called Party Number" },
264     { ANSI_MS_INFO_REC_CLG_PN,          "Calling Party Number" },
265     { ANSI_MS_INFO_REC_CONN_N,          "Connected Number" },
266     { ANSI_MS_INFO_REC_SIGNAL,          "Signal" },
267     { ANSI_MS_INFO_REC_MW,              "Message Waiting" },
268     { ANSI_MS_INFO_REC_SC,              "Service Configuration" },
269     { ANSI_MS_INFO_REC_CLD_PSA,         "Called Party Subaddress" },
270     { ANSI_MS_INFO_REC_CLG_PSA,         "Calling Party Subaddress" },
271     { ANSI_MS_INFO_REC_CONN_SA,         "Connected Subaddress" },
272     { ANSI_MS_INFO_REC_RED_N,           "Redirecting Number" },
273     { ANSI_MS_INFO_REC_RED_SA,          "Redirecting Subaddress" },
274     { ANSI_MS_INFO_REC_MP,              "Meter Pulses" },
275     { ANSI_MS_INFO_REC_PA,              "Parametric Alerting" },
276     { ANSI_MS_INFO_REC_LC,              "Line Control" },
277     { ANSI_MS_INFO_REC_EDISPLAY,        "Extended Display" },
278     { ANSI_MS_INFO_REC_NNSC,            "Non-Negotiable Service Configuration" },
279     { ANSI_MS_INFO_REC_MC_EDISPLAY,     "Multiple Character Extended Display" },
280     { ANSI_MS_INFO_REC_CWI,             "Call Waiting Indicator" },
281     { ANSI_MS_INFO_REC_ERTI,            "Extended Record Type International" },
282     { 0, NULL },
283 };
284 #define NUM_MS_INFO_REC (sizeof(ansi_ms_info_rec_str)/sizeof(value_string))
285 static gint ett_ansi_ms_info_rec[NUM_MS_INFO_REC];
286
287 static gchar *band_class_str[] = {
288     "800 MHz Cellular System",
289     "1.850 to 1.990 GHz Broadband PCS",
290     "872 to 960 MHz TACS Band",
291     "832 to 925 MHz JTACS Band",
292     "1.750 to 1.870 GHz Korean PCS",
293     "450 MHz NMT",
294     "2 GHz IMT-2000 Band",
295     "North American 700 MHz Cellular Band",
296     "1.710 to 1.880 GHz PCS",
297     "880 to 960 MHz Band",
298     "Secondary 800 MHz Band",
299     "400 MHz European PAMR Band",
300     "800 MHz European PAMR Band"
301 };
302 #define NUM_BAND_CLASS_STR      (sizeof(band_class_str)/sizeof(gchar *))
303
304 static gchar *cell_disc_str[] = {
305     "whole Cell Global Identification (CGI)",
306     "LAC/CI",
307     "Cell Identity (CI)",
308     "None",
309     "Location Area Identification (LAI)",
310     "Location Area Code (LAC)",
311     "ALL",
312     "IS-41 whole Cell Global Identification (ICGI)",
313     "Enhanced whole Cell Global Identification (ECGI)"
314 };
315 #define NUM_CELL_DISC_STR       (sizeof(cell_disc_str)/sizeof(gchar *))
316
317 /* Initialize the protocol and registered fields */
318 static int proto_a_bsmap = -1;
319 static int proto_a_dtap = -1;
320
321 static int ansi_a_tap = -1;
322
323 static int hf_ansi_a_none = -1;
324 static int hf_ansi_a_bsmap_msgtype = -1;
325 static int hf_ansi_a_dtap_msgtype = -1;
326 static int hf_ansi_a_length = -1;
327 static int hf_ansi_a_elem_id = -1;
328 static int hf_ansi_a_esn = -1;
329 static int hf_ansi_a_imsi = -1;
330 static int hf_ansi_a_min = -1;
331 static int hf_ansi_a_cld_party_bcd_num = -1;
332 static int hf_ansi_a_clg_party_bcd_num = -1;
333 static int hf_ansi_a_cld_party_ascii_num = -1;
334 static int hf_ansi_a_clg_party_ascii_num = -1;
335 static int hf_ansi_a_cell_ci = -1;
336 static int hf_ansi_a_cell_lac = -1;
337 static int hf_ansi_a_cell_mscid = -1;
338 static int hf_ansi_a_pdsn_ip_addr = -1;
339
340
341 /* Initialize the subtree pointers */
342 static gint ett_bsmap = -1;
343 static gint ett_dtap = -1;
344 static gint ett_elems = -1;
345 static gint ett_elem = -1;
346 static gint ett_dtap_oct_1 = -1;
347 static gint ett_cm_srvc_type = -1;
348 static gint ett_ansi_ms_info_rec_reserved = -1;
349 static gint ett_ansi_enc_info = -1;
350 static gint ett_cell_list = -1;
351
352 #define A_VARIANT_IS634         4
353 #define A_VARIANT_TSB80         5
354 #define A_VARIANT_IS634A        6
355 #define A_VARIANT_IOS2          7
356 #define A_VARIANT_IOS3          8
357 #define A_VARIANT_IOS401        9
358
359 /*
360  * IOS 4, probably most common
361  */
362 static gint a_global_variant = A_VARIANT_IOS401;
363
364 /*
365  * Variables to allow for proper deletion of dissector registration when
366  * the user changes values
367  */
368 static gint a_variant = 0;
369
370 static char a_bigbuf[1024];
371 static gchar a_add_string[1024];
372 static dissector_handle_t data_handle;
373 static dissector_handle_t bsmap_handle;
374 static dissector_handle_t dtap_handle;
375 static dissector_table_t is637_dissector_table; /* IS-637-A Transport Layer (SMS) */
376 static dissector_table_t is683_dissector_table; /* IS-683-A (OTA) */
377 static dissector_table_t is801_dissector_table; /* IS-801 (PLD) */
378 static packet_info *g_pinfo;
379 static proto_tree *g_tree;
380
381
382 typedef struct dgt_set_t
383 {
384     unsigned char out[15];
385 }
386 dgt_set_t;
387
388 static dgt_set_t Dgt_tbcd = {
389     {
390   /*  0   1   2   3   4   5   6   7   8   9   a   b   c   d   e */
391      '0','1','2','3','4','5','6','7','8','9','?','B','C','*','#'
392     }
393 };
394
395 static dgt_set_t Dgt_msid = {
396     {
397   /*  0   1   2   3   4   5   6   7   8   9   a   b   c   d   e */
398      '0','1','2','3','4','5','6','7','8','9','?','?','?','?','?'
399     }
400 };
401
402 /* FUNCTIONS */
403
404 /*
405  * Unpack BCD input pattern into output ASCII pattern
406  *
407  * Input Pattern is supplied using the same format as the digits
408  *
409  * Returns: length of unpacked pattern
410  */
411 static int
412 my_dgt_tbcd_unpack(
413     char        *out,           /* ASCII pattern out */
414     guchar      *in,            /* packed pattern in */
415     int         num_octs,       /* Number of octets to unpack */
416     dgt_set_t   *dgt            /* Digit definitions */
417     )
418 {
419     int cnt = 0;
420     unsigned char i;
421
422     while (num_octs)
423     {
424         /*
425          * unpack first value in byte
426          */
427         i = *in++;
428         *out++ = dgt->out[i & 0x0f];
429         cnt++;
430
431         /*
432          * unpack second value in byte
433          */
434         i >>= 4;
435
436         if (i == 0x0f)  /* odd number bytes - hit filler */
437             break;
438
439         *out++ = dgt->out[i];
440         cnt++;
441         num_octs--;
442     }
443
444     *out = '\0';
445
446     return(cnt);
447 }
448
449 static gchar *
450 my_match_strval(guint32 val, const value_string *vs, gint *idx)
451 {
452     gint i = 0;
453
454     while (vs[i].strptr)
455     {
456         if (vs[i].value == val)
457         {
458             *idx = i;
459             return(vs[i].strptr);
460         }
461
462         i++;
463     }
464
465     *idx = -1;
466     return(NULL);
467 }
468
469 /* ELEMENT FUNCTIONS */
470
471 #define EXTRANEOUS_DATA_CHECK(edc_len, edc_max_len) \
472     if ((edc_len) > (edc_max_len)) \
473     { \
474         proto_tree_add_text(tree, tvb, \
475             curr_offset, (edc_len) - (edc_max_len), "Extraneous Data"); \
476         curr_offset += ((edc_len) - (edc_max_len)); \
477     }
478
479 #define SHORT_DATA_CHECK(sdc_len, sdc_min_len) \
480     if ((sdc_len) < (sdc_min_len)) \
481     { \
482         proto_tree_add_text(tree, tvb, \
483             curr_offset, (sdc_len), "Short Data (?)"); \
484         curr_offset += (sdc_len); \
485         return(curr_offset - offset); \
486     }
487
488 #define EXACT_DATA_CHECK(edc_len, edc_eq_len) \
489     if ((edc_len) != (edc_eq_len)) \
490     { \
491         proto_tree_add_text(tree, tvb, \
492             asn1->offset, (edc_len), "Unexpected Data Length"); \
493         asn1->offset += (edc_len); \
494         return; \
495     }
496
497 #define NO_MORE_DATA_CHECK(nmdc_len) \
498     if ((nmdc_len) == (curr_offset - offset)) return(nmdc_len);
499
500
501 /*
502  * IOS 6.2.2.6
503  */
504 static guint8
505 elem_chan_num(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
506 {
507     guint32     value;
508     guint32     curr_offset;
509
510     len = len;
511     curr_offset = offset;
512
513     value = tvb_get_ntohs(tvb, curr_offset);
514
515     proto_tree_add_text(tree,
516         tvb, curr_offset, 2,
517         "Channel Number: %u",
518         value);
519
520     curr_offset += 2;
521
522     sprintf(add_string, " - (%u)", value);
523
524     /* no length check possible */
525
526     return(curr_offset - offset);
527 }
528
529 /*
530  * IOS 6.2.2.7
531  */
532 static guint8
533 elem_chan_type(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
534 {
535     guint8      oct;
536     guint32     curr_offset;
537     gchar       *str = NULL;
538     gboolean    data;
539
540     curr_offset = offset;
541     data = FALSE;
542
543     oct = tvb_get_guint8(tvb, curr_offset);
544
545     switch (oct)
546     {
547     case 0: str = "No Alert"; break;
548     case 1: str = "Speech"; break;
549     case 2: str = "Data"; data = TRUE; break;
550     case 3: str = "Signaling"; break;
551     default:
552         str = "Unknown";
553         break;
554     }
555
556     proto_tree_add_text(tree,
557         tvb, curr_offset, 1,
558         "Speech or Data Indicator: %s",
559         str);
560
561     sprintf(add_string, " - (%s)", str);
562
563     curr_offset++;
564
565     NO_MORE_DATA_CHECK(len);
566
567     oct = tvb_get_guint8(tvb, curr_offset);
568
569     switch (oct)
570     {
571     case 0: str = "Reserved (invalid)"; break;
572     case 1: str = "DCCH"; break;
573     case 2: str = "Reserved for future use (invalid)"; break;
574     case 8: str = "Full rate TCH channel Bm"; break;
575     case 9: str = "Half rate TCH channel Lm"; break;
576     default:
577         str = "Unknown";
578         break;
579     }
580
581     proto_tree_add_text(tree,
582         tvb, curr_offset, 1,
583         "Channel Rate and Type: %s",
584         str);
585
586     curr_offset++;
587
588     NO_MORE_DATA_CHECK(len);
589
590     oct = tvb_get_guint8(tvb, curr_offset);
591
592     if (data)
593     {
594         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
595         proto_tree_add_text(tree,
596             tvb, curr_offset, 1,
597             "%s :  Extension",
598             a_bigbuf);
599
600         other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
601         proto_tree_add_text(tree,
602             tvb, curr_offset, 1,
603             "%s :  %sTransparent service",
604             a_bigbuf,
605             (oct & 0x40) ? "Non-" : "");
606
607         other_decode_bitfield_value(a_bigbuf, oct, 0x3f, 8);
608         proto_tree_add_text(tree,
609             tvb, curr_offset, 1,
610             "%s :  Reserved",
611             a_bigbuf);
612     }
613     else
614     {
615         switch (oct)
616         {
617         case 0: str = "No Resources Required (invalid)"; break;
618         case 1: str = "Reserved"; break;
619         case 2: str = "Reserved"; break;
620         case 3: str = "TIA/EIA-IS-2000 8 kb/s vocoder"; break;
621         case 4: str = "8 kb/s enhanced vocoder (EVRC)"; break;
622         case 5: str = "13 kb/s vocoder"; break;
623         case 6: str = "ADPCM"; break;
624         default:
625             str = "Reserved";
626             break;
627         }
628
629         proto_tree_add_text(tree,
630             tvb, curr_offset, 1,
631             "Speech Encoding Algorithm/data rate + Transparency Indicator: %s",
632             str);
633     }
634
635     curr_offset++;
636
637     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
638
639     return(curr_offset - offset);
640 }
641
642 /*
643  * IOS 6.2.2.8
644  */
645 static guint8
646 elem_rf_chan_id(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
647 {
648     guint8      oct;
649     guint32     value;
650     guint32     curr_offset;
651
652     len = len;
653     curr_offset = offset;
654
655     proto_tree_add_text(tree, tvb, curr_offset, 1,
656         "Color Code");
657
658     curr_offset++;
659
660     oct = tvb_get_guint8(tvb, curr_offset);
661
662     other_decode_bitfield_value(a_bigbuf, oct, 0xfc, 8);
663     proto_tree_add_text(tree, tvb, curr_offset, 1,
664         "%s :  Reserved",
665         a_bigbuf);
666
667     other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
668     proto_tree_add_text(tree, tvb, curr_offset, 1,
669         "%s :  N-AMPS",
670         a_bigbuf);
671
672     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
673     proto_tree_add_text(tree, tvb, curr_offset, 1,
674         "%s :  ANSI/EIA/TIA-553",
675         a_bigbuf);
676
677     curr_offset++;
678
679     oct = tvb_get_guint8(tvb, curr_offset);
680
681     other_decode_bitfield_value(a_bigbuf, oct, 0xfc, 8);
682     proto_tree_add_text(tree, tvb, curr_offset, 1,
683         "%s :  Reserved",
684         a_bigbuf);
685
686     other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
687     proto_tree_add_text(tree, tvb, curr_offset, 1,
688         "%s :  Timeslot Number",
689         a_bigbuf);
690
691     curr_offset++;
692
693     value = tvb_get_ntohs(tvb, curr_offset);
694
695     other_decode_bitfield_value(a_bigbuf, value >> 8, 0xf8, 8);
696     proto_tree_add_text(tree, tvb, curr_offset, 1,
697         "%s :  Reserved",
698         a_bigbuf);
699
700     other_decode_bitfield_value(a_bigbuf, value >> 8, 0x07, 8);
701     proto_tree_add_text(tree, tvb, curr_offset, 1,
702         "%s :  ARFCN (MSB): %u",
703         a_bigbuf,
704         value & 0x07ff);
705
706     other_decode_bitfield_value(a_bigbuf, value & 0x00ff, 0xff, 8);
707     proto_tree_add_text(tree, tvb, curr_offset + 1, 1,
708         "%s :  ARFCN (LSB)",
709         a_bigbuf);
710
711     sprintf(add_string, " - (ARFCN: %u)", value & 0x07ff);
712
713     curr_offset += 2;
714
715     /* no length check possible */
716
717     return(curr_offset - offset);
718 }
719
720 /*
721  * IOS 6.2.2.9
722  */
723 static guint8
724 elem_sid(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
725 {
726     guint32     value;
727     guint32     curr_offset;
728
729     len = len;
730     curr_offset = offset;
731
732     value = tvb_get_ntohs(tvb, curr_offset);
733
734     other_decode_bitfield_value(a_bigbuf, value >> 8, 0x80, 8);
735     proto_tree_add_text(tree, tvb, curr_offset, 1,
736         "%s :  Reserved",
737         a_bigbuf);
738
739     other_decode_bitfield_value(a_bigbuf, value >> 8, 0x7f, 8);
740     proto_tree_add_text(tree, tvb, curr_offset, 1,
741         "%s :  SID (MSB), %u",
742         a_bigbuf,
743         value & 0x7fff);
744
745     other_decode_bitfield_value(a_bigbuf, value & 0x00ff, 0xff, 8);
746     proto_tree_add_text(tree, tvb, curr_offset + 1, 1,
747         "%s :  SID (LSB)",
748         a_bigbuf);
749
750     sprintf(add_string, " - (SID: %u)", value & 0x7fff);
751
752     curr_offset += 2;
753
754     /* no length check possible */
755
756     return(curr_offset - offset);
757 }
758
759 /*
760  * IOS 6.2.2.10
761  */
762 static guint8
763 elem_is95_chan_id(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
764 {
765     guint8      oct;
766     guint32     value;
767     guint32     curr_offset;
768
769     curr_offset = offset;
770
771     oct = tvb_get_guint8(tvb, curr_offset);
772
773     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
774     proto_tree_add_text(tree, tvb, curr_offset, 1,
775         "%s :  Hard Handoff",
776         a_bigbuf);
777
778     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
779     proto_tree_add_text(tree, tvb, curr_offset, 1,
780         "%s :  Number of Channels to Add: %u",
781         a_bigbuf,
782         (oct & 0x70) >> 4);
783
784     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
785     proto_tree_add_text(tree, tvb, curr_offset, 1,
786         "%s :  Frame Offset: (%u), %.2f ms",
787         a_bigbuf,
788         oct & 0x0f,
789         (oct & 0x0f) * 1.25);
790
791     curr_offset++;
792
793     NO_MORE_DATA_CHECK(len);
794
795     SHORT_DATA_CHECK(len - (curr_offset - offset), 4);
796
797     do
798     {
799         oct = tvb_get_guint8(tvb, curr_offset);
800
801         proto_tree_add_text(tree, tvb, curr_offset, 1,
802             "Walsh Code Channel Index: %u",
803             oct);
804
805         curr_offset++;
806
807         oct = tvb_get_guint8(tvb, curr_offset);
808
809         other_decode_bitfield_value(a_bigbuf, oct, 0xff, 8);
810         proto_tree_add_text(tree, tvb, curr_offset, 1,
811             "%s :  Pilot PN Code (LSB)",
812             a_bigbuf);
813
814         curr_offset++;
815
816         value = oct;
817         oct = tvb_get_guint8(tvb, curr_offset);
818         value |= ((guint32) (oct & 0x80)) << 1;
819
820         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
821         proto_tree_add_text(tree, tvb, curr_offset, 1,
822             "%s :  Pilot PN Code (MSB): %u",
823             a_bigbuf,
824             value);
825
826         other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
827         proto_tree_add_text(tree, tvb, curr_offset, 1,
828             "%s :  Power Combined",
829             a_bigbuf);
830
831         other_decode_bitfield_value(a_bigbuf, oct, 0x20, 8);
832         proto_tree_add_text(tree, tvb, curr_offset, 1,
833             "%s :  Frequency Included",
834             a_bigbuf);
835
836         other_decode_bitfield_value(a_bigbuf, oct, 0x18, 8);
837         proto_tree_add_text(tree, tvb, curr_offset, 1,
838             "%s :  Reserved",
839             a_bigbuf);
840
841         value = tvb_get_guint8(tvb, curr_offset + 1) | ((oct & 0x07) << 8);
842
843         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
844         proto_tree_add_text(tree, tvb, curr_offset, 1,
845             "%s :  ARFCN (MSB): %u",
846             a_bigbuf,
847             value);
848
849         curr_offset++;
850
851         other_decode_bitfield_value(a_bigbuf, value & 0x00ff, 0xff, 8);
852         proto_tree_add_text(tree, tvb, curr_offset, 1,
853             "%s :  ARFCN (LSB)",
854             a_bigbuf);
855
856         if (add_string[0] == '\0')
857         {
858             sprintf(add_string, " - (ARFCN: %u)", value);
859         }
860
861         curr_offset++;
862     }
863     while ((len - (curr_offset - offset)) >= 4);
864
865     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
866
867     return(curr_offset - offset);
868 }
869
870 /*
871  * IOS 6.2.2.11
872  * UNUSED
873  */
874
875 /*
876  * IOS 6.2.2.12
877  */
878 static guint8
879 elem_enc_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
880 {
881     guint8      oct;
882     guint8      oct_len;
883     guint32     curr_offset;
884     gchar       *str;
885     guint8      num_recs;
886     proto_tree  *subtree;
887     proto_item  *item;
888
889     curr_offset = offset;
890
891     num_recs = 0;
892
893     while ((len - (curr_offset - offset)) >= 2)
894     {
895         num_recs++;
896
897         oct = tvb_get_guint8(tvb, curr_offset);
898
899         switch ((oct & 0x7c) >> 2)
900         {
901         case 0: str = "Not Used - Invalid value"; break;
902         case 1: str = "SME Key: Signaling Message Encryption Key"; break;
903         case 2: str = "Reserved (VPM: Voice Privacy Mask)"; break;
904         case 3: str = "Reserved"; break;
905         case 4: str = "Private Longcode"; break;
906         case 5: str = "Data Key (ORYX)"; break;
907         case 6: str = "Initial RAND"; break;
908         default:
909             str = "Reserved";
910             break;
911         }
912
913         item =
914             proto_tree_add_text(tree,
915                 tvb, curr_offset, 1,
916                 "Encryption Info - %u: (%u) %s",
917                 num_recs,
918                 (oct & 0x7c) >> 2,
919                 str);
920
921         subtree = proto_item_add_subtree(item, ett_ansi_enc_info);
922
923         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
924         proto_tree_add_text(subtree, tvb, curr_offset, 1,
925             "%s :  Extension",
926             a_bigbuf);
927
928         other_decode_bitfield_value(a_bigbuf, oct, 0x7c, 8);
929         proto_tree_add_text(subtree, tvb, curr_offset, 1,
930             "%s :  Encryption Parameter Identifier: (%u) %s",
931             a_bigbuf,
932             (oct & 0x7c) >> 2,
933             str);
934
935         other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
936         proto_tree_add_text(subtree, tvb, curr_offset, 1,
937             "%s :  Status: %s",
938             a_bigbuf,
939             (oct & 0x02) ? "active" : "inactive");
940
941         other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
942         proto_tree_add_text(subtree, tvb, curr_offset, 1,
943             "%s :  Available: algorithm is %savailable",
944             a_bigbuf,
945             (oct & 0x01) ? "" : "not ");
946
947         curr_offset++;
948
949         oct_len = tvb_get_guint8(tvb, curr_offset);
950
951         proto_tree_add_uint(subtree, hf_ansi_a_length, tvb,
952             curr_offset, 1, oct_len);
953
954         curr_offset++;
955
956         if (oct_len > 0)
957         {
958             SHORT_DATA_CHECK(len - (curr_offset - offset), oct_len);
959
960             proto_tree_add_text(subtree, tvb, curr_offset, oct_len,
961                 "Encryption Parameter value");
962
963             curr_offset += oct_len;
964         }
965     }
966
967     sprintf(add_string, " - %u record%s",
968         num_recs, plurality(num_recs, "", "s"));
969
970     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
971
972     return(curr_offset - offset);
973 }
974
975 /*
976  * IOS 6.2.2.13
977  * NO ASSOCIATED DATA
978  */
979
980 /*
981  * IOS 6.2.2.14
982  * A3/A7
983  */
984
985 /*
986  * IOS 6.2.2.15
987  */
988 static guint8
989 elem_cm_info_type_2(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
990 {
991     guint8      oct;
992     guint8      num_bands;
993     guint32     curr_offset;
994     gint        temp_int;
995     gchar       *str;
996
997     curr_offset = offset;
998
999     oct = tvb_get_guint8(tvb, curr_offset);
1000
1001     other_decode_bitfield_value(a_bigbuf, oct, 0xe0, 8);
1002     proto_tree_add_text(tree, tvb, curr_offset, 1,
1003         "%s :  Mobile P_REV: %u",
1004         a_bigbuf,
1005         (oct & 0xe0) >> 5);
1006
1007     sprintf(add_string, " - P_REV (%u)", (oct & 0xe0) >> 5);
1008
1009     other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
1010     proto_tree_add_text(tree, tvb, curr_offset, 1,
1011         "%s :  Reserved",
1012         a_bigbuf);
1013
1014     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
1015     proto_tree_add_text(tree, tvb, curr_offset, 1,
1016         "%s :  See List of Entries",
1017         a_bigbuf);
1018
1019     switch (oct & 0x07)
1020     {
1021     case 0: str = "Class 1, vehicle and portable"; break;
1022     case 1: str = "Class 2, portable"; break;
1023     case 2: str = "Class 3, handheld"; break;
1024     case 3: str = "Class 4, handheld"; break;
1025     case 4: str = "Class 5, handheld"; break;
1026     case 5: str = "Class 6, handheld"; break;
1027     case 6: str = "Class 7, handheld"; break;
1028     default:
1029         str = "Class 8, handheld";
1030         break;
1031     }
1032
1033     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
1034     proto_tree_add_text(tree, tvb, curr_offset, 1,
1035         "%s :  RF Power Capability: %s",
1036         a_bigbuf,
1037         str);
1038
1039     curr_offset++;
1040
1041     proto_tree_add_text(tree, tvb, curr_offset, 1,
1042         "Reserved");
1043
1044     curr_offset++;
1045
1046     oct = tvb_get_guint8(tvb, curr_offset);
1047
1048     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
1049     proto_tree_add_text(tree, tvb, curr_offset, 1,
1050         "%s :  NAR_AN_CAP: N-AMPS %ssupported",
1051         a_bigbuf,
1052         (oct & 0x80) ? "" : "not ");
1053
1054     other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
1055     proto_tree_add_text(tree, tvb, curr_offset, 1,
1056         "%s :  IS-95: %ssupported",
1057         a_bigbuf,
1058         (oct & 0x40) ? "" : "not ");
1059
1060     other_decode_bitfield_value(a_bigbuf, oct, 0x20, 8);
1061     proto_tree_add_text(tree, tvb, curr_offset, 1,
1062         "%s :  Slotted: mobile is %sin slotted mode",
1063         a_bigbuf,
1064         (oct & 0x20) ? "" : "not ");
1065
1066     other_decode_bitfield_value(a_bigbuf, oct, 0x18, 8);
1067     proto_tree_add_text(tree, tvb, curr_offset, 1,
1068         "%s :  Reserved",
1069         a_bigbuf);
1070
1071     other_decode_bitfield_value(a_bigbuf, oct, 0x04, 8);
1072     proto_tree_add_text(tree, tvb, curr_offset, 1,
1073         "%s :  DTX: mobile is %scapable of DTX",
1074         a_bigbuf,
1075         (oct & 0x04) ? "" : "not ");
1076
1077     other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
1078     proto_tree_add_text(tree, tvb, curr_offset, 1,
1079         "%s :  Mobile Term: mobile is %scapable of receiving incoming calls",
1080         a_bigbuf,
1081         (oct & 0x02) ? "" : "not ");
1082
1083     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
1084     proto_tree_add_text(tree, tvb, curr_offset, 1,
1085         "%s :  Reserved",
1086         a_bigbuf);
1087
1088     curr_offset++;
1089
1090     NO_MORE_DATA_CHECK(len);
1091
1092     proto_tree_add_text(tree, tvb, curr_offset, 1,
1093         "Reserved");
1094
1095     curr_offset++;
1096
1097     NO_MORE_DATA_CHECK(len);
1098
1099     oct = tvb_get_guint8(tvb, curr_offset);
1100
1101     other_decode_bitfield_value(a_bigbuf, oct, 0xfc, 8);
1102     proto_tree_add_text(tree, tvb, curr_offset, 1,
1103         "%s :  Reserved",
1104         a_bigbuf);
1105
1106     other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
1107     proto_tree_add_text(tree, tvb, curr_offset, 1,
1108         "%s :  Mobile Term: mobile is %scapable of receiving incoming calls",
1109         a_bigbuf,
1110         (oct & 0x02) ? "" : "not ");
1111
1112     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
1113     proto_tree_add_text(tree, tvb, curr_offset, 1,
1114         "%s :  PACA Supported Indicator (PSI): mobile station %s PACA",
1115         a_bigbuf,
1116         (oct & 0x01) ? "supports" : "does not support");
1117
1118     curr_offset++;
1119
1120     NO_MORE_DATA_CHECK(len);
1121
1122     oct = tvb_get_guint8(tvb, curr_offset);
1123
1124     proto_tree_add_text(tree, tvb, curr_offset, 1,
1125         "SCM Length: %u",
1126         oct);
1127
1128     curr_offset++;
1129
1130     oct = tvb_get_guint8(tvb, curr_offset);
1131
1132     proto_tree_add_text(tree, tvb, curr_offset, 1,
1133         "Station Class Mark: %u",
1134         oct);
1135
1136     curr_offset++;
1137
1138     oct = tvb_get_guint8(tvb, curr_offset);
1139
1140     proto_tree_add_text(tree, tvb, curr_offset, 1,
1141         "Count of Band Class Entries: %u",
1142         oct);
1143
1144     curr_offset++;
1145
1146     NO_MORE_DATA_CHECK(len);
1147
1148     oct = tvb_get_guint8(tvb, curr_offset);
1149
1150     proto_tree_add_text(tree, tvb, curr_offset, 1,
1151         "Band Class Entry Length: %u",
1152         oct);
1153
1154     curr_offset++;
1155
1156     NO_MORE_DATA_CHECK(len);
1157
1158     SHORT_DATA_CHECK(len - (curr_offset - offset), 3);
1159
1160     num_bands = 0;
1161     do
1162     {
1163         oct = tvb_get_guint8(tvb, curr_offset);
1164
1165         other_decode_bitfield_value(a_bigbuf, oct, 0xe0, 8);
1166         proto_tree_add_text(tree,
1167             tvb, curr_offset, 1,
1168             "%s :  Reserved",
1169             a_bigbuf);
1170
1171         temp_int = oct & 0x1f;
1172         if ((temp_int < 0) || (temp_int >= (gint) NUM_BAND_CLASS_STR))
1173         {
1174             str = "Reserved";
1175         }
1176         else
1177         {
1178             str = band_class_str[temp_int];
1179         }
1180
1181         other_decode_bitfield_value(a_bigbuf, oct, 0x1f, 8);
1182         proto_tree_add_text(tree,
1183             tvb, curr_offset, 1,
1184             "%s :  Band Class: %s",
1185             a_bigbuf,
1186             str);
1187
1188         curr_offset++;
1189
1190         oct = tvb_get_guint8(tvb, curr_offset);
1191
1192         other_decode_bitfield_value(a_bigbuf, oct, 0xe0, 8);
1193         proto_tree_add_text(tree,
1194             tvb, curr_offset, 1,
1195             "%s :  Reserved",
1196             a_bigbuf);
1197
1198         other_decode_bitfield_value(a_bigbuf, oct, 0x1f, 8);
1199         proto_tree_add_text(tree,
1200             tvb, curr_offset, 1,
1201             "%s :  Band Class %u Air Interfaces Supported: %u",
1202             a_bigbuf,
1203             num_bands,
1204             oct & 0x1f);
1205
1206         curr_offset++;
1207
1208         oct = tvb_get_guint8(tvb, curr_offset);
1209
1210         proto_tree_add_text(tree,
1211             tvb, curr_offset, 1,
1212             "Band Class %u MS Protocol Level: %u",
1213             num_bands,
1214             oct);
1215
1216         curr_offset++;
1217
1218         num_bands++;
1219     }
1220     while ((len - (curr_offset - offset)) >= 3);
1221
1222     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
1223
1224     return(curr_offset - offset);
1225 }
1226
1227 /*
1228  * IOS 6.2.2.16
1229  */
1230 static guint8
1231 elem_mid(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
1232 {
1233     guint8      oct;
1234     guint8      *poctets;
1235     guint32     value;
1236     guint32     curr_offset;
1237     gchar       *str;
1238
1239     curr_offset = offset;
1240
1241     oct = tvb_get_guint8(tvb, curr_offset);
1242
1243     switch (oct & 0x07)
1244     {
1245     case 2:
1246         other_decode_bitfield_value(a_bigbuf, oct, 0xf8, 8);
1247         proto_tree_add_text(tree,
1248             tvb, curr_offset, 1,
1249             "%s :  Reserved",
1250             a_bigbuf);
1251
1252         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
1253         proto_tree_add_text(tree,
1254             tvb, curr_offset, 1,
1255             "%s :  Type of Identity: Broadcast",
1256             a_bigbuf);
1257
1258         curr_offset++;
1259
1260         oct = tvb_get_guint8(tvb, curr_offset);
1261
1262         switch ((oct & 0xc0) >> 6)
1263         {
1264         case 0: str = "Normal"; break;
1265         case 1: str = "Interactive"; break;
1266         case 2: str = "Urgent"; break;
1267         default:
1268             str = "Emergency";
1269             break;
1270         }
1271
1272         other_decode_bitfield_value(a_bigbuf, oct, 0xc0, 8);
1273         proto_tree_add_text(tree,
1274             tvb, curr_offset, 1,
1275             "%s :  Priority: %s",
1276             a_bigbuf,
1277             str);
1278
1279         other_decode_bitfield_value(a_bigbuf, oct, 0x3f, 8);
1280         proto_tree_add_text(tree,
1281             tvb, curr_offset, 1,
1282             "%s :  Message ID: %u",
1283             a_bigbuf,
1284             oct & 0x3f);
1285
1286         curr_offset++;
1287
1288         oct = tvb_get_guint8(tvb, curr_offset);
1289
1290         proto_tree_add_text(tree,
1291             tvb, curr_offset, 1,
1292             "Zone ID: %u",
1293             oct);
1294
1295         sprintf(add_string, " - Broadcast (Zone ID: %u)", oct);
1296
1297         curr_offset++;
1298
1299         value = tvb_get_ntohs(tvb, curr_offset);
1300
1301         switch (value)
1302         {
1303         case 0x0000: str = "Unknown or unspecified"; break;
1304         case 0x0001: str = "Emergency Broadcasts"; break;
1305         case 0x0002: str = "Administrative"; break;
1306         case 0x0003: str = "Maintenance"; break;
1307         case 0x0004: str = "General News - Local"; break;
1308         case 0x0005: str = "General News - Regional"; break;
1309         case 0x0006: str = "General News - National"; break;
1310         case 0x0007: str = "General News - International"; break;
1311         case 0x0008: str = "Business/Financial News - Local"; break;
1312         case 0x0009: str = "Business/Financial News - Regional"; break;
1313         case 0x000A: str = "Business/Financial News - National"; break;
1314         case 0x000B: str = "Business/Financial News - International"; break;
1315         case 0x000C: str = "Sports News - Local"; break;
1316         case 0x000D: str = "Sports News - Regional"; break;
1317         case 0x000E: str = "Sports News - National"; break;
1318         case 0x000F: str = "Sports News - International"; break;
1319         case 0x0010: str = "Entertainment News - Local"; break;
1320         case 0x0011: str = "Entertainment News - Regional"; break;
1321         case 0x0012: str = "Entertainment News - National"; break;
1322         case 0x0013: str = "Entertainment News - International"; break;
1323         case 0x0014: str = "Local Weather"; break;
1324         case 0x0015: str = "Area Traffic Reports"; break;
1325         case 0x0016: str = "Local Airport Flight Schedules"; break;
1326         case 0x0017: str = "Restaurants"; break;
1327         case 0x0018: str = "Lodgings"; break;
1328         case 0x0019: str = "Retail Directory"; break;
1329         case 0x001A: str = "Advertisements"; break;
1330         case 0x001B: str = "Stock Quotes"; break;
1331         case 0x001C: str = "Employment Opportunities"; break;
1332         case 0x001D: str = "Medical/Health/Hospitals"; break;
1333         case 0x001E: str = "Technology News"; break;
1334         case 0x001F: str = "Multi-category"; break;
1335         default:
1336             if ((value >= 0x0020) && (value <= 0x8000)) { str = "Reserved for standard service categories"; }
1337             else { str = "Reserved for proprietary service categories"; }
1338             break;
1339         }
1340
1341         proto_tree_add_text(tree,
1342             tvb, curr_offset, 2,
1343             "Service: (%u) %s",
1344             value,
1345             str);
1346
1347         curr_offset++;
1348
1349         oct = tvb_get_guint8(tvb, curr_offset);
1350
1351         switch (oct)
1352         {
1353         case 0: str = "Unknown or unspecified"; break;
1354         case 1: str = "English"; break;
1355         case 2: str = "French"; break;
1356         case 3: str = "Spanish"; break;
1357         case 4: str = "Japanese"; break;
1358         case 5: str = "Korean"; break;
1359         case 6: str = "Chinese"; break;
1360         case 7: str = "Hebrew"; break;
1361         default:
1362             str = "Reserved";
1363             break;
1364         }
1365
1366         proto_tree_add_text(tree,
1367             tvb, curr_offset, 1,
1368             "Language: (%u) %s",
1369             oct,
1370             str);
1371
1372         curr_offset++;
1373         break;
1374
1375     case 0:
1376         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
1377         proto_tree_add_text(tree,
1378             tvb, curr_offset, 1,
1379             "%s :  Unused",
1380             a_bigbuf);
1381
1382         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
1383         proto_tree_add_text(tree,
1384             tvb, curr_offset, 1,
1385             "%s :  Odd/Even Indicator: %s",
1386             a_bigbuf,
1387             (oct & 0x08) ? "ODD" : "EVEN");
1388
1389         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
1390         proto_tree_add_text(tree,
1391             tvb, curr_offset, 1,
1392             "%s :  Type of Identity: No Identity Code",
1393             a_bigbuf);
1394
1395         strcpy(add_string, " - No Identity Code");
1396
1397         curr_offset++;
1398
1399         if (len > 1)
1400         {
1401             proto_tree_add_text(tree, tvb, curr_offset, len - 1,
1402                 "Format not supported");
1403         }
1404
1405         curr_offset += len - 1;
1406         break;
1407
1408     case 1:
1409         /*
1410          * IS-634 value
1411          */
1412         /* FALLTHRU */
1413
1414     case 6:
1415         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
1416         proto_tree_add_text(tree,
1417             tvb, curr_offset, 1,
1418             "%s :  Identity Digit 1: %c",
1419             a_bigbuf,
1420             Dgt_msid.out[(oct & 0xf0) >> 4]);
1421
1422         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
1423         proto_tree_add_text(tree,
1424             tvb, curr_offset, 1,
1425             "%s :  Odd/Even Indicator: %s",
1426             a_bigbuf,
1427             (oct & 0x08) ? "ODD" : "EVEN");
1428
1429         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
1430         proto_tree_add_text(tree,
1431             tvb, curr_offset, 1,
1432             "%s :  Type of Identity: %s",
1433             a_bigbuf,
1434             ((oct & 0x07) == 1) ? "MIN" : "IMSI");
1435
1436         a_bigbuf[0] = Dgt_msid.out[(oct & 0xf0) >> 4];
1437         curr_offset++;
1438
1439         poctets = tvb_get_string(tvb, curr_offset, len - (curr_offset - offset));
1440
1441         my_dgt_tbcd_unpack(&a_bigbuf[1], poctets, len - (curr_offset - offset),
1442             &Dgt_msid);
1443         g_free(poctets);
1444
1445         proto_tree_add_string_format(tree,
1446             ((oct & 0x07) == 1) ? hf_ansi_a_min : hf_ansi_a_imsi,
1447             tvb, curr_offset, len - (curr_offset - offset),
1448             a_bigbuf,
1449             "BCD Digits: %s",
1450             a_bigbuf);
1451
1452         sprintf(add_string, " - %s (%s)",
1453             ((oct & 0x07) == 1) ? "MIN" : "IMSI",
1454             a_bigbuf);
1455
1456         curr_offset += len - (curr_offset - offset);
1457         break;
1458
1459     case 3:
1460         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
1461         proto_tree_add_text(tree,
1462             tvb, curr_offset, 1,
1463             "%s :  Unused",
1464             a_bigbuf);
1465
1466         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
1467         proto_tree_add_text(tree,
1468             tvb, curr_offset, 1,
1469             "%s :  Odd/Even Indicator: %s",
1470             a_bigbuf,
1471             (oct & 0x08) ? "ODD" : "EVEN");
1472
1473         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
1474         proto_tree_add_text(tree,
1475             tvb, curr_offset, 1,
1476             "%s :  Type of Identity: Interface Directory Number",
1477             a_bigbuf);
1478
1479         strcpy(add_string, " - Interface Directory Number");
1480
1481         curr_offset++;
1482
1483         if (len > 1)
1484         {
1485             proto_tree_add_text(tree, tvb, curr_offset, len - 1,
1486                 "Format not supported");
1487         }
1488
1489         curr_offset += len - 1;
1490         break;
1491
1492     case 4:
1493         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
1494         proto_tree_add_text(tree,
1495             tvb, curr_offset, 1,
1496             "%s :  Unused",
1497             a_bigbuf);
1498
1499         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
1500         proto_tree_add_text(tree,
1501             tvb, curr_offset, 1,
1502             "%s :  Odd/Even Indicator: %s",
1503             a_bigbuf,
1504             (oct & 0x08) ? "ODD" : "EVEN");
1505
1506         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
1507         proto_tree_add_text(tree,
1508             tvb, curr_offset, 1,
1509             "%s :  Type of Identity: TMSI",
1510             a_bigbuf);
1511
1512         strcpy(add_string, " - TMSI");
1513
1514         curr_offset++;
1515
1516         if (len > 1)
1517         {
1518             proto_tree_add_text(tree, tvb, curr_offset, len - 1,
1519                 "Format not supported");
1520         }
1521
1522         curr_offset += len - 1;
1523         break;
1524
1525     case 5:
1526         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
1527         proto_tree_add_text(tree,
1528             tvb, curr_offset, 1,
1529             "%s :  Unused",
1530             a_bigbuf);
1531
1532         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
1533         proto_tree_add_text(tree,
1534             tvb, curr_offset, 1,
1535             "%s :  Odd/Even Indicator: %s",
1536             a_bigbuf,
1537             (oct & 0x08) ? "ODD" : "EVEN");
1538
1539         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
1540         proto_tree_add_text(tree,
1541             tvb, curr_offset, 1,
1542             "%s :  Type of Identity: ESN",
1543             a_bigbuf);
1544
1545         curr_offset++;
1546
1547         value = tvb_get_ntohl(tvb, curr_offset);
1548
1549         proto_tree_add_uint(tree, hf_ansi_a_esn,
1550             tvb, curr_offset, 4,
1551             value);
1552
1553         sprintf(add_string, " - ESN (0x%04x)", value);
1554
1555         curr_offset += 4;
1556         break;
1557
1558     default:
1559         proto_tree_add_text(tree, tvb, curr_offset, len,
1560             "Format Unknown");
1561
1562         strcpy(add_string, " - Format Unknown");
1563
1564         curr_offset += len;
1565         break;
1566     }
1567
1568     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
1569
1570     return(curr_offset - offset);
1571 }
1572
1573 /*
1574  * IOS 6.2.2.17
1575  */
1576 static guint8
1577 elem_sci(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
1578 {
1579     guint8      oct;
1580     guint32     curr_offset;
1581
1582     len = len;
1583     curr_offset = offset;
1584
1585     oct = tvb_get_guint8(tvb, curr_offset);
1586
1587     other_decode_bitfield_value(a_bigbuf, oct, 0xf8, 8);
1588     proto_tree_add_text(tree,
1589         tvb, curr_offset, 1,
1590         "%s :  Reserved",
1591         a_bigbuf);
1592
1593     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
1594     proto_tree_add_text(tree,
1595         tvb, curr_offset, 1,
1596         "%s :  Slot Cycle Index: %u",
1597         a_bigbuf,
1598         oct & 0x07);
1599
1600     sprintf(add_string, " - (%u)", oct & 0x07);
1601
1602     curr_offset++;
1603
1604     /* no length check possible */
1605
1606     return(curr_offset - offset);
1607 }
1608
1609 /*
1610  * IOS 6.2.2.18
1611  */
1612 static guint8
1613 elem_prio(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
1614 {
1615     guint8      oct;
1616     guint32     curr_offset;
1617
1618     curr_offset = offset;
1619
1620     oct = tvb_get_guint8(tvb, curr_offset);
1621
1622     other_decode_bitfield_value(a_bigbuf, oct, 0xc0, 8);
1623     proto_tree_add_text(tree,
1624         tvb, curr_offset, 1,
1625         "%s :  Reserved",
1626         a_bigbuf);
1627
1628     other_decode_bitfield_value(a_bigbuf, oct, 0x3c, 8);
1629     proto_tree_add_text(tree,
1630         tvb, curr_offset, 1,
1631         "%s :  Call Priority Level: %u",
1632         a_bigbuf,
1633         (oct & 0x3c) >> 2);
1634
1635     other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
1636     proto_tree_add_text(tree,
1637         tvb, curr_offset, 1,
1638         "%s :  Queuing %sallowed",
1639         a_bigbuf,
1640         (oct & 0x02) ? "" : "not ");
1641
1642     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
1643     proto_tree_add_text(tree,
1644         tvb, curr_offset, 1,
1645         "%s :  Preemption %sallowed",
1646         a_bigbuf,
1647         (oct & 0x01) ? "" : "not ");
1648
1649     sprintf(add_string, " - (%u)", (oct & 0x3c) >> 2);
1650
1651     curr_offset++;
1652
1653     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
1654
1655     return(curr_offset - offset);
1656 }
1657
1658 /*
1659  * IOS 6.2.2.19
1660  */
1661 static guint8
1662 elem_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
1663 {
1664     guint8      oct;
1665     guint32     value;
1666     guint32     curr_offset;
1667     gchar       *str = NULL;
1668
1669     curr_offset = offset;
1670
1671     oct = tvb_get_guint8(tvb, curr_offset);
1672
1673     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
1674     proto_tree_add_text(tree,
1675         tvb, curr_offset, 1,
1676         "%s :  Extension",
1677         a_bigbuf);
1678
1679     if (oct & 0x80)
1680     {
1681         /* 2 octet cause */
1682
1683         if ((oct & 0x0f) == 0x00)
1684         {
1685             /* national cause */
1686             switch ((oct & 0x70) >> 4)
1687             {
1688             case 0: str = "Normal Event"; break;
1689             case 1: str = "Normal Event"; break;
1690             case 2: str = "Resource Unavailable"; break;
1691             case 3: str = "Service or option not available"; break;
1692             case 4: str = "Service or option not implemented"; break;
1693             case 5: str = "Invalid message (e.g., parameter out of range)"; break;
1694             case 6: str = "Protocol error"; break;
1695             default:
1696                 str = "Interworking";
1697                 break;
1698             }
1699
1700             other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
1701             proto_tree_add_text(tree,
1702                 tvb, curr_offset, 1,
1703                 "%s :  Cause Class: %s",
1704                 a_bigbuf,
1705                 str);
1706
1707             other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
1708             proto_tree_add_text(tree,
1709                 tvb, curr_offset, 1,
1710                 "%s :  National Cause",
1711                 a_bigbuf);
1712
1713             curr_offset++;
1714
1715             proto_tree_add_text(tree, tvb, curr_offset, 1,
1716                 "Cause Value");
1717
1718             curr_offset++;
1719
1720             strcpy(add_string, " - (National Cause)");
1721         }
1722         else
1723         {
1724             value = tvb_get_guint8(tvb, curr_offset + 1);
1725
1726             other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
1727             proto_tree_add_text(tree,
1728                 tvb, curr_offset, 1,
1729                 "%s :  Cause (MSB): %u",
1730                 a_bigbuf,
1731                 ((oct & 0x7f) << 8) | value);
1732
1733             curr_offset++;
1734
1735             other_decode_bitfield_value(a_bigbuf, value, 0xff, 8);
1736             proto_tree_add_text(tree, tvb, curr_offset, 1,
1737                 "%s :  Cause (LSB)",
1738                 a_bigbuf);
1739
1740             curr_offset++;
1741         }
1742     }
1743     else
1744     {
1745         switch (oct)
1746         {
1747         case 0x00: str = "Radio interface message failure"; break;
1748         case 0x01: str = "Radio interface failure"; break;
1749         case 0x02: str = "Uplink Quality"; break;
1750         case 0x03: str = "Uplink strength"; break;
1751         case 0x04: str = "Downlink quality"; break;
1752         case 0x05: str = "Downlink strength"; break;
1753         case 0x06: str = "Distance"; break;
1754         case 0x07: str = "OAM&P intervention"; break;
1755         case 0x08: str = "MS busy"; break;
1756         case 0x09: str = "Call processing"; break;
1757         case 0x0A: str = "Reversion to old channel"; break;
1758         case 0x0B: str = "Handoff successful"; break;
1759         case 0x0C: str = "No response from MS"; break;
1760         case 0x0D: str = "Timer expired"; break;
1761         case 0x0E: str = "Better cell (power budget)"; break;
1762         case 0x0F: str = "Interference"; break;
1763         case 0x10: str = "Packet call going dormant"; break;
1764         case 0x11: str = "Service option not available"; break;
1765         case 0x12: str = "Invalid Call"; break;
1766         case 0x13: str = "Successful operation"; break;
1767         case 0x14: str = "Normal call release"; break;
1768         case 0x1B: str = "Inter-BS Soft Handoff Drop Target"; break;
1769         case 0x1D: str = "Intra-BS Soft Handoff Drop Target"; break;
1770         case 0x20: str = "Equipment failure"; break;
1771         case 0x21: str = "No radio resource available"; break;
1772         case 0x22: str = "Requested terrestrial resource unavailable"; break;
1773         case 0x25: str = "BS not equipped"; break;
1774         case 0x26: str = "MS not equipped (or incapable)"; break;
1775         case 0x29: str = "PACA Call Queued"; break;
1776         case 0x2B: str = "Alternate signaling type reject"; break;
1777         case 0x2D: str = "PACA Queue Overflow"; break;
1778         case 0x2E: str = "PACA Cancel Request Rejected"; break;
1779         case 0x30: str = "Requested transcoding/rate adaptation unavailable"; break;
1780         case 0x31: str = "Lower priority radio resources not available"; break;
1781         case 0x32: str = "PCF resources not available"; break;
1782         case 0x33: str = "TFO Control request Failed"; break;
1783         case 0x40: str = "Ciphering algorithm not supported"; break;
1784         case 0x41: str = "Private Long Code not available or not supported."; break;
1785         case 0x42: str = "Requested MUX option or rates not available."; break;
1786         case 0x43: str = "Requested Privacy Configuration unavailable"; break;
1787         case 0x4F: str = "Terrestrial circuit already allocated.a"; break;
1788         case 0x50: str = "Terrestrial circuit already allocated"; break;
1789         case 0x5F: str = "Protocol Error between BS and MSC.a"; break;
1790         case 0x60: str = "Protocol Error between BS and MSC"; break;
1791         case 0x71: str = "ADDS message too long for delivery on the paging channel"; break;
1792         case 0x72: str = "MS-to-IWF TCP connection failure"; break;
1793         case 0x73: str = "ATH0 (Modem hang up) Command"; break;
1794         case 0x74: str = "+FSH/+FHNG (Fax session ended) Command"; break;
1795         case 0x75: str = "No carrier"; break;
1796         case 0x76: str = "PPP protocol failure"; break;
1797         case 0x77: str = "PPP session closed by the MS"; break;
1798         case 0x78: str = "Do not notify MS"; break;
1799         case 0x79: str = "PDSN resources are not available"; break;
1800         case 0x7A: str = "Data ready to send"; break;
1801         case 0x7F: str = "Handoff procedure time-out"; break;
1802         default:
1803             str = "Reserved for future use";
1804             break;
1805         }
1806
1807         other_decode_bitfield_value(a_bigbuf, oct, 0x7f, 8);
1808         proto_tree_add_text(tree,
1809             tvb, curr_offset, 1,
1810             "%s :  Cause: (%u) %s",
1811             a_bigbuf,
1812             oct & 0x7f,
1813             str);
1814
1815         curr_offset++;
1816
1817         sprintf(add_string, " - (%u) %s", oct & 0x7f, str);
1818     }
1819
1820     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
1821
1822     return(curr_offset - offset);
1823 }
1824
1825 /*
1826  * IOS 6.2.2.20
1827  * Formats everything after the discriminator, shared function.
1828  */
1829 static guint8
1830 elem_cell_id_aux(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string, guint8 disc)
1831 {
1832     guint32     value;
1833     guint32     market_id;
1834     guint32     switch_num;
1835     guint32     curr_offset;
1836
1837     curr_offset = offset;
1838
1839     switch (disc)
1840     {
1841     case 0x02:
1842         value = tvb_get_ntohs(tvb, curr_offset);
1843
1844         proto_tree_add_uint(tree, hf_ansi_a_cell_ci, tvb,
1845             curr_offset, 2, value);
1846
1847         curr_offset += 2;
1848
1849         sprintf(add_string, " - CI (%u)", value);
1850         break;
1851
1852     case 0x05:
1853         value = tvb_get_ntohs(tvb, curr_offset);
1854
1855         proto_tree_add_uint(tree, hf_ansi_a_cell_lac, tvb,
1856             curr_offset, 2, value);
1857
1858         curr_offset += 2;
1859
1860         sprintf(add_string, " - LAC (%u)", value);
1861         break;
1862
1863     case 0x07:
1864         market_id = tvb_get_ntohs(tvb, curr_offset);
1865         switch_num = tvb_get_guint8(tvb, curr_offset + 2);
1866
1867         value = tvb_get_ntoh24(tvb, curr_offset);
1868
1869         proto_tree_add_uint_hidden(tree, hf_ansi_a_cell_mscid, tvb,
1870             curr_offset, 3, value);
1871
1872         proto_tree_add_text(tree, tvb, curr_offset, 3,
1873             "Market ID %u  Switch Number %u",
1874             market_id, switch_num);
1875
1876         curr_offset += 3;
1877
1878         value = tvb_get_ntohs(tvb, curr_offset);
1879
1880         proto_tree_add_uint(tree, hf_ansi_a_cell_ci, tvb,
1881             curr_offset, 2, value);
1882
1883         curr_offset += 2;
1884
1885         sprintf(add_string, " - Market ID (%u) Switch Number (%u) CI (%u)",
1886             market_id,
1887             switch_num,
1888             value);
1889         break;
1890
1891     default:
1892         proto_tree_add_text(tree, tvb, curr_offset, len - 1,
1893             "Cell ID - Non IOS format");
1894
1895         curr_offset += (len - 1);
1896         break;
1897     }
1898
1899     return(curr_offset - offset);
1900 }
1901
1902 static guint8
1903 elem_cell_id(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
1904 {
1905     guint8      oct;
1906     guint32     curr_offset;
1907     gchar       *str = NULL;
1908
1909     len = len;
1910     add_string = add_string;
1911     curr_offset = offset;
1912
1913     oct = tvb_get_guint8(tvb, curr_offset);
1914
1915     if (oct >= (gint) NUM_CELL_DISC_STR)
1916     {
1917         str = "Unknown";
1918     }
1919     else
1920     {
1921         str = cell_disc_str[oct];
1922     }
1923
1924     proto_tree_add_text(tree,
1925         tvb, curr_offset, 1,
1926         "Cell Identification Discriminator: (%u) %s",
1927         oct,
1928         str);
1929
1930     curr_offset++;
1931
1932     curr_offset +=
1933         elem_cell_id_aux(tvb, tree, curr_offset, len - (curr_offset - offset), add_string, oct);
1934
1935     /* no length check possible */
1936
1937     return(curr_offset - offset);
1938 }
1939
1940 /*
1941  * IOS 6.2.2.21
1942  */
1943 static guint8
1944 elem_cell_id_list(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
1945 {
1946     guint8      oct;
1947     guint8      consumed;
1948     guint8      num_cells;
1949     guint32     curr_offset;
1950     proto_item  *item = NULL;
1951     proto_tree  *subtree = NULL;
1952     gchar       *str = NULL;
1953
1954     curr_offset = offset;
1955
1956     oct = tvb_get_guint8(tvb, curr_offset);
1957
1958     if (oct >= (gint) NUM_CELL_DISC_STR)
1959     {
1960         str = "Unknown";
1961     }
1962     else
1963     {
1964         str = cell_disc_str[oct];
1965     }
1966
1967     proto_tree_add_text(tree,
1968         tvb, curr_offset, 1,
1969         "Cell Identification Discriminator: (%u) %s",
1970         oct,
1971         str);
1972
1973     curr_offset++;
1974
1975     NO_MORE_DATA_CHECK(len);
1976
1977     num_cells = 0;
1978     do
1979     {
1980         item =
1981             proto_tree_add_text(tree,
1982                 tvb, curr_offset, -1,
1983                 "Cell %u",
1984                 num_cells + 1);
1985
1986         subtree = proto_item_add_subtree(item, ett_cell_list);
1987
1988         add_string[0] = '\0';
1989         consumed =
1990             elem_cell_id_aux(tvb, subtree, curr_offset, len - (curr_offset - offset), add_string, oct);
1991
1992         if (add_string[0] != '\0')
1993         {
1994             proto_item_append_text(item, add_string);
1995         }
1996
1997         proto_item_set_len(item, consumed);
1998
1999         curr_offset += consumed;
2000
2001         num_cells++;
2002     }
2003     while ((len - (curr_offset - offset)) > 0);
2004
2005     sprintf(add_string, " - %u cell%s",
2006         num_cells, plurality(num_cells, "", "s"));
2007
2008     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2009
2010     return(curr_offset - offset);
2011 }
2012
2013 /*
2014  * IOS 6.2.2.22
2015  */
2016 static guint8
2017 elem_cic(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2018 {
2019     guint32     value;
2020     guint32     curr_offset;
2021
2022     len = len;
2023     curr_offset = offset;
2024
2025     value = tvb_get_ntohs(tvb, curr_offset);
2026
2027     other_decode_bitfield_value(a_bigbuf, value, 0xffe0, 16);
2028     proto_tree_add_text(tree,
2029         tvb, curr_offset, 2,
2030         "%s :  PCM Multiplexer: %u",
2031         a_bigbuf,
2032         (value & 0xffe0) >> 5);
2033
2034     other_decode_bitfield_value(a_bigbuf, value, 0x001f, 16);
2035     proto_tree_add_text(tree,
2036         tvb, curr_offset, 2,
2037         "%s :  Timeslot: %u",
2038         a_bigbuf,
2039         value & 0x001f);
2040
2041     curr_offset += 2;
2042
2043     sprintf(add_string, " - (%u) (0x%04x)", value, value);
2044
2045     /* no length check possible */
2046
2047     return(curr_offset - offset);
2048 }
2049
2050 /*
2051  * IOS 6.2.2.23
2052  */
2053 static guint8
2054 elem_cic_ext(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2055 {
2056     guint8      oct;
2057     guint32     value;
2058     guint32     curr_offset;
2059     gchar       *str;
2060
2061     len = len;
2062     curr_offset = offset;
2063
2064     value = tvb_get_ntohs(tvb, curr_offset);
2065
2066     other_decode_bitfield_value(a_bigbuf, value, 0xffe0, 16);
2067     proto_tree_add_text(tree,
2068         tvb, curr_offset, 2,
2069         "%s :  PCM Multiplexer: %u",
2070         a_bigbuf,
2071         (value & 0xffe0) >> 5);
2072
2073     other_decode_bitfield_value(a_bigbuf, value, 0x001f, 16);
2074     proto_tree_add_text(tree,
2075         tvb, curr_offset, 2,
2076         "%s :  Timeslot: %u",
2077         a_bigbuf,
2078         value & 0x001f);
2079
2080     curr_offset += 2;
2081
2082     sprintf(add_string, " - (%u) (0x%04x)", value, value);
2083
2084     oct = tvb_get_guint8(tvb, curr_offset);
2085
2086     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
2087     proto_tree_add_text(tree,
2088         tvb, curr_offset, 1,
2089         "%s :  Reserved",
2090         a_bigbuf);
2091
2092     switch (oct & 0x0f)
2093     {
2094     case 0x00: str = "Full-rate"; break;
2095     default:
2096         str = "Reserved";
2097         break;
2098     }
2099
2100     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
2101     proto_tree_add_text(tree,
2102         tvb, curr_offset, 1,
2103         "%s :  Circuit Mode: %s",
2104         a_bigbuf,
2105         str);
2106
2107     curr_offset++;
2108
2109     /* no length check possible */
2110
2111     return(curr_offset - offset);
2112 }
2113
2114 /*
2115  * IOS 6.2.2.24
2116  * UNUSED
2117  */
2118
2119 #define ANSI_A_CELL_ID_LEN(_disc) ((_disc == 7) ? 5 : 2)
2120
2121 /*
2122  * IOS 6.2.2.25
2123  */
2124 static guint8
2125 elem_downlink_re(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2126 {
2127     guint8      oct;
2128     guint8      disc;
2129     guint8      consumed;
2130     guint8      num_cells;
2131     guint32     value;
2132     guint32     curr_offset;
2133     proto_item  *item = NULL;
2134     proto_tree  *subtree = NULL;
2135     gchar       *str;
2136
2137     curr_offset = offset;
2138
2139     oct = tvb_get_guint8(tvb, curr_offset);
2140
2141     proto_tree_add_text(tree, tvb, curr_offset, 1,
2142         "Number of Cells: %u",
2143         oct);
2144
2145     curr_offset++;
2146
2147     NO_MORE_DATA_CHECK(len);
2148
2149     disc = tvb_get_guint8(tvb, curr_offset);
2150
2151     if (disc >= (gint) NUM_CELL_DISC_STR)
2152     {
2153         str = "Unknown";
2154     }
2155     else
2156     {
2157         str = cell_disc_str[disc];
2158     }
2159
2160     proto_tree_add_text(tree,
2161         tvb, curr_offset, 1,
2162         "Cell Identification Discriminator: (%u) %s",
2163         disc,
2164         str);
2165
2166     curr_offset++;
2167
2168     NO_MORE_DATA_CHECK(len);
2169
2170     SHORT_DATA_CHECK(len - (curr_offset - offset), (guint32) 3 + ANSI_A_CELL_ID_LEN(disc));
2171
2172     num_cells =0;
2173
2174     do
2175     {
2176         item =
2177             proto_tree_add_text(tree,
2178                 tvb, curr_offset, -1,
2179                 "Cell %u",
2180                 num_cells + 1);
2181
2182         subtree = proto_item_add_subtree(item, ett_cell_list);
2183
2184         add_string[0] = '\0';
2185         consumed =
2186             elem_cell_id_aux(tvb, subtree, curr_offset,
2187                 len - (curr_offset - offset), add_string, disc);
2188
2189         if (add_string[0] != '\0')
2190         {
2191             proto_item_append_text(item, add_string);
2192         }
2193
2194         proto_item_set_len(item, consumed);
2195
2196         curr_offset += consumed;
2197
2198         oct = tvb_get_guint8(tvb, curr_offset);
2199
2200         other_decode_bitfield_value(a_bigbuf, oct, 0xc0, 8);
2201         proto_tree_add_text(tree, tvb, curr_offset, 1,
2202             "%s :  Reserved",
2203             a_bigbuf);
2204
2205         other_decode_bitfield_value(a_bigbuf, oct, 0x3f, 8);
2206         proto_tree_add_text(tree, tvb, curr_offset, 1,
2207             "%s :  Downlink Signal Strength Raw: %u",
2208             a_bigbuf,
2209             oct & 0x3f);
2210
2211         curr_offset++;
2212
2213         value = tvb_get_ntohs(tvb, curr_offset);
2214
2215         proto_tree_add_text(tree,
2216             tvb, curr_offset, 2,
2217             "CDMA Target One Way Delay: %u",
2218             value);
2219
2220         curr_offset += 2;
2221
2222         num_cells++;
2223     }
2224     while ((len - (curr_offset - offset)) >= (guint32) (3 + ANSI_A_CELL_ID_LEN(disc)));
2225
2226     sprintf(add_string, " - %u cell%s",
2227         num_cells, plurality(num_cells, "", "s"));
2228
2229     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2230
2231     return(curr_offset - offset);
2232 }
2233
2234 /*
2235  * IOS 6.2.2.26
2236  * UNUSED
2237  */
2238
2239 /*
2240  * IOS 6.2.2.27
2241  * UNUSED
2242  */
2243
2244 /*
2245  * IOS 6.2.2.28
2246  * UNUSED
2247  */
2248
2249 /*
2250  * IOS 6.2.2.29
2251  * UNUSED
2252  */
2253
2254 /*
2255  * IOS 6.2.2.30
2256  */
2257 static guint8
2258 elem_pdsn_ip_addr(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2259 {
2260     guint32     curr_offset;
2261
2262     add_string = add_string;
2263     curr_offset = offset;
2264
2265     proto_tree_add_item(tree, hf_ansi_a_pdsn_ip_addr, tvb, curr_offset, len, FALSE);
2266
2267 /*
2268     proto_tree_add_text(tree, tvb, curr_offset, len,
2269         "IPv4 Address");
2270 */
2271
2272     curr_offset += len;
2273
2274     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2275
2276     return(curr_offset - offset);
2277 }
2278
2279 /*
2280  * IOS 6.2.2.31
2281  */
2282 static guint8
2283 elem_ho_pow_lev(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2284 {
2285     guint8      oct;
2286     guint8      consumed;
2287     guint8      num_cells;
2288     proto_item  *item = NULL;
2289     proto_tree  *subtree = NULL;
2290     guint32     curr_offset;
2291
2292     curr_offset = offset;
2293
2294     oct = tvb_get_guint8(tvb, curr_offset);
2295
2296     proto_tree_add_text(tree, tvb, curr_offset, 1,
2297         "Number of Cells: %u",
2298         oct);
2299
2300     curr_offset++;
2301
2302     SHORT_DATA_CHECK(len - (curr_offset - offset), (guint32) 6);
2303
2304     oct = tvb_get_guint8(tvb, curr_offset);
2305
2306     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
2307     proto_tree_add_text(tree, tvb, curr_offset, 1,
2308         "%s :  Reserved",
2309         a_bigbuf);
2310
2311     other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
2312     proto_tree_add_text(tree, tvb, curr_offset, 1,
2313         "%s :  ID Type: %u",
2314         a_bigbuf,
2315         (oct & 0x60) >> 5);
2316
2317     other_decode_bitfield_value(a_bigbuf, oct, 0x1f, 8);
2318     proto_tree_add_text(tree, tvb, curr_offset, 1,
2319         "%s :  Handoff Power Level: %u",
2320         a_bigbuf,
2321         oct & 0x1f);
2322
2323     curr_offset++;
2324
2325     item =
2326         proto_tree_add_text(tree,
2327             tvb, curr_offset, -1,
2328             "Cell 1");
2329
2330     subtree = proto_item_add_subtree(item, ett_cell_list);
2331
2332     add_string[0] = '\0';
2333     consumed =
2334         elem_cell_id_aux(tvb, subtree, curr_offset,
2335             len - (curr_offset - offset), add_string, 0x7);
2336
2337     if (add_string[0] != '\0')
2338     {
2339         proto_item_append_text(item, add_string);
2340     }
2341
2342     proto_item_set_len(item, consumed);
2343
2344     curr_offset += consumed;
2345
2346     num_cells = 1;
2347
2348     while ((len - (curr_offset - offset)) >= 3)
2349     {
2350         num_cells++;
2351
2352         oct = tvb_get_guint8(tvb, curr_offset);
2353
2354         other_decode_bitfield_value(a_bigbuf, oct, 0xe0, 8);
2355         proto_tree_add_text(tree, tvb, curr_offset, 1,
2356             "%s :  Reserved",
2357             a_bigbuf);
2358
2359         other_decode_bitfield_value(a_bigbuf, oct, 0x1f, 8);
2360         proto_tree_add_text(tree, tvb, curr_offset, 1,
2361             "%s :  Handoff Power Level: %u",
2362             a_bigbuf,
2363             oct & 0x1f);
2364
2365         curr_offset++;
2366
2367         item =
2368             proto_tree_add_text(tree,
2369                 tvb, curr_offset, -1,
2370                 "Cell %u",
2371                 num_cells);
2372
2373         subtree = proto_item_add_subtree(item, ett_cell_list);
2374
2375         add_string[0] = '\0';
2376         consumed =
2377             elem_cell_id_aux(tvb, subtree, curr_offset,
2378                 len - (curr_offset - offset), add_string, 0x2);
2379
2380         if (add_string[0] != '\0')
2381         {
2382             proto_item_append_text(item, add_string);
2383         }
2384
2385         proto_item_set_len(item, consumed);
2386
2387         curr_offset += consumed;
2388     }
2389
2390     sprintf(add_string, " - %u cell%s",
2391         num_cells, plurality(num_cells, "", "s"));
2392
2393     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2394
2395     return(curr_offset - offset);
2396 }
2397
2398 /*
2399  * IOS 6.2.2.32
2400  */
2401 static guint8
2402 elem_uz_id(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2403 {
2404     guint32     value;
2405     guint32     curr_offset;
2406
2407     curr_offset = offset;
2408
2409     value = tvb_get_ntohs(tvb, curr_offset);
2410
2411     proto_tree_add_text(tree, tvb, curr_offset, 2,
2412         "UZID: %u",
2413         value);
2414
2415     curr_offset += 2;
2416
2417     sprintf(add_string, " - (%u)", value);
2418
2419     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2420
2421     return(curr_offset - offset);
2422 }
2423
2424 /*
2425  * IOS 6.2.2.33
2426  * UNUSED
2427  */
2428
2429 /*
2430  * IOS 6.2.2.34
2431  */
2432 static guint8
2433 elem_is2000_chan_id(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2434 {
2435     guint8      oct;
2436     guint8      num_chan;
2437     guint32     value;
2438     guint32     curr_offset;
2439     gchar       *str;
2440
2441     add_string = add_string;
2442     curr_offset = offset;
2443
2444     oct = tvb_get_guint8(tvb, curr_offset);
2445
2446     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
2447     proto_tree_add_text(tree, tvb, curr_offset, 1,
2448         "%s :  OTD: Mobile will %sbe using OTD",
2449         a_bigbuf,
2450         (oct & 0x80) ? "" : "not ");
2451
2452     num_chan = (oct & 0x70) >> 4;
2453
2454     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
2455     proto_tree_add_text(tree, tvb, curr_offset, 1,
2456         "%s :  Channel Count: %u",
2457         a_bigbuf,
2458         num_chan);
2459
2460     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
2461     proto_tree_add_text(tree, tvb, curr_offset, 1,
2462         "%s :  Frame Offset: (%u), %.2f ms",
2463         a_bigbuf,
2464         oct & 0x0f,
2465         (oct & 0x0f) * 1.25);
2466
2467     curr_offset++;
2468
2469     NO_MORE_DATA_CHECK(len);
2470
2471     SHORT_DATA_CHECK(len - (curr_offset - offset), 6);
2472
2473     do
2474     {
2475         oct = tvb_get_guint8(tvb, curr_offset);
2476
2477         switch (oct)
2478         {
2479         case 0x01: str = "Fundamental Channel (FCH) TIA/EIA/IS-2000"; break;
2480         case 0x02: str = "Dedicated Control Channel (DCCH) TIA/EIA/IS-2000"; break;
2481         case 0x03: str = "Supplemental Channel (SCH) TIA/EIA/IS-2000"; break;
2482         default:
2483             if ((oct >= 0x80) && (oct <= 0x9f)) { str = "Reserved for UMTS"; }
2484             else { str = "Reserved"; }
2485             break;
2486         }
2487
2488         proto_tree_add_text(tree, tvb, curr_offset, 1,
2489             "Physical Channel Type: %s",
2490             str);
2491
2492         curr_offset++;
2493
2494         oct = tvb_get_guint8(tvb, curr_offset);
2495
2496         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
2497         proto_tree_add_text(tree, tvb, curr_offset, 1,
2498             "%s :  Reserved",
2499             a_bigbuf);
2500
2501         switch ((oct & 0x60) >> 5)
2502         {
2503         case 0: str = "Gating rate 1"; break;
2504         case 1: str = "Gating rate 1/2"; break;
2505         case 2: str = "Gating rate 1/4"; break;
2506         default:
2507             str = "Reserved";
2508             break;
2509         }
2510
2511         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
2512         proto_tree_add_text(tree, tvb, curr_offset, 1,
2513             "%s :  Pilot Gating Rate: %s",
2514             a_bigbuf,
2515             str);
2516
2517         other_decode_bitfield_value(a_bigbuf, oct, 0x18, 8);
2518         proto_tree_add_text(tree, tvb, curr_offset, 1,
2519             "%s :  QOF Mask",
2520             a_bigbuf);
2521
2522         value = tvb_get_guint8(tvb, curr_offset + 1);
2523
2524         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
2525         proto_tree_add_text(tree, tvb, curr_offset, 1,
2526             "%s :  Walsh Code Channel Index (MSB): %u",
2527             a_bigbuf,
2528             ((guint32) (oct & 0x07) << 8) | value);
2529
2530         curr_offset++;
2531
2532         other_decode_bitfield_value(a_bigbuf, value, 0xff, 8);
2533         proto_tree_add_text(tree, tvb, curr_offset, 1,
2534             "%s :  Walsh Code Channel Index (LSB)",
2535             a_bigbuf);
2536
2537         curr_offset++;
2538
2539         oct = tvb_get_guint8(tvb, curr_offset);
2540
2541         other_decode_bitfield_value(a_bigbuf, oct, 0xff, 8);
2542         proto_tree_add_text(tree, tvb, curr_offset, 1,
2543             "%s :  Pilot PN Code (LSB)",
2544             a_bigbuf);
2545
2546         curr_offset++;
2547
2548         value = oct;
2549         oct = tvb_get_guint8(tvb, curr_offset);
2550         value |= ((guint32) (oct & 0x80)) << 1;
2551
2552         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
2553         proto_tree_add_text(tree, tvb, curr_offset, 1,
2554             "%s :  Pilot PN Code (MSB): %u",
2555             a_bigbuf,
2556             value);
2557
2558         other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
2559         proto_tree_add_text(tree, tvb, curr_offset, 1,
2560             "%s :  Reserved",
2561             a_bigbuf);
2562
2563         other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
2564         proto_tree_add_text(tree, tvb, curr_offset, 1,
2565             "%s :  Frequency Included",
2566             a_bigbuf);
2567
2568         value = tvb_get_guint8(tvb, curr_offset + 1) | ((oct & 0x07) << 8);
2569
2570         other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
2571         proto_tree_add_text(tree, tvb, curr_offset, 1,
2572             "%s :  ARFCN (MSB): %u",
2573             a_bigbuf,
2574             value);
2575
2576         curr_offset++;
2577
2578         other_decode_bitfield_value(a_bigbuf, value & 0x00ff, 0xff, 8);
2579         proto_tree_add_text(tree, tvb, curr_offset, 1,
2580             "%s :  ARFCN (LSB)",
2581             a_bigbuf);
2582
2583         curr_offset++;
2584     }
2585     while ((len - (curr_offset - offset)) >= 6);
2586
2587     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2588
2589     return(curr_offset - offset);
2590 }
2591
2592 /*
2593  * IOS 6.2.2.35
2594  * NO ASSOCIATED DATA
2595  */
2596
2597 /*
2598  * IOS 6.2.2.36
2599  */
2600 static guint8
2601 elem_is95_ms_meas_chan_id(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2602 {
2603     guint8      oct;
2604     guint32     value;
2605     gint        temp_int;
2606     guint32     curr_offset;
2607     gchar       *str;
2608
2609     curr_offset = offset;
2610
2611     oct = tvb_get_guint8(tvb, curr_offset);
2612
2613     temp_int = (oct & 0xf8) >> 3;
2614     if ((temp_int < 0) || (temp_int >= (gint) NUM_BAND_CLASS_STR))
2615     {
2616         str = "Reserved";
2617     }
2618     else
2619     {
2620         str = band_class_str[temp_int];
2621     }
2622
2623     other_decode_bitfield_value(a_bigbuf, oct, 0xf8, 8);
2624     proto_tree_add_text(tree,
2625         tvb, curr_offset, 1,
2626         "%s :  Band Class: %s",
2627         a_bigbuf,
2628         str);
2629
2630     value = tvb_get_guint8(tvb, curr_offset + 1) | ((oct & 0x07) << 8);
2631
2632     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
2633     proto_tree_add_text(tree, tvb, curr_offset, 1,
2634         "%s :  ARFCN (MSB): %u",
2635         a_bigbuf,
2636         value);
2637
2638     curr_offset++;
2639
2640     other_decode_bitfield_value(a_bigbuf, value & 0x00ff, 0xff, 8);
2641     proto_tree_add_text(tree, tvb, curr_offset, 1,
2642         "%s :  ARFCN (LSB)",
2643         a_bigbuf);
2644
2645     sprintf(add_string, " - (ARFCN: %u)", value);
2646
2647     curr_offset++;
2648
2649     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2650
2651     return(curr_offset - offset);
2652 }
2653
2654 /*
2655  * IOS 6.2.2.37
2656  */
2657 static guint8
2658 elem_clg_party_ascii_num(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2659 {
2660     guint8      oct;
2661     guint32     curr_offset;
2662     guint8      *poctets;
2663     gchar       *str;
2664
2665     curr_offset = offset;
2666
2667     oct = tvb_get_guint8(tvb, curr_offset);
2668
2669     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
2670     proto_tree_add_text(tree, tvb, curr_offset, 1,
2671         "%s :  Extension: %s",
2672         a_bigbuf,
2673         (oct & 0x80) ? "Not extended" : "Extended");
2674
2675     switch ((oct & 0x70) >> 4)
2676     {
2677     case 0: str = "Unknown"; break;
2678     case 1: str = "International number"; break;
2679     case 2: str = "National number"; break;
2680     case 3: str = "Network-specific number"; break;
2681     case 4: str = "Dedicated PAD access, short code"; break;
2682     case 5: str = "Reserved"; break;
2683     case 6: str = "Reserved"; break;
2684     default:
2685         str = "Reserved for extension";
2686         break;
2687     }
2688
2689     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
2690     proto_tree_add_text(tree, tvb, curr_offset, 1,
2691         "%s :  Type of Number: %s",
2692         a_bigbuf,
2693         str);
2694
2695     switch (oct & 0x0f)
2696     {
2697     case 0x00: str = "Unknown"; break;
2698     case 0x01: str = "ISDN/Telephony Numbering (ITU recommendation E.164/E.163)"; break;
2699     case 0x03: str = "Data Numbering (ITU-T Rec. X.121)"; break;
2700     case 0x04: str = "Telex Numbering (ITU-T Rec. F.69)"; break;
2701     case 0x07: str = "Reserved for extension"; break;
2702     case 0x08: str = "National Numbering"; break;
2703     case 0x09: str = "Private Numbering"; break;
2704     default:
2705         str = "Reserved";
2706         break;
2707     }
2708
2709     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
2710     proto_tree_add_text(tree, tvb, curr_offset, 1,
2711         "%s :  Number Plan Identification: %s",
2712         a_bigbuf,
2713         str);
2714
2715     curr_offset++;
2716
2717     if (!(oct & 0x80))
2718     {
2719         /* octet 3a */
2720
2721         oct = tvb_get_guint8(tvb, curr_offset);
2722
2723         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
2724         proto_tree_add_text(tree, tvb, curr_offset, 1,
2725             "%s :  Extension",
2726             a_bigbuf);
2727
2728         switch ((oct & 0x60) >> 5)
2729         {
2730         case 0: str = "Presentation allowed"; break;
2731         case 1: str = "Presentation restricted"; break;
2732         case 2: str = "Number not available due to interworking"; break;
2733         default:
2734             str = "Reserved";
2735             break;
2736         }
2737
2738         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
2739         proto_tree_add_text(tree, tvb, curr_offset, 1,
2740             "%s :  Presentation Indicator: %s",
2741             a_bigbuf,
2742             str);
2743
2744         switch (oct & 0x03)
2745         {
2746         case 0: str = "User-provided, not screened"; break;
2747         case 1: str = "User-provided, verified and passed"; break;
2748         case 2: str = "User-provided, verified and failed"; break;
2749         default:
2750             str = "Network-provided";
2751             break;
2752         }
2753
2754         other_decode_bitfield_value(a_bigbuf, oct, 0x1c, 8);
2755         proto_tree_add_text(tree, tvb, curr_offset, 1,
2756             "%s :  Reserved",
2757             a_bigbuf);
2758
2759         other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
2760         proto_tree_add_text(tree, tvb, curr_offset, 1,
2761             "%s :  Screening Indicator: %s",
2762             a_bigbuf,
2763             str);
2764
2765         curr_offset++;
2766     }
2767
2768     poctets = tvb_get_string(tvb, curr_offset, len - (curr_offset - offset));
2769
2770     proto_tree_add_string_format(tree, hf_ansi_a_clg_party_ascii_num,
2771         tvb, curr_offset, len - (curr_offset - offset),
2772         "Digits: %s",
2773         poctets);
2774
2775     curr_offset += len - (curr_offset - offset);
2776
2777     sprintf(add_string, " - (%s)", poctets);
2778     g_free(poctets);
2779
2780     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2781
2782     return(curr_offset - offset);
2783 }
2784
2785 /*
2786  * IOS 6.2.2.38
2787  */
2788 static guint8
2789 elem_l3_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2790 {
2791     guint32     curr_offset;
2792     tvbuff_t    *l3_tvb;
2793
2794     add_string = add_string;
2795     curr_offset = offset;
2796
2797     proto_tree_add_text(tree, tvb, curr_offset, len,
2798         "Layer 3 Information");
2799
2800     /*
2801      * dissect the embedded DTAP message
2802      */
2803     l3_tvb = tvb_new_subset(tvb, curr_offset, len, len);
2804
2805     call_dissector(dtap_handle, l3_tvb, g_pinfo, g_tree);
2806
2807     curr_offset += len;
2808
2809     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2810
2811     return(curr_offset - offset);
2812 }
2813
2814 /*
2815  * IOS 6.2.2.39
2816  * Protocol Discriminator
2817  */
2818
2819 /*
2820  * IOS 6.2.2.40
2821  * Reserved Octet
2822  */
2823
2824 /*
2825  * IOS 6.2.2.41
2826  * Location Updating Type
2827  * UNUSED in SPEC!
2828  */
2829
2830 /*
2831  * IOS 6.2.2.42
2832  * Simple data no decode required
2833  */
2834
2835 /*
2836  * IOS 6.2.2.43
2837  */
2838 static guint8
2839 elem_lai(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2840 {
2841     guint8      oct;
2842     guint16     value;
2843     guint32     curr_offset;
2844     gchar       mcc[4];
2845     gchar       mnc[4];
2846
2847     len = len;
2848     add_string = add_string;
2849     curr_offset = offset;
2850
2851     oct = tvb_get_guint8(tvb, curr_offset);
2852
2853     mcc[0] = Dgt_tbcd.out[oct & 0x0f];
2854     mcc[1] = Dgt_tbcd.out[(oct & 0xf0) >> 4];
2855
2856     oct = tvb_get_guint8(tvb, curr_offset+1);
2857
2858     mcc[2] = Dgt_tbcd.out[(oct & 0x0f)];
2859     mcc[3] = '\0';
2860
2861     mnc[2] = Dgt_tbcd.out[(oct & 0xf0) >> 4];
2862
2863     oct = tvb_get_guint8(tvb, curr_offset+2);
2864
2865     mnc[0] = Dgt_tbcd.out[(oct & 0x0f)];
2866     mnc[1] = Dgt_tbcd.out[(oct & 0xf0) >> 4];
2867     mnc[3] = '\0';
2868
2869     proto_tree_add_text(tree,
2870         tvb, curr_offset, 3,
2871         "Mobile Country Code (MCC): %s, Mobile Network Code (MNC): %s",
2872         mcc,
2873         mnc);
2874
2875     curr_offset += 3;
2876
2877     value = tvb_get_ntohs(tvb, curr_offset);
2878
2879     proto_tree_add_text(tree,
2880         tvb, curr_offset, 2,
2881         "Location Area Code (LAC): 0x%04x (%u)",
2882         value,
2883         value);
2884
2885     curr_offset += 2;
2886
2887     /* no length check possible */
2888
2889     return(curr_offset - offset);
2890 }
2891
2892 /*
2893  * IOS 6.2.2.44
2894  */
2895 static guint8
2896 elem_rej_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2897 {
2898     guint8      oct;
2899     guint32     curr_offset;
2900     gchar       *str;
2901
2902     len = len;
2903     curr_offset = offset;
2904
2905     oct = tvb_get_guint8(tvb, curr_offset);
2906
2907     switch (oct)
2908     {
2909     case 0x01: str = "Reserved"; break;
2910     case 0x02: str = "MIN/IMSI unknown in HLR"; break;
2911     case 0x03: str = "Illegal MS"; break;
2912     case 0x04: str = "TMSI/IMSI/MIN unknown in VLR"; break;
2913     case 0x05: str = "Reserved"; break;
2914     case 0x0b: str = "Roaming not allowed"; break;
2915     case 0x0c: str = "Location area not allowed"; break;
2916     case 0x20: str = "Service option not supported"; break;
2917     case 0x21: str = "Requested service option not subscribed"; break;
2918     case 0x22: str = "Service option temporarily out of order"; break;
2919     case 0x26: str = "Call cannot be identified"; break;
2920     case 0x51: str = "Network failure"; break;
2921     case 0x56: str = "Congestion"; break;
2922     case 0x62: str = "Message type non-existent or not implemented"; break;
2923     case 0x63: str = "Information element non-existent or not implemented"; break;
2924     case 0x64: str = "Invalid information element contents"; break;
2925     case 0x65: str = "Message not compatible with the call state"; break;
2926     case 0x66: str = "Protocol error, unspecified"; break;
2927     case 0x6e: str = "Invalid message, unspecified"; break;
2928     case 0x6f: str = "Mandatory information element error"; break;
2929     default:
2930         str = "Reserved";
2931         break;
2932     }
2933
2934     proto_tree_add_text(tree,
2935         tvb, curr_offset, 1,
2936         "Reject Cause Value: (%u) %s",
2937         oct,
2938         str);
2939
2940     curr_offset++;
2941
2942     sprintf(add_string, " - (%s)", str);
2943
2944     /* no length check possible */
2945
2946     return(curr_offset - offset);
2947 }
2948
2949 /*
2950  * IOS 6.2.2.45
2951  */
2952 static guint8
2953 elem_auth_chlg_param(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
2954 {
2955     guint8      oct;
2956     guint32     curr_offset;
2957     gchar       *str;
2958
2959     curr_offset = offset;
2960
2961     oct = tvb_get_guint8(tvb, curr_offset);
2962
2963     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
2964     proto_tree_add_text(tree,
2965         tvb, curr_offset, 1,
2966         "%s :  Reserved",
2967         a_bigbuf);
2968
2969     switch (oct & 0x0f)
2970     {
2971     case 1: str = "RAND 32 bits"; break;
2972     case 2: str = "RANDU 24 bits"; break;
2973     case 4: str = "RANDSSD 56 bits"; break;
2974     case 8: str = "RANDBS 32 bits"; break;
2975     default:
2976         str = "Reserved";
2977         break;
2978     }
2979
2980     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
2981     proto_tree_add_text(tree,
2982         tvb, curr_offset, 1,
2983         "%s :  Random Number Type: (%u) %s",
2984         a_bigbuf,
2985         oct & 0x0f,
2986         str);
2987
2988     curr_offset++;
2989
2990     proto_tree_add_text(tree,
2991         tvb, curr_offset, len - (curr_offset - offset),
2992         "RAND/RANDU/RANDBS/RANDSSD Value");
2993
2994     sprintf(add_string, " - (%s)", str);
2995
2996     curr_offset += len - (curr_offset - offset);
2997
2998     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
2999
3000     return(curr_offset - offset);
3001 }
3002
3003 /*
3004  * IOS 6.2.2.46
3005  */
3006 static guint8
3007 elem_auth_resp_param(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3008 {
3009     guint8      oct;
3010     guint32     curr_offset;
3011     gchar       *str;
3012
3013     curr_offset = offset;
3014
3015     oct = tvb_get_guint8(tvb, curr_offset);
3016
3017     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
3018     proto_tree_add_text(tree,
3019         tvb, curr_offset, 1,
3020         "%s :  Reserved",
3021         a_bigbuf);
3022
3023     switch (oct & 0x0f)
3024     {
3025     case 1: str = "AUTHR"; break;
3026     case 2: str = "AUTHU"; break;
3027     case 4: str = "AUTHBS"; break;
3028     default:
3029         str = "Reserved";
3030         break;
3031     }
3032
3033     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
3034     proto_tree_add_text(tree,
3035         tvb, curr_offset, 1,
3036         "%s :  Auth Signature Type: (%u) %s",
3037         a_bigbuf,
3038         oct & 0x0f,
3039         str);
3040
3041     curr_offset++;
3042
3043     proto_tree_add_text(tree,
3044         tvb, curr_offset, len - (curr_offset - offset),
3045         "Auth Signature");
3046
3047     sprintf(add_string, " - (%s)", str);
3048
3049     curr_offset += len - (curr_offset - offset);
3050
3051     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3052
3053     return(curr_offset - offset);
3054 }
3055
3056 /*
3057  * IOS 6.2.2.47
3058  */
3059 static guint8
3060 elem_auth_param_count(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3061 {
3062     guint8      oct;
3063     guint32     curr_offset;
3064
3065     len = len;
3066     curr_offset = offset;
3067
3068     oct = tvb_get_guint8(tvb, curr_offset);
3069
3070     other_decode_bitfield_value(a_bigbuf, oct, 0xc0, 8);
3071     proto_tree_add_text(tree,
3072         tvb, curr_offset, 1,
3073         "%s :  Reserved",
3074         a_bigbuf);
3075
3076     other_decode_bitfield_value(a_bigbuf, oct, 0x3f, 8);
3077     proto_tree_add_text(tree,
3078         tvb, curr_offset, 1,
3079         "%s :  Count: %u",
3080         a_bigbuf,
3081         oct & 0x3f);
3082
3083     curr_offset++;
3084
3085     sprintf(add_string, " - (%u)", oct & 0x3f);
3086
3087     /* no length check possible */
3088
3089     return(curr_offset - offset);
3090 }
3091
3092 /*
3093  * IOS 6.2.2.48
3094  */
3095 static guint8
3096 elem_mwi(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3097 {
3098     guint8      oct;
3099     guint32     curr_offset;
3100
3101     len = len;
3102     curr_offset = offset;
3103
3104     oct = tvb_get_guint8(tvb, curr_offset);
3105
3106     proto_tree_add_text(tree,
3107         tvb, curr_offset, 1,
3108         "Number of Messages: %u",
3109         oct);
3110
3111     curr_offset++;
3112
3113     sprintf(add_string, " - (%u)", oct);
3114
3115     /* no length check possible */
3116
3117     return(curr_offset - offset);
3118 }
3119
3120 /*
3121  * IOS 6.2.2.49
3122  * Progress
3123  * UNUSED in SPEC and no IEI!
3124  */
3125
3126 /*
3127  * IOS 6.2.2.50
3128  */
3129 static guint8
3130 elem_signal(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3131 {
3132     guint8      oct;
3133     guint32     curr_offset;
3134     gchar       *str;
3135
3136     len = len;
3137     curr_offset = offset;
3138
3139     oct = tvb_get_guint8(tvb, curr_offset);
3140
3141     switch (oct)
3142     {
3143     case 0x00: str = "Dial tone on"; break;
3144     case 0x01: str = "Ring back tone on"; break;
3145     case 0x02: str = "Intercept tone on"; break;
3146     case 0x03: str = "Network congestion (reorder) tone on"; break;
3147     case 0x04: str = "Busy tone on"; break;
3148     case 0x05: str = "Confirm tone on"; break;
3149     case 0x06: str = "Answer tone on"; break;
3150     case 0x07: str = "Call waiting tone on"; break;
3151     case 0x08: str = "Off-hook warning tone on"; break;
3152     case 0x3f: str = "Tones off"; break;
3153     case 0x40: str = "Normal Alerting"; break;
3154     case 0x41: str = "Inter-group Alerting"; break;
3155     case 0x42: str = "Special/Priority Alerting"; break;
3156     case 0x43: str = "Reserved (ISDN Alerting pattern 3)"; break;
3157     case 0x44: str = "Ping Ring (abbreviated alert)"; break;
3158     case 0x45: str = "Reserved (ISDN Alerting pattern 5)"; break;
3159     case 0x46: str = "Reserved (ISDN Alerting pattern 6)"; break;
3160     case 0x47: str = "Reserved (ISDN Alerting pattern 7)"; break;
3161     case 0x63: str = "Abbreviated intercept"; break;
3162     case 0x65: str = "Abbreviated reorder"; break;
3163     case 0x4f: str = "Alerting off"; break;
3164     default:
3165         str = "Unknown";
3166         break;
3167     }
3168
3169     proto_tree_add_text(tree,
3170         tvb, curr_offset, 1,
3171         "Signal Value: (%u) %s",
3172         oct,
3173         str);
3174
3175     sprintf(add_string, " - (%s)", str);
3176
3177     curr_offset++;
3178
3179     oct = tvb_get_guint8(tvb, curr_offset);
3180
3181     other_decode_bitfield_value(a_bigbuf, oct, 0xfc, 8);
3182     proto_tree_add_text(tree,
3183         tvb, curr_offset, 1,
3184         "%s :  Reserved",
3185         a_bigbuf);
3186
3187     switch (oct & 0x03)
3188     {
3189     case 0: str = "Medium pitch (standard alert)"; break;
3190     case 1: str = "High pitch"; break;
3191     case 2: str = "Low pitch"; break;
3192     default:
3193         str = "Reserved";
3194         break;
3195     }
3196
3197     proto_tree_add_text(tree,
3198         tvb, curr_offset, 1,
3199         "%s : Alert Pitch: %s",
3200         a_bigbuf,
3201         str);
3202
3203     curr_offset++;
3204
3205     /* no length check possible */
3206
3207     return(curr_offset - offset);
3208 }
3209
3210 /*
3211  * IOS 6.2.2.51
3212  * CM Service Type
3213  */
3214
3215 /*
3216  * IOS 6.2.2.52
3217  */
3218 static guint8
3219 elem_cld_party_bcd_num(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3220 {
3221     guint8      oct;
3222     guint8      *poctets;
3223     guint32     curr_offset;
3224     gchar       *str;
3225
3226     curr_offset = offset;
3227
3228     oct = tvb_get_guint8(tvb, curr_offset);
3229
3230     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
3231     proto_tree_add_text(tree,
3232         tvb, curr_offset, 1,
3233         "%s :  Extension",
3234         a_bigbuf);
3235
3236     switch ((oct & 0x70) >> 4)
3237     {
3238     case 0: str = "Unknown"; break;
3239     case 1: str = "International number"; break;
3240     case 2: str = "National number"; break;
3241     case 3: str = "Network specific number"; break;
3242     case 4: str = "Dedicated PAD access, short code"; break;
3243     case 7: str = "Reserved for extension"; break;
3244     default:
3245         str = "Reserved";
3246         break;
3247     }
3248
3249     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
3250     proto_tree_add_text(tree,
3251         tvb, curr_offset, 1,
3252         "%s :  Type of Number: %s",
3253         a_bigbuf,
3254         str);
3255
3256     switch (oct & 0x0f)
3257     {
3258     case 0x00: str = "Unknown"; break;
3259     case 0x01: str = "ISDN/telephony number plan (ITU recommendation E.164/E.163)"; break;
3260     case 0x03: str = "Data number plan (ITU recommendation X.121)"; break;
3261     case 0x04: str = "Telex numbering plan (ITU recommendation F.69)"; break;
3262     case 0x07: str = "Reserved for extension"; break;
3263     case 0x08: str = "National numbering plan"; break;
3264     case 0x09: str = "Private numbering plan"; break;
3265     default:
3266         str = "Reserved";
3267         break;
3268     }
3269
3270     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
3271     proto_tree_add_text(tree,
3272         tvb, curr_offset, 1,
3273         "%s :  Numbering Plan Identification: %s",
3274         a_bigbuf,
3275         str);
3276
3277     curr_offset++;
3278
3279     poctets = tvb_get_string(tvb, curr_offset, len - (curr_offset - offset));
3280
3281     my_dgt_tbcd_unpack(a_bigbuf, poctets, len - (curr_offset - offset),
3282         &Dgt_tbcd);
3283     g_free(poctets);
3284
3285     proto_tree_add_string_format(tree, hf_ansi_a_cld_party_bcd_num,
3286         tvb, curr_offset, len - (curr_offset - offset),
3287         a_bigbuf,
3288         "BCD Digits: %s",
3289         a_bigbuf);
3290
3291     sprintf(add_string, " - (%s)", a_bigbuf);
3292
3293     curr_offset += len - (curr_offset - offset);
3294
3295     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3296
3297     return(curr_offset - offset);
3298 }
3299
3300 /*
3301  * IOS 6.2.2.53
3302  * UNUSED in SPEC and no IEI!
3303  */
3304 #ifdef MAYBE_USED_FOR_OLDER_CODECS
3305 static guint8
3306 elem_clg_party_bcd_num(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3307 {
3308     guint8      oct;
3309     guint8      *poctets;
3310     guint32     curr_offset;
3311     gchar       *str;
3312
3313     curr_offset = offset;
3314
3315     oct = tvb_get_guint8(tvb, curr_offset);
3316
3317     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
3318     proto_tree_add_text(tree, tvb, curr_offset, 1,
3319         "%s :  Extension: %s",
3320         a_bigbuf,
3321         (oct & 0x80) ? "Not extended" : "Extended");
3322
3323     switch ((oct & 0x70) >> 4)
3324     {
3325     case 0: str = "Unknown"; break;
3326     case 1: str = "International number"; break;
3327     case 2: str = "National number"; break;
3328     case 3: str = "Network specific number"; break;
3329     case 4: str = "Dedicated PAD access, short code"; break;
3330     case 7: str = "Reserved for extension"; break;
3331     default:
3332         str = "Reserved";
3333         break;
3334     }
3335
3336     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
3337     proto_tree_add_text(tree,
3338         tvb, curr_offset, 1,
3339         "%s :  Type of Number: %s",
3340         a_bigbuf,
3341         str);
3342
3343     switch (oct & 0x0f)
3344     {
3345     case 0x00: str = "Unknown"; break;
3346     case 0x01: str = "ISDN/telephony number plan (ITU recommendation E.164/E.163)"; break;
3347     case 0x03: str = "Data number plan (ITU recommendation X.121)"; break;
3348     case 0x04: str = "Telex numbering plan (ITU recommendation F.69)"; break;
3349     case 0x07: str = "Reserved for extension"; break;
3350     case 0x08: str = "National numbering plan"; break;
3351     case 0x09: str = "Private numbering plan"; break;
3352     default:
3353         str = "Reserved";
3354         break;
3355     }
3356
3357     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
3358     proto_tree_add_text(tree,
3359         tvb, curr_offset, 1,
3360         "%s :  Numbering Plan Identification: %s",
3361         a_bigbuf,
3362         str);
3363
3364     curr_offset++;
3365
3366     if (!(oct & 0x80))
3367     {
3368         /* octet 3a */
3369
3370         oct = tvb_get_guint8(tvb, curr_offset);
3371
3372         other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
3373         proto_tree_add_text(tree, tvb, curr_offset, 1,
3374             "%s :  Extension",
3375             a_bigbuf);
3376
3377         switch ((oct & 0x60) >> 5)
3378         {
3379         case 0: str = "Presentation allowed"; break;
3380         case 1: str = "Presentation restricted"; break;
3381         case 2: str = "Number not available due to interworking"; break;
3382         default:
3383             str = "Reserved";
3384             break;
3385         }
3386
3387         other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
3388         proto_tree_add_text(tree, tvb, curr_offset, 1,
3389             "%s :  Presentation Indicator: %s",
3390             a_bigbuf,
3391             str);
3392
3393         switch (oct & 0x03)
3394         {
3395         case 0: str = "User-provided, not screened"; break;
3396         case 1: str = "User-provided, verified and passed"; break;
3397         case 2: str = "User-provided, verified and failed"; break;
3398         default:
3399             str = "Network-provided";
3400             break;
3401         }
3402
3403         other_decode_bitfield_value(a_bigbuf, oct, 0x1c, 8);
3404         proto_tree_add_text(tree, tvb, curr_offset, 1,
3405             "%s :  Reserved",
3406             a_bigbuf);
3407
3408         other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
3409         proto_tree_add_text(tree, tvb, curr_offset, 1,
3410             "%s :  Screening Indicator: %s",
3411             a_bigbuf,
3412             str);
3413
3414         curr_offset++;
3415     }
3416
3417     poctets = tvb_get_string(tvb, curr_offset, len - (curr_offset - offset));
3418
3419     my_dgt_tbcd_unpack(a_bigbuf, poctets, len - (curr_offset - offset),
3420         &Dgt_tbcd);
3421     g_free(poctets);
3422
3423     proto_tree_add_string_format(tree, hf_ansi_a_clg_party_bcd_num,
3424         tvb, curr_offset, len - (curr_offset - offset),
3425         a_bigbuf,
3426         "BCD Digits: %s",
3427         a_bigbuf);
3428
3429     sprintf(add_string, " - (%s)", a_bigbuf);
3430
3431     curr_offset += len - (curr_offset - offset);
3432
3433     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3434
3435     return(curr_offset - offset);
3436 }
3437 #endif
3438
3439 /*
3440  * IOS 6.2.2.54
3441  */
3442 static guint8
3443 elem_qos_params(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3444 {
3445     guint8      oct;
3446     guint32     curr_offset;
3447
3448     curr_offset = offset;
3449
3450     oct = tvb_get_guint8(tvb, curr_offset);
3451
3452     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
3453     proto_tree_add_text(tree,
3454         tvb, curr_offset, 1,
3455         "%s :  Reserved",
3456         a_bigbuf);
3457
3458     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
3459     proto_tree_add_text(tree,
3460         tvb, curr_offset, 1,
3461         "%s :  Packet Priority: %u",
3462         a_bigbuf,
3463         oct & 0x0f);
3464
3465     sprintf(add_string, " - (%u)", oct & 0x0f);
3466
3467     curr_offset++;
3468
3469     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3470
3471     return(curr_offset - offset);
3472 }
3473
3474 /*
3475  * IOS 6.2.2.55
3476  */
3477 static guint8
3478 elem_cause_l3(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3479 {
3480     guint8      oct;
3481     guint32     curr_offset;
3482     gchar       *str = NULL;
3483
3484     curr_offset = offset;
3485
3486     oct = tvb_get_guint8(tvb, curr_offset);
3487
3488     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
3489     proto_tree_add_text(tree,
3490         tvb, curr_offset, 1,
3491         "%s :  Extension",
3492         a_bigbuf);
3493
3494     switch ((oct & 0x60) >> 5)
3495     {
3496     case 0: str = "Standard as described in ITU Recommendation Q.931"; break;
3497     case 1: str = "Reserved for other international standards"; break;
3498     case 2: str = "National standard"; break;
3499     default:
3500         str = "Reserved for other international standards";
3501         break;
3502     }
3503
3504     other_decode_bitfield_value(a_bigbuf, oct, 0x60, 8);
3505     proto_tree_add_text(tree,
3506         tvb, curr_offset, 1,
3507         "%s :  Coding Standard: %s",
3508         a_bigbuf,
3509         str);
3510
3511     other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
3512     proto_tree_add_text(tree,
3513         tvb, curr_offset, 1,
3514         "%s :  Reserved",
3515         a_bigbuf);
3516
3517     switch (oct & 0x0f)
3518     {
3519     case 0: str = "User"; break;
3520     case 1: str = "Private network serving the local user"; break;
3521     case 2: str = "Public network serving the local user"; break;
3522     case 3: str = "Transit network"; break;
3523     case 4: str = "Public network serving the remote user"; break;
3524     case 5: str = "Private network serving the remote user"; break;
3525     case 7: str = "International network"; break;
3526     case 10: str = "Network beyond interworking point"; break;
3527     default:
3528         str = "All other values Reserved"; break;
3529         break;
3530     }
3531
3532     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
3533     proto_tree_add_text(tree,
3534         tvb, curr_offset, 1,
3535         "%s :  Location: %s",
3536         a_bigbuf,
3537         str);
3538
3539     curr_offset++;
3540
3541     oct = tvb_get_guint8(tvb, curr_offset);
3542
3543     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
3544     proto_tree_add_text(tree,
3545         tvb, curr_offset, 1,
3546         "%s :  Extension",
3547         a_bigbuf);
3548
3549     switch ((oct & 0x70) >> 4)
3550     {
3551     case 0: str = "normal event"; break;
3552     case 1: str = "normal event"; break;
3553     case 2: str = "resource unavailable"; break;
3554     case 3: str = "service or option not available"; break;
3555     case 4: str = "service or option not implemented"; break;
3556     case 5: str = "invalid message (e.g., parameter out of range)"; break;
3557     case 6: str = "protocol error (e.g., unknown message)"; break;
3558     default:
3559         str = "interworking";
3560         break;
3561     }
3562
3563     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
3564     proto_tree_add_text(tree,
3565         tvb, curr_offset, 1,
3566         "%s :  Class: (%u) %s",
3567         a_bigbuf,
3568         (oct & 0x70) >> 4,
3569         str);
3570
3571     switch (oct & 0x7f)
3572     {
3573     case 0x01: str = "Unassigned (unallocated) number"; break;
3574     case 0x03: str = "No route to destination"; break;
3575     case 0x06: str = "Channel unacceptable"; break;
3576     case 0x0F: str = "Procedure failed"; break;
3577     case 0x10: str = "Normal Clearing"; break;
3578     case 0x11: str = "User busy"; break;
3579     case 0x12: str = "No user responding"; break;
3580     case 0x13: str = "User alerting, no answer"; break;
3581     case 0x15: str = "Call rejected"; break;
3582     case 0x16: str = "Number changed New destination"; break;
3583     case 0x1A: str = "Non selected user clearing"; break;
3584     case 0x1B: str = "Destination out of order"; break;
3585     case 0x1C: str = "Invalid number format (incomplete number)"; break;
3586     case 0x1D: str = "Facility rejected"; break;
3587     case 0x1F: str = "Normal, unspecified"; break;
3588     case 0x22: str = "No circuit/channel available"; break;
3589     case 0x26: str = "Network out of order"; break;
3590     case 0x29: str = "Temporary failure"; break;
3591     case 0x2A: str = "Switching equipment congestion"; break;
3592     case 0x2B: str = "Access information discarded information element ids"; break;
3593     case 0x2C: str = "requested circuit/channel not available"; break;
3594     case 0x2F: str = "Resources unavailable, unspecified"; break;
3595     case 0x31: str = "Quality of service unavailable"; break;
3596     case 0x32: str = "Requested facility not subscribed"; break;
3597     case 0x33: str = "Request MUX option or rates unavailable"; break;
3598     case 0x39: str = "Bearer capability not authorized"; break;
3599     case 0x3A: str = "Bearer capability not presently available"; break;
3600     case 0x3B: str = "SSD Update Rejected"; break;
3601     case 0x3F: str = "Service or option not available, unspecified"; break;
3602     case 0x41: str = "Bearer service not implemented"; break;
3603     case 0x45: str = "Requested facility not implement"; break;
3604     case 0x46: str = "Only restricted digital information bearer capability is available"; break;
3605     case 0x4F: str = "Service or option not implemented, unspecified"; break;
3606     case 0x51: str = "Reserved"; break;
3607     case 0x58: str = "Incompatible destination incompatible parameter"; break;
3608     case 0x5B: str = "Invalid transit network selection"; break;
3609     case 0x5F: str = "Invalid message, unspecified"; break;
3610     case 0x60: str = "Mandatory information element error information element identifier(s)"; break;
3611     case 0x61: str = "Message type nonexistent or not implemented message type"; break;
3612     case 0x62: str = "Message not compatible with control state message type or message type nonexistent or not implemented"; break;
3613     case 0x64: str = "Invalid information element contents Information element Identifier(s)"; break;
3614     case 0x65: str = "Message not compatible with call state message type"; break;
3615     case 0x6F: str = "Protocol error, unspecified"; break;
3616     case 0x7F: str = "Interworking, unspecified"; break;
3617     default:
3618         str = "Reserved";
3619         break;
3620     }
3621
3622     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
3623     proto_tree_add_text(tree,
3624         tvb, curr_offset, 1,
3625         "%s :  Value: (%u)",
3626         a_bigbuf,
3627         oct & 0x0f);
3628
3629     sprintf(add_string, " - (%u) %s", oct & 0x7f, str);
3630
3631     curr_offset++;
3632
3633     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3634
3635     return(curr_offset - offset);
3636 }
3637
3638 /*
3639  * IOS 6.2.2.56
3640  * A3/A7
3641  */
3642
3643 /*
3644  * IOS 6.2.2.57
3645  * A3/A7
3646  */
3647
3648 /*
3649  * IOS 6.2.2.58
3650  */
3651 static guint8
3652 elem_xmode(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3653 {
3654     guint8      oct;
3655     guint32     curr_offset;
3656
3657     curr_offset = offset;
3658
3659     oct = tvb_get_guint8(tvb, curr_offset);
3660
3661     other_decode_bitfield_value(a_bigbuf, oct, 0xfe, 8);
3662     proto_tree_add_text(tree,
3663         tvb, curr_offset, 1,
3664         "%s :  Reserved",
3665         a_bigbuf);
3666
3667     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
3668     proto_tree_add_text(tree,
3669         tvb, curr_offset, 1,
3670         "%s :  TFO Mode: %s",
3671         a_bigbuf,
3672         (oct & 0x01) ? "TFO" : "tandem");
3673
3674     sprintf(add_string, " - (%s)",
3675         (oct & 0x01) ? "TFO" : "tandem");
3676
3677     curr_offset++;
3678
3679     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3680
3681     return(curr_offset - offset);
3682 }
3683
3684 /*
3685  * IOS 6.2.2.59
3686  * UNUSED
3687  */
3688
3689 /*
3690  * IOS 6.2.2.60
3691  * NO ASSOCIATED DATA
3692  */
3693
3694 /*
3695  * IOS 6.2.2.61
3696  */
3697 static guint8
3698 elem_reg_type(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3699 {
3700     guint8      oct;
3701     guint32     curr_offset;
3702     gchar       *str;
3703
3704     len = len;
3705     curr_offset = offset;
3706
3707     oct = tvb_get_guint8(tvb, curr_offset);
3708
3709     switch (oct)
3710     {
3711     case 0x00: str = "Timer-based"; break;
3712     case 0x01: str = "Power-up"; break;
3713     case 0x02: str = "Zone-based"; break;
3714     case 0x03: str = "Power-down"; break;
3715     case 0x04: str = "Parameter-change"; break;
3716     case 0x05: str = "Ordered"; break;
3717     case 0x06: str = "Distance-based"; break;
3718     default:
3719         str = "Reserved";
3720         break;
3721     }
3722
3723     proto_tree_add_text(tree,
3724         tvb, curr_offset, 1,
3725         "Location Registration Type: %s",
3726         str);
3727
3728     sprintf(add_string, " - (%s)", str);
3729
3730     curr_offset++;
3731
3732     /* no length check possible */
3733
3734     return(curr_offset - offset);
3735 }
3736
3737 /*
3738  * IOS 6.2.2.62
3739  */
3740 static guint8
3741 elem_tag(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3742 {
3743     guint32     value;
3744     guint32     curr_offset;
3745
3746     len = len;
3747     curr_offset = offset;
3748
3749     value = tvb_get_ntohl(tvb, curr_offset);
3750
3751     proto_tree_add_text(tree,
3752         tvb, curr_offset, 4,
3753         "Tag Value: %u",
3754         value);
3755
3756     sprintf(add_string, " - (%u)", value);
3757
3758     curr_offset += 4;
3759
3760     /* no length check possible */
3761
3762     return(curr_offset - offset);
3763 }
3764
3765 /*
3766  * IOS 6.2.2.63
3767  */
3768 static guint8
3769 elem_hho_params(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3770 {
3771     guint8      oct;
3772     gint        temp_int;
3773     guint32     curr_offset;
3774     gchar       *str;
3775
3776     len = len;
3777     curr_offset = offset;
3778
3779     oct = tvb_get_guint8(tvb, curr_offset);
3780
3781     other_decode_bitfield_value(a_bigbuf, oct, 0xe0, 8);
3782     proto_tree_add_text(tree,
3783         tvb, curr_offset, 1,
3784         "%s :  Reserved",
3785         a_bigbuf);
3786
3787     temp_int = oct & 0x1f;
3788     if ((temp_int < 0) || (temp_int >= (gint) NUM_BAND_CLASS_STR))
3789     {
3790         str = "Reserved";
3791     }
3792     else
3793     {
3794         str = band_class_str[temp_int];
3795     }
3796
3797     other_decode_bitfield_value(a_bigbuf, oct, 0x1f, 8);
3798     proto_tree_add_text(tree,
3799         tvb, curr_offset, 1,
3800         "%s :  Band Class: %s",
3801         a_bigbuf,
3802         str);
3803
3804     curr_offset++;
3805
3806     sprintf(add_string, " - (%s)", str);
3807
3808     oct = tvb_get_guint8(tvb, curr_offset);
3809
3810     other_decode_bitfield_value(a_bigbuf, oct, 0xe0, 8);
3811     proto_tree_add_text(tree,
3812         tvb, curr_offset, 1,
3813         "%s :  Number of Preamble Frames: %u",
3814         a_bigbuf,
3815         (oct & 0xe0) >> 5);
3816
3817     other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
3818     proto_tree_add_text(tree,
3819         tvb, curr_offset, 1,
3820         "%s :  Reset L2: %s Layer 2 Acknowledgement",
3821         a_bigbuf,
3822         (oct & 0x10) ? "Reset" : "Do not reset");
3823
3824     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
3825     proto_tree_add_text(tree,
3826         tvb, curr_offset, 1,
3827         "%s :  Reset FPC: %s counters",
3828         a_bigbuf,
3829         (oct & 0x10) ? "Reset" : "Do not reset");
3830
3831     switch ((oct & 0x06) >> 1)
3832     {
3833     case 0: str = "Encryption disabled"; break;
3834     case 1: str = "Encryption enabled"; break;
3835     default:
3836         str = "Unknown";
3837         break;
3838     }
3839
3840     other_decode_bitfield_value(a_bigbuf, oct, 0x06, 8);
3841     proto_tree_add_text(tree,
3842         tvb, curr_offset, 1,
3843         "%s :  Encryption Mode: %s",
3844         a_bigbuf,
3845         str);
3846
3847     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
3848     proto_tree_add_text(tree,
3849         tvb, curr_offset, 1,
3850         "%s :  Private LCM: %s Private Long Code Mask",
3851         a_bigbuf,
3852         (oct & 0x01) ? "Use" : "Do not use");
3853
3854     curr_offset++;
3855
3856     oct = tvb_get_guint8(tvb, curr_offset);
3857
3858     other_decode_bitfield_value(a_bigbuf, oct, 0xe0, 8);
3859     proto_tree_add_text(tree,
3860         tvb, curr_offset, 1,
3861         "%s :  Reserved",
3862         a_bigbuf);
3863
3864     other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
3865     proto_tree_add_text(tree,
3866         tvb, curr_offset, 1,
3867         "%s :  Nom_Pwr_Ext",
3868         a_bigbuf);
3869
3870     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
3871     proto_tree_add_text(tree,
3872         tvb, curr_offset, 1,
3873         "%s :  Nom_Pwr: %u",
3874         a_bigbuf,
3875         oct & 0x0f);
3876
3877     curr_offset++;
3878
3879     oct = tvb_get_guint8(tvb, curr_offset);
3880
3881     other_decode_bitfield_value(a_bigbuf, oct, 0xc0, 8);
3882     proto_tree_add_text(tree,
3883         tvb, curr_offset, 1,
3884         "%s :  Reserved",
3885         a_bigbuf);
3886
3887     other_decode_bitfield_value(a_bigbuf, oct, 0x3e, 8);
3888     proto_tree_add_text(tree,
3889         tvb, curr_offset, 1,
3890         "%s :  FPC Subchannel Information: %u",
3891         a_bigbuf,
3892         (oct & 0x3e) >> 1);
3893
3894     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
3895     proto_tree_add_text(tree,
3896         tvb, curr_offset, 1,
3897         "%s :  FPC SubChannel Information Included",
3898         a_bigbuf);
3899
3900     curr_offset++;
3901
3902     oct = tvb_get_guint8(tvb, curr_offset);
3903
3904     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
3905     proto_tree_add_text(tree,
3906         tvb, curr_offset, 1,
3907         "%s :  Reserved",
3908         a_bigbuf);
3909
3910     other_decode_bitfield_value(a_bigbuf, oct, 0x0e, 8);
3911     proto_tree_add_text(tree,
3912         tvb, curr_offset, 1,
3913         "%s :  Power Control Step: %u",
3914         a_bigbuf,
3915         (oct & 0x0e) >> 1);
3916
3917     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
3918     proto_tree_add_text(tree,
3919         tvb, curr_offset, 1,
3920         "%s :  Power Control Step Included",
3921         a_bigbuf);
3922
3923     curr_offset++;
3924
3925     /* no length check possible */
3926
3927     return(curr_offset - offset);
3928 }
3929
3930 /*
3931  * IOS 6.2.2.64
3932  * UNUSED
3933  */
3934
3935 /*
3936  * IOS 6.2.2.65
3937  */
3938 static guint8
3939 elem_sw_ver(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3940 {
3941     guint8      major, minor, point;
3942     guint32     curr_offset;
3943
3944     curr_offset = offset;
3945
3946     major = tvb_get_guint8(tvb, curr_offset);
3947
3948     proto_tree_add_text(tree,
3949         tvb, curr_offset, 1,
3950         "IOS Major Revision Level: %u",
3951         major);
3952
3953     curr_offset++;
3954
3955     minor = tvb_get_guint8(tvb, curr_offset);
3956
3957     proto_tree_add_text(tree,
3958         tvb, curr_offset, 1,
3959         "IOS Minor Revision Level: %u",
3960         minor);
3961
3962     curr_offset++;
3963
3964     point = tvb_get_guint8(tvb, curr_offset);
3965
3966     proto_tree_add_text(tree,
3967         tvb, curr_offset, 1,
3968         "IOS Point Revision Level: %u",
3969         point);
3970
3971     curr_offset++;
3972
3973     sprintf(add_string, " - (IOS %u.%u.%u)", major, minor, point);
3974
3975     if (len > 3)
3976     {
3977         proto_tree_add_text(tree, tvb, curr_offset, len - 3,
3978             "Manufacturer/Carrier Software Information");
3979
3980         curr_offset += len - 3;
3981     }
3982
3983     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
3984
3985     return(curr_offset - offset);
3986 }
3987 /*
3988  * IOS 6.2.2.66
3989  */
3990 static guint8
3991 elem_so(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
3992 {
3993     guint16     value;
3994     guint32     curr_offset;
3995     gchar       *str;
3996
3997     len = len;
3998     curr_offset = offset;
3999
4000     value = tvb_get_ntohs(tvb, curr_offset);
4001
4002     other_decode_bitfield_value(a_bigbuf, value, 0x8000, 16);
4003     proto_tree_add_text(tree,
4004         tvb, curr_offset, 2,
4005         "%s :  Proprietary Indicator",
4006         a_bigbuf);
4007
4008     other_decode_bitfield_value(a_bigbuf, value, 0x7000, 16);
4009     proto_tree_add_text(tree,
4010         tvb, curr_offset, 2,
4011         "%s :  Service Option Revision",
4012         a_bigbuf);
4013
4014     other_decode_bitfield_value(a_bigbuf, value, 0x0fff, 16);
4015     proto_tree_add_text(tree,
4016         tvb, curr_offset, 2,
4017         "%s :  Base Service Option Number",
4018         a_bigbuf);
4019
4020     switch (value)
4021     {
4022     case 1: str = "Basic Variable Rate Voice Service (8 kbps)"; break;
4023     case 2: str = "Mobile Station Loopback (8 kbps)"; break;
4024     case 3: str = "Enhanced Variable Rate Voice Service (8 kbps)"; break;
4025     case 4: str = "Asynchronous Data Service (9.6 kbps)"; break;
4026     case 5: str = "Group 3 Facsimile (9.6 kbps)"; break;
4027     case 6: str = "Short Message Services (Rate Set 1)"; break;
4028     case 7: str = "Packet Data Service: Internet or ISO Protocol Stack (9.6 kbps)"; break;
4029     case 8: str = "Packet Data Service: CDPD Protocol Stack (9.6 kbps)"; break;
4030     case 9: str = "Mobile Station Loopback (13 kbps)"; break;
4031     case 10: str = "STU-III Transparent Service"; break;
4032     case 11: str = "STU-III Non-Transparent Service"; break;
4033     case 12: str = "Asynchronous Data Service (14.4 or 9.6 kbps)"; break;
4034     case 13: str = "Group 3 Facsimile (14.4 or 9.6 kbps)"; break;
4035     case 14: str = "Short Message Services (Rate Set 2)"; break;
4036     case 15: str = "Packet Data Service: Internet or ISO Protocol Stack (14.4 kbps)"; break;
4037     case 16: str = "Packet Data Service: CDPD Protocol Stack (14.4 kbps)"; break;
4038     case 17: str = "High Rate Voice Service (13 kbps)"; break;
4039     case 32768: str = "QCELP (13 kbps)"; break;
4040     case 32798: /* 0x801e */ str = "Qualcomm Loopback"; break;
4041     case 32799: /* 0x801f */ str = "Qualcomm Markov 8 kbps Loopback"; break;
4042     case 32800: /* 0x8020 */ str = "Qualcomm Packet Data"; break;
4043     case 32801: /* 0x8021 */ str = "Qualcomm Async Data"; break;
4044     case 18: str = "Over-the-Air Parameter Administration (Rate Set 1)"; break;
4045     case 19: str = "Over-the-Air Parameter Administration (Rate Set 2)"; break;
4046     case 20: str = "Group 3 Analog Facsimile (Rate Set 1)"; break;
4047     case 21: str = "Group 3 Analog Facsimile (Rate Set 2)"; break;
4048     case 22: str = "High Speed Packet Data Service: Internet or ISO Protocol Stack (RS1 forward, RS1 reverse)"; break;
4049     case 23: str = "High Speed Packet Data Service: Internet or ISO Protocol Stack (RS1 forward, RS2 reverse)"; break;
4050     case 24: str = "High Speed Packet Data Service: Internet or ISO Protocol Stack (RS2 forward, RS1 reverse)"; break;
4051     case 25: str = "High Speed Packet Data Service: Internet or ISO Protocol Stack (RS2 forward, RS2 reverse)"; break;
4052     case 26: str = "High Speed Packet Data Service: CDPD Protocol Stack (RS1 forward, RS1 reverse)"; break;
4053     case 27: str = "High Speed Packet Data Service: CDPD Protocol Stack (RS1 forward, RS2 reverse)"; break;
4054     case 28: str = "High Speed Packet Data Service: CDPD Protocol Stack (RS2 forward, RS1 reverse)"; break;
4055     case 29: str = "High Speed Packet Data Service: CDPD Protocol Stack (RS2 forward, RS2 reverse)"; break;
4056     case 30: str = "Supplemental Channel Loopback Test for Rate Set 1"; break;
4057     case 31: str = "Supplemental Channel Loopback Test for Rate Set 2"; break;
4058     case 32: str = "Test Data Service Option (TDSO)"; break;
4059     case 33: str = "cdma2000 High Speed Packet Data Service, Internet or ISO Protocol Stack"; break;
4060     case 34: str = "cdma2000 High Speed Packet Data Service, CDPD Protocol Stack"; break;
4061     case 35: str = "Location Services, Rate Set 1 (9.6 kbps)"; break;
4062     case 36: str = "Location Services, Rate Set 2 (14.4 kbps)"; break;
4063     case 37: str = "ISDN Interworking Service (64 kbps)"; break;
4064     case 38: str = "GSM Voice"; break;
4065     case 39: str = "GSM Circuit Data"; break;
4066     case 40: str = "GSM Packet Data"; break;
4067     case 41: str = "GSM Short Message Service"; break;
4068     case 42: str = "None Reserved for MC-MAP standard service options"; break;
4069     case 54: str = "Markov Service Option (MSO)"; break;
4070     case 55: str = "Loopback Service Option (LSO)"; break;
4071     case 56: str = "Selectable Mode Vocoder"; break;
4072     case 57: str = "32 kbps Circuit Video Conferencing"; break;
4073     case 58: str = "64 kbps Circuit Video Conferencing"; break;
4074     case 59: str = "HRPD Accounting Records Identifier"; break;
4075     case 60: str = "Link Layer Assisted Robust Header Compression (LLA ROHC) - Header Removal"; break;
4076     case 61: str = "Link Layer Assisted Robust Header Compression (LLA ROHC) - Header Compression"; break;
4077     case 62: str = "- 4099 None Reserved for standard service options"; break;
4078     case 4100: str = "Asynchronous Data Service, Revision 1 (9.6 or 14.4 kbps)"; break;
4079     case 4101: str = "Group 3 Facsimile, Revision 1 (9.6 or 14.4 kbps)"; break;
4080     case 4102: str = "Reserved for standard service option"; break;
4081     case 4103: str = "Packet Data Service: Internet or ISO Protocol Stack, Revision 1 (9.6 or 14.4 kbps)"; break;
4082     case 4104: str = "Packet Data Service: CDPD Protocol Stack, Revision 1 (9.6 or 14.4 kbps)"; break;
4083     default:
4084         if ((value >= 4105) && (value <= 32767)) { str = "Reserved for standard service options"; }
4085         else if ((value >= 32769) && (value <= 32771)) { str = "Proprietary QUALCOMM Incorporated"; }
4086         else if ((value >= 32772) && (value <= 32775)) { str = "Proprietary OKI Telecom"; }
4087         else if ((value >= 32776) && (value <= 32779)) { str = "Proprietary Lucent Technologies"; }
4088         else if ((value >= 32780) && (value <=32783)) { str = "Nokia"; }
4089         else if ((value >= 32784) && (value <=32787)) { str = "NORTEL NETWORKS"; }
4090         else if ((value >= 32788) && (value <=32791)) { str = "Sony Electronics Inc."; }
4091         else if ((value >= 32792) && (value <=32795)) { str = "Motorola"; }
4092         else if ((value >= 32796) && (value <=32799)) { str = "QUALCOMM Incorporated"; }
4093         else if ((value >= 32800) && (value <=32803)) { str = "QUALCOMM Incorporated"; }
4094         else if ((value >= 32804) && (value <=32807)) { str = "QUALCOMM Incorporated"; }
4095         else if ((value >= 32808) && (value <=32811)) { str = "QUALCOMM Incorporated"; }
4096         else if ((value >= 32812) && (value <=32815)) { str = "Lucent Technologies"; }
4097         else if ((value >= 32816) && (value <=32819)) { str = "Denso International"; }
4098         else if ((value >= 32820) && (value <=32823)) { str = "Motorola"; }
4099         else if ((value >= 32824) && (value <=32827)) { str = "Denso International"; }
4100         else if ((value >= 32828) && (value <=32831)) { str = "Denso International"; }
4101         else if ((value >= 32832) && (value <=32835)) { str = "Denso International"; }
4102         else if ((value >= 32836) && (value <=32839)) { str = "NEC America"; }
4103         else if ((value >= 32840) && (value <=32843)) { str = "Samsung Electronics"; }
4104         else if ((value >= 32844) && (value <=32847)) { str = "Texas Instruments Incorporated"; }
4105         else if ((value >= 32848) && (value <=32851)) { str = "Toshiba Corporation"; }
4106         else if ((value >= 32852) && (value <=32855)) { str = "LG Electronics Inc."; }
4107         else if ((value >= 32856) && (value <=32859)) { str = "VIA Telecom Inc."; }
4108         else { str = "Reserved"; }
4109         break;
4110     }
4111
4112     sprintf(add_string, " - (%u) (0x%04x)", value, value);
4113
4114     proto_tree_add_text(tree,
4115         tvb, curr_offset, 2,
4116         "%s %s",
4117         &add_string[3],
4118         str);
4119
4120     curr_offset += 2;
4121
4122     /* no length check possible */
4123
4124     return(curr_offset - offset);
4125 }
4126
4127 #define ADDS_APP_SMS    0x03
4128 #define ADDS_APP_OTA    0x04
4129 #define ADDS_APP_PLD    0x05
4130
4131 /*
4132  * IOS 6.2.2.67
4133  */
4134 static guint8
4135 elem_adds_user_part(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
4136 {
4137     guint8      oct;
4138     guint8      adds_app;
4139     guint32     curr_offset;
4140     gchar       *str;
4141     tvbuff_t    *adds_tvb;
4142
4143     curr_offset = offset;
4144     adds_app = 0;
4145
4146     oct = tvb_get_guint8(tvb, curr_offset);
4147
4148     other_decode_bitfield_value(a_bigbuf, oct, 0xc0, 8);
4149     proto_tree_add_text(tree,
4150         tvb, curr_offset, 1,
4151         "%s :  Reserved",
4152         a_bigbuf);
4153
4154     adds_app = oct & 0x3f;
4155
4156     switch (adds_app)
4157     {
4158     case ADDS_APP_SMS:
4159         str = "SMS";
4160
4161         adds_tvb = tvb_new_subset(tvb, curr_offset + 1, len - 1, len - 1);
4162
4163         dissector_try_port(is637_dissector_table,
4164             0, adds_tvb, g_pinfo, g_tree);
4165         break;
4166
4167     case ADDS_APP_OTA:
4168         str = "OTA";
4169
4170         adds_tvb = tvb_new_subset(tvb, curr_offset + 1, len - 1, len - 1);
4171
4172         dissector_try_port(is683_dissector_table,
4173             (g_pinfo->p2p_dir == P2P_DIR_RECV), adds_tvb, g_pinfo, g_tree);
4174         break;
4175
4176     case ADDS_APP_PLD:
4177         str = "PLD";
4178
4179         adds_tvb = tvb_new_subset(tvb, curr_offset + 1, len - 1, len - 1);
4180
4181         dissector_try_port(is801_dissector_table,
4182             (g_pinfo->p2p_dir == P2P_DIR_RECV), adds_tvb, g_pinfo, g_tree);
4183         break;
4184
4185     default:
4186         str = "Unknown";
4187         break;
4188     }
4189
4190     other_decode_bitfield_value(a_bigbuf, oct, 0x3f, 8);
4191     proto_tree_add_text(tree,
4192         tvb, curr_offset, 1,
4193         "%s :  Data Burst Type: %s",
4194         a_bigbuf,
4195         str);
4196
4197     curr_offset++;
4198
4199     proto_tree_add_text(tree, tvb, curr_offset, len - 1,
4200         "Application Data Message");
4201
4202     sprintf(add_string, " - (%s)", str);
4203
4204     curr_offset += (len - 1);
4205
4206     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
4207
4208     return(curr_offset - offset);
4209 }
4210
4211 /*
4212  * IOS 6.2.2.68
4213  */
4214 static guint8
4215 elem_is2000_scr(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
4216 {
4217     guint8      oct;
4218     guint32     curr_offset;
4219
4220     add_string = add_string;
4221     curr_offset = offset;
4222
4223     oct = tvb_get_guint8(tvb, curr_offset);
4224
4225     other_decode_bitfield_value(a_bigbuf, oct, 0xf8, 8);
4226     proto_tree_add_text(tree, tvb, curr_offset, 1,
4227         "%s :  Reserved",
4228         a_bigbuf);
4229
4230     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
4231     proto_tree_add_text(tree, tvb, curr_offset, 1,
4232         "%s :  Bit-Exact Length Fill Bits: %u",
4233         a_bigbuf,
4234         oct & 0x07);
4235
4236     curr_offset++;
4237
4238     NO_MORE_DATA_CHECK(len);
4239
4240     proto_tree_add_text(tree, tvb, curr_offset,
4241         len - (curr_offset - offset),
4242         "IS-2000 Service Configuration Record Content");
4243
4244     curr_offset += len - (curr_offset - offset);
4245
4246     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
4247
4248     return(curr_offset - offset);
4249 }
4250
4251 /*
4252  * IOS 6.2.2.69
4253  */
4254 static guint8
4255 elem_is2000_nn_scr(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
4256 {
4257     guint8      oct;
4258     guint8      oct_len;
4259     guint32     curr_offset;
4260
4261     add_string = add_string;
4262     curr_offset = offset;
4263
4264     oct_len = tvb_get_guint8(tvb, curr_offset);
4265
4266     proto_tree_add_text(tree,
4267         tvb, curr_offset, 1,
4268         "Bit-Exact Length Octet Count: %u",
4269         oct_len);
4270
4271     curr_offset++;
4272
4273     NO_MORE_DATA_CHECK(len);
4274
4275     oct = tvb_get_guint8(tvb, curr_offset);
4276
4277     other_decode_bitfield_value(a_bigbuf, oct, 0xf8, 8);
4278     proto_tree_add_text(tree, tvb, curr_offset, 1,
4279         "%s :  Reserved",
4280         a_bigbuf);
4281
4282     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
4283     proto_tree_add_text(tree, tvb, curr_offset, 1,
4284         "%s :  Bit-Exact Length Fill Bits: %u",
4285         a_bigbuf,
4286         oct & 0x07);
4287
4288     curr_offset++;
4289
4290     NO_MORE_DATA_CHECK(len);
4291
4292     if (oct_len > 0)
4293     {
4294         SHORT_DATA_CHECK(len - (curr_offset - offset), oct_len);
4295
4296         proto_tree_add_text(tree, tvb, curr_offset, oct_len,
4297             "IS-2000 Non-Negotiable Service Configuration Record Content");
4298
4299         curr_offset += oct_len;
4300     }
4301
4302     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
4303
4304     return(curr_offset - offset);
4305 }
4306
4307 /*
4308  * IOS 6.2.2.70
4309  */
4310 static guint8
4311 elem_is2000_mob_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
4312 {
4313     guint8      oct;
4314     guint8      oct_len;
4315     guint32     curr_offset;
4316     gchar       *str;
4317
4318     add_string = add_string;
4319     curr_offset = offset;
4320
4321     oct = tvb_get_guint8(tvb, curr_offset);
4322
4323     other_decode_bitfield_value(a_bigbuf, oct, 0xe0, 8);
4324     proto_tree_add_text(tree, tvb, curr_offset, 1,
4325         "%s :  Reserved",
4326         a_bigbuf);
4327
4328     other_decode_bitfield_value(a_bigbuf, oct, 0x10, 8);
4329     proto_tree_add_text(tree, tvb, curr_offset, 1,
4330         "%s :  DCCH Supported: IS-2000 DCCH %ssupported",
4331         a_bigbuf,
4332         (oct & 0x10) ? "" : "not ");
4333
4334     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
4335     proto_tree_add_text(tree, tvb, curr_offset, 1,
4336         "%s :  FCH Supported: IS-2000 FCH %ssupported",
4337         a_bigbuf,
4338         (oct & 0x08) ? "" : "not ");
4339
4340     other_decode_bitfield_value(a_bigbuf, oct, 0x04, 8);
4341     proto_tree_add_text(tree, tvb, curr_offset, 1,
4342         "%s :  OTD Supported: Orthogonal Transmit Diversity %ssupported",
4343         a_bigbuf,
4344         (oct & 0x04) ? "" : "not ");
4345
4346     other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
4347     proto_tree_add_text(tree, tvb, curr_offset, 1,
4348         "%s :  Enhanced RC CFG Supported: Radio configuration in radio class 2 %ssupported",
4349         a_bigbuf,
4350         (oct & 0x02) ? "" : "not ");
4351
4352     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
4353     proto_tree_add_text(tree, tvb, curr_offset, 1,
4354         "%s :  QPCH Supported: Quick Paging Channel %ssupported",
4355         a_bigbuf,
4356         (oct & 0x01) ? "" : "not ");
4357
4358     curr_offset++;
4359
4360     NO_MORE_DATA_CHECK(len);
4361
4362     oct_len = tvb_get_guint8(tvb, curr_offset);
4363
4364     proto_tree_add_text(tree,
4365         tvb, curr_offset, 1,
4366         "FCH Information: Bit-Exact Length Octet Count: %u",
4367         oct_len);
4368
4369     curr_offset++;
4370
4371     NO_MORE_DATA_CHECK(len);
4372
4373     oct = tvb_get_guint8(tvb, curr_offset);
4374
4375     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
4376     proto_tree_add_text(tree, tvb, curr_offset, 1,
4377         "%s :  Reserved",
4378         a_bigbuf);
4379
4380     switch ((oct & 0x70) >> 4)
4381     {
4382     case 0: str = "No mobile assisted geo-location capabilities"; break;
4383     case 1: str = "IS801 capable (Advanced Forward Link Triangulation only (AFLT))"; break;
4384     case 2: str = "IS801 capable (Advanced Forward Link Triangulation and Global Positioning Systems"; break;
4385     case 3: str = "Global Positioning Systems Only"; break;
4386     default:
4387         str = "All Other values reserved";
4388         break;
4389     }
4390
4391     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
4392     proto_tree_add_text(tree, tvb, curr_offset, 1,
4393         "%s :  Geo Location Type: %s",
4394         a_bigbuf,
4395         str);
4396
4397     other_decode_bitfield_value(a_bigbuf, oct, 0x08, 8);
4398     proto_tree_add_text(tree, tvb, curr_offset, 1,
4399         "%s :  Geo Location Included",
4400         a_bigbuf);
4401
4402     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
4403     proto_tree_add_text(tree, tvb, curr_offset, 1,
4404         "%s :  FCH Information: Bit-Exact Length Fill Bits: %u",
4405         a_bigbuf,
4406         oct & 0x07);
4407
4408     curr_offset++;
4409
4410     NO_MORE_DATA_CHECK(len);
4411
4412     if (oct_len > 0)
4413     {
4414         SHORT_DATA_CHECK(len - (curr_offset - offset), oct_len);
4415
4416         proto_tree_add_text(tree, tvb, curr_offset, oct_len,
4417             "FCH Information Content");
4418
4419         curr_offset += oct_len;
4420
4421         NO_MORE_DATA_CHECK(len);
4422     }
4423
4424     oct_len = tvb_get_guint8(tvb, curr_offset);
4425
4426     proto_tree_add_text(tree,
4427         tvb, curr_offset, 1,
4428         "DCCH Information: Bit-Exact Length Octet Count: %u",
4429         oct_len);
4430
4431     curr_offset++;
4432
4433     NO_MORE_DATA_CHECK(len);
4434
4435     oct = tvb_get_guint8(tvb, curr_offset);
4436
4437     other_decode_bitfield_value(a_bigbuf, oct, 0xf8, 8);
4438     proto_tree_add_text(tree, tvb, curr_offset, 1,
4439         "%s :  Reserved",
4440         a_bigbuf);
4441
4442     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
4443     proto_tree_add_text(tree, tvb, curr_offset, 1,
4444         "%s :  DCCH Information: Bit-Exact Length Fill Bits: %u",
4445         a_bigbuf,
4446         oct & 0x07);
4447
4448     curr_offset++;
4449
4450     NO_MORE_DATA_CHECK(len);
4451
4452     if (oct_len > 0)
4453     {
4454         SHORT_DATA_CHECK(len - (curr_offset - offset), oct_len);
4455
4456         proto_tree_add_text(tree, tvb, curr_offset, oct_len,
4457             "DCCH Information Content");
4458
4459         curr_offset += oct_len;
4460     }
4461
4462     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
4463
4464     return(curr_offset - offset);
4465 }
4466
4467 /*
4468  * IOS 6.2.2.71
4469  */
4470 static guint8
4471 elem_ptype(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
4472 {
4473     guint32     value;
4474     guint32     curr_offset;
4475     gchar       *str;
4476
4477     curr_offset = offset;
4478
4479     value = tvb_get_ntohs(tvb, curr_offset);
4480
4481     switch (value)
4482     {
4483     case 0x880b: str = "PPP"; break;
4484     case 0x8881: str = "Unstructured Byte Stream"; break;
4485     default:
4486         str = "Unknown";
4487         break;
4488     }
4489
4490     proto_tree_add_text(tree,
4491         tvb, curr_offset, 2,
4492         "(%u) %s",
4493         value,
4494         str);
4495
4496     sprintf(add_string, " - (%s)", str);
4497
4498     curr_offset += 2;
4499
4500     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
4501
4502     return(curr_offset - offset);
4503 }
4504
4505 /*
4506  * IOS 6.2.2.72
4507  */
4508 static guint8
4509 elem_ms_info_recs(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
4510 {
4511     guint8      oct;
4512     guint8      oct_len;
4513     guint8      rec_type;
4514     guint8      num_recs;
4515     guint32     value;
4516     guint32     curr_offset;
4517     gchar       *str;
4518     gint        ett_elem_idx, idx, i;
4519     proto_tree  *subtree;
4520     proto_item  *item;
4521
4522     curr_offset = offset;
4523
4524     num_recs = 0;
4525
4526     while ((len - (curr_offset - offset)) >= 2)
4527     {
4528         num_recs++;
4529
4530         rec_type = tvb_get_guint8(tvb, curr_offset);
4531
4532         str = my_match_strval((guint32) rec_type, ansi_ms_info_rec_str, &idx);
4533
4534         if (str == NULL)
4535         {
4536             str = "Reserved";
4537             ett_elem_idx = ett_ansi_ms_info_rec_reserved;
4538         }
4539         else
4540         {
4541             ett_elem_idx = ett_ansi_ms_info_rec[idx];
4542         }
4543
4544         item =
4545             proto_tree_add_text(tree,
4546                 tvb, curr_offset, 1,
4547                 "Information Record Type - %u: (%u) %s",
4548                 num_recs,
4549                 rec_type,
4550                 str);
4551
4552         subtree = proto_item_add_subtree(item, ett_elem_idx);
4553
4554         curr_offset++;
4555
4556         oct_len = tvb_get_guint8(tvb, curr_offset);
4557
4558         proto_tree_add_uint(subtree, hf_ansi_a_length, tvb,
4559             curr_offset, 1, oct_len);
4560
4561         curr_offset++;
4562
4563         if (oct_len > 0)
4564         {
4565             SHORT_DATA_CHECK(len - (curr_offset - offset), oct_len);
4566
4567             switch (rec_type)
4568             {
4569             case ANSI_MS_INFO_REC_CLD_PN:
4570                 oct = tvb_get_guint8(tvb, curr_offset);
4571
4572                 switch ((oct & 0xe0) >> 5)
4573                 {
4574                 case 0: str = "Unknown"; break;
4575                 case 1: str = "International number"; break;
4576                 case 2: str = "National number"; break;
4577                 case 3: str = "Network-specific number"; break;
4578                 case 4: str = "Subscriber number"; break;
4579                 case 5: str = "Reserved"; break;
4580                 case 6: str = "Abbreviated number"; break;
4581                 default:
4582                     str = "Reserved for extension";
4583                     break;
4584                 }
4585
4586                 other_decode_bitfield_value(a_bigbuf, oct, 0xe0, 8);
4587                 proto_tree_add_text(subtree, tvb, curr_offset, 1,
4588                     "%s :  Number Type: %s",
4589                     a_bigbuf,
4590                     str);
4591
4592                 switch ((oct & 0x1e) >> 1)
4593                 {
4594                 case 0x00: str = "Unknown"; break;
4595                 case 0x01: str = "ISDN/Telephony Numbering"; break;
4596                 case 0x03: str = "Data Numbering (ITU-T Rec. X.121)"; break;
4597                 case 0x04: str = "Telex Numbering (ITU-T Rec. F.69)"; break;
4598                 case 0x09: str = "Private Numbering"; break;
4599                 case 0x0f: str = "Reserved for extension"; break;
4600                 default:
4601                     str = "Reserved";
4602                     break;
4603                 }
4604
4605                 other_decode_bitfield_value(a_bigbuf, oct, 0x1e, 8);
4606                 proto_tree_add_text(subtree, tvb, curr_offset, 1,
4607                     "%s :  Number Plan: %s",
4608                     a_bigbuf,
4609                     str);
4610
4611                 if (oct_len > 1)
4612                 {
4613                     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
4614                     proto_tree_add_text(subtree, tvb, curr_offset, 1,
4615                         "%s :  MSB of first digit",
4616                         a_bigbuf);
4617
4618                     curr_offset++;
4619
4620                     for (i=0; i < (oct_len - 1); i++)
4621                     {
4622                         a_bigbuf[i] = (oct & 0x01) << 7;
4623
4624                         oct = tvb_get_guint8(tvb, curr_offset + i);
4625
4626                         a_bigbuf[i] |= (oct & 0xfe) >> 1;
4627                     }
4628                     a_bigbuf[i] = '\0';
4629
4630                     proto_tree_add_text(subtree, tvb, curr_offset, oct_len - 1,
4631                         "Digits: %s",
4632                         a_bigbuf);
4633
4634                     curr_offset += (oct_len - 2);
4635                 }
4636
4637                 other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
4638                 proto_tree_add_text(subtree, tvb, curr_offset, 1,
4639                     "%s :  Reserved",
4640                     a_bigbuf);
4641
4642                 curr_offset++;
4643                 break;
4644
4645             case ANSI_MS_INFO_REC_CLG_PN:
4646                 value = tvb_get_ntohs(tvb, curr_offset);
4647
4648                 oct = (value & 0xff00) >> 8;
4649
4650                 switch ((oct & 0xe0) >> 5)
4651                 {
4652                 case 0: str = "Unknown"; break;
4653                 case 1: str = "International number"; break;
4654                 case 2: str = "National number"; break;
4655                 case 3: str = "Network-specific number"; break;
4656                 case 4: str = "Subscriber number"; break;
4657                 case 5: str = "Reserved"; break;
4658                 case 6: str = "Abbreviated number"; break;
4659                 default:
4660                     str = "Reserved for extension";
4661                     break;
4662                 }
4663
4664                 other_decode_bitfield_value(a_bigbuf, value, 0xe000, 16);
4665                 proto_tree_add_text(subtree, tvb, curr_offset, 2,
4666                     "%s :  Number Type: %s",
4667                     a_bigbuf,
4668                     str);
4669
4670                 switch ((oct & 0x1e) >> 1)
4671                 {
4672                 case 0x00: str = "Unknown"; break;
4673                 case 0x01: str = "ISDN/Telephony Numbering"; break;
4674                 case 0x03: str = "Data Numbering (ITU-T Rec. X.121)"; break;
4675                 case 0x04: str = "Telex Numbering (ITU-T Rec. F.69)"; break;
4676                 case 0x09: str = "Private Numbering"; break;
4677                 case 0x0f: str = "Reserved for extension"; break;
4678                 default:
4679                     str = "Reserved";
4680                     break;
4681                 }
4682
4683                 other_decode_bitfield_value(a_bigbuf, value, 0x1e00, 16);
4684                 proto_tree_add_text(subtree, tvb, curr_offset, 2,
4685                     "%s :  Number Plan: %s",
4686                     a_bigbuf,
4687                     str);
4688
4689                 switch ((value & 0x0180) >> 7)
4690                 {
4691                 case 0: str = "Presentation allowed"; break;
4692                 case 1: str = "Presentation restricted"; break;
4693                 case 2: str = "Number not available"; break;
4694                 default:
4695                     str = "Reserved";
4696                     break;
4697                 }
4698
4699                 other_decode_bitfield_value(a_bigbuf, value, 0x0180, 16);
4700                 proto_tree_add_text(subtree, tvb, curr_offset, 2,
4701                     "%s :  Presentation Indicator (PI): %s",
4702                     a_bigbuf,
4703                     str);
4704
4705                 switch ((value & 0x0060) >> 5)
4706                 {
4707                 case 0: str = "User-provided, not screened"; break;
4708                 case 1: str = "User-provided, verified and passed"; break;
4709                 case 2: str = "User-provided, verified and failed"; break;
4710                 default:
4711                     str = "Network-provided";
4712                     break;
4713                 }
4714
4715                 other_decode_bitfield_value(a_bigbuf, value, 0x0060, 16);
4716                 proto_tree_add_text(subtree, tvb, curr_offset, 2,
4717                     "%s :  Screening Indicator (SI): %s",
4718                     a_bigbuf,
4719                     str);
4720
4721                 if (oct_len > 2)
4722                 {
4723                     oct = (value & 0x00ff);
4724
4725                     other_decode_bitfield_value(a_bigbuf, value, 0x001f, 16);
4726                     proto_tree_add_text(subtree, tvb, curr_offset, 2,
4727                         "%s :  MSB of first digit",
4728                         a_bigbuf);
4729
4730                     curr_offset += 2;
4731
4732                     for (i=0; i < (oct_len - 2); i++)
4733                     {
4734                         a_bigbuf[i] = (oct & 0x1f) << 3;
4735
4736                         oct = tvb_get_guint8(tvb, curr_offset + i);
4737
4738                         a_bigbuf[i] |= (oct & 0xe0) >> 5;
4739                     }
4740                     a_bigbuf[i] = '\0';
4741
4742                     proto_tree_add_text(subtree, tvb, curr_offset, oct_len - 2,
4743                         "Digits: %s",
4744                         a_bigbuf);
4745
4746                     curr_offset += (oct_len - 3);
4747
4748                     other_decode_bitfield_value(a_bigbuf, oct, 0x1f, 8);
4749                     proto_tree_add_text(subtree, tvb, curr_offset, 1,
4750                         "%s :  Reserved",
4751                         a_bigbuf);
4752
4753                     curr_offset++;
4754                 }
4755                 else
4756                 {
4757                     other_decode_bitfield_value(a_bigbuf, value, 0x001f, 16);
4758                     proto_tree_add_text(subtree, tvb, curr_offset, 2,
4759                         "%s :  Reserved",
4760                         a_bigbuf);
4761
4762                     curr_offset += 2;
4763                 }
4764                 break;
4765
4766             case ANSI_MS_INFO_REC_MW:
4767                 oct = tvb_get_guint8(tvb, curr_offset);
4768
4769                 proto_tree_add_text(subtree, tvb, curr_offset, 1,
4770                     "Number of messages waiting: %u",
4771                     oct);
4772
4773                 curr_offset++;
4774                 break;
4775
4776             default:
4777                 proto_tree_add_text(subtree,
4778                     tvb, curr_offset, oct_len,
4779                     "Record Content");
4780
4781                 curr_offset += oct_len;
4782                 break;
4783             }
4784         }
4785     }
4786
4787     sprintf(add_string, " - %u record%s",
4788         num_recs, plurality(num_recs, "", "s"));
4789
4790     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
4791
4792     return(curr_offset - offset);
4793 }
4794
4795 /*
4796  * IOS 6.2.2.73
4797  */
4798 static guint8
4799 elem_ext_ho_dir_params(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
4800 {
4801     guint8      oct;
4802     guint32     value;
4803     guint32     curr_offset;
4804
4805     add_string = add_string;
4806     curr_offset = offset;
4807
4808     oct = tvb_get_guint8(tvb, curr_offset);
4809
4810     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
4811     proto_tree_add_text(tree, tvb, curr_offset, 1,
4812         "%s :  Search Window A Size (Srch_Win_A): %u",
4813         a_bigbuf,
4814         (oct & 0xf0) >> 4);
4815
4816     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
4817     proto_tree_add_text(tree, tvb, curr_offset, 1,
4818         "%s :  Search Window N Size (Srch_Win_N): %u",
4819         a_bigbuf,
4820         oct & 0x0f);
4821
4822     curr_offset++;
4823
4824     NO_MORE_DATA_CHECK(len);
4825
4826     oct = tvb_get_guint8(tvb, curr_offset);
4827
4828     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
4829     proto_tree_add_text(tree, tvb, curr_offset, 1,
4830         "%s :  Search Window R Size (Srch_Win_R): %u",
4831         a_bigbuf,
4832         (oct & 0xf0) >> 4);
4833
4834     value = tvb_get_guint8(tvb, curr_offset + 1);
4835
4836     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
4837     proto_tree_add_text(tree, tvb, curr_offset, 1,
4838         "%s :  Add Pilot Threshold (T_Add) (MSB): %u",
4839         a_bigbuf,
4840         (oct & 0x0f) << 2 | (value & 0xc0) >> 6);
4841
4842     curr_offset++;
4843
4844     oct = value;
4845
4846     other_decode_bitfield_value(a_bigbuf, oct, 0xc0, 8);
4847     proto_tree_add_text(tree, tvb, curr_offset, 1,
4848         "%s :  Add Pilot Threshold (T_Add) (LSB)",
4849         a_bigbuf);
4850
4851     other_decode_bitfield_value(a_bigbuf, oct, 0x3f, 8);
4852     proto_tree_add_text(tree, tvb, curr_offset, 1,
4853         "%s :  Drop Pilot Threshold (T_Drop): %u",
4854         a_bigbuf,
4855         oct & 0x3f);
4856
4857     curr_offset++;
4858
4859     NO_MORE_DATA_CHECK(len);
4860
4861     oct = tvb_get_guint8(tvb, curr_offset);
4862
4863     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
4864     proto_tree_add_text(tree, tvb, curr_offset, 1,
4865         "%s :  Compare Threshold (T_Comp): %u",
4866         a_bigbuf,
4867         (oct & 0xf0) >> 4);
4868
4869     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
4870     proto_tree_add_text(tree, tvb, curr_offset, 1,
4871         "%s :  Drop Timer Value (T_TDrop): %u",
4872         a_bigbuf,
4873         oct & 0x0f);
4874
4875     curr_offset++;
4876
4877     NO_MORE_DATA_CHECK(len);
4878
4879     oct = tvb_get_guint8(tvb, curr_offset);
4880
4881     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
4882     proto_tree_add_text(tree, tvb, curr_offset, 1,
4883         "%s :  Neighbor Max Age (Nghbor_Max_AGE): %u",
4884         a_bigbuf,
4885         (oct & 0xf0) >> 4);
4886
4887     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
4888     proto_tree_add_text(tree, tvb, curr_offset, 1,
4889         "%s :  Reserved",
4890         a_bigbuf);
4891
4892     curr_offset++;
4893
4894     NO_MORE_DATA_CHECK(len);
4895
4896     oct = tvb_get_guint8(tvb, curr_offset);
4897
4898     other_decode_bitfield_value(a_bigbuf, oct, 0xc0, 8);
4899     proto_tree_add_text(tree, tvb, curr_offset, 1,
4900         "%s :  Reserved",
4901         a_bigbuf);
4902
4903     other_decode_bitfield_value(a_bigbuf, oct, 0x3f, 8);
4904     proto_tree_add_text(tree, tvb, curr_offset, 1,
4905         "%s :  SOFT_SLOPE: %u",
4906         a_bigbuf,
4907         oct & 0x3f);
4908
4909     curr_offset++;
4910
4911     NO_MORE_DATA_CHECK(len);
4912
4913     oct = tvb_get_guint8(tvb, curr_offset);
4914
4915     other_decode_bitfield_value(a_bigbuf, oct, 0xc0, 8);
4916     proto_tree_add_text(tree, tvb, curr_offset, 1,
4917         "%s :  Reserved",
4918         a_bigbuf);
4919
4920     other_decode_bitfield_value(a_bigbuf, oct, 0x3f, 8);
4921     proto_tree_add_text(tree, tvb, curr_offset, 1,
4922         "%s :  ADD_INTERCEPT: %u",
4923         a_bigbuf,
4924         oct & 0x3f);
4925
4926     curr_offset++;
4927
4928     NO_MORE_DATA_CHECK(len);
4929
4930     oct = tvb_get_guint8(tvb, curr_offset);
4931
4932     other_decode_bitfield_value(a_bigbuf, oct, 0xc0, 8);
4933     proto_tree_add_text(tree, tvb, curr_offset, 1,
4934         "%s :  Reserved",
4935         a_bigbuf);
4936
4937     other_decode_bitfield_value(a_bigbuf, oct, 0x3f, 8);
4938     proto_tree_add_text(tree, tvb, curr_offset, 1,
4939         "%s :  DROP_INTERCEPT: %u",
4940         a_bigbuf,
4941         oct & 0x3f);
4942
4943     curr_offset++;
4944
4945     NO_MORE_DATA_CHECK(len);
4946
4947     oct = tvb_get_guint8(tvb, curr_offset);
4948
4949     proto_tree_add_text(tree, tvb, curr_offset, 1,
4950         "Target BS P_REV: %u",
4951         oct);
4952
4953     curr_offset++;
4954
4955     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
4956
4957     return(curr_offset - offset);
4958 }
4959
4960 /*
4961  * IOS 6.2.2.74
4962  * UNUSED in SPEC and no IEI!
4963  */
4964
4965 /*
4966  * IOS 6.2.2.75
4967  * UNUSED in SPEC and no IEI!
4968  */
4969
4970 /*
4971  * IOS 6.2.2.76
4972  * UNUSED
4973  */
4974
4975 /*
4976  * IOS 6.2.2.77
4977  * UNUSED in SPEC and no IEI!
4978  */
4979
4980 /*
4981  * IOS 6.2.2.78
4982  * UNUSED in SPEC and no IEI!
4983  */
4984
4985 /*
4986  * IOS 6.2.2.79
4987  */
4988 static guint8
4989 elem_cdma_sowd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
4990 {
4991     guint8      oct;
4992     guint32     value;
4993     guint32     curr_offset;
4994     gchar       *str = NULL;
4995
4996     curr_offset = offset;
4997
4998     curr_offset += elem_cell_id(tvb, tree, offset, len, add_string);
4999     add_string[0] = '\0';
5000
5001     value = tvb_get_ntohs(tvb, curr_offset);
5002
5003     proto_tree_add_text(tree,
5004         tvb, curr_offset, 2,
5005         "CDMA Serving One Way Delay: %u",
5006         value);
5007
5008     curr_offset += 2;
5009
5010     oct = tvb_get_guint8(tvb, curr_offset);
5011
5012     other_decode_bitfield_value(a_bigbuf, oct, 0xfc, 8);
5013     proto_tree_add_text(tree,
5014         tvb, curr_offset, 1,
5015         "%s :  Reserved",
5016         a_bigbuf);
5017
5018     switch (oct & 0x03)
5019     {
5020     case 0: str = "100 nsec"; break;
5021     case 1: str = "50 nsec"; break;
5022     case 2: str = "1/16 CDMA PN Chip"; break;
5023     case 3: str = "Reserved"; break;
5024     }
5025
5026     other_decode_bitfield_value(a_bigbuf, oct, 0x03, 8);
5027     proto_tree_add_text(tree,
5028         tvb, curr_offset, 1,
5029         "%s :  Resolution: %s",
5030         a_bigbuf,
5031         str);
5032
5033     curr_offset++;
5034
5035     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5036
5037     return(curr_offset - offset);
5038 }
5039
5040 /*
5041  * IOS 6.2.2.80
5042  * UNUSED
5043  */
5044
5045 /*
5046  * IOS 6.2.2.81
5047  * UNUSED
5048  */
5049
5050 /*
5051  * IOS 6.2.2.82
5052  */
5053 static guint8
5054 elem_re_res(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
5055 {
5056     guint8      oct;
5057     guint32     curr_offset;
5058     gchar       *str;
5059
5060     len = len;
5061     add_string = add_string;
5062     curr_offset = offset;
5063
5064     oct = tvb_get_guint8(tvb, curr_offset);
5065
5066     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
5067     proto_tree_add_text(tree,
5068         tvb, curr_offset, 1,
5069         "%s :  Reserved",
5070         a_bigbuf);
5071
5072     other_decode_bitfield_value(a_bigbuf, oct, 0x40, 8);
5073     proto_tree_add_text(tree,
5074         tvb, curr_offset, 1,
5075         "%s :  Include Priority: MSC %s include priority in Assignment Request",
5076         a_bigbuf,
5077         (oct & 0x40) ? "should" : "does not need to");
5078
5079     switch ((oct & 0x30) >> 4)
5080     {
5081     case 0: str = "Not reported"; break;
5082     case 1: str = "radio environment is acceptable"; break;
5083     case 2: str = "radio environment is marginally acceptable"; break;
5084     default:
5085         str = "radio environment is poor";
5086         break;
5087     }
5088
5089     other_decode_bitfield_value(a_bigbuf, oct, 0x30, 8);
5090     proto_tree_add_text(tree,
5091         tvb, curr_offset, 1,
5092         "%s :  Forward: %s",
5093         a_bigbuf,
5094         str);
5095
5096     switch ((oct & 0x0c) >> 2)
5097     {
5098     case 0: str = "Not reported"; break;
5099     case 1: str = "radio environment is acceptable"; break;
5100     case 2: str = "radio environment is marginally acceptable"; break;
5101     default:
5102         str = "radio environment is poor";
5103         break;
5104     }
5105
5106     other_decode_bitfield_value(a_bigbuf, oct, 0x0c, 8);
5107     proto_tree_add_text(tree,
5108         tvb, curr_offset, 1,
5109         "%s :  Reverse: %s",
5110         a_bigbuf,
5111         str);
5112
5113     other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
5114     proto_tree_add_text(tree,
5115         tvb, curr_offset, 1,
5116         "%s :  Alloc: resources are %sallocated",
5117         a_bigbuf,
5118         (oct & 0x02) ? "" : "not ");
5119
5120     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
5121     proto_tree_add_text(tree,
5122         tvb, curr_offset, 1,
5123         "%s :  Avail: resources are %savailable",
5124         a_bigbuf,
5125         (oct & 0x01) ? "" : "not ");
5126
5127     curr_offset++;
5128
5129     /* no length check possible */
5130
5131     return(curr_offset - offset);
5132 }
5133
5134 /*
5135  * IOS 6.2.2.83
5136  * UNUSED in SPEC and no IEI!
5137  */
5138
5139 /*
5140  * IOS 6.2.2.84
5141  * UNUSED
5142  */
5143
5144 /*
5145  * IOS 6.2.2.85
5146  * UNUSED
5147  */
5148
5149 /*
5150  * IOS 6.2.2.86
5151  * UNUSED
5152  */
5153
5154 /*
5155  * IOS 6.2.2.87
5156  * UNUSED
5157  */
5158
5159 /*
5160  * IOS 6.2.2.88
5161  * UNUSED
5162  */
5163
5164 /*
5165  * IOS 6.2.2.89
5166  * A3/A7
5167  */
5168
5169 /*
5170  * IOS 6.2.2.90
5171  * UNUSED in SPEC and no IEI!
5172  */
5173
5174 /*
5175  * IOS 6.2.2.91
5176  * A3/A7
5177  */
5178
5179 /*
5180  * IOS 6.2.2.92
5181  * UNUSED
5182  */
5183
5184 /*
5185  * IOS 6.2.2.93
5186  * UNUSED
5187  */
5188
5189 /*
5190  * IOS 6.2.2.94
5191  * UNUSED
5192  */
5193
5194 /*
5195  * IOS 6.2.2.95
5196  * UNUSED
5197  */
5198
5199 /*
5200  * IOS 6.2.2.96
5201  * A3/A7
5202  */
5203
5204 /*
5205  * IOS 6.2.2.97
5206  * A3/A7
5207  */
5208
5209 /*
5210  * IOS 6.2.2.98
5211  * A3/A7
5212  */
5213
5214 /*
5215  * IOS 6.2.2.99
5216  * A3/A7
5217  */
5218
5219 /*
5220  * IOS 6.2.2.100
5221  * UNUSED
5222  */
5223
5224 /*
5225  * IOS 6.2.2.101
5226  * UNUSED
5227  */
5228
5229 /*
5230  * IOS 6.2.2.102
5231  * UNUSED
5232  */
5233
5234 /*
5235  * IOS 6.2.2.103
5236  * UNUSED
5237  */
5238
5239 /*
5240  * IOS 6.2.2.104
5241  * UNUSED
5242  */
5243
5244 /*
5245  * IOS 6.2.2.105
5246  */
5247 static guint8
5248 elem_cld_party_ascii_num(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
5249 {
5250     guint8      oct;
5251     guint32     curr_offset;
5252     guint8      *poctets;
5253     gchar       *str;
5254
5255     curr_offset = offset;
5256
5257     oct = tvb_get_guint8(tvb, curr_offset);
5258
5259     other_decode_bitfield_value(a_bigbuf, oct, 0x80, 8);
5260     proto_tree_add_text(tree, tvb, curr_offset, 1,
5261         "%s :  Extension",
5262         a_bigbuf);
5263
5264     switch ((oct & 0x70) >> 4)
5265     {
5266     case 0: str = "Unknown"; break;
5267     case 1: str = "International number"; break;
5268     case 2: str = "National number"; break;
5269     case 3: str = "Network specific number"; break;
5270     case 4: str = "Dedicated PAD access, short code"; break;
5271     case 7: str = "Reserved for extension"; break;
5272     default:
5273         str = "Reserved";
5274         break;
5275     }
5276
5277     other_decode_bitfield_value(a_bigbuf, oct, 0x70, 8);
5278     proto_tree_add_text(tree,
5279         tvb, curr_offset, 1,
5280         "%s :  Type of Number: %s",
5281         a_bigbuf,
5282         str);
5283
5284     switch (oct & 0x0f)
5285     {
5286     case 0x00: str = "Unknown"; break;
5287     case 0x01: str = "ISDN/telephony number plan (ITU recommendation E.164/E.163)"; break;
5288     case 0x03: str = "Data number plan (ITU recommendation X.121)"; break;
5289     case 0x04: str = "Telex numbering plan (ITU recommendation F.69)"; break;
5290     case 0x07: str = "Reserved for extension"; break;
5291     case 0x08: str = "National numbering plan"; break;
5292     case 0x09: str = "Private numbering plan"; break;
5293     default:
5294         str = "Reserved";
5295         break;
5296     }
5297
5298     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
5299     proto_tree_add_text(tree,
5300         tvb, curr_offset, 1,
5301         "%s :  Numbering Plan Identification: %s",
5302         a_bigbuf,
5303         str);
5304
5305     curr_offset++;
5306
5307     poctets = tvb_get_string(tvb, curr_offset, len - (curr_offset - offset));
5308
5309     proto_tree_add_string_format(tree, hf_ansi_a_cld_party_ascii_num,
5310         tvb, curr_offset, len - (curr_offset - offset),
5311         "Digits: %s",
5312         poctets);
5313
5314     curr_offset += len - (curr_offset - offset);
5315
5316     sprintf(add_string, " - (%s)", poctets);
5317     g_free(poctets);
5318
5319     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5320
5321     return(curr_offset - offset);
5322 }
5323
5324 /*
5325  * IOS 6.2.2.106
5326  */
5327 static guint8
5328 elem_band_class(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
5329 {
5330     guint8      oct;
5331     guint32     curr_offset;
5332     gint        temp_int;
5333     gchar       *str;
5334
5335     curr_offset = offset;
5336
5337     oct = tvb_get_guint8(tvb, curr_offset);
5338
5339     other_decode_bitfield_value(a_bigbuf, oct, 0xe0, 8);
5340     proto_tree_add_text(tree,
5341         tvb, curr_offset, 1,
5342         "%s :  Reserved",
5343         a_bigbuf);
5344
5345     temp_int = oct & 0x1f;
5346     if ((temp_int < 0) || (temp_int >= (gint) NUM_BAND_CLASS_STR))
5347     {
5348         str = "Reserved";
5349     }
5350     else
5351     {
5352         str = band_class_str[temp_int];
5353     }
5354
5355     other_decode_bitfield_value(a_bigbuf, oct, 0x1f, 8);
5356     proto_tree_add_text(tree,
5357         tvb, curr_offset, 1,
5358         "%s :  Band Class: %s",
5359         a_bigbuf,
5360         str);
5361
5362     curr_offset++;
5363
5364     sprintf(add_string, " - (%s)", str);
5365
5366     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5367
5368     return(curr_offset - offset);
5369 }
5370
5371 /*
5372  * IOS 6.2.2.107
5373  * UNUSED
5374  */
5375
5376 /*
5377  * IOS 6.2.2.108
5378  * A3/A7
5379  */
5380
5381 /*
5382  * IOS 6.2.2.109
5383  * A3/A7
5384  */
5385
5386 /*
5387  * IOS 6.2.2.110
5388  */
5389 static guint8
5390 elem_is2000_cause(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
5391 {
5392     guint32     curr_offset;
5393
5394     add_string = add_string;
5395     curr_offset = offset;
5396
5397     proto_tree_add_text(tree, tvb, curr_offset, len, "IS-95/IS-2000 Cause Information");
5398
5399     curr_offset += len;
5400
5401     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5402
5403     return(curr_offset - offset);
5404 }
5405
5406 /*
5407  * IOS 6.2.2.111
5408  * UNUSED
5409  */
5410
5411 /*
5412  * IOS 6.2.2.112
5413  * UNUSED
5414  */
5415
5416 /*
5417  * IOS 6.2.2.113
5418  * UNUSED
5419  */
5420
5421 /*
5422  * IOS 6.2.2.114
5423  */
5424 static guint8
5425 elem_auth_event(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
5426 {
5427     guint8      oct;
5428     guint32     curr_offset;
5429     gchar       *str;
5430
5431     add_string = add_string;
5432     curr_offset = offset;
5433
5434     if (len == 1)
5435     {
5436         oct = tvb_get_guint8(tvb, curr_offset);
5437
5438         switch (oct)
5439         {
5440         case 0x01: str = "Event: Authentication parameters were NOT received from mobile"; break;
5441         case 0x02: str = "Event: RANDC mis-match"; break;
5442         default:
5443             str = "Event";
5444             break;
5445         }
5446
5447         proto_tree_add_text(tree, tvb, curr_offset, len,
5448             str);
5449     }
5450     else
5451     {
5452         proto_tree_add_text(tree, tvb, curr_offset, len, "Event");
5453     }
5454
5455     curr_offset += len;
5456
5457     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5458
5459     return(curr_offset - offset);
5460 }
5461
5462 /*
5463  * IOS 6.2.2.115
5464  * UNUSED
5465  */
5466
5467 /*
5468  * IOS 6.2.2.116
5469  * UNUSED
5470  */
5471
5472 /*
5473  * IOS 6.2.2.117
5474  * UNUSED
5475  */
5476
5477 /*
5478  * IOS 6.2.2.118
5479  * UNUSED
5480  */
5481
5482 /*
5483  * IOS 6.2.2.119
5484  * A3/A7
5485  */
5486
5487 /*
5488  * IOS 6.2.2.120
5489  * A3/A7
5490  */
5491
5492 /*
5493  * IOS 6.2.2.121
5494  * A3/A7
5495  */
5496
5497 /*
5498  * IOS 6.2.2.122
5499  * UNUSED
5500  */
5501
5502 /*
5503  * IOS 6.2.2.123
5504  * UNUSED
5505  */
5506
5507 /*
5508  * IOS 6.2.2.124
5509  * UNUSED
5510  */
5511
5512 /*
5513  * IOS 6.2.2.125
5514  * A3/A7
5515  */
5516
5517 /*
5518  * IOS 6.2.2.126
5519  * UNUSED
5520  */
5521
5522 /*
5523  * IOS 6.2.2.127
5524  * UNUSED
5525  */
5526
5527 /*
5528  * IOS 6.2.2.128
5529  * A3/A7
5530  */
5531
5532 /*
5533  * IOS 6.2.2.129
5534  * UNUSED
5535  */
5536
5537 /*
5538  * IOS 6.2.2.130
5539  * UNUSED
5540  */
5541
5542 /*
5543  * IOS 6.2.2.131
5544  * UNUSED
5545  */
5546
5547 /*
5548  * IOS 6.2.2.132
5549  * A3/A7
5550  */
5551
5552 /*
5553  * IOS 6.2.2.133
5554  * UNUSED
5555  */
5556
5557 /*
5558  * IOS 6.2.2.134
5559  * A3/A7
5560  */
5561
5562 /*
5563  * IOS 6.2.2.135
5564  * UNUSED
5565  */
5566
5567 /*
5568  * IOS 6.2.2.136
5569  * UNUSED
5570  */
5571
5572 /*
5573  * IOS 6.2.2.137
5574  * Generic decode is good enough
5575  */
5576
5577 /*
5578  * IOS 6.2.2.138
5579  * UNUSED
5580  */
5581
5582 /*
5583  * IOS 6.2.2.139
5584  * UNUSED
5585  */
5586
5587 /*
5588  * IOS 6.2.2.140
5589  * UNUSED
5590  */
5591
5592 /*
5593  * IOS 6.2.2.141
5594  * A3/A7
5595  */
5596
5597 /*
5598  * IOS 6.2.2.142
5599  * A3/A7
5600  */
5601
5602 /*
5603  * IOS 6.2.2.143
5604  * A3/A7
5605  */
5606
5607 /*
5608  * IOS 6.2.2.144
5609  * A3/A7
5610  */
5611
5612 /*
5613  * IOS 6.2.2.145
5614  * A3/A7
5615  */
5616
5617 /*
5618  * IOS 6.2.2.146
5619  * A3/A7
5620  */
5621
5622 /*
5623  * IOS 6.2.2.147
5624  * A3/A7
5625  */
5626
5627 /*
5628  * IOS 6.2.2.148
5629  */
5630 static guint8
5631 elem_cct_group(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
5632 {
5633     guint8      oct;
5634     guint32     value;
5635     guint32     curr_offset;
5636
5637     curr_offset = offset;
5638
5639     oct = tvb_get_guint8(tvb, curr_offset);
5640
5641     other_decode_bitfield_value(a_bigbuf, oct, 0xfc, 8);
5642     proto_tree_add_text(tree,
5643         tvb, curr_offset, 1,
5644         "%s :  Reserved",
5645         a_bigbuf);
5646
5647     other_decode_bitfield_value(a_bigbuf, oct, 0x02, 8);
5648     proto_tree_add_text(tree,
5649         tvb, curr_offset, 1,
5650         "%s :  All Circuits",
5651         a_bigbuf);
5652
5653     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
5654     proto_tree_add_text(tree,
5655         tvb, curr_offset, 1,
5656         "%s :  Inclusive",
5657         a_bigbuf);
5658
5659     curr_offset++;
5660
5661     NO_MORE_DATA_CHECK(len);
5662
5663     oct = tvb_get_guint8(tvb, curr_offset);
5664
5665     proto_tree_add_text(tree,
5666         tvb, curr_offset, 1,
5667         "Count: %u circuit%s",
5668         oct, plurality(oct, "", "s"));
5669
5670     sprintf(add_string, " - %u circuit%s",
5671         oct, plurality(oct, "", "s"));
5672
5673     curr_offset++;
5674
5675     value = tvb_get_ntohs(tvb, curr_offset);
5676
5677     other_decode_bitfield_value(a_bigbuf, value, 0xffe0, 16);
5678     proto_tree_add_text(tree,
5679         tvb, curr_offset, 2,
5680         "%s :  PCM Multiplexer: %u",
5681         a_bigbuf,
5682         (value & 0xffe0) >> 5);
5683
5684     other_decode_bitfield_value(a_bigbuf, value, 0x001f, 16);
5685     proto_tree_add_text(tree,
5686         tvb, curr_offset, 2,
5687         "%s :  Timeslot: %u",
5688         a_bigbuf,
5689         value & 0x001f);
5690
5691     curr_offset += 2;
5692
5693     NO_MORE_DATA_CHECK(len);
5694
5695     proto_tree_add_text(tree,
5696         tvb, curr_offset, len - (curr_offset - offset),
5697         "Circuit Bitmap");
5698
5699     curr_offset += len - (curr_offset - offset);
5700
5701     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5702
5703     return(curr_offset - offset);
5704 }
5705
5706 /*
5707  * IOS 6.2.2.149
5708  */
5709 static guint8
5710 elem_paca_ts(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
5711 {
5712     guint32     curr_offset;
5713
5714     add_string = add_string;
5715     curr_offset = offset;
5716
5717     proto_tree_add_text(tree, tvb, curr_offset, len, "PACA Queuing Time");
5718
5719     curr_offset += len;
5720
5721     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5722
5723     return(curr_offset - offset);
5724 }
5725
5726 /*
5727  * IOS 6.2.2.150
5728  */
5729 static guint8
5730 elem_paca_order(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
5731 {
5732     guint8      oct;
5733     guint32     curr_offset;
5734     gchar       *str;
5735
5736     curr_offset = offset;
5737
5738     oct = tvb_get_guint8(tvb, curr_offset);
5739
5740     other_decode_bitfield_value(a_bigbuf, oct, 0xf8, 8);
5741     proto_tree_add_text(tree,
5742         tvb, curr_offset, 1,
5743         "%s :  Reserved",
5744         a_bigbuf);
5745
5746     switch (oct & 0x07)
5747     {
5748     case 0: str = "Reserved"; break;
5749     case 1: str = "Update Queue Position and notify MS"; break;
5750     case 2: str = "Remove MS from the queue and release MS"; break;
5751     case 3: str = "Remove MS from the queue"; break;
5752     case 4: str = "MS Requested PACA Cancel"; break;
5753     case 5: str = "BS Requested PACA Cancel"; break;
5754     default:
5755         str = "All other values Reserved";
5756         break;
5757     }
5758
5759     other_decode_bitfield_value(a_bigbuf, oct, 0x07, 8);
5760     proto_tree_add_text(tree,
5761         tvb, curr_offset, 1,
5762         "%s :  PACA Action Required: %s",
5763         a_bigbuf,
5764         str);
5765
5766     curr_offset++;
5767
5768     sprintf(add_string, " - (%s)", str);
5769
5770     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5771
5772     return(curr_offset - offset);
5773 }
5774
5775 /*
5776  * IOS 6.2.2.151
5777  */
5778 static guint8
5779 elem_paca_reoi(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string)
5780 {
5781     guint8      oct;
5782     guint32     curr_offset;
5783
5784     curr_offset = offset;
5785
5786     oct = tvb_get_guint8(tvb, curr_offset);
5787
5788     other_decode_bitfield_value(a_bigbuf, oct, 0xfe, 8);
5789     proto_tree_add_text(tree,
5790         tvb, curr_offset, 1,
5791         "%s :  Reserved",
5792         a_bigbuf);
5793
5794     other_decode_bitfield_value(a_bigbuf, oct, 0x01, 8);
5795     proto_tree_add_text(tree,
5796         tvb, curr_offset, 1,
5797         "%s :  PACA Reorigination Indicator (PRI)",
5798         a_bigbuf);
5799
5800     curr_offset++;
5801
5802     sprintf(add_string, " - (%sReorigination)", (oct & 0x01) ? "" : "Not ");
5803
5804     EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
5805
5806     return(curr_offset - offset);
5807 }
5808
5809 /*
5810  * IOS 6.2.2.152
5811  * A3/A7
5812  */
5813
5814 /*
5815  * IOS 6.2.2.153
5816  * A3/A7
5817  */
5818
5819 typedef enum
5820 {
5821     ANSI_A_E_ACC_NET_ID,        /* Access Network Identifiers */
5822     ANSI_A_E_ADDS_USER_PART,    /* ADDS User Part */
5823     ANSI_A_E_AMPS_HHO_PARAM,    /* AMPS Hard Handoff Parameters */
5824     ANSI_A_E_ANCH_PDSN_ADDR,    /* Anchor PDSN Address */
5825     ANSI_A_E_ANCH_PP_ADDR,      /* Anchor P-P Address */
5826     ANSI_A_E_AUTH_CHLG_PARAM,   /* Authentication Challenge Parameter */
5827     ANSI_A_E_AUTH_CNF_PARAM,    /* Authentication Confirmation Parameter (RANDC) */
5828     ANSI_A_E_AUTH_DATA, /* Authentication Data */
5829     ANSI_A_E_AUTH_EVENT,        /* Authentication Event */
5830     ANSI_A_E_AUTH_PARAM_COUNT,  /* Authentication Parameter COUNT */
5831     ANSI_A_E_AUTH_RESP_PARAM,   /* Authentication Response Parameter */
5832     ANSI_A_E_BAND_CLASS,        /* Band Class */
5833     ANSI_A_E_CLD_PARTY_ASCII_NUM,       /* Called Party ASCII Number */
5834     ANSI_A_E_CLD_PARTY_BCD_NUM, /* Called Party BCD Number */
5835     ANSI_A_E_CLG_PARTY_ASCII_NUM,       /* Calling Party ASCII Number */
5836     ANSI_A_E_CAUSE,     /* Cause */
5837     ANSI_A_E_CAUSE_L3,  /* Cause Layer 3 */
5838     ANSI_A_E_CDMA_SOWD, /* CDMA Serving One Way Delay */
5839     ANSI_A_E_CELL_ID,   /* Cell Identifier */
5840     ANSI_A_E_CELL_ID_LIST,      /* Cell Identifier List */
5841     ANSI_A_E_CHAN_NUM,  /* Channel Number */
5842     ANSI_A_E_CHAN_TYPE, /* Channel Type */
5843     ANSI_A_E_CCT_GROUP, /* Circuit Group */
5844     ANSI_A_E_CIC,       /* Circuit Identity Code */
5845     ANSI_A_E_CIC_EXT,   /* Circuit Identity Code Extension */
5846     ANSI_A_E_CM_INFO_TYPE_2,    /* Classmark Information Type 2 */
5847     ANSI_A_E_DOWNLINK_RE,       /* Downlink Radio Environment */
5848     ANSI_A_E_DOWNLINK_RE_LIST,  /* Downlink Radio Environment List */
5849     ANSI_A_E_ENC_INFO,  /* Encryption Information */
5850     ANSI_A_E_EXT_HO_DIR_PARAMS, /* Extended Handoff Direction Parameters */
5851     ANSI_A_E_GEO_LOC,   /* Geographic Location */
5852     ANSI_A_E_SSCI,      /* Special Service Call Indicator */
5853     ANSI_A_E_HO_POW_LEV,        /* Handoff Power Level */
5854     ANSI_A_E_HHO_PARAMS,        /* Hard Handoff Parameters */
5855     ANSI_A_E_IE_REQD,   /* Information Element Requested */
5856     ANSI_A_E_IS2000_CHAN_ID,    /* IS-2000 Channel Identity */
5857     ANSI_A_E_IS2000_CHAN_ID_3X, /* IS-2000 Channel Identity 3X */
5858     ANSI_A_E_IS2000_MOB_CAP,    /* IS-2000 Mobile Capabilities */
5859     ANSI_A_E_IS2000_NN_SCR,     /* IS-2000 Non-Negotiable Service Configuration Record */
5860     ANSI_A_E_IS2000_SCR,        /* IS-2000 Service Configuration Record */
5861     ANSI_A_E_IS2000_CAUSE,      /* IS-95/IS-2000 Cause Value */
5862     ANSI_A_E_IS2000_RED_RECORD, /* IS-2000 Redirection Record */
5863     ANSI_A_E_IS95_CHAN_ID,      /* IS-95 Channel Identity */
5864     ANSI_A_E_IS95_MS_MEAS_CHAN_ID,      /* IS-95 MS Measured Channel Identity */
5865     ANSI_A_E_L3_INFO,   /* Layer 3 Information */
5866     ANSI_A_E_LAI,       /* Location Area Information */
5867     ANSI_A_E_MWI,       /* Message Waiting Indication */
5868     ANSI_A_E_MID,       /* Mobile Identity */
5869     ANSI_A_E_MS_INFO_RECS,      /* MS Information Records */
5870     ANSI_A_E_ORIG_CI,   /* Origination Continuation Indicator */
5871     ANSI_A_E_PACA_ORDER,        /* PACA Order */
5872     ANSI_A_E_PACA_REOI, /* PACA Reorigination Indicator */
5873     ANSI_A_E_PACA_TS,   /* PACA Timestamp */
5874     ANSI_A_E_PSP,       /* Packet Session Parameters */
5875     ANSI_A_E_PDSN_IP_ADDR,      /* PDSN IP Address */
5876     ANSI_A_E_PDI,       /* Power Down Indicator */
5877     ANSI_A_E_PRIO,      /* Priority */
5878     ANSI_A_E_PREV,      /* Protocol Revision */
5879     ANSI_A_E_PTYPE,     /* Protocol Type */
5880     ANSI_A_E_PSMM_COUNT,        /* PSMM Count */
5881     ANSI_A_E_QOS_PARAMS,        /* Quality of Service Parameters */
5882     ANSI_A_E_RE_RES,    /* Radio Environment and Resources */
5883     ANSI_A_E_REG_TYPE,  /* Registration Type */
5884     ANSI_A_E_REJ_CAUSE, /* Reject Cause */
5885     ANSI_A_E_RESP_REQ,  /* Response Request */
5886     ANSI_A_E_RET_CAUSE, /* Return Cause */
5887     ANSI_A_E_RF_CHAN_ID,        /* RF Channel Identity */
5888     ANSI_A_E_SO,        /* Service Option */
5889     ANSI_A_E_SOCI,      /* Service Option Connection Identifier (SOCI) */
5890     ANSI_A_E_SO_LIST,   /* Service Option List */
5891     ANSI_A_E_S_RED_INFO,        /* Service Redirection Info */
5892     ANSI_A_E_SR_ID,     /* Session Reference Identifier (SR_ID) */
5893     ANSI_A_E_SID,       /* SID */
5894     ANSI_A_E_SIGNAL,    /* Signal */
5895     ANSI_A_E_SCI,       /* Slot Cycle Index */
5896     ANSI_A_E_SW_VER,    /* Software Version */
5897     ANSI_A_E_SRNC_TRNC_TC,      /* Source RNC to Target RNC Transparent Container */
5898     ANSI_A_E_S_PDSN_ADDR,       /* Source PDSN Address */
5899     ANSI_A_E_TAG,       /* Tag */
5900     ANSI_A_E_TRNC_SRNC_TC,      /* Target RNC to Source RNC Transparent Container */
5901     ANSI_A_E_XMODE,     /* Transcoder Mode */
5902     ANSI_A_E_UZ_ID,     /* User Zone ID */
5903     ANSI_A_E_VP_REQ,    /* Voice Privacy Request */
5904     ANSI_A_E_NONE       /* NONE */
5905 }
5906 elem_idx_t;
5907
5908 #define NUM_ELEM_1 (sizeof(ansi_a_ios401_elem_1_strings)/sizeof(value_string))
5909 static gint ett_ansi_elem_1[NUM_ELEM_1];
5910 static guint8 (*elem_1_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar *add_string) = {
5911     NULL,       /* Access Network Identifiers */
5912     elem_adds_user_part,        /* ADDS User Part */
5913     NULL,       /* AMPS Hard Handoff Parameters */
5914     NULL,       /* Anchor PDSN Address */
5915     NULL,       /* Anchor P-P Address */
5916     elem_auth_chlg_param,       /* Authentication Challenge Parameter */
5917     NULL /* no decode required */,      /* Authentication Confirmation Parameter (RANDC) */
5918     NULL /* no decode required */,      /* Authentication Data */
5919     elem_auth_event,    /* Authentication Event */
5920     elem_auth_param_count,      /* Authentication Parameter COUNT */
5921     elem_auth_resp_param,       /* Authentication Response Parameter */
5922     elem_band_class,    /* Band Class */
5923     elem_cld_party_ascii_num,   /* Called Party ASCII Number */
5924     elem_cld_party_bcd_num,     /* Called Party BCD Number */
5925     elem_clg_party_ascii_num,   /* Calling Party ASCII Number */
5926     elem_cause, /* Cause */
5927     elem_cause_l3,      /* Cause Layer 3 */
5928     elem_cdma_sowd,     /* CDMA Serving One Way Delay */
5929     elem_cell_id,       /* Cell Identifier */
5930     elem_cell_id_list,  /* Cell Identifier List */
5931     elem_chan_num,      /* Channel Number */
5932     elem_chan_type,     /* Channel Type */
5933     elem_cct_group,     /* Circuit Group */
5934     elem_cic,   /* Circuit Identity Code */
5935     elem_cic_ext,       /* Circuit Identity Code Extension */
5936     elem_cm_info_type_2,        /* Classmark Information Type 2 */
5937     elem_downlink_re,   /* Downlink Radio Environment */
5938     NULL,       /* Downlink Radio Environment List */
5939     elem_enc_info,      /* Encryption Information */
5940     elem_ext_ho_dir_params,     /* Extended Handoff Direction Parameters */
5941     NULL,       /* Geographic Location */
5942     NULL,       /* Special Service Call Indicator */
5943     elem_ho_pow_lev,    /* Handoff Power Level */
5944     elem_hho_params,    /* Hard Handoff Parameters */
5945     NULL,       /* Information Element Requested */
5946     elem_is2000_chan_id,        /* IS-2000 Channel Identity */
5947     NULL,       /* IS-2000 Channel Identity 3X */
5948     elem_is2000_mob_cap,        /* IS-2000 Mobile Capabilities */
5949     elem_is2000_nn_scr, /* IS-2000 Non-Negotiable Service Configuration Record */
5950     elem_is2000_scr,    /* IS-2000 Service Configuration Record */
5951     elem_is2000_cause,  /* IS-95/IS-2000 Cause Value */
5952     NULL,       /* IS-2000 Redirection Record */
5953     elem_is95_chan_id,  /* IS-95 Channel Identity */
5954     elem_is95_ms_meas_chan_id,  /* IS-95 MS Measured Channel Identity */
5955     elem_l3_info,       /* Layer 3 Information */
5956     elem_lai,   /* Location Area Information */
5957     elem_mwi,   /* Message Waiting Indication */
5958     elem_mid,   /* Mobile Identity */
5959     elem_ms_info_recs,  /* MS Information Records */
5960     NULL,       /* Origination Continuation Indicator */
5961     elem_paca_order,    /* PACA Order */
5962     elem_paca_reoi,     /* PACA Reorigination Indicator */
5963     elem_paca_ts,       /* PACA Timestamp */
5964     NULL,       /* Packet Session Parameters */
5965     elem_pdsn_ip_addr,  /* PDSN IP Address */
5966     NULL /* no associated data */,      /* Power Down Indicator */
5967     elem_prio,  /* Priority */
5968     NULL,       /* Protocol Revision */
5969     elem_ptype, /* Protocol Type */
5970     NULL,       /* PSMM Count */
5971     elem_qos_params,    /* Quality of Service Parameters */
5972     elem_re_res,        /* Radio Environment and Resources */
5973     elem_reg_type,      /* Registration Type */
5974     elem_rej_cause,     /* Reject Cause */
5975     NULL /* no associated data */,      /* Response Request */
5976     NULL,       /* Return Cause */
5977     elem_rf_chan_id,    /* RF Channel Identity */
5978     elem_so,    /* Service Option */
5979     NULL,       /* Service Option Connection Identifier (SOCI) */
5980     NULL,       /* Service Option List */
5981     NULL,       /* Service Redirection Info */
5982     NULL,       /* Session Reference Identifier (SR_ID) */
5983     elem_sid,   /* SID */
5984     elem_signal,        /* Signal */
5985     elem_sci,   /* Slot Cycle Index */
5986     elem_sw_ver,        /* Software Version */
5987     NULL,       /* Source RNC to Target RNC Transparent Container */
5988     NULL,       /* Source PDSN Address */
5989     elem_tag,   /* Tag */
5990     NULL,       /* Target RNC to Source RNC Transparent Container */
5991     elem_xmode, /* Transcoder Mode */
5992     elem_uz_id, /* User Zone ID */
5993     NULL /* no associated data */,      /* Voice Privacy Request */
5994     NULL,       /* NONE */
5995 };
5996
5997 /* MESSAGE FUNCTIONS */
5998
5999 /*
6000  * Type Length Value (TLV) element dissector
6001  */
6002 static guint8
6003 elem_tlv(tvbuff_t *tvb, proto_tree *tree, elem_idx_t idx, guint32 offset, guint len, gchar *name_add)
6004 {
6005     guint8      oct, parm_len;
6006     guint8      consumed;
6007     guint32     curr_offset;
6008     proto_tree  *subtree;
6009     proto_item  *item;
6010
6011     len = len;
6012     curr_offset = offset;
6013     consumed = 0;
6014
6015     oct = tvb_get_guint8(tvb, curr_offset);
6016
6017     if (oct == (guint8) ansi_a_ios401_elem_1_strings[idx].value)
6018     {
6019         parm_len = tvb_get_guint8(tvb, curr_offset + 1);
6020
6021         item =
6022             proto_tree_add_text(tree,
6023                 tvb, curr_offset, parm_len + 2,
6024                 "%s%s",
6025                 ansi_a_ios401_elem_1_strings[idx].strptr,
6026                 (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
6027
6028         subtree = proto_item_add_subtree(item, ett_ansi_elem_1[idx]);
6029
6030         proto_tree_add_uint(subtree, hf_ansi_a_elem_id, tvb,
6031             curr_offset, 1, oct);
6032
6033         proto_tree_add_uint(subtree, hf_ansi_a_length, tvb,
6034             curr_offset + 1, 1, parm_len);
6035
6036         if (parm_len > 0)
6037         {
6038             if (elem_1_fcn[idx] == NULL)
6039             {
6040                 proto_tree_add_text(subtree,
6041                     tvb, curr_offset + 2, parm_len,
6042                     "Element Value");
6043
6044                 consumed = parm_len;
6045             }
6046             else
6047             {
6048                 a_add_string[0] = '\0';
6049                 consumed =
6050                     (*elem_1_fcn[idx])(tvb, subtree, curr_offset + 2,
6051                         parm_len, a_add_string);
6052
6053                 if (a_add_string[0] != '\0')
6054                 {
6055                     proto_item_append_text(item, a_add_string);
6056                     a_add_string[0] = '\0';
6057                 }
6058             }
6059         }
6060
6061         consumed += 2;
6062     }
6063
6064     return(consumed);
6065 }
6066
6067 /*
6068  * Type Value (TV) element dissector
6069  *
6070  * Length cannot be used in these functions, big problem if a element dissector
6071  * is not defined for these.
6072  */
6073 static guint8
6074 elem_tv(tvbuff_t *tvb, proto_tree *tree, elem_idx_t idx, guint32 offset, gchar *name_add)
6075 {
6076     guint8      oct;
6077     guint8      consumed;
6078     guint32     curr_offset;
6079     proto_tree  *subtree;
6080     proto_item  *item;
6081
6082     curr_offset = offset;
6083     consumed = 0;
6084
6085     oct = tvb_get_guint8(tvb, curr_offset);
6086
6087     if (oct == (guint8) ansi_a_ios401_elem_1_strings[idx].value)
6088     {
6089         item =
6090             proto_tree_add_text(tree,
6091                 tvb, curr_offset, -1,
6092                 "%s%s",
6093                 ansi_a_ios401_elem_1_strings[idx].strptr,
6094                 (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
6095
6096         subtree = proto_item_add_subtree(item, ett_ansi_elem_1[idx]);
6097
6098         proto_tree_add_uint(subtree, hf_ansi_a_elem_id, tvb, curr_offset, 1, oct);
6099
6100         if (elem_1_fcn[idx] == NULL)
6101         {
6102             /* BAD THING, CANNOT DETERMINE LENGTH */
6103
6104             proto_tree_add_text(subtree,
6105                 tvb, curr_offset + 1, 1,
6106                 "No element dissector, rest of dissection may be incorrect");
6107
6108             consumed = 1;
6109         }
6110         else
6111         {
6112             a_add_string[0] = '\0';
6113             consumed = (*elem_1_fcn[idx])(tvb, subtree, curr_offset + 1, -1, a_add_string);
6114
6115             if (a_add_string[0] != '\0')
6116             {
6117                 proto_item_append_text(item, a_add_string);
6118                 a_add_string[0] = '\0';
6119             }
6120         }
6121
6122         consumed++;
6123
6124         proto_item_set_len(item, consumed);
6125     }
6126
6127     return(consumed);
6128 }
6129
6130 /*
6131  * Type (T) element dissector
6132  *
6133  * Length cannot be used in these functions, big problem if a element dissector
6134  * is not defined for these.
6135  */
6136 static guint8
6137 elem_t(tvbuff_t *tvb, proto_tree *tree, elem_idx_t idx, guint32 offset, gchar *name_add)
6138 {
6139     guint8      oct;
6140     guint32     curr_offset;
6141     guint8      consumed;
6142
6143     curr_offset = offset;
6144     consumed = 0;
6145
6146     oct = tvb_get_guint8(tvb, curr_offset);
6147
6148     if (oct == (guint8) ansi_a_ios401_elem_1_strings[idx].value)
6149     {
6150         proto_tree_add_uint_format(tree, hf_ansi_a_elem_id, tvb, curr_offset, 1, oct,
6151             "%s%s",
6152             ansi_a_ios401_elem_1_strings[idx].strptr,
6153             (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
6154
6155         consumed = 1;
6156     }
6157
6158     return(consumed);
6159 }
6160
6161 /*
6162  * Length Value (LV) element dissector
6163  */
6164 static guint8
6165 elem_lv(tvbuff_t *tvb, proto_tree *tree, elem_idx_t idx, guint32 offset, guint len, gchar *name_add)
6166 {
6167     guint8      parm_len;
6168     guint8      consumed;
6169     guint32     curr_offset;
6170     proto_tree  *subtree;
6171     proto_item  *item;
6172
6173     len = len;
6174     curr_offset = offset;
6175     consumed = 0;
6176
6177     parm_len = tvb_get_guint8(tvb, curr_offset);
6178
6179     item =
6180         proto_tree_add_text(tree,
6181             tvb, curr_offset, parm_len + 1,
6182             "%s%s",
6183             ansi_a_ios401_elem_1_strings[idx].strptr,
6184             (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
6185
6186     subtree = proto_item_add_subtree(item, ett_ansi_elem_1[idx]);
6187
6188     proto_tree_add_uint(subtree, hf_ansi_a_length, tvb,
6189         curr_offset, 1, parm_len);
6190
6191     if (parm_len > 0)
6192     {
6193         if (elem_1_fcn[idx] == NULL)
6194         {
6195             proto_tree_add_text(subtree,
6196                 tvb, curr_offset + 1, parm_len,
6197                 "Element Value");
6198
6199             consumed = parm_len;
6200         }
6201         else
6202         {
6203             a_add_string[0] = '\0';
6204             consumed =
6205                 (*elem_1_fcn[idx])(tvb, subtree, curr_offset + 1,
6206                     parm_len, a_add_string);
6207
6208             if (a_add_string[0] != '\0')
6209             {
6210                 proto_item_append_text(item, a_add_string);
6211                 a_add_string[0] = '\0';
6212             }
6213         }
6214     }
6215
6216     return(consumed + 1);
6217 }
6218
6219 /*
6220  * Value (V) element dissector
6221  *
6222  * Length cannot be used in these functions, big problem if a element dissector
6223  * is not defined for these.
6224  */
6225 static guint8
6226 elem_v(tvbuff_t *tvb, proto_tree *tree, elem_idx_t idx, guint32 offset)
6227 {
6228     guint8      consumed;
6229     guint32     curr_offset;
6230
6231     curr_offset = offset;
6232     consumed = 0;
6233
6234     if (elem_1_fcn[idx] == NULL)
6235     {
6236         /* BAD THING, CANNOT DETERMINE LENGTH */
6237
6238         proto_tree_add_text(tree,
6239             tvb, curr_offset, 1,
6240             "No element dissector, rest of dissection may be incorrect");
6241
6242         consumed = 1;
6243     }
6244     else
6245     {
6246         a_add_string[0] = '\0';
6247         consumed = (*elem_1_fcn[idx])(tvb, tree, curr_offset, -1, a_add_string);
6248         a_add_string[0] = '\0';
6249     }
6250
6251     return(consumed);
6252 }
6253
6254
6255 #define ELEM_MAND_TLV(elem_idx, elem_name_addition) \
6256 {\
6257     if ((consumed = elem_tlv(tvb, tree, elem_idx, curr_offset, curr_len, elem_name_addition)) > 0) \
6258     { \
6259         curr_offset += consumed; \
6260         curr_len -= consumed; \
6261     } \
6262     else \
6263     { \
6264         proto_tree_add_text(tree, \
6265             tvb, curr_offset, 0, \
6266             "Missing Mandatory element (0x%02x) %s%s, rest of dissection is suspect", \
6267                 ansi_a_ios401_elem_1_strings[elem_idx].value, \
6268                 ansi_a_ios401_elem_1_strings[elem_idx].strptr, \
6269                 (elem_name_addition == NULL) || (elem_name_addition[0] == '\0') ? "" : elem_name_addition \
6270             ); \
6271     } \
6272     if (curr_len <= 0) return; \
6273 }
6274
6275 #define ELEM_OPT_TLV(elem_idx, elem_name_addition) \
6276 {\
6277     if ((consumed = elem_tlv(tvb, tree, elem_idx, curr_offset, curr_len, elem_name_addition)) > 0) \
6278     { \
6279         curr_offset += consumed; \
6280         curr_len -= consumed; \
6281     } \
6282     if (curr_len <= 0) return; \
6283 }
6284
6285 #define ELEM_MAND_TV(elem_idx, elem_name_addition) \
6286 {\
6287     if ((consumed = elem_tv(tvb, tree, elem_idx, curr_offset, elem_name_addition)) > 0) \
6288     { \
6289         curr_offset += consumed; \
6290         curr_len -= consumed; \
6291     } \
6292     else \
6293     { \
6294         proto_tree_add_text(tree, \
6295             tvb, curr_offset, 0, \
6296             "Missing Mandatory element (0x%02x) %s%s, rest of dissection is suspect", \
6297                 ansi_a_ios401_elem_1_strings[elem_idx].value, \
6298                 ansi_a_ios401_elem_1_strings[elem_idx].strptr, \
6299                 (elem_name_addition == NULL) || (elem_name_addition[0] == '\0') ? "" : elem_name_addition \
6300             ); \
6301     } \
6302     if (curr_len <= 0) return; \
6303 }
6304
6305 #define ELEM_OPT_TV(elem_idx, elem_name_addition) \
6306 {\
6307     if ((consumed = elem_tv(tvb, tree, elem_idx, curr_offset, elem_name_addition)) > 0) \
6308     { \
6309         curr_offset += consumed; \
6310         curr_len -= consumed; \
6311     } \
6312     if (curr_len <= 0) return; \
6313 }
6314
6315 #define ELEM_OPT_T(elem_idx, elem_name_addition) \
6316 {\
6317     if ((consumed = elem_t(tvb, tree, elem_idx, curr_offset, elem_name_addition)) > 0) \
6318     { \
6319         curr_offset += consumed; \
6320         curr_len -= consumed; \
6321     } \
6322     if (curr_len <= 0) return; \
6323 }
6324
6325 #define ELEM_MAND_LV(elem_idx, elem_name_addition) \
6326 {\
6327     if ((consumed = elem_lv(tvb, tree, elem_idx, curr_offset, curr_len, elem_name_addition)) > 0) \
6328     { \
6329         curr_offset += consumed; \
6330         curr_len -= consumed; \
6331     } \
6332     else \
6333     { \
6334         /* Mandatory, but nothing we can do */ \
6335     } \
6336     if (curr_len <= 0) return; \
6337 }
6338
6339 #define ELEM_MAND_V(elem_idx) \
6340 {\
6341     if ((consumed = elem_v(tvb, tree, elem_idx, curr_offset)) > 0) \
6342     { \
6343         curr_offset += consumed; \
6344         curr_len -= consumed; \
6345     } \
6346     else \
6347     { \
6348         /* Mandatory, but nothing we can do */ \
6349     } \
6350     if (curr_len <= 0) return; \
6351 }
6352
6353
6354 /*
6355  * IOS 6.1.2.1
6356  */
6357 static void
6358 bsmap_cl3_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
6359 {
6360     guint8      consumed;
6361     guint32     curr_offset;
6362     guint       curr_len;
6363
6364     curr_offset = offset;
6365     curr_len = len;
6366
6367     ELEM_MAND_TLV(ANSI_A_E_CELL_ID, "");
6368
6369     ELEM_MAND_TLV(ANSI_A_E_L3_INFO, "");
6370
6371     EXTRANEOUS_DATA_CHECK(curr_len, 0);
6372 }
6373
6374 /*
6375  * IOS 6.1.2.2
6376  */
6377 static void
6378 dtap_cm_srvc_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
6379 {
6380     guint32     curr_offset;
6381     guint32     consumed;
6382     guint       curr_len;
6383     guint8      oct;
6384     proto_tree  *subtree;
6385     proto_item  *item;
6386     gchar       *str;
6387
6388     curr_offset = offset;
6389     curr_len = len;
6390
6391     /*
6392      * special dissection for CM Service Type
6393      */
6394     oct = tvb_get_guint8(tvb, curr_offset);
6395
6396     switch (oct & 0x0f)
6397     {
6398     case 0x01: str = "Mobile Originating Call"; break;
6399     default:
6400         str = "Unknown";
6401         break;
6402     }
6403
6404     item =
6405         proto_tree_add_text(tree,
6406             tvb, curr_offset, 1,
6407             "CM Service Type: %s",
6408             str);
6409
6410     subtree = proto_item_add_subtree(item, ett_cm_srvc_type);
6411
6412     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
6413     proto_tree_add_text(subtree,
6414         tvb, curr_offset, 1,
6415         "%s :  Element ID",
6416         a_bigbuf);
6417
6418     other_decode_bitfield_value(a_bigbuf, oct, 0x0f, 8);
6419     proto_tree_add_text(subtree,
6420         tvb, curr_offset, 1,
6421         "%s :  Service Type: (%u) %s",
6422         a_bigbuf,
6423         oct & 0x0f,
6424         str);
6425
6426     curr_offset++;
6427     curr_len--;
6428
6429     ELEM_MAND_LV(ANSI_A_E_CM_INFO_TYPE_2, "");
6430
6431     ELEM_MAND_LV(ANSI_A_E_MID, "");
6432
6433     ELEM_OPT_TLV(ANSI_A_E_CLD_PARTY_BCD_NUM, "");
6434
6435     ELEM_OPT_TLV(ANSI_A_E_MID, "");
6436
6437     ELEM_OPT_TV(ANSI_A_E_SCI, "");
6438
6439     ELEM_OPT_TLV(ANSI_A_E_AUTH_RESP_PARAM, "");
6440
6441     ELEM_OPT_TV(ANSI_A_E_AUTH_CNF_PARAM, "");
6442
6443     ELEM_OPT_TV(ANSI_A_E_AUTH_PARAM_COUNT, "");
6444
6445     ELEM_OPT_TLV(ANSI_A_E_AUTH_CHLG_PARAM, "");
6446
6447     ELEM_OPT_TV(ANSI_A_E_SO, "");
6448
6449     ELEM_OPT_T(ANSI_A_E_VP_REQ, "");
6450
6451     ELEM_OPT_TV(ANSI_A_E_RE_RES, "");
6452
6453     ELEM_OPT_TLV(ANSI_A_E_CLD_PARTY_ASCII_NUM, "");
6454
6455     ELEM_OPT_TV(ANSI_A_E_CIC, "");
6456
6457     ELEM_OPT_TLV(ANSI_A_E_AUTH_EVENT, "");
6458
6459     ELEM_OPT_TLV(ANSI_A_E_AUTH_DATA, "");
6460
6461     ELEM_OPT_TLV(ANSI_A_E_PACA_REOI, "");
6462
6463     ELEM_OPT_TLV(ANSI_A_E_UZ_ID, "");
6464
6465     ELEM_OPT_TLV(ANSI_A_E_IS2000_MOB_CAP, "");
6466
6467     ELEM_OPT_TLV(ANSI_A_E_CDMA_SOWD, "");
6468
6469     EXTRANEOUS_DATA_CHECK(curr_len, 0);
6470 }
6471
6472 /*
6473  * IOS 6.1.2.3
6474  */
6475 static void
6476 bsmap_page_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
6477 {
6478     guint32     curr_offset;
6479     guint32     consumed;
6480     guint       curr_len;
6481
6482     curr_offset = offset;
6483     curr_len = len;
6484
6485     ELEM_MAND_TLV(ANSI_A_E_MID, "");
6486
6487     ELEM_OPT_TV(ANSI_A_E_TAG, "");
6488
6489     ELEM_OPT_TLV(ANSI_A_E_CELL_ID_LIST, "");
6490
6491     ELEM_OPT_TV(ANSI_A_E_SCI, "");
6492
6493     ELEM_OPT_TV(ANSI_A_E_SO, "");
6494
6495     ELEM_OPT_TLV(ANSI_A_E_IS2000_MOB_CAP, "");
6496
6497     EXTRANEOUS_DATA_CHECK(curr_len, 0);
6498 }
6499
6500 /*
6501  * IOS 6.1.2.4
6502  */
6503 static void
6504 dtap_page_resp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
6505 {
6506     guint32     curr_offset;
6507     guint32     consumed;
6508     guint       curr_len;
6509
6510     curr_offset = offset;
6511     curr_len = len;
6512
6513     ELEM_MAND_LV(ANSI_A_E_CM_INFO_TYPE_2, "");
6514
6515     ELEM_MAND_LV(ANSI_A_E_MID, "");
6516
6517     ELEM_OPT_TV(ANSI_A_E_TAG, "");
6518
6519     ELEM_OPT_TLV(ANSI_A_E_MID, "");
6520
6521     ELEM_OPT_TV(ANSI_A_E_SCI, "");
6522
6523     ELEM_OPT_TLV(ANSI_A_E_AUTH_RESP_PARAM, "");
6524
6525     ELEM_OPT_TV(ANSI_A_E_AUTH_CNF_PARAM, "");
6526
6527     ELEM_OPT_TV(ANSI_A_E_AUTH_PARAM_COUNT, "");
6528
6529     ELEM_OPT_TLV(ANSI_A_E_AUTH_CHLG_PARAM, "");
6530
6531     ELEM_OPT_TV(ANSI_A_E_SO, "");
6532
6533     ELEM_OPT_T(ANSI_A_E_VP_REQ, "");
6534
6535     ELEM_OPT_TV(ANSI_A_E_CIC, "");
6536
6537     ELEM_OPT_TLV(ANSI_A_E_AUTH_EVENT, "");
6538
6539     ELEM_OPT_TV(ANSI_A_E_RE_RES, "");
6540
6541     ELEM_OPT_TLV(ANSI_A_E_UZ_ID, "");
6542
6543     ELEM_OPT_TLV(ANSI_A_E_IS2000_MOB_CAP, "");
6544
6545     ELEM_OPT_TLV(ANSI_A_E_CDMA_SOWD, "");
6546
6547     EXTRANEOUS_DATA_CHECK(curr_len, 0);
6548 }
6549
6550 /*
6551  * IOS 6.1.2.12
6552  */
6553 static void
6554 dtap_progress(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
6555 {
6556     guint32     curr_offset;
6557     guint32     consumed;
6558     guint       curr_len;
6559
6560     curr_offset = offset;
6561     curr_len = len;
6562
6563     ELEM_OPT_TV(ANSI_A_E_SIGNAL, "");
6564
6565     ELEM_OPT_TLV(ANSI_A_E_MS_INFO_RECS, "");
6566
6567     EXTRANEOUS_DATA_CHECK(curr_len, 0);
6568 }
6569
6570 /*
6571  * IOS 6.1.2.15
6572  */
6573 static void
6574 bsmap_ass_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
6575 {
6576     guint8      consumed;
6577     guint32     curr_offset;
6578     guint       curr_len;
6579
6580     curr_offset = offset;
6581     curr_len = len;
6582
6583     ELEM_MAND_TLV(ANSI_A_E_CHAN_TYPE, "");
6584
6585     ELEM_OPT_TV(ANSI_A_E_CIC, "");
6586
6587     ELEM_OPT_TLV(ANSI_A_E_ENC_INFO, "");
6588
6589     ELEM_OPT_TV(ANSI_A_E_SO, "");
6590
6591     ELEM_OPT_TV(ANSI_A_E_SIGNAL, "");
6592
6593     ELEM_OPT_TLV(ANSI_A_E_CLG_PARTY_ASCII_NUM, "");
6594
6595     ELEM_OPT_TLV(ANSI_A_E_MS_INFO_RECS, "");
6596
6597     ELEM_OPT_TLV(ANSI_A_E_PRIO, "");
6598
6599     ELEM_OPT_TLV(ANSI_A_E_PACA_TS, "");
6600
6601     ELEM_OPT_TLV(ANSI_A_E_QOS_PARAMS, "");
6602
6603     EXTRANEOUS_DATA_CHECK(curr_len, 0);
6604 }
6605
6606 /*
6607  * IOS 6.1.2.16
6608  */
6609 static void
6610 bsmap_ass_complete(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
6611 {
6612     guint8      consumed;
6613     guint32     curr_offset;
6614     guint       curr_len;
6615
6616     curr_offset = offset;
6617     curr_len = len;
6618
6619     ELEM_MAND_TV(ANSI_A_E_CHAN_NUM, "");
6620
6621     ELEM_OPT_TLV(ANSI_A_E_ENC_INFO, "");
6622
6623     ELEM_OPT_TV(ANSI_A_E_SO, "");
6624
6625     EXTRANEOUS_DATA_CHECK(curr_len, 0);
6626 }
6627
6628 /*
6629  * IOS 6.1.2.17
6630  */
6631 static void
6632 bsmap_ass_failure(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
6633 {
6634     guint8      consumed;
6635     guint32     curr_offset;
6636     guint       curr_len;
6637
6638     curr_offset = offset;
6639     curr_len = len;
6640
6641     ELEM_MAND_TLV(ANSI_A_E_CAUSE, "");
6642
6643     EXTRANEOUS_DATA_CHECK(curr_len, 0);
6644 }
6645
6646 /*
6647  * IOS 6.1.2.20
6648  */
6649 static void
6650 bsmap_clr_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
6651 {
6652     guint8      consumed;
6653     guint32     curr_offset;
6654     guint       curr_len;
6655
6656     curr_offset = offset;
6657     curr_len = len;
6658
6659     ELEM_MAND_TLV(ANSI_A_E_CAUSE, "");
6660
6661     ELEM_OPT_TLV(ANSI_A_E_CAUSE_L3, "");
6662
6663     EXTRANEOUS_DATA_CHECK(curr_len, 0);
6664 }
6665
6666 /*
6667  * IOS 6.1.2.21
6668  */
6669 static void
6670 bsmap_clr_command(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
6671 {
6672     guint8      consumed;
6673     guint32     curr_offset;
6674     guint       curr_len;
6675
6676     curr_offset = offset;
6677     curr_len = len;
6678
6679     ELEM_MAND_TLV(ANSI_A_E_CAUSE, "");
6680
6681     ELEM_OPT_TLV(ANSI_A_E_CAUSE_L3, "");
6682
6683     EXTRANEOUS_DATA_CHECK(curr_len, 0);
6684 }
6685
6686 /*
6687  * IOS 6.1.2.22
6688  */
6689 static void
6690 bsmap_clr_complete(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
6691 {
6692     guint8      consumed;
6693     guint32     curr_offset;
6694     guint       curr_len;
6695
6696     curr_offset = offset;
6697     curr_len = len;
6698
6699     ELEM_OPT_T(ANSI_A_E_PDI, "");
6700
6701     EXTRANEOUS_DATA_CHECK(curr_len, 0);
6702 }
6703
6704 /*
6705  * IOS 6.1.2.24
6706  */
6707 static void
6708 dtap_alert_with_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
6709 {
6710     guint32     curr_offset;
6711     guint32     consumed;
6712     guint       curr_len;
6713
6714     curr_offset = offset;
6715     curr_len = len;
6716
6717     ELEM_OPT_TLV(ANSI_A_E_MS_INFO_RECS, "");
6718
6719     EXTRANEOUS_DATA_CHECK(curr_len, 0);
6720 }
6721
6722 /*
6723  * IOS 6.1.2.28
6724  */
6725 static void
6726 bsmap_bs_srvc_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
6727 {
6728     guint32     curr_offset;
6729     guint32     consumed;
6730     guint       curr_len;
6731
6732     curr_offset = offset;
6733     curr_len = len;
6734
6735     ELEM_MAND_TLV(ANSI_A_E_MID, "");
6736
6737     ELEM_OPT_TLV(ANSI_A_E_MID, "");
6738
6739     ELEM_OPT_TV(ANSI_A_E_SO, "");
6740
6741     ELEM_OPT_TV(ANSI_A_E_TAG, "");
6742
6743     EXTRANEOUS_DATA_CHECK(curr_len, 0);
6744 }
6745
6746 /*
6747  * IOS 6.1.2.29
6748  */
6749 static void
6750 bsmap_bs_srvc_resp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
6751 {
6752     guint32     curr_offset;
6753     guint32     consumed;
6754     guint       curr_len;
6755
6756     curr_offset = offset;
6757     curr_len = len;
6758
6759     ELEM_MAND_TLV(ANSI_A_E_MID, "");
6760
6761     ELEM_OPT_TLV(ANSI_A_E_MID, "");
6762
6763     ELEM_OPT_TV(ANSI_A_E_TAG, "");
6764
6765     ELEM_OPT_TLV(ANSI_A_E_CAUSE, "");
6766
6767     EXTRANEOUS_DATA_CHECK(curr_len, 0);
6768 }
6769
6770 /*
6771  * IOS 6.1.3.7
6772  */
6773 static void
6774 dtap_flash_with_info(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
6775 {
6776     guint32     curr_offset;
6777     guint32     consumed;
6778     guint       curr_len;
6779
6780     curr_offset = offset;
6781     curr_len = len;
6782
6783     ELEM_OPT_TLV(ANSI_A_E_CLD_PARTY_BCD_NUM, "");
6784
6785     ELEM_OPT_TV(ANSI_A_E_SIGNAL, "");
6786
6787     ELEM_OPT_TV(ANSI_A_E_MWI, "");
6788
6789     ELEM_OPT_TLV(ANSI_A_E_CLG_PARTY_ASCII_NUM, "");
6790
6791     ELEM_OPT_TV(ANSI_A_E_TAG, "");
6792
6793     ELEM_OPT_TLV(ANSI_A_E_MS_INFO_RECS, "");
6794
6795     EXTRANEOUS_DATA_CHECK(curr_len, 0);
6796 }
6797
6798 /*
6799  * IOS 6.1.3.8
6800  */
6801 static void
6802 dtap_flash_with_info_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
6803 {
6804     guint32     curr_offset;
6805     guint32     consumed;
6806     guint       curr_len;
6807
6808     curr_offset = offset;
6809     curr_len = len;
6810
6811     ELEM_OPT_TV(ANSI_A_E_TAG, "");
6812
6813     EXTRANEOUS_DATA_CHECK(curr_len, 0);
6814 }
6815
6816 /*
6817  * IOS 6.1.3.9
6818  */
6819 static void
6820 bsmap_feat_noti(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
6821 {
6822     guint32     curr_offset;
6823     guint32     consumed;
6824     guint       curr_len;
6825
6826     curr_offset = offset;
6827     curr_len = len;
6828
6829     ELEM_MAND_TLV(ANSI_A_E_MID, "");
6830
6831     ELEM_OPT_TV(ANSI_A_E_TAG, "");
6832
6833     ELEM_OPT_TLV(ANSI_A_E_CELL_ID_LIST, "");
6834
6835     ELEM_OPT_TV(ANSI_A_E_SCI, "");
6836
6837     ELEM_OPT_TV(ANSI_A_E_SIGNAL, "");
6838
6839     ELEM_OPT_TV(ANSI_A_E_MWI, "");
6840
6841     ELEM_OPT_TLV(ANSI_A_E_CLG_PARTY_ASCII_NUM, "");
6842
6843     ELEM_OPT_TLV(ANSI_A_E_MS_INFO_RECS, "");
6844
6845     ELEM_OPT_TLV(ANSI_A_E_IS2000_MOB_CAP, "");
6846
6847     EXTRANEOUS_DATA_CHECK(curr_len, 0);
6848 }
6849
6850 /*
6851  * IOS 6.1.3.10
6852  */
6853 static void
6854 bsmap_feat_noti_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
6855 {
6856     guint32     curr_offset;
6857     guint32     consumed;
6858     guint       curr_len;
6859
6860     curr_offset = offset;
6861     curr_len = len;
6862
6863     ELEM_MAND_TLV(ANSI_A_E_MID, "");
6864
6865     ELEM_OPT_TV(ANSI_A_E_TAG, "");
6866
6867     EXTRANEOUS_DATA_CHECK(curr_len, 0);
6868 }
6869
6870 /*
6871  * IOS 6.1.3.11
6872  */
6873 static void
6874 bsmap_paca_command(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
6875 {
6876     guint32     curr_offset;
6877     guint32     consumed;
6878     guint       curr_len;
6879
6880     curr_offset = offset;
6881     curr_len = len;
6882
6883     ELEM_OPT_TLV(ANSI_A_E_PRIO, "");
6884
6885     ELEM_OPT_TLV(ANSI_A_E_PACA_TS, "");
6886
6887     EXTRANEOUS_DATA_CHECK(curr_len, 0);
6888 }
6889
6890 /*
6891  * IOS 6.1.3.12
6892  */
6893 static void
6894 bsmap_paca_command_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
6895 {
6896     guint32     curr_offset;
6897     guint32     consumed;
6898     guint       curr_len;
6899
6900     curr_offset = offset;
6901     curr_len = len;
6902
6903     ELEM_OPT_TLV(ANSI_A_E_CAUSE, "");
6904
6905     EXTRANEOUS_DATA_CHECK(curr_len, 0);
6906 }
6907
6908 /*
6909  * IOS 6.1.3.13
6910  */
6911 static void
6912 bsmap_paca_update(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
6913 {
6914     guint32     curr_offset;
6915     guint32     consumed;
6916     guint       curr_len;
6917
6918     curr_offset = offset;
6919     curr_len = len;
6920
6921     ELEM_OPT_TLV(ANSI_A_E_MID, "");
6922
6923     ELEM_OPT_TLV(ANSI_A_E_MID, "");
6924
6925     ELEM_OPT_TLV(ANSI_A_E_PACA_ORDER, "");
6926
6927     ELEM_OPT_TLV(ANSI_A_E_PRIO, "");
6928
6929     ELEM_OPT_TLV(ANSI_A_E_AUTH_RESP_PARAM, "");
6930
6931     ELEM_OPT_TV(ANSI_A_E_AUTH_CNF_PARAM, "");
6932
6933     ELEM_OPT_TV(ANSI_A_E_AUTH_PARAM_COUNT, "");
6934
6935     ELEM_OPT_TLV(ANSI_A_E_AUTH_CHLG_PARAM, "");
6936
6937     ELEM_OPT_TLV(ANSI_A_E_AUTH_EVENT, "");
6938
6939     EXTRANEOUS_DATA_CHECK(curr_len, 0);
6940 }
6941
6942 /*
6943  * IOS 6.1.3.14
6944  */
6945 static void
6946 bsmap_paca_update_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
6947 {
6948     guint32     curr_offset;
6949     guint32     consumed;
6950     guint       curr_len;
6951
6952     curr_offset = offset;
6953     curr_len = len;
6954
6955     ELEM_OPT_TLV(ANSI_A_E_MID, "");
6956
6957     ELEM_OPT_TLV(ANSI_A_E_PRIO, "");
6958
6959     ELEM_OPT_TLV(ANSI_A_E_CAUSE, "");
6960
6961     EXTRANEOUS_DATA_CHECK(curr_len, 0);
6962 }
6963
6964 /*
6965  * IOS 6.1.4.1
6966  */
6967 static void
6968 bsmap_auth_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
6969 {
6970     guint32     curr_offset;
6971     guint32     consumed;
6972     guint       curr_len;
6973
6974     curr_offset = offset;
6975     curr_len = len;
6976
6977     ELEM_MAND_TLV(ANSI_A_E_AUTH_CHLG_PARAM, "");
6978
6979     ELEM_OPT_TLV(ANSI_A_E_MID, "");
6980
6981     ELEM_OPT_TV(ANSI_A_E_TAG, "");
6982
6983     ELEM_OPT_TLV(ANSI_A_E_CELL_ID_LIST, "");
6984
6985     ELEM_OPT_TV(ANSI_A_E_SCI, "");
6986
6987     EXTRANEOUS_DATA_CHECK(curr_len, 0);
6988 }
6989
6990 static void
6991 dtap_auth_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
6992 {
6993     guint32     curr_offset;
6994     guint32     consumed;
6995     guint       curr_len;
6996
6997     curr_offset = offset;
6998     curr_len = len;
6999
7000     ELEM_MAND_LV(ANSI_A_E_AUTH_CHLG_PARAM, "");
7001
7002     ELEM_OPT_TLV(ANSI_A_E_IS2000_MOB_CAP, "");
7003
7004     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7005 }
7006
7007 /*
7008  * IOS 6.1.4.2
7009  */
7010 static void
7011 bsmap_auth_resp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7012 {
7013     guint32     curr_offset;
7014     guint32     consumed;
7015     guint       curr_len;
7016
7017     curr_offset = offset;
7018     curr_len = len;
7019
7020     ELEM_MAND_TLV(ANSI_A_E_AUTH_RESP_PARAM, "");
7021
7022     ELEM_OPT_TLV(ANSI_A_E_MID, "");
7023
7024     ELEM_OPT_TV(ANSI_A_E_TAG, "");
7025
7026     ELEM_OPT_TLV(ANSI_A_E_MID, "");
7027
7028     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7029 }
7030
7031 static void
7032 dtap_auth_resp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7033 {
7034     guint32     curr_offset;
7035     guint32     consumed;
7036     guint       curr_len;
7037
7038     curr_offset = offset;
7039     curr_len = len;
7040
7041     ELEM_MAND_LV(ANSI_A_E_AUTH_RESP_PARAM, "");
7042
7043     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7044 }
7045
7046 /*
7047  * IOS 6.1.4.3
7048  */
7049 static void
7050 bsmap_user_zone_update(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7051 {
7052     guint32     curr_offset;
7053     guint32     consumed;
7054     guint       curr_len;
7055
7056     curr_offset = offset;
7057     curr_len = len;
7058
7059     ELEM_OPT_TLV(ANSI_A_E_UZ_ID, "");
7060
7061     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7062 }
7063
7064 /*
7065  * IOS 6.1.4.4
7066  */
7067 static void
7068 dtap_ssd_update_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7069 {
7070     guint32     curr_offset;
7071     guint32     consumed;
7072     guint       curr_len;
7073
7074     curr_offset = offset;
7075     curr_len = len;
7076
7077     ELEM_MAND_LV(ANSI_A_E_AUTH_CHLG_PARAM, "");
7078
7079     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7080 }
7081
7082 /*
7083  * IOS 6.1.4.5
7084  */
7085 static void
7086 dtap_bs_challenge(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7087 {
7088     guint32     curr_offset;
7089     guint32     consumed;
7090     guint       curr_len;
7091
7092     curr_offset = offset;
7093     curr_len = len;
7094
7095     ELEM_MAND_LV(ANSI_A_E_AUTH_CHLG_PARAM, "");
7096
7097     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7098 }
7099
7100 /*
7101  * IOS 6.1.4.6
7102  */
7103 static void
7104 dtap_bs_challenge_resp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7105 {
7106     guint32     curr_offset;
7107     guint32     consumed;
7108     guint       curr_len;
7109
7110     curr_offset = offset;
7111     curr_len = len;
7112
7113     ELEM_MAND_LV(ANSI_A_E_AUTH_RESP_PARAM, "");
7114
7115     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7116 }
7117
7118 /*
7119  * IOS 6.1.4.7
7120  */
7121 static void
7122 dtap_ssd_update_resp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7123 {
7124     guint32     curr_offset;
7125     guint32     consumed;
7126     guint       curr_len;
7127
7128     curr_offset = offset;
7129     curr_len = len;
7130
7131     ELEM_OPT_TLV(ANSI_A_E_CAUSE_L3, "");
7132
7133     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7134 }
7135
7136 /*
7137  * IOS 6.1.4.8
7138  */
7139 static void
7140 dtap_lu_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7141 {
7142     guint32     curr_offset;
7143     guint32     consumed;
7144     guint       curr_len;
7145
7146     curr_offset = offset;
7147     curr_len = len;
7148
7149     ELEM_MAND_LV(ANSI_A_E_MID, "");
7150
7151     ELEM_OPT_TV(ANSI_A_E_LAI, "");
7152
7153     ELEM_OPT_TLV(ANSI_A_E_CM_INFO_TYPE_2, "");
7154
7155     ELEM_OPT_TV(ANSI_A_E_REG_TYPE, "");
7156
7157     ELEM_OPT_TLV(ANSI_A_E_MID, "");
7158
7159     ELEM_OPT_TV(ANSI_A_E_SCI, "");
7160
7161     ELEM_OPT_TLV(ANSI_A_E_AUTH_RESP_PARAM, "");
7162
7163     ELEM_OPT_TV(ANSI_A_E_AUTH_CNF_PARAM, "");
7164
7165     ELEM_OPT_TV(ANSI_A_E_AUTH_PARAM_COUNT, "");
7166
7167     ELEM_OPT_TLV(ANSI_A_E_AUTH_CHLG_PARAM, "");
7168
7169     ELEM_OPT_TLV(ANSI_A_E_AUTH_EVENT, "");
7170
7171     ELEM_OPT_TLV(ANSI_A_E_UZ_ID, "");
7172
7173     ELEM_OPT_TLV(ANSI_A_E_IS2000_MOB_CAP, "");
7174
7175     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7176 }
7177
7178 /*
7179  * IOS 6.1.4.9
7180  */
7181 static void
7182 dtap_lu_accept(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7183 {
7184     guint32     curr_offset;
7185     guint32     consumed;
7186     guint       curr_len;
7187
7188     curr_offset = offset;
7189     curr_len = len;
7190
7191     ELEM_OPT_TV(ANSI_A_E_LAI, "");
7192
7193     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7194 }
7195
7196 /*
7197  * IOS 6.1.4.10
7198  */
7199 static void
7200 dtap_lu_reject(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7201 {
7202     guint32     curr_offset;
7203     guint32     consumed;
7204     guint       curr_len;
7205
7206     curr_offset = offset;
7207     curr_len = len;
7208
7209     ELEM_MAND_V(ANSI_A_E_REJ_CAUSE);
7210
7211     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7212 }
7213
7214 /*
7215  * IOS 6.1.4.18
7216  */
7217 static void
7218 bsmap_priv_mode_command(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7219 {
7220     guint32     curr_offset;
7221     guint32     consumed;
7222     guint       curr_len;
7223
7224     curr_offset = offset;
7225     curr_len = len;
7226
7227     ELEM_MAND_TLV(ANSI_A_E_ENC_INFO, "");
7228
7229     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7230 }
7231
7232 /*
7233  * IOS 6.1.4.19
7234  */
7235 static void
7236 bsmap_priv_mode_complete(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7237 {
7238     guint32     curr_offset;
7239     guint32     consumed;
7240     guint       curr_len;
7241
7242     curr_offset = offset;
7243     curr_len = len;
7244
7245     ELEM_OPT_TLV(ANSI_A_E_ENC_INFO, "");
7246
7247     ELEM_OPT_T(ANSI_A_E_VP_REQ, "");
7248
7249     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7250 }
7251
7252 /*
7253  * IOS 6.1.5.4
7254  */
7255 static void
7256 bsmap_ho_reqd(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7257 {
7258     guint32     curr_offset;
7259     guint32     consumed;
7260     guint       curr_len;
7261
7262     curr_offset = offset;
7263     curr_len = len;
7264
7265     ELEM_MAND_TLV(ANSI_A_E_CAUSE, "");
7266
7267     ELEM_MAND_TLV(ANSI_A_E_CELL_ID_LIST, " (Target)");
7268
7269     ELEM_OPT_TLV(ANSI_A_E_CM_INFO_TYPE_2, "");
7270
7271     ELEM_OPT_T(ANSI_A_E_RESP_REQ, "");
7272
7273     ELEM_OPT_TLV(ANSI_A_E_ENC_INFO, "");
7274
7275     ELEM_OPT_TLV(ANSI_A_E_IS95_CHAN_ID, "");
7276
7277     ELEM_OPT_TLV(ANSI_A_E_MID, "");
7278
7279     ELEM_OPT_TLV(ANSI_A_E_DOWNLINK_RE, "");
7280
7281     ELEM_OPT_TV(ANSI_A_E_SO, "");
7282
7283     ELEM_OPT_TLV(ANSI_A_E_CDMA_SOWD, "");
7284
7285     ELEM_OPT_TLV(ANSI_A_E_IS95_MS_MEAS_CHAN_ID, "");
7286
7287     ELEM_OPT_TLV(ANSI_A_E_IS2000_CHAN_ID, "");
7288
7289     ELEM_OPT_TLV(ANSI_A_E_QOS_PARAMS, "");
7290
7291     ELEM_OPT_TLV(ANSI_A_E_IS2000_MOB_CAP, "");
7292
7293     ELEM_OPT_TLV(ANSI_A_E_IS2000_SCR, "");
7294
7295     ELEM_OPT_TLV(ANSI_A_E_PDSN_IP_ADDR, "");
7296
7297     ELEM_OPT_TLV(ANSI_A_E_PTYPE, "");
7298
7299     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7300 }
7301
7302 /*
7303  * IOS 6.1.5.5
7304  */
7305 static void
7306 bsmap_ho_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7307 {
7308     guint32     curr_offset;
7309     guint32     consumed;
7310     guint       curr_len;
7311
7312     curr_offset = offset;
7313     curr_len = len;
7314
7315     ELEM_MAND_TLV(ANSI_A_E_CHAN_TYPE, "");
7316
7317     ELEM_MAND_TLV(ANSI_A_E_ENC_INFO, "");
7318
7319     ELEM_MAND_TLV(ANSI_A_E_CM_INFO_TYPE_2, "");
7320
7321     ELEM_MAND_TLV(ANSI_A_E_CELL_ID_LIST, "(Target)");
7322
7323     ELEM_OPT_TLV(ANSI_A_E_CIC_EXT, "");
7324
7325     ELEM_OPT_TLV(ANSI_A_E_IS95_CHAN_ID, "");
7326
7327     ELEM_OPT_TLV(ANSI_A_E_MID, "");
7328
7329     ELEM_OPT_TLV(ANSI_A_E_MID, "");
7330
7331     ELEM_OPT_TLV(ANSI_A_E_DOWNLINK_RE, "");
7332
7333     ELEM_OPT_TV(ANSI_A_E_SO, "");
7334
7335     ELEM_OPT_TLV(ANSI_A_E_CDMA_SOWD, "");
7336
7337     ELEM_OPT_TLV(ANSI_A_E_IS95_MS_MEAS_CHAN_ID, "");
7338
7339     ELEM_OPT_TLV(ANSI_A_E_IS2000_CHAN_ID, "");
7340
7341     ELEM_OPT_TLV(ANSI_A_E_QOS_PARAMS, "");
7342
7343     ELEM_OPT_TLV(ANSI_A_E_IS2000_MOB_CAP, "");
7344
7345     ELEM_OPT_TLV(ANSI_A_E_IS2000_SCR, "");
7346
7347     ELEM_OPT_TLV(ANSI_A_E_PDSN_IP_ADDR, "");
7348
7349     ELEM_OPT_TLV(ANSI_A_E_PTYPE, "");
7350
7351     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7352 }
7353
7354 /*
7355  * IOS 6.1.5.6
7356  */
7357 static void
7358 bsmap_ho_req_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7359 {
7360     guint32     curr_offset;
7361     guint32     consumed;
7362     guint       curr_len;
7363
7364     curr_offset = offset;
7365     curr_len = len;
7366
7367     ELEM_OPT_TLV(ANSI_A_E_IS95_CHAN_ID, "");
7368
7369     ELEM_OPT_TLV(ANSI_A_E_CELL_ID_LIST, "");
7370
7371     ELEM_OPT_TLV(ANSI_A_E_EXT_HO_DIR_PARAMS, "");
7372
7373     ELEM_OPT_TV(ANSI_A_E_HHO_PARAMS, "");
7374
7375     ELEM_OPT_TLV(ANSI_A_E_IS2000_CHAN_ID, "");
7376
7377     ELEM_OPT_TLV(ANSI_A_E_IS2000_SCR, "");
7378
7379     ELEM_OPT_TLV(ANSI_A_E_IS2000_NN_SCR, "");
7380
7381     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7382 }
7383
7384 /*
7385  * IOS 6.1.5.7
7386  */
7387 static void
7388 bsmap_ho_failure(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7389 {
7390     guint32     curr_offset;
7391     guint32     consumed;
7392     guint       curr_len;
7393
7394     curr_offset = offset;
7395     curr_len = len;
7396
7397     ELEM_MAND_TLV(ANSI_A_E_CAUSE, "");
7398
7399     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7400 }
7401
7402 /*
7403  * IOS 6.1.5.8
7404  */
7405 static void
7406 bsmap_ho_command(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7407 {
7408     guint32     curr_offset;
7409     guint32     consumed;
7410     guint       curr_len;
7411
7412     curr_offset = offset;
7413     curr_len = len;
7414
7415     ELEM_OPT_TV(ANSI_A_E_RF_CHAN_ID, "");
7416
7417     ELEM_OPT_TLV(ANSI_A_E_IS95_CHAN_ID, "");
7418
7419     ELEM_OPT_TLV(ANSI_A_E_CELL_ID_LIST, "");
7420
7421     ELEM_OPT_TLV(ANSI_A_E_HO_POW_LEV, "");
7422
7423     ELEM_OPT_TV(ANSI_A_E_SID, "");
7424
7425     ELEM_OPT_TLV(ANSI_A_E_EXT_HO_DIR_PARAMS, "");
7426
7427     ELEM_OPT_TV(ANSI_A_E_HHO_PARAMS, "");
7428
7429     ELEM_OPT_TLV(ANSI_A_E_IS2000_CHAN_ID, "");
7430
7431     ELEM_OPT_TLV(ANSI_A_E_IS2000_SCR, "");
7432
7433     ELEM_OPT_TLV(ANSI_A_E_IS2000_NN_SCR, "");
7434
7435     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7436 }
7437
7438 /*
7439  * IOS 6.1.5.9
7440  */
7441 static void
7442 bsmap_ho_reqd_rej(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7443 {
7444     guint32     curr_offset;
7445     guint32     consumed;
7446     guint       curr_len;
7447
7448     curr_offset = offset;
7449     curr_len = len;
7450
7451     ELEM_MAND_TLV(ANSI_A_E_CAUSE, "");
7452
7453     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7454 }
7455
7456 /*
7457  * IOS 6.1.5.12
7458  */
7459 static void
7460 bsmap_ho_performed(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7461 {
7462     guint32     curr_offset;
7463     guint32     consumed;
7464     guint       curr_len;
7465
7466     curr_offset = offset;
7467     curr_len = len;
7468
7469     ELEM_MAND_TLV(ANSI_A_E_CAUSE, "");
7470
7471     ELEM_OPT_TLV(ANSI_A_E_CELL_ID_LIST, "");
7472
7473     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7474 }
7475
7476 /*
7477  * IOS 6.1.6.2
7478  */
7479 static void
7480 bsmap_block(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7481 {
7482     guint32     curr_offset;
7483     guint32     consumed;
7484     guint       curr_len;
7485
7486     curr_offset = offset;
7487     curr_len = len;
7488
7489     ELEM_MAND_TV(ANSI_A_E_CIC, "");
7490
7491     ELEM_MAND_TLV(ANSI_A_E_CAUSE, "");
7492
7493     ELEM_OPT_TLV(ANSI_A_E_CCT_GROUP, "");
7494
7495     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7496 }
7497
7498 /*
7499  * IOS 6.1.6.3
7500  */
7501 static void
7502 bsmap_block_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7503 {
7504     guint32     curr_offset;
7505     guint32     consumed;
7506     guint       curr_len;
7507
7508     curr_offset = offset;
7509     curr_len = len;
7510
7511     ELEM_MAND_TV(ANSI_A_E_CIC, "");
7512
7513     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7514 }
7515
7516 /*
7517  * IOS 6.1.6.4
7518  */
7519 static void
7520 bsmap_unblock(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7521 {
7522     guint32     curr_offset;
7523     guint32     consumed;
7524     guint       curr_len;
7525
7526     curr_offset = offset;
7527     curr_len = len;
7528
7529     ELEM_MAND_TV(ANSI_A_E_CIC, "");
7530
7531     ELEM_OPT_TLV(ANSI_A_E_CCT_GROUP, "");
7532
7533     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7534 }
7535
7536 /*
7537  * IOS 6.1.6.5
7538  */
7539 static void
7540 bsmap_unblock_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7541 {
7542     guint32     curr_offset;
7543     guint32     consumed;
7544     guint       curr_len;
7545
7546     curr_offset = offset;
7547     curr_len = len;
7548
7549     ELEM_MAND_TV(ANSI_A_E_CIC, "");
7550
7551     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7552 }
7553
7554 /*
7555  * IOS 6.1.6.6
7556  */
7557 static void
7558 bsmap_reset(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7559 {
7560     guint32     curr_offset;
7561     guint32     consumed;
7562     guint       curr_len;
7563
7564     curr_offset = offset;
7565     curr_len = len;
7566
7567     ELEM_MAND_TLV(ANSI_A_E_CAUSE, "");
7568
7569     ELEM_OPT_TLV(ANSI_A_E_SW_VER, "");
7570
7571     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7572 }
7573
7574 /*
7575  * IOS 6.1.6.7
7576  */
7577 static void
7578 bsmap_reset_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7579 {
7580     guint32     curr_offset;
7581     guint32     consumed;
7582     guint       curr_len;
7583
7584     curr_offset = offset;
7585     curr_len = len;
7586
7587     ELEM_OPT_TLV(ANSI_A_E_SW_VER, "");
7588
7589     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7590 }
7591
7592 /*
7593  * IOS 6.1.6.8
7594  */
7595 static void
7596 bsmap_reset_cct(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7597 {
7598     guint32     curr_offset;
7599     guint32     consumed;
7600     guint       curr_len;
7601
7602     curr_offset = offset;
7603     curr_len = len;
7604
7605     ELEM_MAND_TV(ANSI_A_E_CIC, "");
7606
7607     ELEM_MAND_TLV(ANSI_A_E_CAUSE, "");
7608
7609     ELEM_OPT_TLV(ANSI_A_E_CCT_GROUP, "");
7610
7611     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7612 }
7613
7614 /*
7615  * IOS 6.1.6.9
7616  */
7617 static void
7618 bsmap_reset_cct_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7619 {
7620     guint32     curr_offset;
7621     guint32     consumed;
7622     guint       curr_len;
7623
7624     curr_offset = offset;
7625     curr_len = len;
7626
7627     ELEM_MAND_TV(ANSI_A_E_CIC, "");
7628
7629     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7630 }
7631
7632 /*
7633  * IOS 6.1.6.10
7634  */
7635 static void
7636 bsmap_xmode_req(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7637 {
7638     guint32     curr_offset;
7639     guint32     consumed;
7640     guint       curr_len;
7641
7642     curr_offset = offset;
7643     curr_len = len;
7644
7645     ELEM_MAND_TLV(ANSI_A_E_XMODE, "");
7646
7647     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7648 }
7649
7650 /*
7651  * IOS 6.1.6.11
7652  */
7653 static void
7654 bsmap_xmode_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7655 {
7656     guint32     curr_offset;
7657     guint32     consumed;
7658     guint       curr_len;
7659
7660     curr_offset = offset;
7661     curr_len = len;
7662
7663     ELEM_MAND_TLV(ANSI_A_E_CAUSE, "");
7664
7665     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7666 }
7667
7668 /*
7669  * IOS 6.1.7.1
7670  */
7671 static void
7672 bsmap_adds_page(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7673 {
7674     guint32     curr_offset;
7675     guint32     consumed;
7676     guint       curr_len;
7677
7678     curr_offset = offset;
7679     curr_len = len;
7680
7681     ELEM_MAND_TLV(ANSI_A_E_MID, "");
7682
7683     ELEM_MAND_TLV(ANSI_A_E_ADDS_USER_PART, "");
7684
7685     ELEM_OPT_TV(ANSI_A_E_TAG, "");
7686
7687     ELEM_OPT_TLV(ANSI_A_E_CELL_ID_LIST, "");
7688
7689     ELEM_OPT_TV(ANSI_A_E_SCI, "");
7690
7691     ELEM_OPT_TLV(ANSI_A_E_IS2000_MOB_CAP, "");
7692
7693     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7694 }
7695
7696 /*
7697  * IOS 6.1.7.2
7698  */
7699 static void
7700 bsmap_adds_transfer(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7701 {
7702     guint32     curr_offset;
7703     guint32     consumed;
7704     guint       curr_len;
7705
7706     curr_offset = offset;
7707     curr_len = len;
7708
7709     ELEM_MAND_TLV(ANSI_A_E_MID, "");
7710
7711     ELEM_MAND_TLV(ANSI_A_E_ADDS_USER_PART, "");
7712
7713     ELEM_OPT_TLV(ANSI_A_E_MID, "");
7714
7715     ELEM_OPT_TLV(ANSI_A_E_AUTH_RESP_PARAM, "");
7716
7717     ELEM_OPT_TV(ANSI_A_E_AUTH_CNF_PARAM, "");
7718
7719     ELEM_OPT_TV(ANSI_A_E_AUTH_PARAM_COUNT, "");
7720
7721     ELEM_OPT_TLV(ANSI_A_E_AUTH_CHLG_PARAM, "");
7722
7723     ELEM_OPT_TLV(ANSI_A_E_AUTH_EVENT, "");
7724
7725     ELEM_OPT_TLV(ANSI_A_E_CELL_ID, "");
7726
7727     ELEM_OPT_TLV(ANSI_A_E_CDMA_SOWD, "");
7728
7729     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7730 }
7731
7732 /*
7733  * IOS 6.1.7.3
7734  */
7735 static void
7736 dtap_adds_deliver(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7737 {
7738     guint32     curr_offset;
7739     guint32     consumed;
7740     guint       curr_len;
7741
7742     curr_offset = offset;
7743     curr_len = len;
7744
7745     ELEM_MAND_LV(ANSI_A_E_ADDS_USER_PART, "");
7746
7747     ELEM_OPT_TV(ANSI_A_E_TAG, "");
7748
7749     ELEM_OPT_TLV(ANSI_A_E_CDMA_SOWD, "");
7750
7751     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7752 }
7753
7754 /*
7755  * IOS 6.1.7.4
7756  */
7757 static void
7758 bsmap_adds_page_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7759 {
7760     guint32     curr_offset;
7761     guint32     consumed;
7762     guint       curr_len;
7763
7764     curr_offset = offset;
7765     curr_len = len;
7766
7767     ELEM_MAND_TLV(ANSI_A_E_MID, "");
7768
7769     ELEM_OPT_TV(ANSI_A_E_TAG, "");
7770
7771     ELEM_OPT_TLV(ANSI_A_E_MID, "");
7772
7773     ELEM_OPT_TLV(ANSI_A_E_CAUSE, "");
7774
7775     ELEM_OPT_TLV(ANSI_A_E_CELL_ID, "");
7776
7777     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7778 }
7779
7780 /*
7781  * IOS 6.1.7.5
7782  */
7783 static void
7784 dtap_adds_deliver_ack(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7785 {
7786     guint32     curr_offset;
7787     guint32     consumed;
7788     guint       curr_len;
7789
7790     curr_offset = offset;
7791     curr_len = len;
7792
7793     ELEM_OPT_TV(ANSI_A_E_TAG, "");
7794
7795     ELEM_OPT_TLV(ANSI_A_E_CAUSE, "");
7796
7797     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7798 }
7799
7800 /*
7801  * IOS 6.1.8.1
7802  */
7803 static void
7804 bsmap_rejection(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7805 {
7806     guint32     curr_offset;
7807     guint32     consumed;
7808     guint       curr_len;
7809
7810     curr_offset = offset;
7811     curr_len = len;
7812
7813     ELEM_OPT_TLV(ANSI_A_E_MID, "");
7814
7815     ELEM_OPT_TLV(ANSI_A_E_MID, "");
7816
7817     ELEM_OPT_TLV(ANSI_A_E_IS2000_CAUSE, "");
7818
7819     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7820 }
7821
7822 static void
7823 dtap_rejection(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len)
7824 {
7825     guint32     curr_offset;
7826     guint32     consumed;
7827     guint       curr_len;
7828
7829     curr_offset = offset;
7830     curr_len = len;
7831
7832     ELEM_OPT_TLV(ANSI_A_E_IS2000_CAUSE, "");
7833
7834     EXTRANEOUS_DATA_CHECK(curr_len, 0);
7835 }
7836
7837 #define ANSI_A_IOS401_BSMAP_NUM_MSG (sizeof(ansi_a_ios401_bsmap_strings)/sizeof(value_string))
7838 static gint ett_bsmap_msg[ANSI_A_IOS401_BSMAP_NUM_MSG];
7839 static void (*bsmap_msg_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
7840     NULL,       /* Additional Service Notification */
7841     bsmap_adds_page,    /* ADDS Page */
7842     bsmap_adds_page_ack,        /* ADDS Page Ack */
7843     bsmap_adds_transfer,        /* ADDS Transfer */
7844     NULL,       /* ADDS Transfer Ack */
7845     bsmap_ass_complete, /* Assignment Complete */
7846     bsmap_ass_failure,  /* Assignment Failure */
7847     bsmap_ass_req,      /* Assignment Request */
7848     bsmap_auth_req,     /* Authentication Request */
7849     bsmap_auth_resp,    /* Authentication Response */
7850     NULL,       /* Base Station Challenge */
7851     NULL,       /* Base Station Challenge Response */
7852     bsmap_block,        /* Block */
7853     bsmap_block_ack,    /* Block Acknowledge */
7854     bsmap_bs_srvc_req,  /* BS Service Request */
7855     bsmap_bs_srvc_resp, /* BS Service Response */
7856     bsmap_clr_command,  /* Clear Command */
7857     bsmap_clr_complete, /* Clear Complete */
7858     bsmap_clr_req,      /* Clear Request */
7859     bsmap_cl3_info,     /* Complete Layer 3 Information */
7860     bsmap_feat_noti,    /* Feature Notification */
7861     bsmap_feat_noti_ack,        /* Feature Notification Ack */
7862     bsmap_ho_command,   /* Handoff Command */
7863     NULL /* no associated data */,      /* Handoff Commenced */
7864     NULL /* no associated data */,      /* Handoff Complete */
7865     bsmap_ho_failure,   /* Handoff Failure */
7866     bsmap_ho_performed, /* Handoff Performed */
7867     bsmap_ho_req,       /* Handoff Request */
7868     bsmap_ho_req_ack,   /* Handoff Request Acknowledge */
7869     bsmap_ho_reqd,      /* Handoff Required */
7870     bsmap_ho_reqd_rej,  /* Handoff Required Reject */
7871     bsmap_paca_command, /* PACA Command */
7872     bsmap_paca_command_ack,     /* PACA Command Ack */
7873     bsmap_paca_update,  /* PACA Update */
7874     bsmap_paca_update_ack,      /* PACA Update Ack */
7875     bsmap_page_req,     /* Paging Request */
7876     bsmap_priv_mode_command,    /* Privacy Mode Command */
7877     bsmap_priv_mode_complete,   /* Privacy Mode Complete */
7878     NULL,       /* Radio Measurements for Position Request */
7879     NULL,       /* Radio Measurements for Position Response */
7880     bsmap_rejection,    /* Rejection */
7881     NULL,       /* Registration Request */
7882     bsmap_reset,        /* Reset */
7883     bsmap_reset_ack,    /* Reset Acknowledge */
7884     bsmap_reset_cct,    /* Reset Circuit */
7885     bsmap_reset_cct_ack,        /* Reset Circuit Acknowledge */
7886     NULL,       /* SSD Update Request */
7887     NULL,       /* SSD Update Response */
7888     NULL,       /* Status Request */
7889     NULL,       /* Status Response */
7890     bsmap_xmode_ack,    /* Transcoder Control Acknowledge */
7891     bsmap_xmode_req,    /* Transcoder Control Request */
7892     bsmap_unblock,      /* Unblock */
7893     bsmap_unblock_ack,  /* Unblock Acknowledge */
7894     NULL,       /* User Zone Reject */
7895     bsmap_user_zone_update,     /* User Zone Update */
7896     NULL,       /* NONE */
7897 };
7898
7899 #define ANSI_A_IOS401_DTAP_NUM_MSG (sizeof(ansi_a_ios401_dtap_strings)/sizeof(value_string))
7900 static gint ett_dtap_msg[ANSI_A_IOS401_DTAP_NUM_MSG];
7901 static void (*dtap_msg_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len) = {
7902     NULL,       /* Additional Service Request */
7903     dtap_adds_deliver,  /* ADDS Deliver */
7904     dtap_adds_deliver_ack,      /* ADDS Deliver Ack */
7905     dtap_alert_with_info,       /* Alert With Information */
7906     dtap_auth_req,      /* Authentication Request */
7907     dtap_auth_resp,     /* Authentication Response */
7908     dtap_bs_challenge,  /* Base Station Challenge */
7909     dtap_bs_challenge_resp,     /* Base Station Challenge Response */
7910     dtap_cm_srvc_req,   /* CM Service Request */
7911     NULL,       /* CM Service Request Continuation */
7912     NULL /* no associated data */,      /* Connect */
7913     dtap_flash_with_info,       /* Flash with Information */
7914     dtap_flash_with_info_ack,   /* Flash with Information Ack */
7915     dtap_lu_accept,     /* Location Updating Accept */
7916     dtap_lu_reject,     /* Location Updating Reject */
7917     dtap_lu_req,        /* Location Updating Request */
7918     dtap_page_resp,     /* Paging Response */
7919     NULL /* no associated data */,      /* Parameter Update Confirm */
7920     NULL /* no associated data */,      /* Parameter Update Request */
7921     dtap_rejection,     /* Rejection */
7922     dtap_progress,      /* Progress */
7923     NULL,       /* Service Redirection */
7924     NULL,       /* Service Release */
7925     NULL,       /* Service Release Complete */
7926     dtap_ssd_update_req,        /* SSD Update Request */
7927     dtap_ssd_update_resp,       /* SSD Update Response */
7928     NULL,       /* Status Request */
7929     NULL,       /* Status Response */
7930     NULL,       /* User Zone Reject */
7931     NULL,       /* User Zone Update */
7932     NULL,       /* User Zone Update Request */
7933     NULL,       /* NONE */
7934 };
7935
7936 /* GENERIC MAP DISSECTOR FUNCTIONS */
7937
7938 static void
7939 dissect_bsmap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
7940 {
7941     static ansi_a_tap_rec_t     tap_rec[4];
7942     static ansi_a_tap_rec_t     *tap_p;
7943     static int                  tap_current=0;
7944     guint8                      oct;
7945     guint32                     offset, saved_offset;
7946     guint32                     len;
7947     gint                        idx;
7948     proto_item                  *bsmap_item = NULL;
7949     proto_tree                  *bsmap_tree = NULL;
7950     gchar                       *msg_str;
7951
7952
7953     if (check_col(pinfo->cinfo, COL_INFO))
7954     {
7955         col_append_str(pinfo->cinfo, COL_INFO, "(BSMAP) ");
7956     }
7957
7958     /*
7959      * set tap record pointer
7960      */
7961     tap_current++;
7962     if (tap_current == 4)
7963     {
7964         tap_current = 0;
7965     }
7966     tap_p = &tap_rec[tap_current];
7967
7968
7969     offset = 0;
7970     saved_offset = offset;
7971
7972     g_pinfo = pinfo;
7973     g_tree = tree;
7974
7975     len = tvb_length(tvb);
7976
7977     /*
7978      * add BSMAP message name
7979      */
7980     oct = tvb_get_guint8(tvb, offset++);
7981
7982     msg_str = my_match_strval((guint32) oct, ansi_a_ios401_bsmap_strings, &idx);
7983
7984     /*
7985      * create the a protocol tree
7986      */
7987     if (msg_str == NULL)
7988     {
7989         bsmap_item =
7990             proto_tree_add_protocol_format(tree, proto_a_bsmap, tvb, 0, len,
7991                 "ANSI A-I/F BSMAP - Unknown BSMAP Message Type (%u)",
7992                 oct);
7993
7994         bsmap_tree = proto_item_add_subtree(bsmap_item, ett_bsmap);
7995     }
7996     else
7997     {
7998         bsmap_item =
7999             proto_tree_add_protocol_format(tree, proto_a_bsmap, tvb, 0, -1,
8000                 "ANSI A-I/F BSMAP - %s",
8001                 msg_str);
8002
8003         bsmap_tree = proto_item_add_subtree(bsmap_item, ett_bsmap_msg[idx]);
8004
8005         if (check_col(pinfo->cinfo, COL_INFO))
8006         {
8007             col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", msg_str);
8008         }
8009     }
8010
8011     /*
8012      * add BSMAP message name
8013      */
8014     proto_tree_add_uint_format(bsmap_tree, hf_ansi_a_bsmap_msgtype,
8015         tvb, saved_offset, 1, oct, "Message Type");
8016
8017     tap_p->pdu_type = BSSAP_PDU_TYPE_BSMAP;
8018     tap_p->message_type = oct;
8019
8020     tap_queue_packet(ansi_a_tap, pinfo, tap_p);
8021
8022     if (msg_str == NULL) return;
8023
8024     if ((len - offset) <= 0) return;
8025
8026     /*
8027      * decode elements
8028      */
8029     if (bsmap_msg_fcn[idx] == NULL)
8030     {
8031         proto_tree_add_text(bsmap_tree,
8032             tvb, offset, len - offset,
8033             "Message Elements");
8034     }
8035     else
8036     {
8037         (*bsmap_msg_fcn[idx])(tvb, bsmap_tree, offset, len - offset);
8038     }
8039 }
8040
8041 static void
8042 dissect_dtap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
8043 {
8044     static ansi_a_tap_rec_t     tap_rec[4];
8045     static ansi_a_tap_rec_t     *tap_p;
8046     static int                  tap_current=0;
8047     guint8                      oct;
8048     guint32                     offset, saved_offset;
8049     guint32                     len;
8050     guint32                     oct_1, oct_2;
8051     gint                        idx;
8052     proto_item                  *dtap_item = NULL;
8053     proto_tree                  *dtap_tree = NULL;
8054     proto_item                  *oct_1_item = NULL;
8055     proto_tree                  *oct_1_tree = NULL;
8056     gchar                       *msg_str;
8057     gchar                       *str;
8058
8059
8060     len = tvb_length(tvb);
8061
8062     if (len < 3)
8063     {
8064         /*
8065          * too short to be DTAP
8066          */
8067         call_dissector(data_handle, tvb, pinfo, tree);
8068         return;
8069     }
8070
8071     if (check_col(pinfo->cinfo, COL_INFO))
8072     {
8073         col_append_str(pinfo->cinfo, COL_INFO, "(DTAP) ");
8074     }
8075
8076     /*
8077      * set tap record pointer
8078      */
8079     tap_current++;
8080     if (tap_current == 4)
8081     {
8082         tap_current = 0;
8083     }
8084     tap_p = &tap_rec[tap_current];
8085
8086
8087     offset = 0;
8088     saved_offset = offset;
8089
8090     g_pinfo = pinfo;
8091     g_tree = tree;
8092
8093     /*
8094      * get protocol discriminator
8095      */
8096     oct_1 = tvb_get_guint8(tvb, offset++);
8097     oct_2 = tvb_get_guint8(tvb, offset++);
8098
8099     /*
8100      * add DTAP message name
8101      */
8102     saved_offset = offset;
8103     oct = tvb_get_guint8(tvb, offset++);
8104
8105     msg_str = my_match_strval((guint32) oct, ansi_a_ios401_dtap_strings, &idx);
8106
8107     /*
8108      * create the a protocol tree
8109      */
8110     if (msg_str == NULL)
8111     {
8112         dtap_item =
8113             proto_tree_add_protocol_format(tree, proto_a_dtap, tvb, 0, len,
8114                 "ANSI A-I/F DTAP - Unknown DTAP Message Type (%u)",
8115                 oct);
8116
8117         dtap_tree = proto_item_add_subtree(dtap_item, ett_dtap);
8118     }
8119     else
8120     {
8121         dtap_item =
8122             proto_tree_add_protocol_format(tree, proto_a_dtap, tvb, 0, -1,
8123                 "ANSI A-I/F DTAP - %s",
8124                 msg_str);
8125
8126         dtap_tree = proto_item_add_subtree(dtap_item, ett_dtap_msg[idx]);
8127
8128         if (check_col(pinfo->cinfo, COL_INFO))
8129         {
8130             col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", msg_str);
8131         }
8132     }
8133
8134     /*
8135      * octet 1
8136      */
8137     switch (oct_1 & 0x0f)
8138     {
8139     case 3: str = "Call Control, call related SS"; break;
8140     case 5: str = "Mobility Management"; break;
8141     case 6: str = "Radio Resource Management"; break;
8142     case 9: str = "Facility Management"; break;
8143     case 11: str = "Other Signaling Procedures"; break;
8144     case 15: str = "Reserved for tests"; break;
8145     default:
8146         str = "Unknown";
8147         break;
8148     }
8149
8150     oct_1_item =
8151         proto_tree_add_text(dtap_tree,
8152             tvb, 0, 1,
8153             "Protocol Discriminator: %s",
8154             str);
8155
8156     oct_1_tree = proto_item_add_subtree(oct_1_item, ett_dtap_oct_1);
8157
8158     other_decode_bitfield_value(a_bigbuf, oct_1, 0xf0, 8);
8159     proto_tree_add_text(oct_1_tree,
8160         tvb, 0, 1,
8161         "%s :  Reserved",
8162         a_bigbuf);
8163
8164     other_decode_bitfield_value(a_bigbuf, oct_1, 0x0f, 8);
8165     proto_tree_add_text(oct_1_tree,
8166         tvb, 0, 1,
8167         "%s :  Protocol Discriminator: %u",
8168         a_bigbuf,
8169         oct_1 & 0x0f);
8170
8171     /*
8172      * octet 2
8173      */
8174     switch (a_variant)
8175     {
8176     case A_VARIANT_IS634:
8177         other_decode_bitfield_value(a_bigbuf, oct_2, 0x80, 8);
8178         proto_tree_add_text(dtap_tree,
8179             tvb, 1, 1,
8180             "%s :  Transaction Identifier (TI) Flag: %s",
8181             a_bigbuf,
8182             ((oct_2 & 0x80) ?  "allocated by receiver" : "allocated by sender"));
8183
8184         other_decode_bitfield_value(a_bigbuf, oct_2, 0x70, 8);
8185         proto_tree_add_text(dtap_tree,
8186             tvb, 1, 1,
8187             "%s :  Transaction Identifier (TI): %u",
8188             a_bigbuf,
8189             (oct_2 & 0x70) >> 4);
8190
8191         other_decode_bitfield_value(a_bigbuf, oct_2, 0x0f, 8);
8192         proto_tree_add_text(dtap_tree,
8193             tvb, 1, 1,
8194             "%s :  Reserved",
8195             a_bigbuf);
8196         break;
8197
8198     default:
8199         proto_tree_add_text(dtap_tree,
8200             tvb, 1, 1,
8201             "Reserved Octet");
8202         break;
8203     }
8204
8205     /*
8206      * add DTAP message name
8207      */
8208     proto_tree_add_uint_format(dtap_tree, hf_ansi_a_dtap_msgtype,
8209         tvb, saved_offset, 1, oct,
8210         "Message Type");
8211
8212     tap_p->pdu_type = BSSAP_PDU_TYPE_DTAP;
8213     tap_p->message_type = oct;
8214
8215     tap_queue_packet(ansi_a_tap, pinfo, tap_p);
8216
8217     if (msg_str == NULL) return;
8218
8219     if ((len - offset) <= 0) return;
8220
8221     /*
8222      * decode elements
8223      */
8224     if (dtap_msg_fcn[idx] == NULL)
8225     {
8226         proto_tree_add_text(dtap_tree,
8227             tvb, offset, len - offset,
8228             "Message Elements");
8229     }
8230     else
8231     {
8232         (*dtap_msg_fcn[idx])(tvb, dtap_tree, offset, len - offset);
8233     }
8234 }
8235
8236
8237 /* Register the protocol with Ethereal */
8238 void
8239 proto_register_ansi_a(void)
8240 {
8241     module_t            *ansi_a_module;
8242     guint               i;
8243     gint                last_offset;
8244
8245     /* Setup list of header fields */
8246
8247     static hf_register_info hf[] =
8248     {
8249         { &hf_ansi_a_bsmap_msgtype,
8250             { "BSMAP Message Type",     "ansi_a.bsmap_msgtype",
8251             FT_UINT8, BASE_HEX, VALS(ansi_a_ios401_bsmap_strings), 0x0,
8252             "", HFILL }
8253         },
8254         { &hf_ansi_a_dtap_msgtype,
8255             { "DTAP Message Type",      "ansi_a.dtap_msgtype",
8256             FT_UINT8, BASE_HEX, VALS(ansi_a_ios401_dtap_strings), 0x0,
8257             "", HFILL }
8258         },
8259         { &hf_ansi_a_elem_id,
8260             { "Element ID",     "ansi_a.elem_id",
8261             FT_UINT8, BASE_DEC, VALS(ansi_a_ios401_elem_1_strings), 0,
8262             "", HFILL }
8263         },
8264         { &hf_ansi_a_length,
8265             { "Length",         "ansi_a.len",
8266             FT_UINT8, BASE_DEC, NULL, 0,
8267             "", HFILL }
8268         },
8269         { &hf_ansi_a_none,
8270             { "Sub tree",       "ansi_a.none",
8271             FT_NONE, 0, 0, 0,
8272             "", HFILL }
8273         },
8274         { &hf_ansi_a_esn,
8275             { "ESN",    "ansi_a.esn",
8276             FT_UINT32, BASE_HEX, 0, 0x0,
8277             "", HFILL }
8278         },
8279         { &hf_ansi_a_imsi,
8280             { "IMSI",   "ansi_a.imsi",
8281             FT_STRING, BASE_DEC, 0, 0,
8282             "", HFILL }
8283         },
8284         { &hf_ansi_a_min,
8285             { "MIN",    "ansi_a.min",
8286             FT_STRING, BASE_DEC, 0, 0,
8287             "", HFILL }
8288         },
8289         { &hf_ansi_a_cld_party_bcd_num,
8290             { "Called Party BCD Number",        "ansi_a.cld_party_bcd_num",
8291             FT_STRING, BASE_DEC, 0, 0,
8292             "", HFILL }
8293         },
8294         { &hf_ansi_a_clg_party_bcd_num,
8295             { "Calling Party BCD Number",       "ansi_a.clg_party_bcd_num",
8296             FT_STRING, BASE_DEC, 0, 0,
8297             "", HFILL }
8298         },
8299         { &hf_ansi_a_cld_party_ascii_num,
8300             { "Called Party ASCII Number",      "ansi_a.cld_party_ascii_num",
8301             FT_STRING, BASE_DEC, 0, 0,
8302             "", HFILL }
8303         },
8304         { &hf_ansi_a_clg_party_ascii_num,
8305             { "Calling Party ASCII Number",     "ansi_a.clg_party_ascii_num",
8306             FT_STRING, BASE_DEC, 0, 0,
8307             "", HFILL }
8308         },
8309         { &hf_ansi_a_cell_ci,
8310             { "Cell CI",        "ansi_a.cell_ci",
8311             FT_UINT16, BASE_HEX, 0, 0x0,
8312             "", HFILL }
8313         },
8314         { &hf_ansi_a_cell_lac,
8315             { "Cell LAC",       "ansi_a.cell_lac",
8316             FT_UINT16, BASE_HEX, 0, 0x0,
8317             "", HFILL }
8318         },
8319         { &hf_ansi_a_cell_mscid,
8320             { "Cell MSCID",     "ansi_a.cell_mscid",
8321             FT_UINT24, BASE_HEX, 0, 0x0,
8322             "", HFILL }
8323         },
8324         { &hf_ansi_a_pdsn_ip_addr,
8325             { "PDSN IP Address", "ansi_a.pdsn_ip_addr",
8326             FT_IPv4, BASE_NONE, NULL, 0,
8327             "IP Address", HFILL}},
8328     };
8329
8330     static enum_val_t a_variant_options[] = {
8331             { "IS-634 rev. 0",  A_VARIANT_IS634 },
8332             { "TSB-80",         A_VARIANT_TSB80 },
8333             { "IS-634-A",       A_VARIANT_IS634A },
8334             { "IOS 2.x",        A_VARIANT_IOS2 },
8335             { "IOS 3.x",        A_VARIANT_IOS3 },
8336             { "IOS 4.0.1",      A_VARIANT_IOS401 },
8337             { NULL,             0 }
8338
8339     };
8340
8341     /* Setup protocol subtree array */
8342 #define MAX_NUM_DTAP_MSG        ANSI_A_MAX(ANSI_A_IOS401_DTAP_NUM_MSG, 0)
8343 #define MAX_NUM_BSMAP_MSG       ANSI_A_MAX(ANSI_A_IOS401_BSMAP_NUM_MSG, 0)
8344 #define NUM_INDIVIDUAL_ELEMS    9
8345     gint **ett;
8346     gint ett_len = (NUM_INDIVIDUAL_ELEMS+MAX_NUM_DTAP_MSG+MAX_NUM_BSMAP_MSG+NUM_ELEM_1+NUM_MS_INFO_REC) * sizeof(gint *);
8347
8348     /*
8349      * XXX - at least one version of the HP C compiler apparently doesn't
8350      * recognize constant expressions using the "?" operator as being
8351      * constant expressions, so you can't use the expression that
8352      * initializes "ett_let" as an array size.  Therefore, we dynamically
8353      * allocate the array instead.
8354      */
8355     ett = g_malloc(ett_len);
8356
8357     memset((void *) ett_dtap_msg, -1, sizeof(gint) * MAX_NUM_DTAP_MSG);
8358     memset((void *) ett_bsmap_msg, -1, sizeof(gint) * MAX_NUM_BSMAP_MSG);
8359     memset((void *) ett_ansi_elem_1, -1, sizeof(gint) * NUM_ELEM_1);
8360     memset((void *) ett_ansi_ms_info_rec, -1, sizeof(gint) * NUM_MS_INFO_REC);
8361
8362     ett[0] = &ett_bsmap;
8363     ett[1] = &ett_dtap;
8364     ett[2] = &ett_elems;
8365     ett[3] = &ett_elem;
8366     ett[4] = &ett_dtap_oct_1;
8367     ett[5] = &ett_cm_srvc_type;
8368     ett[6] = &ett_ansi_ms_info_rec_reserved;
8369     ett[7] = &ett_ansi_enc_info;
8370     ett[8] = &ett_cell_list;
8371
8372     last_offset = NUM_INDIVIDUAL_ELEMS;
8373
8374     for (i=0; i < MAX_NUM_DTAP_MSG; i++, last_offset++)
8375     {
8376         ett[last_offset] = &ett_dtap_msg[i];
8377     }
8378
8379     for (i=0; i < MAX_NUM_BSMAP_MSG; i++, last_offset++)
8380     {
8381         ett[last_offset] = &ett_bsmap_msg[i];
8382     }
8383
8384     for (i=0; i < NUM_ELEM_1; i++, last_offset++)
8385     {
8386         ett[last_offset] = &ett_ansi_elem_1[i];
8387     }
8388
8389     for (i=0; i < NUM_MS_INFO_REC; i++, last_offset++)
8390     {
8391         ett[last_offset] = &ett_ansi_ms_info_rec[i];
8392     }
8393
8394     /* Register the protocol name and description */
8395
8396     proto_a_bsmap =
8397         proto_register_protocol("ANSI A-I/F BSMAP", "ANSI BSMAP", "ansi_a_bsmap");
8398
8399     proto_register_field_array(proto_a_bsmap, hf, array_length(hf));
8400
8401     proto_a_dtap =
8402         proto_register_protocol("ANSI A-I/F DTAP", "ANSI DTAP", "ansi_a_dtap");
8403
8404     is637_dissector_table =
8405         register_dissector_table("ansi_a.sms", "IS-637-A (SMS)",
8406         FT_UINT8, BASE_DEC);
8407
8408     is683_dissector_table =
8409         register_dissector_table("ansi_a.ota", "IS-683-A (OTA)",
8410         FT_UINT8, BASE_DEC);
8411
8412     is801_dissector_table =
8413         register_dissector_table("ansi_a.pld", "IS-801 (PLD)",
8414         FT_UINT8, BASE_DEC);
8415
8416     proto_register_subtree_array(ett, ett_len / sizeof(gint *));
8417
8418     ansi_a_tap = register_tap("ansi_a");
8419
8420     /*
8421      * setup for preferences
8422      */
8423     ansi_a_module = prefs_register_protocol(proto_a_bsmap, proto_reg_handoff_ansi_a);
8424
8425     prefs_register_enum_preference(ansi_a_module,
8426         "global_variant",
8427         "Dissect PDU as",
8428         "(if other than the default of IOS 4.0.1)",
8429         &a_global_variant,
8430         a_variant_options,
8431         FALSE);
8432
8433     g_free(ett);
8434 }
8435
8436
8437 void
8438 proto_reg_handoff_ansi_a(void)
8439 {
8440     static int                  ansi_a_prefs_initialized = FALSE;
8441
8442
8443     if (!ansi_a_prefs_initialized)
8444     {
8445         bsmap_handle = create_dissector_handle(dissect_bsmap, proto_a_bsmap);
8446         dtap_handle = create_dissector_handle(dissect_dtap, proto_a_dtap);
8447
8448         ansi_a_prefs_initialized = TRUE;
8449     }
8450     else
8451     {
8452         dissector_delete("bsap.pdu_type",  BSSAP_PDU_TYPE_BSMAP, bsmap_handle);
8453         dissector_delete("bsap.pdu_type",  BSSAP_PDU_TYPE_DTAP, dtap_handle);
8454     }
8455
8456     if (a_variant != a_global_variant)
8457     {
8458         a_variant = a_global_variant;
8459     }
8460
8461     dissector_add("bsap.pdu_type",  BSSAP_PDU_TYPE_BSMAP, bsmap_handle);
8462     dissector_add("bsap.pdu_type",  BSSAP_PDU_TYPE_DTAP, dtap_handle);
8463
8464     data_handle = find_dissector("data");
8465 }