emem -> wmem conversion:
[metze/wireshark/wip.git] / epan / dissectors / packet-gsm_a_common.c
1 /* packet-gsm_a_common.c
2  * Common routines for GSM A Interface dissection
3  *
4  * Copyright 2003, Michael Lum <mlum [AT] telostech.com>
5  * In association with Telos Technology Inc.
6  *
7  * Split from packet-gsm_a.c by Neil Piercy <Neil [AT] littlebriars.co.uk>
8  *
9  * $Id$
10  *
11  * Wireshark - Network traffic analyzer
12  * By Gerald Combs <gerald@wireshark.org>
13  * Copyright 1998 Gerald Combs
14  *
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28  */
29
30 #include "config.h"
31
32 #include <math.h>
33
34 #include <glib.h>
35
36 #include <epan/packet.h>
37 #include <epan/expert.h>
38 #include <epan/tap.h>
39 #include <epan/wmem/wmem.h>
40
41 #include "packet-bssap.h"
42 #include "packet-sccp.h"
43 #include "packet-gsm_a_common.h"
44 #include "packet-gmr1_common.h"
45 #include "packet-e212.h"
46
47
48 static const value_string gsm_common_elem_strings[] = {
49     /* Common Information Elements 10.5.1 */
50     { DE_CELL_ID, "Cell Identity" },
51     { DE_CIPH_KEY_SEQ_NUM, "Ciphering Key Sequence Number" },
52     { DE_LAI, "Location Area Identification (LAI)" },
53     { DE_MID, "Mobile Identity" },
54     { DE_MS_CM_1, "Mobile Station Classmark 1" },
55     { DE_MS_CM_2, "Mobile Station Classmark 2" },
56     { DE_MS_CM_3, "Mobile Station Classmark 3" },
57     { DE_SPARE_NIBBLE, "Spare Half Octet" },
58     { DE_D_GB_CALL_REF, "Descriptive group or broadcast call reference" },
59     { DE_G_CIPH_KEY_NUM, "Group Cipher Key Number" },
60     { DE_PD_SAPI, "PD and SAPI $(CCBS)$" },
61     { DE_PRIO, "Priority Level" },
62     { DE_CN_COMMON_GSM_MAP_NAS_SYS_INFO, "CN Common GSM-MAP NAS system information" },
63     { DE_CS_DOMAIN_SPEC_SYS_INFO, "CS domain specific system information" },
64     { DE_PS_DOMAIN_SPEC_SYS_INFO, "PS domain specific system information" },
65     { DE_PLMN_LIST, "PLMN List" },
66     { DE_NAS_CONT_FOR_PS_HO, "NAS container for PS HO" },
67     { DE_MS_NET_FEAT_SUP, "MS network feature support" },
68     { 0, NULL }
69 };
70 value_string_ext gsm_common_elem_strings_ext = VALUE_STRING_EXT_INIT(gsm_common_elem_strings);
71
72 static const value_string gsm_a_skip_ind_vals[] = {
73     { 0, "No indication of selected PLMN"},
74     { 1, "PLMN identity of the Common PLMN in the broadcast system information"},
75     { 2, "PLMN identity of the first Additional PLMN in the broadcast system information"},
76     { 3, "PLMN identity of the second Additional PLMN in the broadcast system information"},
77     { 4, "PLMN identity of the third Additional PLMN in the broadcast sytem information"},
78     { 5, "PLMN identity of the fourth Additional PLMN in the broadcast system information"},
79     { 6, "Reserved"},
80     { 7, "Reserved"},
81     { 0, NULL }
82 };
83
84 static const true_false_string gsm_a_extension_value = {
85     "No Extension",
86     "Extended"
87 };
88
89
90 /* Mobile Station Classmark Value strings
91  */
92
93 /* Mobile Station Classmark
94  * Revision level
95  */
96 static const value_string gsm_a_msc_rev_vals[] = {
97     { 0, "Reserved for GSM phase 1"},
98     { 1, "Used by GSM phase 2 mobile stations"},
99     { 2, "Used by mobile stations supporting R99 or later versions of the protocol"},
100     { 3, "Reserved for future use"},
101     { 0, NULL }
102 };
103
104 /* ES IND (octet 3, bit 5) "Controlled Early Classmark Sending" option implementation */
105 static const true_false_string ES_IND_vals = {
106     "Controlled Early Classmark Sending option is implemented in the MS",
107     "Controlled Early Classmark Sending option is not implemented in the MS"
108 };
109 /* A5/1 algorithm supported (octet 3, bit 4) */
110 static const true_false_string A5_1_algorithm_sup_vals = {
111     "encryption algorithm A5/1 not available",
112     "encryption algorithm A5/1 available"
113 };
114 /* RF Power Capability (Octet 3) */
115 static const value_string RF_power_capability_vals[] = {
116     { 0, "class 1"},
117     { 1, "class 2"},
118     { 2, "class 3"},
119     { 3, "class 4"},
120     { 4, "class 5"},
121     { 7, "RF Power capability is irrelevant in this information element"},
122     { 0, NULL }
123 };
124 /* PS capability (pseudo-synchronization capability) (octet 4) */
125 static const true_false_string ps_sup_cap_vals = {
126     "PS capability present",
127     "PS capability not present"
128 };
129 /* SS Screening Indicator (octet 4)defined in 3GPP TS 24.080 */
130 static const value_string SS_screening_indicator_vals[] = {
131     { 0, "Default value of phase 1"},
132     { 1, "Capability of handling of ellipsis notation and phase 2 error handling "},
133     { 2, "For future use"},
134     { 3, "For future use"},
135     { 0, NULL }
136 };
137 /* SM capability (MT SMS pt to pt capability) (octet 4)*/
138 static const true_false_string SM_capability_vals = {
139     "Mobile station supports mobile terminated point to point SMS",
140     "Mobile station does not support mobile terminated point to point SMS"
141 };
142 /* VBS notification reception (octet 4) */
143 static const true_false_string VBS_notification_rec_vals = {
144     "VBS capability and notifications wanted",
145     "no VBS capability or no notifications wanted"
146 };
147 /* VGCS notification reception (octet 4) */
148 static const true_false_string VGCS_notification_rec_vals = {
149     "VGCS capability and notifications wanted",
150     "no VGCS capability or no notifications wanted"
151 };
152 /* FC Frequency Capability (octet 4 ) */
153 static const true_false_string FC_frequency_cap_vals = {
154     "The MS does support the E-GSM or R-GSM",
155     "The MS does not support the E-GSM or R-GSM band"
156 };
157 /* CM3 (octet 5, bit 8) */
158 static const true_false_string CM3_vals = {
159     "The MS supports options that are indicated in classmark 3 IE",
160     "The MS does not support any options that are indicated in CM3"
161 };
162 /* LCS VA capability (LCS value added location request notification capability) (octet 5,bit 6) */
163 static const true_false_string LCS_VA_cap_vals = {
164     "LCS value added location request notification capability supported",
165     "LCS value added location request notification capability not supported"
166 };
167 /* UCS2 treatment (octet 5, bit 5) */
168 static const true_false_string UCS2_treatment_vals = {
169     "the ME has no preference between the use of the default alphabet and the use of UCS2",
170     "the ME has a preference for the default alphabet"
171 };
172 /* SoLSA (octet 5, bit 4) */
173 static const true_false_string SoLSA_vals = {
174     "The ME supports SoLSA",
175     "The ME does not support SoLSA"
176 };
177 /* CMSP: CM Service Prompt (octet 5, bit 3) */
178 static const true_false_string CMSP_vals = {
179     "Network initiated MO CM connection request supported for at least one CM protocol",
180     "Network initiated MO CM connection request not supported"
181 };
182 /* A5/7 algorithm supported */
183 static const true_false_string A5_7_algorithm_sup_vals = {
184     "encryption algorithm A5/7 available",
185     "encryption algorithm A5/7 not available"
186 };
187 /* A5/6 algorithm supported */
188 static const true_false_string A5_6_algorithm_sup_vals = {
189     "encryption algorithm A5/6 available",
190     "encryption algorithm A5/6 not available"
191 };
192 /* A5/5 algorithm supported */
193 static const true_false_string A5_5_algorithm_sup_vals = {
194     "encryption algorithm A5/5 available",
195     "encryption algorithm A5/5 not available"
196 };
197 /* A5/4 algorithm supported */
198 static const true_false_string A5_4_algorithm_sup_vals = {
199     "encryption algorithm A5/4 available",
200     "encryption algorithm A5/4 not available"
201 };
202 /* A5/3 algorithm supported (octet 5, bit 2) */
203 static const true_false_string A5_3_algorithm_sup_vals = {
204     "encryption algorithm A5/3 available",
205     "encryption algorithm A5/3 not available"
206 };
207 /* A5/2 algorithm supported (octet 5, bit 1) */
208 static const true_false_string A5_2_algorithm_sup_vals = {
209     "encryption algorithm A5/2 available",
210     "encryption algorithm A5/2 not available"
211 };
212
213 static const value_string mobile_identity_type_vals[] = {
214     { 0, "No Identity"},
215     { 1, "IMSI"},
216     { 2, "IMEI"},
217     { 3, "IMEISV"},
218     { 4, "TMSI/P-TMSI/M-TMSI"},
219     { 5, "TMGI and optional MBMS Session Identity"}, /* ETSI TS 124 008 V6.8.0 (2005-03) p326 */
220     { 0, NULL }
221 };
222
223 static const true_false_string oddevenind_vals = {
224     "Odd number of identity digits",
225     "Even number of identity digits"
226 };
227
228 static const true_false_string true_false_vals = {
229     "true",
230     "false"
231 };
232
233 const value_string gsm_a_sms_vals[] = {
234     {  0, "1/4 timeslot (~144 microseconds)" },
235     {  1, "2/4 timeslot (~288 microseconds)" },
236     {  2, "3/4 timeslot (~433 microseconds)" },
237     {  3, "4/4 timeslot (~577 microseconds)" },
238     {  4, "5/4 timeslot (~721 microseconds)" },
239     {  5, "6/4 timeslot (~865 microseconds)" },
240     {  6, "7/4 timeslot (~1009 microseconds)" },
241     {  7, "8/4 timeslot (~1154 microseconds)" },
242     {  8, "9/4 timeslot (~1298 microseconds)" },
243     {  9, "10/4 timeslot (~1442 microseconds)" },
244     { 10, "11/4 timeslot (~1586 microseconds)" },
245     { 11, "12/4 timeslot (~1730 microseconds)" },
246     { 12, "13/4 timeslot (~1874 microseconds)" },
247     { 13, "14/4 timeslot (~2019 microseconds)" },
248     { 14, "15/4 timeslot (~2163 microseconds)" },
249     { 15, "16/4 timeslot (~2307 microseconds)" },
250     {  0, NULL}
251 };
252
253 static const true_false_string ms_assisted_e_otd_vals = {
254     "MS assisted E-OTD supported",
255     "MS assisted E-OTD not supported"
256 };
257
258 static const true_false_string ms_based_e_otd_vals = {
259     "MS based E-OTD supported",
260     "MS based E-OTD not supported"
261 };
262
263 static const true_false_string ms_assisted_gps_vals = {
264     "MS assisted GPS supported",
265     "MS assisted GPS not supported"
266 };
267
268 static const true_false_string ms_based_gps_vals = {
269     "MS based GPS supported",
270     "MS based GPS not supported"
271 };
272
273 static const true_false_string ms_conventional_gps_vals = {
274     "Conventional GPS supported",
275     "Conventional GPS not supported"
276 };
277
278 static const true_false_string modulation_capability_vals = {
279     "8-PSK supported for uplink transmission and downlink reception",
280     "8-PSK supported for downlink reception only"
281 };
282
283 static const value_string eight_psk_rf_power_capability_vals[] = {
284     { 0, "Reserved" },
285     { 1, "Power class E1" },
286     { 2, "Power class E2" },
287     { 3, "Power class E3" },
288     { 0, NULL}
289 };
290
291 static const value_string gsm_400_bands_supported_vals[] = {
292     { 1, "GSM 480 supported, GSM 450 not supported" },
293     { 2, "GSM 450 supported, GSM 480 not supported" },
294     { 3, "GSM 450 supported, GSM 480 supported" },
295     { 0, NULL}
296 };
297
298 static const true_false_string umts_fdd_rat_cap_vals = {
299     "UMTS FDD supported",
300     "UMTS FDD not supported"
301 };
302
303 static const true_false_string umts_384_mcps_tdd_rat_cap_vals = {
304     "UMTS 3.84 Mcps TDD supported",
305     "UMTS 3.84 Mcps TDD not supported"
306 };
307
308 static const true_false_string cdma_2000_rat_cap_vals = {
309     "CDMA 2000 supported",
310     "CDMA 2000 not supported"
311 };
312
313 static const value_string dtm_gprs_multi_slot_class_vals[] = {
314     { 0, "Unused. If received, the network shall interpret this as 1" },
315     { 1, "Multislot class 5 supported" },
316     { 2, "Multislot class 9 supported" },
317     { 3, "Multislot class 11 supported" },
318     { 0, NULL}
319 };
320
321 static const true_false_string single_slot_dtm_vals = {
322     "Single Slot DTM supported",
323     "Single Slot DTM not supported"
324 };
325
326 static const value_string gsm_band_vals[] = {
327     { 0, "E-GSM is supported" },
328     { 1, "P-GSM is supported" },
329     { 2, "GSM 1800 is supported" },
330     { 3, "GSM 450 is supported" },
331     { 4, "GSM 480 is supported" },
332     { 5, "GSM 850 is supported" },
333     { 6, "GSM 1900 is supported" },
334     { 7, "GSM 750 is supported" },
335     { 8, "GSM 710 is supported" },
336     { 9, "T-GSM 810 is supported" },
337     { 0, NULL}
338 };
339
340 static const true_false_string umts_128_mcps_tdd_rat_cap_vals = {
341     "UMTS 1.28 Mcps TDD supported",
342     "UMTS 1.28 Mcps TDD not supported"
343 };
344
345 static const true_false_string geran_feature_package_1_vals = {
346     "GERAN feature package 1 supported",
347     "GERAN feature package 1 not supported"
348 };
349
350 static const true_false_string flo_iu_cap_vals = {
351     "FLO in GERAN Iu Mode supported",
352     "FLO in GERAN Iu Mode not supported"
353 };
354
355 static const true_false_string geran_feature_package_2_vals = {
356     "GERAN feature package 2 supported",
357     "GERAN feature package 2 not supported"
358 };
359
360 static const value_string gmsk_multislot_power_prof_vals[] = {
361     { 0, "GMSK_MULTISLOT_POWER_PROFILE 0" },
362     { 1, "GMSK_MULTISLOT_POWER_PROFILE 1" },
363     { 2, "GMSK_MULTISLOT_POWER_PROFILE 2" },
364     { 3, "GMSK_MULTISLOT_POWER_PROFILE 3" },
365     { 0, NULL}
366 };
367
368 static const value_string eight_psk_multislot_power_prof_vals[] = {
369     { 0, "8-PSK_MULTISLOT_POWER_PROFILE 0" },
370     { 1, "8-PSK_MULTISLOT_POWER_PROFILE 1" },
371     { 2, "8-PSK_MULTISLOT_POWER_PROFILE 2" },
372     { 3, "8-PSK_MULTISLOT_POWER_PROFILE 3" },
373     { 0, NULL}
374 };
375
376 static const value_string t_gsm_400_bands_supported_vals[] = {
377     { 1, "T-GSM 380 supported, T-GSM 410 not supported" },
378     { 2, "T-GSM 410 supported, T-GSM 380 not supported" },
379     { 3, "T-GSM 410 supported, T-GSM 380 supported" },
380     { 0, NULL}
381 };
382
383 static const value_string downlink_adv_receiver_perf_vals[] = {
384     { 0, "Downlink Advanced Receiver Performance not supported" },
385     { 1, "Downlink Advanced Receiver Performance - phase I supported" },
386     { 2, "Downlink Advanced Receiver Performance - phase II supported" },
387     { 0, NULL}
388 };
389
390 static const true_false_string dtm_enhancements_cap_vals = {
391     "The mobile station supports enhanced DTM CS establishment and release procedures",
392     "The mobile station does not support enhanced DTM CS establishment and release procedures"
393 };
394
395 static const true_false_string offset_required_vals = {
396     "The mobile station requires the offset",
397     "The mobile station does not require the offset"
398 };
399
400 static const value_string dtm_gprs_high_multi_slot_class_vals[] = {
401     { 0, "Unused. If received, the network shall interpret this as \"0 0 1\"" },
402     { 1, "Multislot class 31 or 36 supported" },
403     { 2, "Multislot class 32 or 37 supported" },
404     { 3, "Multislot class 33 or 38 supported" },
405     { 4, "Multislot class 41 supported" },
406     { 5, "Multislot class 42 supported" },
407     { 6, "Multislot class 43 supported" },
408     { 7, "Multislot class 44 supported" },
409     { 0, NULL}
410 };
411
412 static const true_false_string repeated_acch_cap_vals = {
413     "The mobile station supports Repeated SACCH and Repeated Downlink FACCH",
414     "The mobile station does not support Repeated SACCH"
415 };
416
417 static const true_false_string ciphering_mode_setting_cap_vals = {
418     "The mobile station supports the Ciphering Mode Setting IE in the DTM ASSIGNMENT COMMAND message",
419     "The mobile station does not support the Ciphering Mode Setting IE in the DTM ASSIGNMENT COMMAND message"
420 };
421
422 static const true_false_string additional_positioning_caps_vals = {
423     "The mobile station supports additional positioning capabilities which can be retrieved using RRLP",
424     "The mobile station does not support additional positioning capabilities which can be retrieved using RRLP"
425 };
426
427 static const true_false_string e_utra_fdd_support_vals = {
428     "E-UTRA FDD supported",
429     "E-UTRA FDD not supported"
430 };
431
432 static const true_false_string e_utra_tdd_support_vals = {
433     "E-UTRA TDD supported",
434     "E-UTRA TDD not supported"
435 };
436
437 static const true_false_string e_utra_meas_and_report_support_vals = {
438     "E-UTRAN Neighbour Cell measurements and measurement reporting while having an RR connection supported",
439     "E-UTRAN Neighbour Cell measurements and measurement reporting while having an RR connection not supported"
440 };
441
442 static const true_false_string prio_based_resel_support_vals = {
443     "Priority-based cell reselection supported",
444     "Priority-based cell reselection not supported"
445 };
446
447 static const true_false_string utra_csg_cells_reporting_vals = {
448     "Reporting of UTRAN CSG cells supported",
449     "Reporting of UTRAN CSG cells not supported"
450 };
451
452 static const value_string vamos_level_vals[] = {
453     { 0, "VAMOS not supported" },
454     { 1, "VAMOS I supported" },
455     { 2, "VAMOS II supported" },
456     { 3, "Unused. If received, the network shall interpret this as VAMOS II supported" },
457     { 0, NULL}
458 };
459
460 const value_string tighter_cap_level_vals[] = {
461     { 0, "TIGHTER not supported" },
462     { 1, "TIGHTER supported for speech and signalling channels only" },
463     { 2, "TIGHTER supported for speech and signalling channels and for GPRS and EGPRS, but not for EGPRS2" },
464     { 3, "TIGHTER supported for speech and signalling channels and for GPRS, EGPRS and EGPRS2" },
465     { 0, NULL}
466 };
467
468 const value_string cs_to_ps_srvcc_geran_to_utra_vals[] = {
469     { 0, "CS to PS SRVCC from GERAN to UMTS FDD and 1.28 Mcps TDD not supported" },
470     { 1, "CS to PS SRVCC from GERAN to UMTS FDD supported" },
471     { 2, "CS to PS SRVCC from GERAN to UMTS 1.28 Mcps TDD supported" },
472     { 3, "CS to PS SRVCC from GERAN to UMTS FDD and 1.28 Mcps TDD supported" },
473     { 0, NULL}
474 };
475
476 const value_string cs_to_ps_srvcc_geran_to_eutra_vals[] = {
477     { 0, "CS to PS SRVCC from GERAN to E-UTRA FDD and TDD not supported" },
478     { 1, "CS to PS SRVCC from GERAN to E-UTRA FDD supported" },
479     { 2, "CS to PS SRVCC from GERAN to E-UTRA TDD supported" },
480     { 3, "CS to PS SRVCC from GERAN to E-UTRA FDD and TDD supported" },
481     { 0, NULL}
482 };
483
484 static const value_string gsm_a_rr_rxlev_vals [] = {
485     {  0, "< -110 dBm"},
486     {  1, "-110 <= x < -109 dBm"},
487     {  2, "-109 <= x < -108 dBm"},
488     {  3, "-108 <= x < -107 dBm"},
489     {  4, "-107 <= x < -106 dBm"},
490     {  5, "-106 <= x < -105 dBm"},
491     {  6, "-105 <= x < -104 dBm"},
492     {  7, "-104 <= x < -103 dBm"},
493     {  8, "-103 <= x < -102 dBm"},
494     {  9, "-102 <= x < -101 dBm"},
495     { 10, "-101 <= x < -100 dBm"},
496     { 11, "-100 <= x < -99 dBm"},
497     { 12, "-99 <= x < -98 dBm"},
498     { 13, "-98 <= x < -97 dBm"},
499     { 14, "-97 <= x < -96 dBm"},
500     { 15, "-96 <= x < -95 dBm"},
501     { 16, "-95 <= x < -94 dBm"},
502     { 17, "-94 <= x < -93 dBm"},
503     { 18, "-93 <= x < -92 dBm"},
504     { 19, "-92 <= x < -91 dBm"},
505     { 20, "-91 <= x < -90 dBm"},
506     { 21, "-90 <= x < -89 dBm"},
507     { 22, "-89 <= x < -88 dBm"},
508     { 23, "-88 <= x < -87 dBm"},
509     { 24, "-87 <= x < -86 dBm"},
510     { 25, "-86 <= x < -85 dBm"},
511     { 26, "-85 <= x < -84 dBm"},
512     { 27, "-84 <= x < -83 dBm"},
513     { 28, "-83 <= x < -82 dBm"},
514     { 29, "-82 <= x < -81 dBm"},
515     { 30, "-81 <= x < -80 dBm"},
516     { 31, "-80 <= x < -79 dBm"},
517     { 32, "-79 <= x < -78 dBm"},
518     { 33, "-78 <= x < -77 dBm"},
519     { 34, "-77 <= x < -76 dBm"},
520     { 35, "-76 <= x < -75 dBm"},
521     { 36, "-75 <= x < -74 dBm"},
522     { 37, "-74 <= x < -73 dBm"},
523     { 38, "-73 <= x < -72 dBm"},
524     { 39, "-72 <= x < -71 dBm"},
525     { 40, "-71 <= x < -70 dBm"},
526     { 41, "-70 <= x < -69 dBm"},
527     { 42, "-69 <= x < -68 dBm"},
528     { 43, "-68 <= x < -67 dBm"},
529     { 44, "-67 <= x < -66 dBm"},
530     { 45, "-66 <= x < -65 dBm"},
531     { 46, "-65 <= x < -64 dBm"},
532     { 47, "-64 <= x < -63 dBm"},
533     { 48, "-63 <= x < -62 dBm"},
534     { 49, "-62 <= x < -61 dBm"},
535     { 50, "-61 <= x < -60 dBm"},
536     { 51, "-60 <= x < -59 dBm"},
537     { 52, "-59 <= x < -58 dBm"},
538     { 53, "-58 <= x < -57 dBm"},
539     { 54, "-57 <= x < -56 dBm"},
540     { 55, "-56 <= x < -55 dBm"},
541     { 56, "-55 <= x < -54 dBm"},
542     { 57, "-54 <= x < -53 dBm"},
543     { 58, "-53 <= x < -52 dBm"},
544     { 59, "-52 <= x < -51 dBm"},
545     { 60, "-51 <= x < -50 dBm"},
546     { 61, "-50 <= x < -49 dBm"},
547     { 62, "-49 <= x < -48 dBm"},
548     { 63, ">= -48 dBm"},
549     { 0, NULL}
550 };
551 value_string_ext gsm_a_rr_rxlev_vals_ext = VALUE_STRING_EXT_INIT(gsm_a_rr_rxlev_vals);
552
553 /* Initialize the protocol and registered fields */
554 static int proto_a_common = -1;
555
556 int gsm_a_tap = -1;
557
558 int hf_gsm_a_common_elem_id = -1;
559 static int hf_gsm_a_l_ext = -1;
560 static int hf_gsm_a_imsi = -1;
561 int hf_gsm_a_tmsi = -1;
562 static int hf_gsm_a_imei = -1;
563 static int hf_gsm_a_imeisv = -1;
564
565 static int hf_gsm_a_MSC_rev = -1;
566 static int hf_gsm_a_ES_IND = -1;
567 static int hf_gsm_a_A5_1_algorithm_sup = -1;
568 static int hf_gsm_a_RF_power_capability = -1;
569 static int hf_gsm_a_ps_sup_cap = -1;
570 static int hf_gsm_a_SS_screening_indicator = -1;
571 static int hf_gsm_a_SM_capability = -1;
572 static int hf_gsm_a_VBS_notification_rec = -1;
573 static int hf_gsm_a_VGCS_notification_rec = -1;
574 static int hf_gsm_a_FC_frequency_cap = -1;
575 static int hf_gsm_a_CM3 = -1;
576 static int hf_gsm_a_LCS_VA_cap = -1;
577 static int hf_gsm_a_UCS2_treatment = -1;
578 static int hf_gsm_a_SoLSA = -1;
579 static int hf_gsm_a_CMSP = -1;
580 static int hf_gsm_a_A5_7_algorithm_sup = -1;
581 static int hf_gsm_a_A5_6_algorithm_sup = -1;
582 static int hf_gsm_a_A5_5_algorithm_sup = -1;
583 static int hf_gsm_a_A5_4_algorithm_sup = -1;
584 static int hf_gsm_a_A5_3_algorithm_sup = -1;
585 static int hf_gsm_a_A5_2_algorithm_sup = -1;
586
587 static int hf_gsm_a_odd_even_ind = -1;
588 static int hf_gsm_a_unused = -1;
589 static int hf_gsm_a_mobile_identity_type = -1;
590 static int hf_gsm_a_tmgi_mcc_mnc_ind = -1;
591 static int hf_gsm_a_mbs_ses_id_ind = -1;
592 static int hf_gsm_a_mbs_service_id = -1;
593 static int hf_gsm_a_mbs_session_id = -1;
594 static int hf_gsm_a_length = -1;
595 int hf_gsm_a_extension = -1;
596 int hf_gsm_a_L3_protocol_discriminator = -1;
597 int hf_gsm_a_call_prio = -1;
598 int hf_gsm_a_skip_ind = -1;
599 int hf_gsm_a_spare_bits = -1;
600 int hf_gsm_a_lac = -1;
601
602 static int hf_gsm_a_spare_nibble = -1;
603 static int hf_gsm_a_type_of_ciph_alg = -1;
604 static int hf_gsm_a_att = -1;
605 static int hf_gsm_a_nmo_1 = -1;
606 static int hf_gsm_a_nmo = -1;
607 static int hf_gsm_a_old_xid = -1;
608 static int hf_gsm_a_iov_ui = -1;
609 static int hf_gsm_a_ext_periodic_timers = -1;
610 static int hf_gsm_a_b7spare = -1;
611 int hf_gsm_a_b8spare = -1;
612 static int hf_gsm_a_multi_bnd_sup_fields = -1;
613 static int hf_gsm_a_pgsm_supported = -1;
614 static int hf_gsm_a_egsm_supported = -1;
615 static int hf_gsm_a_gsm1800_supported = -1;
616 static int hf_gsm_a_ass_radio_cap1 = -1;
617 static int hf_gsm_a_ass_radio_cap2 = -1;
618 static int hf_gsm_a_rsupport = -1;
619 static int hf_gsm_a_r_capabilities = -1;
620 static int hf_gsm_a_multislot_capabilities = -1;
621 static int hf_gsm_a_multislot_class = -1;
622 static int hf_gsm_a_ucs2_treatment = -1;
623 static int hf_gsm_a_extended_measurement_cap = -1;
624 static int hf_gsm_a_ms_measurement_capability = -1;
625 static int hf_gsm_a_sms_value =-1;
626 static int hf_gsm_a_sm_value =-1;
627 static int hf_gsm_a_key_seq = -1;
628 static int hf_gsm_a_ms_pos_method_cap_present = -1;
629 static int hf_gsm_a_ms_pos_method = -1;
630 static int hf_gsm_a_ms_assisted_e_otd = -1;
631 static int hf_gsm_a_ms_based_e_otd = -1;
632 static int hf_gsm_a_ms_assisted_gps = -1;
633 static int hf_gsm_a_ms_based_gps = -1;
634 static int hf_gsm_a_ms_conventional_gps = -1;
635 static int hf_gsm_a_ecsd_multi_slot_capability = -1;
636 static int hf_gsm_a_ecsd_multi_slot_class = -1;
637 static int hf_gsm_a_8_psk_struct_present = -1;
638 static int hf_gsm_a_8_psk_struct = -1;
639 static int hf_gsm_a_modulation_capability = -1;
640 static int hf_gsm_a_8_psk_rf_power_capability_1_present = -1;
641 static int hf_gsm_a_8_psk_rf_power_capability_1 = -1;
642 static int hf_gsm_a_8_psk_rf_power_capability_2_present = -1;
643 static int hf_gsm_a_8_psk_rf_power_capability_2 = -1;
644 static int hf_gsm_a_gsm_400_band_info_present = -1;
645 static int hf_gsm_a_gsm_400_bands_supported = -1;
646 static int hf_gsm_a_gsm_400_assoc_radio_cap = -1;
647 static int hf_gsm_a_gsm_850_assoc_radio_cap_present = -1;
648 static int hf_gsm_a_gsm_850_assoc_radio_cap = -1;
649 static int hf_gsm_a_gsm_1900_assoc_radio_cap_present = -1;
650 static int hf_gsm_a_gsm_1900_assoc_radio_cap = -1;
651 static int hf_gsm_a_cm3_A5_bits = -1;
652 static int hf_gsm_a_umts_fdd_rat_cap = -1;
653 static int hf_gsm_a_umts_384_mcps_tdd_rat_cap = -1;
654 static int hf_gsm_a_cdma_2000_rat_cap = -1;
655 static int hf_gsm_a_dtm_e_gprs_multi_slot_info_present = -1;
656 static int hf_gsm_a_dtm_gprs_multi_slot_class = -1;
657 static int hf_gsm_a_single_slot_dtm = -1;
658 static int hf_gsm_a_dtm_egprs_multi_slot_class_present = -1;
659 static int hf_gsm_a_dtm_egprs_multi_slot_class = -1;
660 static int hf_gsm_a_single_band_support = -1;
661 static int hf_gsm_a_gsm_band = -1;
662 static int hf_gsm_a_gsm_750_assoc_radio_cap_present = -1;
663 static int hf_gsm_a_gsm_750_assoc_radio_cap = -1;
664 static int hf_gsm_a_umts_128_mcps_tdd_rat_cap = -1;
665 static int hf_gsm_a_geran_feature_package_1 = -1;
666 static int hf_gsm_a_ext_dtm_e_gprs_multi_slot_info_present = -1;
667 static int hf_gsm_a_ext_dtm_gprs_multi_slot_class = -1;
668 static int hf_gsm_a_ext_dtm_egprs_multi_slot_class = -1;
669 static int hf_gsm_a_high_multislot_cap_present = -1;
670 static int hf_gsm_a_high_multislot_cap = -1;
671 static int hf_gsm_a_geran_iu_mode_support = -1;
672 static int hf_gsm_a_geran_iu_mode_cap = -1;
673 static int hf_gsm_a_geran_iu_mode_cap_length = -1;
674 static int hf_gsm_a_flo_iu_cap = -1;
675 static int hf_gsm_a_geran_feature_package_2 = -1;
676 static int hf_gsm_a_gmsk_multislot_power_prof = -1;
677 static int hf_gsm_a_8_psk_multislot_power_prof = -1;
678 static int hf_gsm_a_t_gsm_400_band_info_present = -1;
679 static int hf_gsm_a_t_gsm_400_bands_supported = -1;
680 static int hf_gsm_a_t_gsm_400_assoc_radio_cap = -1;
681 static int hf_gsm_a_t_gsm_900_assoc_radio_cap_present = -1;
682 static int hf_gsm_a_t_gsm_900_assoc_radio_cap = -1;
683 static int hf_gsm_a_downlink_adv_receiver_perf = -1;
684 static int hf_gsm_a_dtm_enhancements_cap = -1;
685 static int hf_gsm_a_dtm_e_gprs_high_multi_slot_info_present = -1;
686 static int hf_gsm_a_dtm_gprs_high_multi_slot_class = -1;
687 static int hf_gsm_a_offset_required = -1;
688 static int hf_gsm_a_dtm_egprs_high_multi_slot_class_present = -1;
689 static int hf_gsm_a_dtm_egprs_high_multi_slot_class = -1;
690 static int hf_gsm_a_repeated_acch_cap = -1;
691 static int hf_gsm_a_gsm_710_assoc_radio_cap_present = -1;
692 static int hf_gsm_a_gsm_710_assoc_radio_cap = -1;
693 static int hf_gsm_a_t_gsm_810_assoc_radio_cap_present = -1;
694 static int hf_gsm_a_t_gsm_810_assoc_radio_cap = -1;
695 static int hf_gsm_a_ciphering_mode_setting_cap = -1;
696 static int hf_gsm_a_additional_positioning_caps = -1;
697 static int hf_gsm_a_e_utra_fdd_support = -1;
698 static int hf_gsm_a_e_utra_tdd_support = -1;
699 static int hf_gsm_a_e_utra_meas_and_report_support = -1;
700 static int hf_gsm_a_prio_based_resel_support = -1;
701 static int hf_gsm_a_utra_csg_cells_reporting = -1;
702 static int hf_gsm_a_vamos_level = -1;
703 static int hf_gsm_a_tighter_cap = -1;
704 static int hf_gsm_a_selective_ciph_down_sacch = -1;
705 static int hf_gsm_a_cs_to_ps_srvcc_geran_to_utra = -1;
706 static int hf_gsm_a_cs_to_ps_srvcc_geran_to_eutra = -1;
707 static int hf_gsm_a_geran_network_sharing_support = -1;
708
709 static int hf_gsm_a_geo_loc_type_of_shape = -1;
710 static int hf_gsm_a_geo_loc_sign_of_lat = -1;
711 static int hf_gsm_a_geo_loc_deg_of_lat =-1;
712 static int hf_gsm_a_geo_loc_deg_of_long =-1;
713 static int hf_gsm_a_geo_loc_uncertainty_code = -1;
714 static int hf_gsm_a_geo_loc_uncertainty_semi_major = -1;
715 static int hf_gsm_a_geo_loc_uncertainty_semi_minor = -1;
716 static int hf_gsm_a_geo_loc_orientation_of_major_axis = -1;
717 static int hf_gsm_a_geo_loc_uncertainty_altitude = -1;
718 static int hf_gsm_a_geo_loc_confidence = -1;
719 static int hf_gsm_a_geo_loc_no_of_points = -1;
720 static int hf_gsm_a_velocity_type = -1;
721 static int hf_gsm_a_bearing = -1;
722 static int hf_gsm_a_horizontal_speed = -1;
723 static int hf_gsm_a_uncertainty_speed = -1;
724 static int hf_gsm_a_h_uncertainty_speed = -1;
725 static int hf_gsm_a_v_uncertainty_speed = -1;
726 static int hf_gsm_a_vertical_speed = -1;
727 static int hf_gsm_a_d = -1;
728 static int hf_gsm_a_geo_loc_D = -1;
729 static int hf_gsm_a_geo_loc_altitude = -1;
730 static int hf_gsm_a_geo_loc_inner_radius = -1;
731 static int hf_gsm_a_geo_loc_uncertainty_radius = -1;
732 static int hf_gsm_a_geo_loc_offset_angle = -1;
733 static int hf_gsm_a_geo_loc_included_angle = -1;
734
735 static expert_field ei_gsm_a_extraneous_data = EI_INIT;
736
737 static char a_bigbuf[1024];
738
739 sccp_msg_info_t* sccp_msg;
740 sccp_assoc_info_t* sccp_assoc;
741
742 #define NUM_GSM_COMMON_ELEM (sizeof(gsm_common_elem_strings)/sizeof(value_string))
743 gint ett_gsm_common_elem[NUM_GSM_COMMON_ELEM];
744
745
746 #define  ELLIPSOID_POINT 0
747 #define  ELLIPSOID_POINT_WITH_UNCERT_CIRC 1
748 #define  ELLIPSOID_POINT_WITH_UNCERT_ELLIPSE 3
749 #define  POLYGON 5
750 #define  ELLIPSOID_POINT_WITH_ALT 8
751 #define  ELLIPSOID_POINT_WITH_ALT_AND_UNCERT_ELLIPSOID 9
752 #define  ELLIPSOID_ARC 10
753 /*
754 4 3 2 1
755 0 0 0 0 Ellipsoid Point
756 0 0 0 1 Ellipsoid point with uncertainty Circle
757 0 0 1 1 Ellipsoid point with uncertainty Ellipse
758 0 1 0 1 Polygon
759 1 0 0 0 Ellipsoid point with altitude
760 1 0 0 1 Ellipsoid point with altitude and uncertainty Ellipsoid
761 1 0 1 0 Ellipsoid Arc
762 other values reserved for future use
763 */
764
765 /* TS 23 032 Table 2a: Coding of Type of Shape */
766 static const value_string type_of_shape_vals[] = {
767     { ELLIPSOID_POINT,                               "Ellipsoid Point"},
768     { ELLIPSOID_POINT_WITH_UNCERT_CIRC,              "Ellipsoid point with uncertainty Circle"},
769     { ELLIPSOID_POINT_WITH_UNCERT_ELLIPSE,           "Ellipsoid point with uncertainty Ellipse"},
770     { POLYGON,                                       "Polygon"},
771     { ELLIPSOID_POINT_WITH_ALT,                      "Ellipsoid point with altitude"},
772     { ELLIPSOID_POINT_WITH_ALT_AND_UNCERT_ELLIPSOID, "Ellipsoid point with altitude and uncertainty Ellipsoid"},
773     { ELLIPSOID_ARC,                                 "Ellipsoid Arc"},
774     { 0,    NULL }
775 };
776
777 /* 3GPP TS 23.032 7.3.1 */
778 static const value_string sign_of_latitude_vals[] = {
779     { 0,  "North"},
780     { 1,  "South"},
781     { 0,  NULL }
782 };
783
784 static const value_string dir_of_alt_vals[] = {
785     { 0,  "Altitude expresses height"},
786     { 1,  "Altitude expresses depth"},
787     { 0,  NULL }
788 };
789
790 void
791 dissect_geographical_description(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree) {
792
793     proto_item *lat_item, *long_item, *major_item, *minor_item, *alt_item, *uncer_item;
794     /*proto_tree *subtree; */
795     guint8      type_of_shape;
796     /*guint8 no_of_points;*/
797     int         offset = 0;
798     int         length;
799     guint8      value;
800     guint32     uvalue32;
801     gint32      svalue32;
802
803     /*subtree = proto_item_add_subtree(item, ett_gsm_a_geo_desc);*/
804
805     length = tvb_reported_length_remaining(tvb, 0);
806     /* Geographical Location
807      * The Location Estimate field is composed of 1 or more octets with an internal structure
808      * according to section 7 in [23.032].
809      */
810     proto_tree_add_item(tree, hf_gsm_a_geo_loc_type_of_shape, tvb, 0, 1, ENC_BIG_ENDIAN);
811     if (length < 2)
812         return;
813     type_of_shape = tvb_get_guint8(tvb,offset)>>4;
814     switch (type_of_shape) {
815     case ELLIPSOID_POINT:
816         /* Ellipsoid Point */
817     case ELLIPSOID_POINT_WITH_UNCERT_CIRC:
818         /* Ellipsoid Point with uncertainty Circle */
819     case ELLIPSOID_POINT_WITH_UNCERT_ELLIPSE:
820         /* Ellipsoid Point with uncertainty Ellipse */
821     case ELLIPSOID_POINT_WITH_ALT:
822         /* Ellipsoid Point with Altitude */
823     case ELLIPSOID_POINT_WITH_ALT_AND_UNCERT_ELLIPSOID:
824         /* Ellipsoid Point with altitude and uncertainty ellipsoid */
825     case ELLIPSOID_ARC:
826         /* Ellipsoid Arc */
827         offset++;
828         if (length < 4)
829             return;
830         proto_tree_add_item(tree, hf_gsm_a_geo_loc_sign_of_lat, tvb, offset, 1, ENC_BIG_ENDIAN);
831
832         uvalue32  = tvb_get_ntoh24(tvb,offset);
833         /* convert degrees (X/0x7fffff) * 90 = degrees */
834         lat_item = proto_tree_add_item(tree, hf_gsm_a_geo_loc_deg_of_lat, tvb, offset, 3, ENC_BIG_ENDIAN);
835         proto_item_append_text(lat_item, " (%s%.5f degrees)",
836             (uvalue32 & 0x00800000) ? "-" : "",
837             ((double)(uvalue32 & 0x7fffff)/8388607.0) * 90);
838         if (length < 7)
839             return;
840         offset    = offset + 3;
841         svalue32   = tvb_get_ntoh24(tvb,offset);
842         svalue32 |= (svalue32 & 0x800000) ? 0xff000000 : 0x00000000;
843         long_item = proto_tree_add_item(tree, hf_gsm_a_geo_loc_deg_of_long, tvb, offset, 3, ENC_BIG_ENDIAN);
844         /* (X/0xffffff) *360 = degrees */
845         proto_item_append_text(long_item, " (%.5f degrees)",
846             ((double)svalue32/16777215.0) * 360);
847         offset = offset + 3;
848         if (type_of_shape == ELLIPSOID_POINT_WITH_UNCERT_CIRC) {
849             /* Ellipsoid Point with uncertainty Circle */
850             if (length < 8)
851                 return;
852             /* Uncertainty code */
853             value = tvb_get_guint8(tvb,offset)&0x7f;
854             uncer_item = proto_tree_add_item(tree, hf_gsm_a_geo_loc_uncertainty_code, tvb, offset, 1, ENC_BIG_ENDIAN);
855             proto_item_append_text(uncer_item, " (%.1f m)", 10 * (pow(1.1, (double)value) - 1));
856         }else if (type_of_shape == ELLIPSOID_POINT_WITH_UNCERT_ELLIPSE) {
857             /* Ellipsoid Point with uncertainty Ellipse */
858             /* Uncertainty semi-major octet 10
859              * To convert to metres 10*(((1.1)^X)-1)
860              */
861             value      = tvb_get_guint8(tvb,offset) & 0x7f;
862             major_item = proto_tree_add_item(tree, hf_gsm_a_geo_loc_uncertainty_semi_major, tvb, offset, 1, ENC_BIG_ENDIAN);
863             proto_item_append_text(major_item, " (%.1f m)", 10 * (pow(1.1, (double)value) - 1));
864             offset++;
865             /* Uncertainty semi-minor Octet 11
866              * To convert to metres 10*(((1.1)^X)-1)
867              */
868             value      = tvb_get_guint8(tvb,offset)&0x7f;
869             minor_item = proto_tree_add_item(tree, hf_gsm_a_geo_loc_uncertainty_semi_minor, tvb, offset, 1, ENC_BIG_ENDIAN);
870             proto_item_append_text(minor_item, " (%.1f m)", 10 * (pow(1.1, (double)value) - 1));
871             offset++;
872             /* Orientation of major axis octet 12
873              * allowed value from 0-179 to convert
874              * to actual degrees multiply by 2.
875              */
876             value = tvb_get_guint8(tvb,offset)&0x7f;
877             proto_tree_add_uint(tree, hf_gsm_a_geo_loc_orientation_of_major_axis, tvb, offset, 1, value*2);
878             offset++;
879             /* Confidence */
880             proto_tree_add_item(tree, hf_gsm_a_geo_loc_confidence, tvb, offset, 1, ENC_BIG_ENDIAN);
881             offset++;
882         }else if (type_of_shape == ELLIPSOID_POINT_WITH_ALT) {
883             /* Ellipsoid Point with Altitude */
884             /*D: Direction of Altitude */
885             proto_tree_add_item(tree, hf_gsm_a_geo_loc_D, tvb, offset, 1, ENC_BIG_ENDIAN);
886             /* Altitude */
887             proto_tree_add_item(tree, hf_gsm_a_geo_loc_altitude, tvb, offset, 2, ENC_BIG_ENDIAN);
888         }else if (type_of_shape == ELLIPSOID_POINT_WITH_ALT_AND_UNCERT_ELLIPSOID) {
889             /* Ellipsoid Point with altitude and uncertainty ellipsoid */
890             /*D: Direction of Altitude octet 8,9 */
891             proto_tree_add_item(tree, hf_gsm_a_geo_loc_D, tvb, offset, 1, ENC_BIG_ENDIAN);
892             /* Altitude Octet 8,9*/
893             proto_tree_add_item(tree, hf_gsm_a_geo_loc_altitude, tvb, offset, 2, ENC_BIG_ENDIAN);
894             offset = offset +2;
895             /* Uncertainty semi-major octet 10
896              * To convert to metres 10*(((1.1)^X)-1)
897              */
898             value      = tvb_get_guint8(tvb,offset)&0x7f;
899             major_item = proto_tree_add_item(tree, hf_gsm_a_geo_loc_uncertainty_semi_major, tvb, offset, 1, ENC_BIG_ENDIAN);
900             proto_item_append_text(major_item, " (%.1f m)", 10 * (pow(1.1, (double)value) - 1));
901             offset++;
902             /* Uncertainty semi-minor Octet 11
903              * To convert to metres 10*(((1.1)^X)-1)
904              */
905             value      = tvb_get_guint8(tvb,offset)&0x7f;
906             minor_item = proto_tree_add_item(tree, hf_gsm_a_geo_loc_uncertainty_semi_minor, tvb, offset, 1, ENC_BIG_ENDIAN);
907             proto_item_append_text(minor_item, " (%.1f m)", 10 * (pow(1.1, (double)value) - 1));
908             offset++;
909             /* Orientation of major axis octet 12
910              * allowed value from 0-179 to convert
911              * to actual degrees multiply by 2.
912              */
913             value = tvb_get_guint8(tvb,offset)&0x7f;
914             proto_tree_add_uint(tree, hf_gsm_a_geo_loc_orientation_of_major_axis, tvb, offset, 1, value*2);
915             offset++;
916             /* Uncertainty Altitude 13
917              * to convert to metres 45*(((1.025)^X)-1)
918              */
919             value = tvb_get_guint8(tvb,offset)&0x7f;
920             alt_item = proto_tree_add_item(tree, hf_gsm_a_geo_loc_uncertainty_altitude, tvb, offset, 1, ENC_BIG_ENDIAN);
921             proto_item_append_text(alt_item, " (%.1f m)", 45 * (pow(1.025, (double)value) - 1));
922             offset++;
923             /* Confidence octet 14
924              */
925             proto_tree_add_item(tree, hf_gsm_a_geo_loc_confidence, tvb, offset, 1, ENC_BIG_ENDIAN);
926         }else if (type_of_shape == ELLIPSOID_ARC) {
927             /* Ellipsoid Arc */
928             /* Inner radius */
929             proto_tree_add_item(tree, hf_gsm_a_geo_loc_inner_radius, tvb, offset, 2, ENC_BIG_ENDIAN);
930             offset = offset + 2;
931             /* Uncertainty radius */
932             proto_tree_add_item(tree, hf_gsm_a_geo_loc_uncertainty_radius, tvb, offset, 1, ENC_BIG_ENDIAN);
933             offset++;
934             /* Offset angle */
935             proto_tree_add_item(tree, hf_gsm_a_geo_loc_offset_angle, tvb, offset, 1, ENC_BIG_ENDIAN);
936             offset++;
937             /* Included angle */
938             proto_tree_add_item(tree, hf_gsm_a_geo_loc_included_angle, tvb, offset, 1, ENC_BIG_ENDIAN);
939             offset++;
940             /* Confidence */
941             proto_tree_add_item(tree, hf_gsm_a_geo_loc_confidence, tvb, offset, 1, ENC_BIG_ENDIAN);
942         }
943
944         break;
945     case POLYGON:                   /* Polygon */
946         /* Number of points */
947         proto_tree_add_item(tree, hf_gsm_a_geo_loc_no_of_points, tvb, offset, 1, ENC_BIG_ENDIAN);
948 #if 0
949         no_of_points = tvb_get_guint8(tvb,offset)&0x0f;
950         while ( no_of_points > 0) {
951             offset++;
952
953             no_of_points--;
954         }
955 #endif
956         break;
957     default:
958         break;
959     }
960
961 }
962
963 /* TS 23.032
964  * Ch. 8 Description of Velocity
965  */
966 /* 8.6 Coding of Velocity Type */
967 static const value_string gsm_a_velocity_type_vals[] = {
968     { 0,  "Horizontal Velocity"},
969     { 1,  "Horizontal with Vertical Velocity"},
970     { 2,  "Horizontal Velocity with Uncertainty"},
971     { 3,  "Horizontal with Vertical Velocity and Uncertainty"},
972     { 4,  "reserved for future use"},
973     { 5,  "reserved for future use"},
974     { 6,  "reserved for future use"},
975     { 7,  "reserved for future use"},
976     { 8,  "reserved for future use"},
977     { 9,  "reserved for future use"},
978     { 10, "reserved for future use"},
979     { 11, "reserved for future use"},
980     { 12, "reserved for future use"},
981     { 13, "reserved for future use"},
982     { 14, "reserved for future use"},
983     { 15, "reserved for future use"},
984     { 0,  NULL }
985 };
986
987 static const true_false_string gsm_a_dir_of_ver_speed_vals = {
988     "Downward",
989     "Upward"
990 };
991
992 guint16
993 dissect_description_of_velocity(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
994 {
995     proto_item *velocity_item;
996     guint32     curr_offset;
997     guint8      velocity_type, uncertainty_speed = 0;
998
999     curr_offset = offset;
1000
1001     /* Bit 8 - 5 Velocity Type */
1002     velocity_type = tvb_get_guint8(tvb,curr_offset);
1003     proto_tree_add_item(tree, hf_gsm_a_velocity_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1004     curr_offset++;
1005
1006     switch (velocity_type) {
1007     case 0:
1008         /* 8.12 Coding of Horizontal Velocity */
1009         /* Spare bits */
1010         proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, (curr_offset<<3)+4, 3, ENC_BIG_ENDIAN);
1011         /* Bearing is encoded in increments of 1 degree measured clockwise from North using a 9 bit binary coded number N. */
1012         proto_tree_add_bits_item(tree, hf_gsm_a_bearing, tvb, (curr_offset<<3)+7, 9, ENC_BIG_ENDIAN);
1013         curr_offset += 2;
1014         /* Horizontal speed is encoded in increments of 1 kilometre per hour using a 16 bit binary coded number N. */
1015         velocity_item = proto_tree_add_item(tree, hf_gsm_a_horizontal_speed, tvb, offset, 2, ENC_BIG_ENDIAN);
1016         proto_item_append_text(velocity_item, " km/h");
1017         curr_offset += 2;
1018         break;
1019     case 1:
1020         /* 8.13 Coding of Horizontal with Vertical Velocity */
1021         /* Spare bits */
1022         proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, (curr_offset<<3)+4, 2, ENC_BIG_ENDIAN);
1023         /* D: Direction of Vertical Speed */
1024         proto_tree_add_item(tree, hf_gsm_a_d, tvb, offset, 1, ENC_BIG_ENDIAN);
1025         /* Bearing is encoded in increments of 1 degree measured clockwise from North using a 9 bit binary coded number N. */
1026         proto_tree_add_bits_item(tree, hf_gsm_a_bearing, tvb, (curr_offset<<3)+7, 9, ENC_BIG_ENDIAN);
1027         curr_offset += 2;
1028         /* Horizontal speed is encoded in increments of 1 kilometre per hour using a 16 bit binary coded number N. */
1029         velocity_item = proto_tree_add_item(tree, hf_gsm_a_horizontal_speed, tvb, offset, 2, ENC_BIG_ENDIAN);
1030         proto_item_append_text(velocity_item, " km/h");
1031         curr_offset += 2;
1032         /* Vertical Speed Octet 5
1033          * Vertical speed is encoded in increments of 1 kilometre per hour using 8 bits giving a number N between 0 and 28-1.
1034          */
1035         velocity_item = proto_tree_add_item(tree, hf_gsm_a_vertical_speed, tvb, offset, 1, ENC_BIG_ENDIAN);
1036         proto_item_append_text(velocity_item, " km/h");
1037         curr_offset++;
1038         break;
1039     case 2:
1040         /* 8.14 Coding of Horizontal Velocity with Uncertainty */
1041         /* Spare bits */
1042         proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, (curr_offset<<3)+4, 3, ENC_BIG_ENDIAN);
1043         /* Bearing is encoded in increments of 1 degree measured clockwise from North using a 9 bit binary coded number N. */
1044         proto_tree_add_bits_item(tree, hf_gsm_a_bearing, tvb, (curr_offset<<3)+7, 9, ENC_BIG_ENDIAN);
1045         curr_offset += 2;
1046         /* Horizontal speed is encoded in increments of 1 kilometre per hour using a 16 bit binary coded number N. */
1047         velocity_item = proto_tree_add_item(tree, hf_gsm_a_horizontal_speed, tvb, offset, 2, ENC_BIG_ENDIAN);
1048         proto_item_append_text(velocity_item, " km/h");
1049         curr_offset += 2;
1050         /* Uncertainty Speed Octet 5
1051          * Uncertainty speed is encoded in increments of 1 kilometre per hour using an 8 bit binary coded number N. The value of
1052          * N gives the uncertainty speed except for N=255 which indicates that the uncertainty is not specified.
1053          */
1054         uncertainty_speed = tvb_get_guint8(tvb,curr_offset);
1055         velocity_item = proto_tree_add_item(tree, hf_gsm_a_uncertainty_speed, tvb, offset, 2, ENC_BIG_ENDIAN);
1056         if (uncertainty_speed == 255) {
1057             proto_item_append_text(velocity_item, " not specified");
1058         }else{
1059             proto_item_append_text(velocity_item, " km/h");
1060         }
1061         offset++;
1062         break;
1063     case 3:
1064         /* 8.15 Coding of Horizontal with Vertical Velocity and Uncertainty */
1065         /* Spare bits */
1066         proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, (curr_offset<<3)+4, 2, ENC_BIG_ENDIAN);
1067         /* D: Direction of Vertical Speed */
1068         proto_tree_add_item(tree, hf_gsm_a_d, tvb, offset, 1, ENC_BIG_ENDIAN);
1069         /* Bearing is encoded in increments of 1 degree measured clockwise from North using a 9 bit binary coded number N. */
1070         proto_tree_add_bits_item(tree, hf_gsm_a_bearing, tvb, (curr_offset<<3)+7, 9, ENC_BIG_ENDIAN);
1071         curr_offset += 2;
1072         /* Horizontal speed is encoded in increments of 1 kilometre per hour using a 16 bit binary coded number N. */
1073         velocity_item = proto_tree_add_item(tree, hf_gsm_a_horizontal_speed, tvb, offset, 2, ENC_BIG_ENDIAN);
1074         proto_item_append_text(velocity_item, " km/h");
1075         curr_offset += 2;
1076         /* Vertical Speed Octet 5
1077          * Vertical speed is encoded in increments of 1 kilometre per hour using 8 bits giving a number N between 0 and 28-1.
1078          */
1079         velocity_item = proto_tree_add_item(tree, hf_gsm_a_vertical_speed, tvb, offset, 1, ENC_BIG_ENDIAN);
1080         proto_item_append_text(velocity_item, " km/h");
1081         curr_offset++;
1082
1083         /* Horizontal Uncertainty Speed Octet 6 */
1084         uncertainty_speed = tvb_get_guint8(tvb,curr_offset);
1085         velocity_item = proto_tree_add_item(tree, hf_gsm_a_h_uncertainty_speed, tvb, offset, 2, ENC_BIG_ENDIAN);
1086         if (uncertainty_speed == 255) {
1087             proto_item_append_text(velocity_item, " not specified");
1088         }else{
1089             proto_item_append_text(velocity_item, " km/h");
1090         }
1091         offset++;
1092
1093         /* Vertical Uncertainty Speed Octet 7 */
1094         uncertainty_speed = tvb_get_guint8(tvb,curr_offset);
1095         velocity_item = proto_tree_add_item(tree, hf_gsm_a_v_uncertainty_speed, tvb, offset, 2, ENC_BIG_ENDIAN);
1096         if (uncertainty_speed == 255) {
1097             proto_item_append_text(velocity_item, " not specified");
1098         }else{
1099             proto_item_append_text(velocity_item, " km/h");
1100         }
1101         offset++;
1102
1103         break;
1104     default:
1105         break;
1106     }
1107
1108     return(curr_offset-offset);
1109 }
1110
1111 const char* get_gsm_a_msg_string(int pdu_type, int idx)
1112 {
1113     const char *msg_string = NULL;
1114
1115     switch (pdu_type) {
1116     case GSM_A_PDU_TYPE_BSSMAP:
1117         msg_string = val_to_str_ext(idx, &gsm_bssmap_elem_strings_ext, "GSM_A_PDU_TYPE_BSSMAP (%u)");
1118         break;
1119     case GSM_A_PDU_TYPE_DTAP:
1120         msg_string = val_to_str_ext(idx, &gsm_dtap_elem_strings_ext, "GSM_A_PDU_TYPE_DTAP (%u)");
1121         break;
1122     case GSM_A_PDU_TYPE_RP:
1123         msg_string = val_to_str_ext(idx, &gsm_rp_elem_strings_ext, "GSM_A_PDU_TYPE_RP (%u)");
1124         break;
1125     case GSM_A_PDU_TYPE_RR:
1126         msg_string = val_to_str_ext(idx, &gsm_rr_elem_strings_ext, "GSM_A_PDU_TYPE_RR (%u)");
1127         break;
1128     case GSM_A_PDU_TYPE_COMMON:
1129         msg_string = val_to_str_ext(idx, &gsm_common_elem_strings_ext, "GSM_A_PDU_TYPE_COMMON (%u)");
1130         break;
1131     case GSM_A_PDU_TYPE_GM:
1132         msg_string = val_to_str_ext(idx, &gsm_gm_elem_strings_ext, "GSM_A_PDU_TYPE_GM (%u)");
1133         break;
1134     case GSM_A_PDU_TYPE_BSSLAP:
1135         msg_string = val_to_str_ext(idx, &gsm_bsslap_elem_strings_ext, "GSM_A_PDU_TYPE_BSSLAP (%u)");
1136         break;
1137     case GSM_PDU_TYPE_BSSMAP_LE:
1138         msg_string = val_to_str_ext(idx, &gsm_bssmap_le_elem_strings_ext, "GSM_PDU_TYPE_BSSMAP_LE (%u)");
1139         break;
1140     case NAS_PDU_TYPE_COMMON:
1141         msg_string = val_to_str_ext(idx, &nas_eps_common_elem_strings_ext, "NAS_PDU_TYPE_COMMON (%u)");
1142         break;
1143     case NAS_PDU_TYPE_EMM:
1144         msg_string = val_to_str_ext(idx, &nas_emm_elem_strings_ext, "NAS_PDU_TYPE_EMM (%u)");
1145         break;
1146     case NAS_PDU_TYPE_ESM:
1147         msg_string = val_to_str_ext(idx, &nas_esm_elem_strings_ext, "NAS_PDU_TYPE_ESM (%u)");
1148         break;
1149     case SGSAP_PDU_TYPE:
1150         msg_string = val_to_str_ext(idx, &sgsap_elem_strings_ext, "SGSAP_PDU_TYPE (%u)");
1151         break;
1152     case BSSGP_PDU_TYPE:
1153         msg_string = val_to_str_ext(idx, &bssgp_elem_strings_ext, "BSSGP_PDU_TYPE (%u)");
1154         break;
1155     case GMR1_IE_COMMON:
1156         msg_string = val_to_str_ext(idx, &gmr1_ie_common_strings_ext, "GMR1_IE_COMMON (%u)");
1157         break;
1158     case GMR1_IE_RR:
1159         msg_string = val_to_str_ext(idx, &gmr1_ie_rr_strings_ext, "GMR1_IE_RR (%u)");
1160         break;
1161     default:
1162         DISSECTOR_ASSERT_NOT_REACHED();
1163     }
1164
1165     return msg_string;
1166 }
1167
1168 static int get_hf_elem_id(int pdu_type)
1169 {
1170     int hf_elem_id = 0;
1171
1172     switch (pdu_type) {
1173     case GSM_A_PDU_TYPE_BSSMAP:
1174         hf_elem_id = hf_gsm_a_bssmap_elem_id;
1175         break;
1176     case GSM_A_PDU_TYPE_DTAP:
1177         hf_elem_id = hf_gsm_a_dtap_elem_id;
1178         break;
1179     case GSM_A_PDU_TYPE_RP:
1180         hf_elem_id = hf_gsm_a_rp_elem_id;
1181         break;
1182     case GSM_A_PDU_TYPE_RR:
1183         hf_elem_id = hf_gsm_a_rr_elem_id;
1184         break;
1185     case GSM_A_PDU_TYPE_COMMON:
1186         hf_elem_id = hf_gsm_a_common_elem_id;
1187         break;
1188     case GSM_A_PDU_TYPE_GM:
1189         hf_elem_id = hf_gsm_a_gm_elem_id;
1190         break;
1191     case GSM_A_PDU_TYPE_BSSLAP:
1192         hf_elem_id = hf_gsm_a_bsslap_elem_id;
1193         break;
1194     case GSM_PDU_TYPE_BSSMAP_LE:
1195         hf_elem_id = hf_gsm_bssmap_le_elem_id;
1196         break;
1197     case NAS_PDU_TYPE_COMMON:
1198         hf_elem_id = hf_nas_eps_common_elem_id;
1199         break;
1200     case NAS_PDU_TYPE_EMM:
1201         hf_elem_id = hf_nas_eps_emm_elem_id;
1202         break;
1203     case NAS_PDU_TYPE_ESM:
1204         hf_elem_id = hf_nas_eps_esm_elem_id;
1205         break;
1206     case SGSAP_PDU_TYPE:
1207         hf_elem_id = hf_sgsap_elem_id;
1208         break;
1209     case BSSGP_PDU_TYPE:
1210         hf_elem_id = hf_bssgp_elem_id;
1211         break;
1212     case GMR1_IE_COMMON:
1213     case GMR1_IE_RR:
1214         hf_elem_id = hf_gmr1_elem_id;
1215         break;
1216     default:
1217         DISSECTOR_ASSERT_NOT_REACHED();
1218     }
1219
1220     return hf_elem_id;
1221 }
1222
1223 /*
1224  * Type Length Value (TLV) element dissector
1225  */
1226 guint16 elem_tlv(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint8 iei, gint pdu_type, int idx, guint32 offset, guint len _U_, const gchar *name_add)
1227 {
1228     guint8              oct;
1229     guint16             parm_len;
1230     guint8              lengt_length = 1;
1231     guint16             consumed;
1232     guint32             curr_offset;
1233     proto_tree         *subtree;
1234     proto_item         *item;
1235     value_string_ext    elem_names_ext;
1236     gint               *elem_ett;
1237     const gchar        *elem_name;
1238     guint16 (**elem_funcs)(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string, int string_len);
1239
1240     curr_offset = offset;
1241     consumed = 0;
1242
1243     SET_ELEM_VARS(pdu_type, elem_names_ext, elem_ett, elem_funcs);
1244
1245     oct = tvb_get_guint8(tvb, curr_offset);
1246
1247     if (oct == iei) {
1248         parm_len = tvb_get_guint8(tvb, curr_offset + 1);
1249
1250         elem_name = try_val_to_str_ext(idx, &elem_names_ext);
1251
1252         item =
1253         proto_tree_add_text(tree,
1254             tvb, curr_offset, parm_len + 1 + lengt_length,
1255             "%s%s", elem_name ? elem_name : "Unknown - aborting dissection",
1256             (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
1257
1258         /* idx is out of range */
1259         if (elem_name == NULL)
1260             return(consumed);
1261
1262         subtree = proto_item_add_subtree(item, elem_ett[idx]);
1263
1264         proto_tree_add_uint(subtree,
1265             get_hf_elem_id(pdu_type), tvb,
1266             curr_offset, 1, oct);
1267
1268         proto_tree_add_uint(subtree, hf_gsm_a_length, tvb,
1269             curr_offset + 1, lengt_length, parm_len);
1270
1271         if (parm_len > 0)
1272         {
1273             if (elem_funcs[idx] == NULL)
1274             {
1275                 proto_tree_add_text(subtree,
1276                     tvb, curr_offset + 1 + lengt_length, parm_len,
1277                     "Element Value");
1278                 /* See ASSERT above */
1279                 consumed = (guint8)parm_len;
1280             }
1281             else
1282             {
1283                 gchar *a_add_string;
1284
1285                 a_add_string = (gchar *)wmem_alloc(wmem_packet_scope(), 1024);
1286                 a_add_string[0] = '\0';
1287                 consumed =
1288                 (*elem_funcs[idx])(tvb, subtree, pinfo, curr_offset + 2,
1289                     parm_len, a_add_string, 1024);
1290
1291                 if (a_add_string[0] != '\0')
1292                 {
1293                     proto_item_append_text(item, "%s", a_add_string);
1294                 }
1295             }
1296         }
1297
1298         consumed += 1 + lengt_length;
1299     }
1300
1301     return(consumed);
1302 }
1303
1304 /*
1305  * Type Extendable Length Value (TELV) element dissector
1306  * This is a version where the length field can be one or two octets depending
1307  * if the extension bit is set or not (TS 48.016 p 10.1.2).
1308  *         8        7 6 5 4 3 2 1
1309  * octet 2 0/1 ext  length
1310  * octet 2a length
1311  */
1312 guint16 elem_telv(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint8 iei, gint pdu_type, int idx, guint32 offset, guint len _U_, const gchar *name_add)
1313 {
1314     guint8              oct;
1315     guint16             parm_len;
1316     guint8              lengt_length = 1;
1317     guint16             consumed;
1318     guint32             curr_offset;
1319     proto_tree         *subtree;
1320     proto_item         *item;
1321     value_string_ext    elem_names_ext;
1322     gint               *elem_ett;
1323     const gchar        *elem_name;
1324     guint16 (**elem_funcs)(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string, int string_len);
1325
1326     curr_offset = offset;
1327     consumed = 0;
1328
1329     SET_ELEM_VARS(pdu_type, elem_names_ext, elem_ett, elem_funcs);
1330
1331     oct = tvb_get_guint8(tvb, curr_offset);
1332
1333     if (oct == iei) {
1334         parm_len = tvb_get_guint8(tvb, curr_offset + 1);
1335         if ((parm_len&0x80) == 0) {
1336             /* length in 2 octets */
1337             parm_len = tvb_get_ntohs(tvb, curr_offset + 1);
1338             lengt_length = 2;
1339         }else{
1340             parm_len = parm_len & 0x7f;
1341         }
1342
1343         elem_name = try_val_to_str_ext(idx, &elem_names_ext);
1344
1345         item =
1346         proto_tree_add_text(tree,
1347             tvb, curr_offset, parm_len + 1 + lengt_length,
1348             "%s%s", elem_name ? elem_name : "Unknown - aborting dissection",
1349             (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
1350
1351         /* idx is out of range */
1352         if (elem_name == NULL)
1353             return(consumed);
1354
1355         subtree = proto_item_add_subtree(item, elem_ett[idx]);
1356
1357         proto_tree_add_uint(subtree,
1358             get_hf_elem_id(pdu_type), tvb,
1359             curr_offset, 1, oct);
1360
1361         proto_tree_add_item(subtree, hf_gsm_a_l_ext, tvb, curr_offset+1, 1, ENC_BIG_ENDIAN);
1362
1363         proto_tree_add_uint(subtree, hf_gsm_a_length, tvb,
1364             curr_offset + 1, lengt_length, parm_len);
1365
1366         if (parm_len > 0)
1367         {
1368             if (elem_funcs[idx] == NULL)
1369             {
1370                 proto_tree_add_text(subtree,
1371                     tvb, curr_offset + 1 + lengt_length, parm_len,
1372                     "Element Value");
1373                 /* See ASSERT above */
1374                 consumed = parm_len;
1375             }
1376             else
1377             {
1378                 gchar *a_add_string;
1379
1380                 a_add_string = (gchar*)wmem_alloc(wmem_packet_scope(), 1024);
1381                 a_add_string[0] = '\0';
1382                 consumed =
1383                 (*elem_funcs[idx])(tvb, subtree, pinfo, curr_offset + 1 + lengt_length,
1384                     parm_len, a_add_string, 1024);
1385
1386                 if (a_add_string[0] != '\0')
1387                 {
1388                     proto_item_append_text(item, "%s", a_add_string);
1389                 }
1390             }
1391         }
1392
1393         consumed += 1 + lengt_length;
1394     }
1395
1396     return(consumed);
1397 }
1398
1399 /*
1400  * Type Length Value Extended(TLV-E) element dissector
1401  * TS 24.007
1402  * information elements of format LV-E or TLV-E with value part consisting of zero,
1403  * one or more octets and a maximum of 65535 octets (type 6). This category is used in EPS only.
1404  */
1405 guint16 elem_tlv_e(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint8 iei, gint pdu_type, int idx, guint32 offset, guint len _U_, const gchar *name_add)
1406 {
1407     guint8              oct;
1408     guint16             parm_len;
1409     guint16             consumed;
1410     guint32             curr_offset;
1411     proto_tree         *subtree;
1412     proto_item         *item;
1413     value_string_ext    elem_names_ext;
1414     gint               *elem_ett;
1415     const gchar        *elem_name;
1416     guint16 (**elem_funcs)(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string, int string_len);
1417
1418     curr_offset = offset;
1419     consumed = 0;
1420
1421     SET_ELEM_VARS(pdu_type, elem_names_ext, elem_ett, elem_funcs);
1422
1423     oct = tvb_get_guint8(tvb, curr_offset);
1424
1425     if (oct == iei) {
1426         parm_len = tvb_get_ntohs(tvb, curr_offset + 1);
1427
1428         elem_name = try_val_to_str_ext(idx, &elem_names_ext);
1429
1430         item = proto_tree_add_text(tree, tvb, curr_offset, parm_len + 1 + 2,
1431             "%s%s", elem_name ? elem_name : "Unknown - aborting dissection",
1432             (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
1433
1434         /* idx is out of range */
1435         if (elem_name == NULL)
1436             return(consumed);
1437
1438         subtree = proto_item_add_subtree(item, elem_ett[idx]);
1439
1440         proto_tree_add_uint(subtree,
1441             get_hf_elem_id(pdu_type), tvb,
1442             curr_offset, 1, oct);
1443
1444         proto_tree_add_uint(subtree, hf_gsm_a_length, tvb,
1445             curr_offset + 1, 2, parm_len);
1446
1447         if (parm_len > 0)
1448         {
1449             if (elem_funcs[idx] == NULL)
1450             {
1451                 proto_tree_add_text(subtree,
1452                     tvb, curr_offset + 1 + 2, parm_len,
1453                     "Element Value");
1454                 /* See ASSERT above */
1455                 consumed = parm_len;
1456             }
1457             else
1458             {
1459                 gchar *a_add_string;
1460
1461                 a_add_string = (gchar*)wmem_alloc(wmem_packet_scope(), 1024);
1462                 a_add_string[0] = '\0';
1463                 consumed =
1464                 (*elem_funcs[idx])(tvb, subtree, pinfo, curr_offset + 1 + 2,
1465                     parm_len, a_add_string, 1024);
1466
1467                 if (a_add_string[0] != '\0')
1468                 {
1469                     proto_item_append_text(item, "%s", a_add_string);
1470                 }
1471             }
1472         }
1473
1474         consumed += 1 + 2;
1475     }
1476
1477     return(consumed);
1478 }
1479
1480 /*
1481  * Type Value (TV) element dissector
1482  *
1483  * Length cannot be used in these functions, big problem if a element dissector
1484  * is not defined for these.
1485  */
1486 guint16 elem_tv(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint8 iei, gint pdu_type, int idx, guint32 offset, const gchar *name_add)
1487 {
1488     guint8              oct;
1489     guint16             consumed;
1490     guint32             curr_offset;
1491     proto_tree         *subtree;
1492     proto_item         *item;
1493     value_string_ext    elem_names_ext;
1494     gint               *elem_ett;
1495     const gchar        *elem_name;
1496     guint16 (**elem_funcs)(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string, int string_len);
1497
1498     curr_offset = offset;
1499     consumed = 0;
1500
1501     SET_ELEM_VARS(pdu_type, elem_names_ext, elem_ett, elem_funcs);
1502
1503     oct = tvb_get_guint8(tvb, curr_offset);
1504
1505     if (oct == iei)
1506     {
1507         elem_name = try_val_to_str_ext(idx, &elem_names_ext);
1508
1509         item =
1510             proto_tree_add_text(tree, tvb, curr_offset, -1,
1511                 "%s%s", elem_name ? elem_name : "Unknown - aborting dissection",
1512                 (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
1513
1514         /* idx is out of range */
1515         if (elem_name == NULL)
1516             return(consumed);
1517
1518         subtree = proto_item_add_subtree(item, elem_ett[idx]);
1519
1520         proto_tree_add_uint(subtree,
1521             get_hf_elem_id(pdu_type), tvb,
1522             curr_offset, 1, oct);
1523
1524         if (elem_funcs[idx] == NULL)
1525         {
1526             /* BAD THING, CANNOT DETERMINE LENGTH */
1527
1528             proto_tree_add_text(subtree,
1529                 tvb, curr_offset + 1, 1,
1530                 "No element dissector, rest of dissection may be incorrect");
1531
1532             consumed = 1;
1533         }
1534         else
1535         {
1536             gchar *a_add_string;
1537
1538             a_add_string = (gchar*)wmem_alloc(wmem_packet_scope(), 1024);
1539             a_add_string[0] = '\0';
1540             consumed = (*elem_funcs[idx])(tvb, subtree, pinfo, curr_offset + 1, -1, a_add_string, 1024);
1541
1542             if (a_add_string[0] != '\0')
1543             {
1544                 proto_item_append_text(item, "%s", a_add_string);
1545             }
1546         }
1547
1548         consumed++;
1549
1550         proto_item_set_len(item, consumed);
1551     }
1552
1553     return(consumed);
1554 }
1555
1556 /*
1557  * Type Value (TV) element dissector
1558  * Where top half nibble is IEI and bottom half nibble is value.
1559  *
1560  * Length cannot be used in these functions, big problem if a element dissector
1561  * is not defined for these.
1562  */
1563 guint16 elem_tv_short(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint8 iei, gint pdu_type, int idx, guint32 offset, const gchar *name_add)
1564 {
1565     guint8              oct;
1566     guint16             consumed;
1567     guint32             curr_offset;
1568     proto_tree         *subtree;
1569     proto_item         *item;
1570     value_string_ext    elem_names_ext;
1571     gint               *elem_ett;
1572     const gchar        *elem_name;
1573     guint16 (**elem_funcs)(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string, int string_len);
1574     char                buf[10+1];
1575
1576     curr_offset = offset;
1577     consumed = 0;
1578
1579     SET_ELEM_VARS(pdu_type, elem_names_ext, elem_ett, elem_funcs);
1580
1581     oct = tvb_get_guint8(tvb, curr_offset);
1582
1583     if ((oct & 0xf0) == (iei & 0xf0))
1584     {
1585         elem_name = try_val_to_str_ext(idx, &elem_names_ext);
1586
1587         item =
1588             proto_tree_add_text(tree,
1589                 tvb, curr_offset, -1,
1590                 "%s%s", elem_name ? elem_name : "Unknown - aborting dissection",
1591                 (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
1592
1593         /* idx is out of range */
1594         if (elem_name == NULL)
1595             return(consumed);
1596
1597         subtree = proto_item_add_subtree(item, elem_ett[idx]);
1598
1599         other_decode_bitfield_value(buf, oct, 0xf0, 8);
1600         proto_tree_add_text(subtree,
1601             tvb, curr_offset, 1,
1602             "%s = Element ID: 0x%1x-",
1603             buf, oct>>4);
1604
1605         if (elem_funcs[idx] == NULL)
1606         {
1607             /* BAD THING, CANNOT DETERMINE LENGTH */
1608
1609             proto_tree_add_text(subtree,
1610                 tvb, curr_offset, 1,
1611                 "No element dissector, rest of dissection may be incorrect");
1612
1613             consumed++;
1614         }
1615         else
1616         {
1617             gchar *a_add_string;
1618
1619             a_add_string = (gchar*)wmem_alloc(wmem_packet_scope(), 1024);
1620             a_add_string[0] = '\0';
1621             consumed = (*elem_funcs[idx])(tvb, subtree, pinfo, curr_offset, RIGHT_NIBBLE, a_add_string, 1024);
1622
1623             if (a_add_string[0] != '\0')
1624             {
1625                 proto_item_append_text(item, "%s", a_add_string);
1626             }
1627         }
1628
1629         proto_item_set_len(item, consumed);
1630     }
1631
1632     return(consumed);
1633 }
1634
1635 /*
1636  * Type (T) element dissector
1637  */
1638 guint16 elem_t(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint8 iei, gint pdu_type, int idx, guint32 offset, const gchar *name_add)
1639 {
1640     guint8              oct;
1641     guint32             curr_offset;
1642     guint16             consumed;
1643     value_string_ext    elem_names_ext;
1644     gint               *elem_ett;
1645     guint16 (**elem_funcs)(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string, int string_len);
1646
1647     curr_offset = offset;
1648     consumed = 0;
1649
1650     SET_ELEM_VARS(pdu_type, elem_names_ext, elem_ett, elem_funcs);
1651
1652     (void)elem_ett;
1653     (void)elem_funcs;
1654
1655     oct = tvb_get_guint8(tvb, curr_offset);
1656
1657     if (oct == iei)
1658     {
1659         proto_tree_add_uint_format(tree,
1660             get_hf_elem_id(pdu_type), tvb,
1661             curr_offset, 1, oct,
1662             "%s%s",
1663             val_to_str_ext(idx, &elem_names_ext, "Unknown (%u)"),
1664             (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
1665
1666         consumed = 1;
1667     }
1668
1669     return(consumed);
1670 }
1671
1672 /*
1673  * Length Value (LV) element dissector
1674  */
1675 guint16
1676 elem_lv(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gint pdu_type, int idx, guint32 offset, guint len _U_, const gchar *name_add)
1677 {
1678     guint8              parm_len;
1679     guint16             consumed;
1680     guint32             curr_offset;
1681     proto_tree         *subtree;
1682     proto_item         *item;
1683     value_string_ext    elem_names_ext;
1684     gint               *elem_ett;
1685     const gchar        *elem_name;
1686     guint16 (**elem_funcs)(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string, int string_len);
1687
1688     curr_offset = offset;
1689     consumed = 0;
1690
1691     SET_ELEM_VARS(pdu_type, elem_names_ext, elem_ett, elem_funcs);
1692
1693     parm_len = tvb_get_guint8(tvb, curr_offset);
1694
1695     elem_name = try_val_to_str_ext(idx, &elem_names_ext);
1696
1697     item =
1698         proto_tree_add_text(tree,
1699             tvb, curr_offset, parm_len + 1,
1700             "%s%s", elem_name ? elem_name : "Unknown - aborting dissection",
1701             (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
1702
1703     /* idx is out of range */
1704     if (elem_name == NULL)
1705         return(consumed);
1706
1707     subtree = proto_item_add_subtree(item, elem_ett[idx]);
1708
1709     proto_tree_add_uint(subtree, hf_gsm_a_length, tvb,
1710         curr_offset, 1, parm_len);
1711
1712     if (parm_len > 0)
1713     {
1714         if (elem_funcs[idx] == NULL)
1715         {
1716             proto_tree_add_text(subtree,
1717                 tvb, curr_offset + 1, parm_len,
1718                 "Element Value");
1719
1720             consumed = parm_len;
1721         }
1722         else
1723         {
1724             gchar *a_add_string;
1725
1726             a_add_string = (gchar*)wmem_alloc(wmem_packet_scope(), 1024);
1727             a_add_string[0] = '\0';
1728             consumed =
1729                 (*elem_funcs[idx])(tvb, subtree, pinfo, curr_offset + 1,
1730                     parm_len, a_add_string, 1024);
1731
1732             if (a_add_string[0] != '\0')
1733             {
1734                 proto_item_append_text(item, "%s", a_add_string);
1735             }
1736         }
1737     }
1738
1739     return(consumed + 1);
1740 }
1741
1742 /*
1743  * Length Value Extended(LV-E) element dissector
1744  */
1745 guint16 elem_lv_e(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gint pdu_type, int idx, guint32 offset, guint len _U_, const gchar *name_add)
1746 {
1747     guint16             parm_len;
1748     guint16             consumed;
1749     guint32             curr_offset;
1750     proto_tree         *subtree;
1751     proto_item         *item;
1752     value_string_ext    elem_names_ext;
1753     gint               *elem_ett;
1754     const gchar        *elem_name;
1755     guint16 (**elem_funcs)(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string, int string_len);
1756
1757     curr_offset = offset;
1758     consumed = 0;
1759
1760     SET_ELEM_VARS(pdu_type, elem_names_ext, elem_ett, elem_funcs);
1761
1762     parm_len = tvb_get_ntohs(tvb, curr_offset);
1763
1764     elem_name = try_val_to_str_ext(idx, &elem_names_ext);
1765
1766     item = proto_tree_add_text(tree, tvb, curr_offset, parm_len + 2,
1767             "%s%s", elem_name ? elem_name : "Unknown - aborting dissection",
1768             (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
1769
1770     /* idx is out of range */
1771     if (elem_name == NULL)
1772         return(consumed);
1773
1774     subtree = proto_item_add_subtree(item, elem_ett[idx]);
1775
1776     proto_tree_add_uint(subtree, hf_gsm_a_length, tvb,
1777         curr_offset, 2, parm_len);
1778
1779     if (parm_len > 0)
1780     {
1781         if (elem_funcs[idx] == NULL)
1782         {
1783             proto_tree_add_text(subtree,
1784                 tvb, curr_offset + 2, parm_len,
1785                 "Element Value");
1786
1787             consumed = parm_len;
1788         }
1789         else
1790         {
1791             gchar *a_add_string;
1792
1793             a_add_string = (gchar*)wmem_alloc(wmem_packet_scope(), 1024);
1794             a_add_string[0] = '\0';
1795             consumed =
1796                 (*elem_funcs[idx])(tvb, subtree, pinfo, curr_offset + 2,
1797                     parm_len, a_add_string, 1024);
1798
1799             if (a_add_string[0] != '\0')
1800             {
1801                 proto_item_append_text(item, "%s", a_add_string);
1802             }
1803         }
1804     }
1805
1806     return(consumed + 2);
1807 }
1808 /*
1809  * Value (V) element dissector
1810  *
1811  * Length cannot be used in these functions, big problem if a element dissector
1812  * is not defined for these.
1813  */
1814 guint16 elem_v(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gint pdu_type, int idx, guint32 offset, const gchar *name_add)
1815 {
1816     guint16             consumed;
1817     guint32             curr_offset;
1818     proto_tree         *subtree;
1819     proto_item         *item;
1820     value_string_ext    elem_names_ext;
1821     gint               *elem_ett;
1822     const gchar        *elem_name;
1823     guint16 (**elem_funcs)(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string, int string_len);
1824
1825     curr_offset = offset;
1826     consumed = 0;
1827
1828     SET_ELEM_VARS(pdu_type, elem_names_ext, elem_ett, elem_funcs);
1829
1830     elem_name = try_val_to_str_ext(idx, &elem_names_ext);
1831
1832     if (elem_name == NULL || elem_funcs[idx] == NULL)
1833     {
1834         /* BAD THING, CANNOT DETERMINE LENGTH */
1835
1836         proto_tree_add_text(tree,
1837             tvb, curr_offset, 1,
1838             "No element dissector, rest of dissection may be incorrect");
1839
1840         consumed = 1;
1841     }
1842     else
1843     {
1844         gchar *a_add_string;
1845
1846         item =
1847             proto_tree_add_text(tree,
1848                 tvb, curr_offset, 0,
1849                 "%s%s", elem_name,
1850                 (name_add == NULL) || (name_add[0] == '\0') ? "" : name_add);
1851
1852         subtree = proto_item_add_subtree(item, elem_ett[idx]);
1853
1854         a_add_string= (gchar*)wmem_alloc(wmem_packet_scope(), 1024);
1855         a_add_string[0] = '\0';
1856         consumed = (*elem_funcs[idx])(tvb, subtree, pinfo, curr_offset, -1, a_add_string, 1024);
1857         if (a_add_string[0] != '\0')
1858         {
1859             proto_item_append_text(item, "%s", a_add_string);
1860         }
1861         proto_item_set_len(item, consumed);
1862     }
1863
1864     return(consumed);
1865 }
1866
1867 /*
1868  * Short Value (V_SHORT) element dissector
1869  *
1870  * nibble is used in this function to indicate right or left nibble of the octet
1871  * This is expected to be used right nibble first, as the tables of 24.008.
1872  */
1873
1874 guint16 elem_v_short(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gint pdu_type, int idx, guint32 offset, guint32 nibble)
1875 {
1876     guint16             consumed = 1;
1877     guint32             curr_offset;
1878     proto_tree         *subtree;
1879     proto_item         *item;
1880     value_string_ext    elem_names_ext;
1881     gint               *elem_ett;
1882     elem_fcn           *elem_funcs;
1883     gchar              *a_add_string;
1884     const gchar        *elem_name;
1885
1886     curr_offset = offset;
1887
1888     SET_ELEM_VARS(pdu_type, elem_names_ext, elem_ett, elem_funcs);
1889
1890     elem_name = try_val_to_str_ext(idx, &elem_names_ext);
1891
1892     item = proto_tree_add_text(tree,
1893             tvb, curr_offset, 0,
1894             "%s%s", elem_name ? elem_name : "Unknown - aborting dissection",
1895             "");
1896
1897     /* idx is out of range */
1898     if (elem_name == NULL)
1899         return(consumed);
1900
1901     subtree = proto_item_add_subtree(item, elem_ett[idx]);
1902
1903     a_add_string= (gchar*)wmem_alloc(wmem_packet_scope(), 1024);
1904     a_add_string[0] = '\0';
1905
1906     if (elem_funcs[idx] == NULL)
1907     {
1908         /* NOT NECESSARILY A BAD THING - LENGTH IS HALF OCTET */
1909         (void)de_spare_nibble(tvb, subtree, pinfo, curr_offset, nibble, a_add_string, 1024);
1910     }
1911     else
1912     {
1913         (void)(*elem_funcs[idx])(tvb, subtree, pinfo, curr_offset, nibble, a_add_string, 1024);
1914     }
1915
1916     if (a_add_string[0] != '\0')
1917     {
1918         proto_item_append_text(item, "%s", a_add_string);
1919     }
1920     proto_item_set_len(item, consumed);
1921
1922     return(consumed);
1923 }
1924
1925
1926 static dgt_set_t Dgt_tbcd = {
1927     {
1928   /*  0   1   2   3   4   5   6   7   8   9   a   b   c   d   e */
1929      '0','1','2','3','4','5','6','7','8','9','?','B','C','*','#'
1930     }
1931 };
1932
1933 static dgt_set_t Dgt1_9_bcd = {
1934     {
1935   /*  0   1   2   3   4   5   6   7   8   9   a   b   c   d   e */
1936      '0','1','2','3','4','5','6','7','8','9','?','?','?','?','?'
1937     }
1938 };
1939
1940 /* FUNCTIONS */
1941
1942 /*
1943  * Unpack BCD input pattern into output ASCII pattern
1944  *
1945  * Input Pattern is supplied using the same format as the digits
1946  *
1947  * Returns: length of unpacked pattern
1948  */
1949 int
1950 my_dgt_tbcd_unpack(
1951     char    *out,       /* ASCII pattern out */
1952     guchar  *in,        /* packed pattern in */
1953     int     num_octs,   /* Number of octets to unpack */
1954     dgt_set_t   *dgt        /* Digit definitions */
1955     )
1956 {
1957     int cnt = 0;
1958     unsigned char i;
1959
1960     while (num_octs)
1961     {
1962         /*
1963          * unpack first value in byte
1964          */
1965         i = *in++;
1966         *out++ = dgt->out[i & 0x0f];
1967         cnt++;
1968
1969         /*
1970          * unpack second value in byte
1971          */
1972         i >>= 4;
1973
1974         if (i == 0x0f)  /* odd number bytes - hit filler */
1975             break;
1976
1977         *out++ = dgt->out[i];
1978         cnt++;
1979         num_octs--;
1980     }
1981
1982     *out = '\0';
1983
1984     return(cnt);
1985 }
1986
1987 /*
1988  * Decode the MCC/MNC from 3 octets in 'octs'
1989  */
1990 static void
1991 mcc_mnc_aux(guint8 *octs, gchar *mcc, gchar *mnc)
1992 {
1993     if ((octs[0] & 0x0f) <= 9)
1994     {
1995         mcc[0] = Dgt_tbcd.out[octs[0] & 0x0f];
1996     }
1997     else
1998     {
1999         mcc[0] = (octs[0] & 0x0f) + 55;
2000     }
2001
2002     if (((octs[0] & 0xf0) >> 4) <= 9)
2003     {
2004         mcc[1] = Dgt_tbcd.out[(octs[0] & 0xf0) >> 4];
2005     }
2006     else
2007     {
2008         mcc[1] = ((octs[0] & 0xf0) >> 4) + 55;
2009     }
2010
2011     if ((octs[1] & 0x0f) <= 9)
2012     {
2013         mcc[2] = Dgt_tbcd.out[octs[1] & 0x0f];
2014     }
2015     else
2016     {
2017         mcc[2] = (octs[1] & 0x0f) + 55;
2018     }
2019
2020     mcc[3] = '\0';
2021
2022     if (((octs[1] & 0xf0) >> 4) <= 9)
2023     {
2024         mnc[2] = Dgt_tbcd.out[(octs[1] & 0xf0) >> 4];
2025     }
2026     else
2027     {
2028         mnc[2] = ((octs[1] & 0xf0) >> 4) + 55;
2029     }
2030
2031     if ((octs[2] & 0x0f) <= 9)
2032     {
2033         mnc[0] = Dgt_tbcd.out[octs[2] & 0x0f];
2034     }
2035     else
2036     {
2037         mnc[0] = (octs[2] & 0x0f) + 55;
2038     }
2039
2040     if (((octs[2] & 0xf0) >> 4) <= 9)
2041     {
2042         mnc[1] = Dgt_tbcd.out[(octs[2] & 0xf0) >> 4];
2043     }
2044     else
2045     {
2046         mnc[1] = ((octs[2] & 0xf0) >> 4) + 55;
2047     }
2048
2049     if (mnc[1] == 'F')
2050     {
2051         /*
2052          * only a 1 digit MNC (very old)
2053          */
2054         mnc[1] = '\0';
2055     }
2056     else if (mnc[2] == 'F')
2057     {
2058         /*
2059          * only a 2 digit MNC
2060          */
2061         mnc[2] = '\0';
2062     }
2063     else
2064     {
2065         mnc[3] = '\0';
2066     }
2067 }
2068
2069 /* 3GPP TS 24.008
2070  * [3] 10.5.1.1 Cell Identity
2071  */
2072 guint16
2073 de_cell_id(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len, gchar *add_string, int string_len)
2074 {
2075     guint32 curr_offset;
2076
2077     curr_offset = offset;
2078
2079     curr_offset +=
2080     /* 0x02 CI */
2081     be_cell_id_aux(tvb, tree, pinfo, offset, len, add_string, string_len, 0x02);
2082
2083     /* no length check possible */
2084
2085     return(curr_offset - offset);
2086 }
2087 /*
2088  * 10.5.1.2 Ciphering Key Sequence Number
2089  */
2090
2091
2092 /*
2093  * Key sequence (octet 1)
2094  * Bits
2095  * 3 2 1
2096  * 0 0 0
2097  * through
2098  * 1 1 0
2099  * Possible values for the ciphering key sequence number
2100  * 1 1 1 No key is available (MS to network);Reserved (network to MS)
2101  */
2102
2103 static const value_string gsm_a_key_seq_vals[] = {
2104     { 0, "Ciphering key sequence number"},
2105     { 1, "Ciphering key sequence number"},
2106     { 2, "Ciphering key sequence number"},
2107     { 3, "Ciphering key sequence number"},
2108     { 4, "Ciphering key sequence number"},
2109     { 5, "Ciphering key sequence number"},
2110     { 6, "Ciphering key sequence number"},
2111     { 7, "No key is available (MS to network)"},
2112     { 0,    NULL }
2113 };
2114
2115 static guint16
2116 de_ciph_key_seq_num( tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2117 {
2118     guint32 curr_offset, bit_offset;
2119
2120     curr_offset = offset;
2121
2122     if (RIGHT_NIBBLE == len)
2123         bit_offset = 4;
2124     else
2125         bit_offset = 0;
2126
2127     proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, (curr_offset<<3)+bit_offset, 1, ENC_BIG_ENDIAN);
2128     proto_tree_add_bits_item(tree, hf_gsm_a_key_seq, tvb, (curr_offset<<3)+bit_offset+1, 3, ENC_BIG_ENDIAN);
2129     curr_offset++;
2130
2131     return(curr_offset - offset);
2132 }
2133
2134
2135 /*
2136  * [3] 10.5.1.3
2137  */
2138
2139 guint16
2140 de_lai(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2141 {
2142     guint8      octs[3];
2143     guint16     value;
2144     guint32     curr_offset;
2145     proto_tree *subtree;
2146     proto_item *item;
2147     gchar       mcc[4];
2148     gchar       mnc[4];
2149
2150     curr_offset = offset;
2151
2152     item = proto_tree_add_text(tree,
2153                                tvb, curr_offset, 5, "%s",
2154                                val_to_str_ext_const(DE_LAI, &gsm_common_elem_strings_ext, ""));
2155
2156     subtree = proto_item_add_subtree(item, ett_gsm_common_elem[DE_LAI]);
2157
2158     octs[0] = tvb_get_guint8(tvb, curr_offset);
2159     octs[1] = tvb_get_guint8(tvb, curr_offset + 1);
2160     octs[2] = tvb_get_guint8(tvb, curr_offset + 2);
2161
2162     mcc_mnc_aux(octs, mcc, mnc);
2163
2164     curr_offset = dissect_e212_mcc_mnc(tvb, pinfo, subtree, curr_offset, TRUE);
2165
2166     value = tvb_get_ntohs(tvb, curr_offset);
2167
2168     proto_tree_add_item(subtree, hf_gsm_a_lac, tvb, curr_offset, 2, ENC_BIG_ENDIAN);
2169
2170     proto_item_append_text(item, " - %s/%s/%u", mcc,mnc,value);
2171
2172     curr_offset += 2;
2173
2174     /* no length check possible */
2175
2176     return(curr_offset - offset);
2177 }
2178
2179 /*
2180  * [3] 10.5.1.4 Mobile Identity
2181  * 3GPP TS 24.008 version 7.8.0 Release 7
2182  */
2183 static const true_false_string gsm_a_present_vals = {
2184     "Present" ,
2185     "Not present"
2186 };
2187
2188 guint16
2189 de_mid(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string, int string_len)
2190 {
2191     guint8    oct;
2192     guint32   curr_offset;
2193     guint8   *poctets;
2194     guint32   value;
2195     gboolean  odd;
2196     const gchar *digit_str;
2197
2198     curr_offset = offset;
2199
2200     oct = tvb_get_guint8(tvb, curr_offset);
2201
2202     switch (oct & 0x07)
2203     {
2204     case 0: /* No Identity */
2205         proto_tree_add_item(tree, hf_gsm_a_unused, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2206         proto_tree_add_item(tree, hf_gsm_a_odd_even_ind, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2207         proto_tree_add_item(tree, hf_gsm_a_mobile_identity_type, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2208
2209         if (add_string)
2210             g_snprintf(add_string, string_len, " - No Identity Code");
2211
2212         curr_offset++;
2213
2214         if (len > 1)
2215         {
2216             proto_tree_add_text(tree, tvb, curr_offset, len - 1,
2217                 "Format not supported");
2218         }
2219
2220         curr_offset += len - 1;
2221         break;
2222
2223     case 3: /* IMEISV */
2224         /* FALLTHRU */
2225
2226     case 1: /* IMSI */
2227         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
2228         proto_tree_add_text(tree,
2229             tvb, curr_offset, 1,
2230             "%s = Identity Digit 1: %c",
2231             a_bigbuf,
2232             Dgt1_9_bcd.out[(oct & 0xf0) >> 4]);
2233
2234         odd = oct & 0x08;
2235
2236         proto_tree_add_item(tree, hf_gsm_a_odd_even_ind, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2237
2238         proto_tree_add_item(tree, hf_gsm_a_mobile_identity_type, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2239
2240         digit_str = tvb_bcd_dig_to_ep_str(tvb ,curr_offset , len - (curr_offset - offset), NULL, TRUE);
2241
2242         proto_tree_add_string_format(tree,
2243             ((oct & 0x07) == 3) ? hf_gsm_a_imeisv : hf_gsm_a_imsi,
2244             tvb, curr_offset, len - (curr_offset - offset),
2245             digit_str,
2246             "BCD Digits: %s",
2247             digit_str);
2248
2249         if (sccp_assoc && ! sccp_assoc->calling_party) {
2250             sccp_assoc->calling_party = wmem_strdup_printf(wmem_file_scope(), 
2251                 ((oct & 0x07) == 3) ? "IMEISV: %s" : "IMSI: %s",
2252                 digit_str );
2253         }
2254
2255         if (add_string)
2256             g_snprintf(add_string, string_len, " - %s (%s)",
2257                 ((oct & 0x07) == 3) ? "IMEISV" : "IMSI",
2258                 digit_str);
2259
2260         curr_offset += len - (curr_offset - offset);
2261
2262         if (!odd)
2263         {
2264             oct = tvb_get_guint8(tvb, curr_offset - 1);
2265
2266             other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
2267             proto_tree_add_text(tree,
2268                 tvb, curr_offset - 1, 1,
2269                 "%s = Filler",
2270                 a_bigbuf);
2271         }
2272         break;
2273
2274     case 2: /* IMEI */
2275         other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
2276         proto_tree_add_text(tree,
2277             tvb, curr_offset, 1,
2278             "%s = Identity Digit 1: %c",
2279             a_bigbuf,
2280             Dgt1_9_bcd.out[(oct & 0xf0) >> 4]);
2281
2282         proto_tree_add_item(tree, hf_gsm_a_odd_even_ind, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2283
2284         proto_tree_add_item(tree, hf_gsm_a_mobile_identity_type, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2285
2286         a_bigbuf[0] = Dgt1_9_bcd.out[(oct & 0xf0) >> 4];
2287         curr_offset++;
2288
2289         poctets = tvb_get_string(wmem_packet_scope(), tvb, curr_offset, len - (curr_offset - offset));
2290
2291         my_dgt_tbcd_unpack(&a_bigbuf[1], poctets, len - (curr_offset - offset),
2292             &Dgt1_9_bcd);
2293
2294         proto_tree_add_string_format(tree,
2295             hf_gsm_a_imei,
2296             tvb, curr_offset, len - (curr_offset - offset),
2297             a_bigbuf,
2298             "BCD Digits: %s",
2299             a_bigbuf);
2300
2301         if (add_string)
2302             g_snprintf(add_string, string_len, " - IMEI (%s)", a_bigbuf);
2303
2304         curr_offset += len - (curr_offset - offset);
2305         break;
2306
2307     case 4: /* TMSI/P-TMSI/M-TMSI */
2308         proto_tree_add_item(tree, hf_gsm_a_unused, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2309         proto_tree_add_item(tree, hf_gsm_a_odd_even_ind, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2310         proto_tree_add_item(tree, hf_gsm_a_mobile_identity_type, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2311         curr_offset++;
2312
2313         value = tvb_get_ntohl(tvb, curr_offset);
2314
2315         proto_tree_add_uint(tree, hf_gsm_a_tmsi,
2316             tvb, curr_offset, 4,
2317             value);
2318
2319         if (add_string)
2320             g_snprintf(add_string, string_len, " - TMSI/P-TMSI (0x%04x)", value);
2321
2322         curr_offset += 4;
2323         break;
2324
2325     case 5: /* TMGI and optional MBMS Session Identity */
2326         /* Spare bits (octet 3) Bits 8-7 */
2327         proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, curr_offset<<3, 2, ENC_BIG_ENDIAN);
2328         /* MBMS Session Identity indication (octet 3) Bit 6 */
2329         proto_tree_add_item(tree, hf_gsm_a_mbs_ses_id_ind, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2330         /* MCC/MNC indication (octet 3) Bit 5 */
2331         proto_tree_add_item(tree, hf_gsm_a_tmgi_mcc_mnc_ind, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2332         /* Odd/even indication (octet 3) Bit 4 */
2333         proto_tree_add_item(tree, hf_gsm_a_odd_even_ind, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2334         /* Type of identity (octet 3) Bits 3-1 */
2335         proto_tree_add_item(tree, hf_gsm_a_mobile_identity_type, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2336         curr_offset++;
2337         /* MBMS Service ID (octet 4, 5 and 6) */
2338         proto_tree_add_item(tree, hf_gsm_a_mbs_service_id, tvb, curr_offset, 3, ENC_BIG_ENDIAN);
2339         curr_offset += 3;
2340         if ((oct&0x10) == 0x10) {
2341             /* MCC/MNC*/
2342             /* MCC, Mobile country code (octet 6a, octet 6b bits 1 to 4)*/
2343             /* MNC, Mobile network code (octet 6b bits 5 to 8, octet 6c) */
2344             curr_offset = dissect_e212_mcc_mnc(tvb, pinfo, tree, curr_offset, TRUE);
2345         }
2346         if ((oct&0x20) == 0x20) {
2347             /* MBMS Session Identity (octet 7)
2348              * The MBMS Session Identity field is encoded as the value part
2349              * of the MBMS Session Identity IE as specified in 3GPP TS 48.018 [86].
2350              */
2351             proto_tree_add_item(tree, hf_gsm_a_mbs_session_id, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2352             curr_offset++;
2353         }
2354         break;
2355
2356     default:    /* Reserved */
2357         proto_tree_add_item(tree, hf_gsm_a_odd_even_ind, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2358         proto_tree_add_item(tree, hf_gsm_a_mobile_identity_type, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2359         proto_tree_add_text(tree, tvb, curr_offset, len,
2360             "Mobile station identity Format %u, Format Unknown", (oct & 0x07));
2361
2362         if (add_string)
2363             g_snprintf(add_string, string_len, " - Format Unknown");
2364
2365         curr_offset += len;
2366         break;
2367     }
2368
2369     EXTRANEOUS_DATA_CHECK_EXPERT(len, curr_offset - offset, pinfo, &ei_gsm_a_extraneous_data);
2370
2371     return(curr_offset - offset);
2372 }
2373
2374 /*
2375  * [3] 10.5.1.5
2376  */
2377 guint16
2378 de_ms_cm_1(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
2379 {
2380     guint32     curr_offset;
2381     proto_tree *subtree;
2382     proto_item *item;
2383
2384     curr_offset = offset;
2385
2386     item =
2387     proto_tree_add_text(tree,
2388         tvb, curr_offset, 1, "%s",
2389         val_to_str_ext_const(DE_MS_CM_1, &gsm_common_elem_strings_ext, ""));
2390
2391     subtree = proto_item_add_subtree(item, ett_gsm_common_elem[DE_MS_CM_1]);
2392
2393     proto_tree_add_item(subtree, hf_gsm_a_b8spare, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2394
2395     proto_tree_add_item(subtree, hf_gsm_a_MSC_rev, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2396
2397     proto_tree_add_item(subtree, hf_gsm_a_ES_IND, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2398
2399     proto_tree_add_item(subtree, hf_gsm_a_A5_1_algorithm_sup, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2400
2401     proto_tree_add_item(subtree, hf_gsm_a_RF_power_capability, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2402
2403     curr_offset++;
2404
2405     /* no length check possible */
2406
2407     return(curr_offset - offset);
2408 }
2409
2410 /*
2411  * [3] 10.5.1.6 Mobile Station Classmark 2
2412  * 3GPP TS 24.008 version 7.8.0 Release 7
2413  */
2414 guint16
2415 de_ms_cm_2(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2416 {
2417     guint32 curr_offset;
2418     curr_offset = offset;
2419
2420     proto_tree_add_item(tree, hf_gsm_a_b8spare, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2421
2422     proto_tree_add_item(tree, hf_gsm_a_MSC_rev, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2423
2424     proto_tree_add_item(tree, hf_gsm_a_ES_IND, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2425
2426     proto_tree_add_item(tree, hf_gsm_a_A5_1_algorithm_sup, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2427
2428     proto_tree_add_item(tree, hf_gsm_a_RF_power_capability, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2429
2430     curr_offset++;
2431
2432     NO_MORE_DATA_CHECK(len);
2433
2434     proto_tree_add_item(tree, hf_gsm_a_b8spare, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2435
2436     proto_tree_add_item(tree, hf_gsm_a_ps_sup_cap, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2437
2438     proto_tree_add_item(tree, hf_gsm_a_SS_screening_indicator, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2439
2440     /* SM capability (MT SMS pt to pt capability) (octet 4)*/
2441     proto_tree_add_item(tree, hf_gsm_a_SM_capability, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2442     /* VBS notification reception (octet 4) */
2443     proto_tree_add_item(tree, hf_gsm_a_VBS_notification_rec, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2444     /*VGCS notification reception (octet 4)*/
2445     proto_tree_add_item(tree, hf_gsm_a_VGCS_notification_rec, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2446     /* FC Frequency Capability (octet 4 ) */
2447     proto_tree_add_item(tree, hf_gsm_a_FC_frequency_cap, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2448
2449     curr_offset++;
2450
2451     NO_MORE_DATA_CHECK(len);
2452
2453     /* CM3 (octet 5, bit 8) */
2454     proto_tree_add_item(tree, hf_gsm_a_CM3, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2455     /* spare bit 7 */
2456     proto_tree_add_item(tree, hf_gsm_a_b7spare, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2457     /* LCS VA capability (LCS value added location request notification capability) (octet 5,bit 6) */
2458     proto_tree_add_item(tree, hf_gsm_a_LCS_VA_cap, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2459     /* UCS2 treatment (octet 5, bit 5) */
2460     proto_tree_add_item(tree, hf_gsm_a_UCS2_treatment, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2461     /* SoLSA (octet 5, bit 4) */
2462     proto_tree_add_item(tree, hf_gsm_a_SoLSA, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2463     /* CMSP: CM Service Prompt (octet 5, bit 3) */
2464     proto_tree_add_item(tree, hf_gsm_a_CMSP, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2465     /* A5/3 algorithm supported (octet 5, bit 2) */
2466     proto_tree_add_item(tree, hf_gsm_a_A5_3_algorithm_sup, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2467     /* A5/2 algorithm supported (octet 5, bit 1) */
2468     proto_tree_add_item(tree, hf_gsm_a_A5_2_algorithm_sup, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
2469
2470     curr_offset++;
2471
2472     EXTRANEOUS_DATA_CHECK_EXPERT(len, curr_offset - offset, pinfo, &ei_gsm_a_extraneous_data);
2473
2474     return(curr_offset - offset);
2475 }
2476
2477 /*
2478  * [3] 10.5.1.7 Mobile Station Classmark 3
2479  * 3GPP TS 24.008 version 11.7.0 Release 11
2480  */
2481 #define AVAILABLE_BITS_CHECK(n) \
2482     bits_left = ((len + offset) << 3) - bit_offset; \
2483     if (bits_left < (n)) { \
2484         if (bits_left) \
2485             proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, bit_offset, bits_left, ENC_BIG_ENDIAN); \
2486         return(len); \
2487     }
2488
2489 guint16
2490 de_ms_cm_3(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
2491 {
2492     guint32     curr_offset;
2493     guint32     bit_offset;     /* Offset in bits */
2494     guint8      length;
2495     proto_tree *subtree;
2496     proto_item *item;
2497     guint32     bits_left, target_bit_offset, old_bit_offset;
2498     guint64     multi_bnd_sup_fields, rsupport, multislotCapability;
2499     guint64     msMeasurementCapability, msPosMethodCapPresent;
2500     guint64     ecsdMultiSlotCapability, eightPskStructPresent, eightPskStructRfPowerCapPresent;
2501     guint64     gsm400BandInfoPresent, gsm850AssocRadioCapabilityPresent;
2502     guint64     gsm1900AssocRadioCapabilityPresent, dtmEGprsMultiSlotInfoPresent;
2503     guint64     dtmEgprsMultiSlotClassPresent, singleBandSupport;
2504     guint64     gsm750AssocRadioCapabilityPresent, extDtmEGprsMultiSlotInfoPresent;
2505     guint64     highMultislotCapPresent, geranIuModeSupport;
2506     guint64     tGsm400BandInfoPresent, tGsm900AssocRadioCapabilityPresent, dtmEGprsHighMultiSlotInfoPresent;
2507     guint64     dtmEgprsHighMultiSlotClassPresent, gsm710AssocRadioCapabilityPresent;
2508     guint64     tGsm810AssocRadioCapabilityPresent;
2509
2510     curr_offset = offset;
2511
2512     bit_offset = curr_offset << 3;
2513
2514     /* Spare bit */
2515     proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
2516     bit_offset++;
2517
2518     /* Multiband supported field
2519      * { < Multiband supported : { 000 } >
2520      * < A5 bits >
2521      * | < Multiband supported : { 101 | 110 } >
2522      * < A5 bits >
2523      * < Associated Radio Capability 2 : bit(4) >
2524      * < Associated Radio Capability 1 : bit(4) >
2525      * | < Multiband supported : { 001 | 010 | 100 } >
2526      * < A5 bits >
2527      * < spare bit >(4)
2528      * < Associated Radio Capability 1 : bit(4) > }
2529      */
2530
2531     item = proto_tree_add_bits_ret_val(tree, hf_gsm_a_multi_bnd_sup_fields, tvb, bit_offset, 3, &multi_bnd_sup_fields, ENC_BIG_ENDIAN);
2532     subtree = proto_item_add_subtree(item, ett_gsm_common_elem[DE_MS_CM_3]);
2533
2534     proto_tree_add_bits_item(subtree, hf_gsm_a_gsm1800_supported, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
2535     bit_offset++;
2536
2537     proto_tree_add_bits_item(subtree, hf_gsm_a_egsm_supported, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
2538     bit_offset++;
2539
2540     proto_tree_add_bits_item(subtree, hf_gsm_a_pgsm_supported, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
2541     bit_offset++;
2542
2543     item = proto_tree_add_bits_item(tree, hf_gsm_a_cm3_A5_bits, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
2544     subtree = proto_item_add_subtree(item, ett_gsm_common_elem[DE_MS_CM_3]);
2545
2546     /* < A5 bits > */
2547     proto_tree_add_bits_item(subtree, hf_gsm_a_A5_7_algorithm_sup, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
2548     bit_offset++;
2549     proto_tree_add_bits_item(subtree, hf_gsm_a_A5_6_algorithm_sup, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
2550     bit_offset++;
2551     proto_tree_add_bits_item(subtree, hf_gsm_a_A5_5_algorithm_sup, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
2552     bit_offset++;
2553     proto_tree_add_bits_item(subtree, hf_gsm_a_A5_4_algorithm_sup, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
2554     bit_offset++;
2555
2556     switch (multi_bnd_sup_fields) {
2557     case 0:
2558         /* A5 bits dissected is done */
2559         break;
2560         /*
2561          * | < Multiband supported : { 001 | 010 | 100 } >
2562          */
2563     case 1:
2564     case 2:
2565     case 4:
2566         /* < spare bit >(4) */
2567         proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
2568         bit_offset += 4;
2569         /* < Associated Radio Capability 1 : bit(4) > */
2570         proto_tree_add_bits_item(tree, hf_gsm_a_ass_radio_cap1, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
2571         bit_offset += 4;
2572         break;
2573         /* < Multiband supported : { 101 | 110 } > */
2574     case 5:
2575         /* fall trough */
2576     case 6:
2577         /* < Associated Radio Capability 2 : bit(4) > */
2578         proto_tree_add_bits_item(tree, hf_gsm_a_ass_radio_cap2, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
2579         bit_offset += 4;
2580         /* < Associated Radio Capability 1 : bit(4) > */
2581         proto_tree_add_bits_item(tree, hf_gsm_a_ass_radio_cap1, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
2582         bit_offset += 4;
2583         break;
2584     default:
2585         break;
2586     }
2587     /* Extract R Support */
2588     AVAILABLE_BITS_CHECK(1);
2589     proto_tree_add_bits_ret_val(tree, hf_gsm_a_rsupport, tvb, bit_offset, 1, &rsupport, ENC_BIG_ENDIAN);
2590     bit_offset++;
2591
2592     if (rsupport == 1)
2593     {
2594         /*
2595          * { 0 | 1 < R Support > }
2596          * Extract R Capabilities
2597          */
2598         proto_tree_add_bits_item(tree, hf_gsm_a_r_capabilities, tvb, bit_offset, 3, ENC_BIG_ENDIAN);
2599         bit_offset = bit_offset + 3;
2600     }
2601
2602     /*
2603      * { 0 | 1 < HSCSD Multi Slot Capability > }
2604      * Extract Multislot capability
2605      */
2606     AVAILABLE_BITS_CHECK(1);
2607     proto_tree_add_bits_ret_val(tree, hf_gsm_a_multislot_capabilities, tvb, bit_offset, 1, &multislotCapability, ENC_BIG_ENDIAN);
2608     bit_offset++;
2609
2610     if (multislotCapability == 1)
2611     {
2612         /* Extract Multislot Class */
2613         proto_tree_add_bits_item(tree, hf_gsm_a_multislot_class, tvb, bit_offset, 5, ENC_BIG_ENDIAN);
2614         bit_offset = bit_offset + 5;
2615     }
2616
2617     /* < UCS2 treatment: bit > */
2618     AVAILABLE_BITS_CHECK(1);
2619     proto_tree_add_bits_item(tree, hf_gsm_a_ucs2_treatment, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
2620     bit_offset = bit_offset + 1;
2621
2622     /* < Extended Measurement Capability : bit > */
2623     AVAILABLE_BITS_CHECK(1);
2624     proto_tree_add_bits_item(tree, hf_gsm_a_extended_measurement_cap, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
2625     bit_offset = bit_offset + 1;
2626
2627     /* { 0 | 1 < MS measurement capability > }
2628      * Extract MS Measurement capability
2629      */
2630     AVAILABLE_BITS_CHECK(1);
2631     proto_tree_add_bits_ret_val(tree, hf_gsm_a_ms_measurement_capability, tvb, bit_offset, 1, &msMeasurementCapability, ENC_BIG_ENDIAN);
2632     bit_offset = bit_offset + 1;
2633
2634     if (msMeasurementCapability == 1)
2635     {
2636         /* Extract SMS Value n/4 */
2637         proto_tree_add_bits_item(tree, hf_gsm_a_sms_value, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
2638         bit_offset = bit_offset + 4;
2639
2640         /* Extract SM Value n/4 */
2641         proto_tree_add_bits_item(tree, hf_gsm_a_sm_value, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
2642         bit_offset = bit_offset + 4;
2643     }
2644
2645     /* { 0 | 1 < MS Positioning Method Capability > }
2646      * Extract MS Positioning Method Capability
2647      */
2648     AVAILABLE_BITS_CHECK(1);
2649     proto_tree_add_bits_ret_val(tree, hf_gsm_a_ms_pos_method_cap_present, tvb, bit_offset, 1, &msPosMethodCapPresent, ENC_BIG_ENDIAN);
2650     bit_offset = bit_offset + 1;
2651
2652     if (msPosMethodCapPresent == 1)
2653     {
2654         /* Extract MS Positioning Method */
2655         item = proto_tree_add_bits_item(tree, hf_gsm_a_ms_pos_method, tvb, bit_offset, 5, ENC_BIG_ENDIAN);
2656         subtree = proto_item_add_subtree(item, ett_gsm_common_elem[DE_MS_CM_3]);
2657
2658         proto_tree_add_bits_item(subtree, hf_gsm_a_ms_assisted_e_otd, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
2659         bit_offset++;
2660
2661         proto_tree_add_bits_item(subtree, hf_gsm_a_ms_based_e_otd, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
2662         bit_offset++;
2663
2664         proto_tree_add_bits_item(subtree, hf_gsm_a_ms_assisted_gps, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
2665         bit_offset++;
2666
2667         proto_tree_add_bits_item(subtree, hf_gsm_a_ms_based_gps, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
2668         bit_offset++;
2669
2670         proto_tree_add_bits_item(subtree, hf_gsm_a_ms_conventional_gps, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
2671         bit_offset++;
2672     }
2673
2674     /* { 0 | 1 < ECSD Multi Slot Capability > }
2675      * Extract ECSD Multi Slot Capability
2676      */
2677     AVAILABLE_BITS_CHECK(1);
2678     proto_tree_add_bits_ret_val(tree, hf_gsm_a_ecsd_multi_slot_capability, tvb, bit_offset, 1, &ecsdMultiSlotCapability, ENC_BIG_ENDIAN);
2679     bit_offset = bit_offset + 1;
2680
2681     if (ecsdMultiSlotCapability == 1)
2682     {
2683         /* Extract ECSD Multi Slot Class */
2684         proto_tree_add_bits_item(tree, hf_gsm_a_ecsd_multi_slot_class, tvb, bit_offset, 5, ENC_BIG_ENDIAN);
2685         bit_offset = bit_offset + 5;
2686     }
2687
2688     /* { 0 | 1 < 8-PSK Struct > }
2689      * Extract 8-PSK struct presence
2690      */
2691     AVAILABLE_BITS_CHECK(1);
2692     proto_tree_add_bits_ret_val(tree, hf_gsm_a_8_psk_struct_present, tvb, bit_offset, 1, &eightPskStructPresent, ENC_BIG_ENDIAN);
2693     bit_offset = bit_offset + 1;
2694
2695     if (eightPskStructPresent == 1)
2696     {
2697         /* At lest Modulation Capability and cap1,cap2 presens indicators is present */
2698         guint8 psk_struct_len = 3;
2699         guint32 tmp_bit_offset = bit_offset;
2700
2701         /* Check if Power Capability 1 is present */
2702         tmp_bit_offset++;
2703         if(tvb_get_bits8(tvb,tmp_bit_offset,1) == 1){
2704             psk_struct_len+=2;
2705             tmp_bit_offset+=2;
2706         }
2707         tmp_bit_offset++;
2708         /* Check if Power Capability 2 is present */
2709         if(tvb_get_bits8(tvb,tmp_bit_offset,1) == 1){
2710             psk_struct_len+=2;
2711         }
2712         /* Extract 8-PSK struct */
2713         item = proto_tree_add_bits_item(tree, hf_gsm_a_8_psk_struct, tvb, bit_offset, psk_struct_len, ENC_BIG_ENDIAN);
2714         subtree = proto_item_add_subtree(item, ett_gsm_common_elem[DE_MS_CM_3]);
2715         old_bit_offset = bit_offset;
2716
2717         /* Extract Modulation Capability */
2718         proto_tree_add_bits_item(subtree, hf_gsm_a_modulation_capability, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
2719         bit_offset = bit_offset + 1;
2720
2721         /* Extract 8_PSK RF Power Capability 1 */
2722         proto_tree_add_bits_ret_val(subtree, hf_gsm_a_8_psk_rf_power_capability_1_present, tvb, bit_offset,
2723                                     1, &eightPskStructRfPowerCapPresent, ENC_BIG_ENDIAN);
2724         bit_offset = bit_offset + 1;
2725         if (eightPskStructRfPowerCapPresent == 1)
2726         {
2727             proto_tree_add_bits_item(subtree, hf_gsm_a_8_psk_rf_power_capability_1, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
2728             bit_offset = bit_offset + 2;
2729         }
2730
2731         /* Extract 8_PSK RF Power Capability 2 */
2732         proto_tree_add_bits_ret_val(subtree, hf_gsm_a_8_psk_rf_power_capability_2_present, tvb, bit_offset,
2733                                     1, &eightPskStructRfPowerCapPresent, ENC_BIG_ENDIAN);
2734         bit_offset = bit_offset + 1;
2735         if (eightPskStructRfPowerCapPresent == 1)
2736         {
2737             proto_tree_add_bits_item(subtree, hf_gsm_a_8_psk_rf_power_capability_2, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
2738             bit_offset = bit_offset + 2;
2739         }
2740         length = (guint8)((bit_offset - old_bit_offset)>>3);
2741         if ((bit_offset - old_bit_offset) & 0x07)
2742             length++;
2743         proto_item_set_len(item, length);
2744     }
2745
2746     /* { 0 | 1 < GSM 400 Bands Supported : { 01 | 10 | 11 } >
2747      *   < GSM 400 Associated Radio Capability: bit(4) > }
2748      * Extract GSM 400 Band Information presence
2749      */
2750     AVAILABLE_BITS_CHECK(1);
2751     proto_tree_add_bits_ret_val(tree, hf_gsm_a_gsm_400_band_info_present, tvb, bit_offset, 1, &gsm400BandInfoPresent, ENC_BIG_ENDIAN);
2752     bit_offset = bit_offset + 1;
2753
2754     if (gsm400BandInfoPresent == 1)
2755     {
2756         /* Extract GSM 400 Bands Supported */
2757         proto_tree_add_bits_item(tree, hf_gsm_a_gsm_400_bands_supported, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
2758         bit_offset = bit_offset + 2;
2759
2760         /* Extract GSM 400 Associated Radio Capability */
2761         proto_tree_add_bits_item(tree, hf_gsm_a_gsm_400_assoc_radio_cap, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
2762         bit_offset = bit_offset + 4;
2763     }
2764
2765     /* { 0 | 1 <GSM 850 Associated Radio Capability : bit(4) > }
2766      * Extract GSM 850 Associated Radio Capability presence
2767      */
2768     AVAILABLE_BITS_CHECK(1);
2769     proto_tree_add_bits_ret_val(tree, hf_gsm_a_gsm_850_assoc_radio_cap_present, tvb, bit_offset, 1, &gsm850AssocRadioCapabilityPresent, ENC_BIG_ENDIAN);
2770     bit_offset = bit_offset + 1;
2771
2772     if (gsm850AssocRadioCapabilityPresent == 1)
2773     {
2774         /* Extract GSM 850 Associated Radio Capability */
2775         proto_tree_add_bits_item(tree, hf_gsm_a_gsm_850_assoc_radio_cap, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
2776         bit_offset = bit_offset + 4;
2777     }
2778
2779     /* { 0 | 1 <GSM 1900 Associated Radio Capability : bit(4) > }
2780      * Extract GSM 1900 Associated Radio Capability presence
2781      */
2782     AVAILABLE_BITS_CHECK(1);
2783     proto_tree_add_bits_ret_val(tree, hf_gsm_a_gsm_1900_assoc_radio_cap_present, tvb, bit_offset, 1, &gsm1900AssocRadioCapabilityPresent, ENC_BIG_ENDIAN);
2784     bit_offset = bit_offset + 1;
2785
2786     if (gsm1900AssocRadioCapabilityPresent == 1)
2787     {
2788         /* Extract GSM 1900 Associated Radio Capability */
2789         proto_tree_add_bits_item(tree, hf_gsm_a_gsm_1900_assoc_radio_cap, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
2790         bit_offset = bit_offset + 4;
2791     }
2792
2793     /* < UMTS FDD Radio Access Technology Capability : bit >
2794      * Extract UMTS FDD Radio Access Technology Capability
2795      */
2796     AVAILABLE_BITS_CHECK(1);
2797     proto_tree_add_bits_item(tree, hf_gsm_a_umts_fdd_rat_cap, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
2798     bit_offset = bit_offset + 1;
2799
2800     /* < UMTS 3.84 Mcps TDD Radio Access Technology Capability : bit >
2801      * Extract UMTS 3.84 Mcps TDD Radio Access Technology Capability
2802      */
2803     AVAILABLE_BITS_CHECK(1);
2804     proto_tree_add_bits_item(tree, hf_gsm_a_umts_384_mcps_tdd_rat_cap, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
2805     bit_offset = bit_offset + 1;
2806
2807     /* < CDMA 2000 Radio Access Technology Capability : bit >
2808      * Extract CDMA 2000 Radio Access Technology Capability
2809      */
2810     AVAILABLE_BITS_CHECK(1);
2811     proto_tree_add_bits_item(tree, hf_gsm_a_cdma_2000_rat_cap, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
2812     bit_offset = bit_offset + 1;
2813
2814     /* { 0 | 1 < DTM GPRS Multi Slot Class : bit(2) >
2815      *   < Single Slot DTM : bit >
2816      *   {0 | 1< DTM EGPRS Multi Slot Class : bit(2) > } }
2817      * Extract DTM E/GPRS Information presence
2818      */
2819     AVAILABLE_BITS_CHECK(1);
2820     proto_tree_add_bits_ret_val(tree, hf_gsm_a_dtm_e_gprs_multi_slot_info_present, tvb, bit_offset, 1, &dtmEGprsMultiSlotInfoPresent, ENC_BIG_ENDIAN);
2821     bit_offset = bit_offset + 1;
2822
2823     if (dtmEGprsMultiSlotInfoPresent == 1)
2824     {
2825         /* Extract DTM GPRS Multi Slot Class */
2826         proto_tree_add_bits_item(tree, hf_gsm_a_dtm_gprs_multi_slot_class, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
2827         bit_offset = bit_offset + 2;
2828
2829         /* Extract Single Slot DTM */
2830         proto_tree_add_bits_item(tree, hf_gsm_a_single_slot_dtm, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
2831         bit_offset = bit_offset + 1;
2832
2833         /* Extract DTM EGPRS Multi Slot Class Presence */
2834         proto_tree_add_bits_ret_val(tree, hf_gsm_a_dtm_egprs_multi_slot_class_present, tvb, bit_offset, 1, &dtmEgprsMultiSlotClassPresent, ENC_BIG_ENDIAN);
2835         bit_offset = bit_offset + 1;
2836
2837         /* Extract DTM EGPRS Multi Slot Class */
2838         if (dtmEgprsMultiSlotClassPresent == 1)
2839         {
2840             proto_tree_add_bits_item(tree, hf_gsm_a_dtm_egprs_multi_slot_class, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
2841             bit_offset = bit_offset + 2;
2842         }
2843     }
2844
2845     /*
2846      * Release 4 starts here
2847      *
2848      * { 0 | 1 < Single Band Support > } -- Release 4 starts here:
2849      * Extract Single Band Support
2850      */
2851     AVAILABLE_BITS_CHECK(1);
2852     proto_tree_add_bits_ret_val(tree, hf_gsm_a_single_band_support, tvb, bit_offset, 1, &singleBandSupport, ENC_BIG_ENDIAN);
2853     bit_offset = bit_offset + 1;
2854
2855     if (singleBandSupport == 1)
2856     {
2857         /* Extract Single Band Support */
2858         proto_tree_add_bits_item(tree, hf_gsm_a_gsm_band, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
2859         bit_offset = bit_offset + 4;
2860     }
2861
2862     /* { 0 | 1 <GSM 750 Associated Radio Capability : bit(4) > }
2863      * Extract GSM 750 Associated Radio Capability presence
2864      */
2865     AVAILABLE_BITS_CHECK(1);
2866     proto_tree_add_bits_ret_val(tree, hf_gsm_a_gsm_750_assoc_radio_cap_present, tvb, bit_offset, 1, &gsm750AssocRadioCapabilityPresent, ENC_BIG_ENDIAN);
2867     bit_offset = bit_offset + 1;
2868
2869     if (gsm750AssocRadioCapabilityPresent == 1)
2870     {
2871         /* Extract GSM 750 Associated Radio Capability */
2872         proto_tree_add_bits_item(tree, hf_gsm_a_gsm_750_assoc_radio_cap, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
2873         bit_offset = bit_offset + 4;
2874     }
2875
2876     /* < UMTS 1.28 Mcps TDD Radio Access Technology Capability : bit >
2877      * Extract UMTS 1.28 Mcps TDD Radio Access Technology Capability
2878      */
2879     AVAILABLE_BITS_CHECK(1);
2880     proto_tree_add_bits_item(tree, hf_gsm_a_umts_128_mcps_tdd_rat_cap, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
2881     bit_offset = bit_offset + 1;
2882
2883     /* < GERAN Feature Package 1 : bit >
2884      * Extract GERAN Feature Package 1
2885      */
2886     AVAILABLE_BITS_CHECK(1);
2887     proto_tree_add_bits_item(tree, hf_gsm_a_geran_feature_package_1, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
2888     bit_offset = bit_offset + 1;
2889
2890     /* { 0 | 1 < Extended DTM GPRS Multi Slot Class : bit(2) >
2891      *   < Extended DTM EGPRS Multi Slot Class : bit(2) > }
2892      * Extract Extended DTM E/GPRS Information presence
2893      */
2894     AVAILABLE_BITS_CHECK(1);
2895     proto_tree_add_bits_ret_val(tree, hf_gsm_a_ext_dtm_e_gprs_multi_slot_info_present, tvb, bit_offset, 1, &extDtmEGprsMultiSlotInfoPresent, ENC_BIG_ENDIAN);
2896     bit_offset = bit_offset + 1;
2897
2898     if (extDtmEGprsMultiSlotInfoPresent == 1)
2899     {
2900         /* Extract Extended DTM GPRS Multi Slot Class */
2901         proto_tree_add_bits_item(tree, hf_gsm_a_ext_dtm_gprs_multi_slot_class, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
2902         bit_offset = bit_offset + 2;
2903
2904         /* Extract Extended DTM EGPRS Multi Slot Class */
2905         proto_tree_add_bits_item(tree, hf_gsm_a_ext_dtm_egprs_multi_slot_class, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
2906         bit_offset = bit_offset + 2;
2907     }
2908
2909     /*
2910      * Release 5 starts here
2911      *
2912      * { 0 | 1 < High Multislot Capability : bit(2) > } -- Release 5 starts here.
2913      * Extract High Multislot Capability presence
2914      */
2915     AVAILABLE_BITS_CHECK(1);
2916     proto_tree_add_bits_ret_val(tree, hf_gsm_a_high_multislot_cap_present, tvb, bit_offset, 1, &highMultislotCapPresent, ENC_BIG_ENDIAN);
2917     bit_offset = bit_offset + 1;
2918
2919     if (highMultislotCapPresent == 1)
2920     {
2921         /* Extract High Multislot Capability */
2922         proto_tree_add_bits_item(tree, hf_gsm_a_high_multislot_cap, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
2923         bit_offset = bit_offset + 2;
2924     }
2925
2926     /*
2927      * { 0 | 1 < GERAN Iu Mode Capabilities > } -- "1" also means support of GERAN Iu mode
2928      * Extract GERAN Iu Mode Capabilities presence
2929      */
2930     AVAILABLE_BITS_CHECK(1);
2931     proto_tree_add_bits_ret_val(tree, hf_gsm_a_geran_iu_mode_support, tvb, bit_offset, 1, &geranIuModeSupport, ENC_BIG_ENDIAN);
2932     bit_offset = bit_offset + 1;
2933
2934     if (geranIuModeSupport == 1)
2935     {
2936         /* Extract GERAN Iu Mode Capabilities Length */
2937         length = tvb_get_bits8(tvb, bit_offset, 4);
2938
2939         /* Extract GERAN Iu Mode Capabilities */
2940         item = proto_tree_add_bits_item(tree, hf_gsm_a_geran_iu_mode_cap, tvb, bit_offset, length + 4, ENC_BIG_ENDIAN);
2941         subtree = proto_item_add_subtree(item, ett_gsm_common_elem[DE_MS_CM_3]);
2942
2943         /* Add GERAN Iu Mode Capabilities Length in subtree */
2944         proto_tree_add_bits_item(subtree, hf_gsm_a_geran_iu_mode_cap_length, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
2945         bit_offset += 4;
2946         target_bit_offset = bit_offset + length;
2947
2948         /* Extract FLO Iu Capability */
2949         proto_tree_add_bits_item(subtree, hf_gsm_a_flo_iu_cap, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
2950         bit_offset += 1;
2951
2952         /* If needed, add spare bits */
2953         if (target_bit_offset > bit_offset)
2954         {
2955             proto_tree_add_bits_item(subtree, hf_gsm_a_spare_bits, tvb, bit_offset, target_bit_offset - bit_offset, ENC_BIG_ENDIAN);
2956             bit_offset = target_bit_offset;
2957         }
2958     }
2959
2960     /* < GERAN Feature Package 2 : bit >
2961      * Extract GERAN Feature Package 2
2962      */
2963     AVAILABLE_BITS_CHECK(1);
2964     proto_tree_add_bits_item(tree, hf_gsm_a_geran_feature_package_2, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
2965     bit_offset = bit_offset + 1;
2966
2967     /* < GMSK Multislot Power Profile : bit (2) >
2968      * Extract GMSK Multislot Power Profile
2969      */
2970     AVAILABLE_BITS_CHECK(2);
2971     proto_tree_add_bits_item(tree, hf_gsm_a_gmsk_multislot_power_prof, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
2972     bit_offset = bit_offset + 2;
2973
2974     /* < 8-PSK Multislot Power Profile : bit (2) >
2975      * Extract GMSK Multislot Power Profile
2976      */
2977     AVAILABLE_BITS_CHECK(2);
2978     proto_tree_add_bits_item(tree, hf_gsm_a_8_psk_multislot_power_prof, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
2979     bit_offset = bit_offset + 2;
2980
2981     /*
2982      * Release 6 starts here
2983      *
2984      * { 0 | 1 < T-GSM 400 Bands Supported : { 01 | 10 | 11 } > -- Release 6 starts here.
2985      *   < T-GSM 400 Associated Radio Capability: bit(4) > }
2986      */
2987     AVAILABLE_BITS_CHECK(1);
2988     proto_tree_add_bits_ret_val(tree, hf_gsm_a_t_gsm_400_band_info_present, tvb, bit_offset, 1, &tGsm400BandInfoPresent, ENC_BIG_ENDIAN);
2989     bit_offset = bit_offset + 1;
2990
2991     if (tGsm400BandInfoPresent == 1)
2992     {
2993         /* Extract T-GSM 400 Bands Supported */
2994         proto_tree_add_bits_item(tree, hf_gsm_a_t_gsm_400_bands_supported, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
2995         bit_offset = bit_offset + 2;
2996
2997         /* Extract T-GSM 400 Associated Radio Capability */
2998         proto_tree_add_bits_item(tree, hf_gsm_a_t_gsm_400_assoc_radio_cap, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
2999         bit_offset = bit_offset + 4;
3000     }
3001
3002     /* { 0 | 1 < T-GSM 900 Associated Radio Capability: bit(4) > }
3003      * Extract T-GSM 900 Associated Radio Capability presence
3004      */
3005     AVAILABLE_BITS_CHECK(1);
3006     proto_tree_add_bits_ret_val(tree, hf_gsm_a_t_gsm_900_assoc_radio_cap_present, tvb, bit_offset, 1, &tGsm900AssocRadioCapabilityPresent, ENC_BIG_ENDIAN);
3007     bit_offset = bit_offset + 1;
3008
3009     if (tGsm900AssocRadioCapabilityPresent == 1)
3010     {
3011         /* Extract T-GSM 900 Associated Radio Capability */
3012         proto_tree_add_bits_item(tree, hf_gsm_a_t_gsm_900_assoc_radio_cap, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
3013         bit_offset = bit_offset + 4;
3014     }
3015
3016     /* < Downlink Advanced Receiver Performance : bit (2)>
3017      * Extract Downlink Advanced Receiver Performance
3018      */
3019     AVAILABLE_BITS_CHECK(2);
3020     proto_tree_add_bits_item(tree, hf_gsm_a_downlink_adv_receiver_perf, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
3021     bit_offset = bit_offset + 2;
3022
3023     /* < DTM Enhancements Capability : bit >
3024      * Extract DTM Enhancements Capability
3025      */
3026     AVAILABLE_BITS_CHECK(1);
3027     proto_tree_add_bits_item(tree, hf_gsm_a_dtm_enhancements_cap, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
3028     bit_offset = bit_offset + 1;
3029
3030     /* { 0 | 1 < DTM GPRS High Multi Slot Class : bit(3) >
3031      *   < Offset required : bit>
3032      *   { 0 | 1 < DTM EGPRS High Multi Slot Class : bit(3) > } }
3033      * Extract DTM E/GPRS High Multi Slot Information presence
3034      */
3035     AVAILABLE_BITS_CHECK(1);
3036     proto_tree_add_bits_ret_val(tree, hf_gsm_a_dtm_e_gprs_high_multi_slot_info_present, tvb, bit_offset, 1, &dtmEGprsHighMultiSlotInfoPresent, ENC_BIG_ENDIAN);
3037     bit_offset = bit_offset + 1;
3038
3039     if (dtmEGprsHighMultiSlotInfoPresent == 1)
3040     {
3041         /* Extract DTM GPRS High Multi Slot Class */
3042         proto_tree_add_bits_item(tree, hf_gsm_a_dtm_gprs_high_multi_slot_class, tvb, bit_offset, 3, ENC_BIG_ENDIAN);
3043         bit_offset = bit_offset + 3;
3044
3045         /* Extract Offset Required */
3046         proto_tree_add_bits_item(tree, hf_gsm_a_offset_required, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
3047         bit_offset = bit_offset + 1;
3048
3049         /* Extract DTM EGPRS High Multi Slot Class Presence */
3050         proto_tree_add_bits_ret_val(tree, hf_gsm_a_dtm_egprs_high_multi_slot_class_present, tvb, bit_offset, 1, &dtmEgprsHighMultiSlotClassPresent, ENC_BIG_ENDIAN);
3051         bit_offset = bit_offset + 1;
3052
3053         /* Extract DTM EGPRS High Multi Slot Class */
3054         if (dtmEgprsHighMultiSlotClassPresent == 1)
3055         {
3056             proto_tree_add_bits_item(tree, hf_gsm_a_dtm_egprs_high_multi_slot_class, tvb, bit_offset, 3, ENC_BIG_ENDIAN);
3057             bit_offset = bit_offset + 3;
3058         }
3059     }
3060
3061     /* < Repeated ACCH Capability : bit >
3062      * Extract Repeated ACCH Capability
3063      */
3064     AVAILABLE_BITS_CHECK(1);
3065     proto_tree_add_bits_item(tree, hf_gsm_a_repeated_acch_cap, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
3066     bit_offset = bit_offset + 1;
3067
3068     /*
3069      * Release 7 starts here
3070      *
3071      * { 0 | 1 <GSM 710 Associated Radio Capability : bit(4) > } -- Release 7 starts here.
3072      * Extract GSM 710 Associated Radio Capability presence
3073      */
3074     AVAILABLE_BITS_CHECK(1);
3075     proto_tree_add_bits_ret_val(tree, hf_gsm_a_gsm_710_assoc_radio_cap_present, tvb, bit_offset, 1, &gsm710AssocRadioCapabilityPresent, ENC_BIG_ENDIAN);
3076     bit_offset = bit_offset + 1;
3077
3078     if (gsm710AssocRadioCapabilityPresent == 1)
3079     {
3080         /* Extract GSM 710 Associated Radio Capability */
3081         proto_tree_add_bits_item(tree, hf_gsm_a_gsm_710_assoc_radio_cap, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
3082         bit_offset = bit_offset + 4;
3083     }
3084
3085     /* { 0 | 1 < T-GSM 810 Associated Radio Capability: bit(4) > }
3086      * Extract T-GSM 810 Associated Radio Capability presence
3087      */
3088     AVAILABLE_BITS_CHECK(1);
3089     proto_tree_add_bits_ret_val(tree, hf_gsm_a_t_gsm_810_assoc_radio_cap_present, tvb, bit_offset, 1, &tGsm810AssocRadioCapabilityPresent, ENC_BIG_ENDIAN);
3090     bit_offset = bit_offset + 1;
3091
3092     if (tGsm810AssocRadioCapabilityPresent == 1)
3093     {
3094         /* Extract T-GSM 810 Associated Radio Capability */
3095         proto_tree_add_bits_item(tree, hf_gsm_a_t_gsm_810_assoc_radio_cap, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
3096         bit_offset = bit_offset + 4;
3097     }
3098
3099     /* < Ciphering Mode Setting Capability : bit >
3100      * Extract Ciphering Mode Setting Capability
3101      */
3102     AVAILABLE_BITS_CHECK(1);
3103     proto_tree_add_bits_item(tree, hf_gsm_a_ciphering_mode_setting_cap, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
3104     bit_offset = bit_offset + 1;
3105
3106     /* < Additional Positioning Capabilities : bit >
3107      * Extract Additional Positioning Capabilities
3108      */
3109     AVAILABLE_BITS_CHECK(1);
3110     proto_tree_add_bits_item(tree, hf_gsm_a_additional_positioning_caps, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
3111     bit_offset = bit_offset + 1;
3112
3113     /*
3114      * Release 8 starts here
3115      *
3116      * <E-UTRA FDD support : bit > -- Release 8 starts here.
3117      * Extract E-UTRA FDD support
3118      */
3119     AVAILABLE_BITS_CHECK(1);
3120     proto_tree_add_bits_item(tree, hf_gsm_a_e_utra_fdd_support, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
3121     bit_offset = bit_offset + 1;
3122
3123     /*
3124      * <E-UTRA TDD support : bit >
3125      * Extract E-UTRA TDD support
3126      */
3127     AVAILABLE_BITS_CHECK(1);
3128     proto_tree_add_bits_item(tree, hf_gsm_a_e_utra_tdd_support, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
3129     bit_offset = bit_offset + 1;
3130
3131     /*
3132      * <E-UTRA Measurement and Reporting support : bit >
3133      * Extract E-UTRA Measurement and Reporting support
3134      */
3135     AVAILABLE_BITS_CHECK(1);
3136     proto_tree_add_bits_item(tree, hf_gsm_a_e_utra_meas_and_report_support, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
3137     bit_offset = bit_offset + 1;
3138
3139     /*
3140      * <Priority-based reselection support : bit >
3141      * Extract Priority-based reselection support
3142      */
3143     AVAILABLE_BITS_CHECK(1);
3144     proto_tree_add_bits_item(tree, hf_gsm_a_prio_based_resel_support, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
3145     bit_offset = bit_offset + 1;
3146
3147     /*
3148      * Release 9 starts here
3149      *
3150      * <UTRA CSG Cells Reporting : bit > -- Release 9 starts here.
3151      * Extract UTRA CSG Cells Reporting
3152      */
3153     AVAILABLE_BITS_CHECK(1);
3154     proto_tree_add_bits_item(tree, hf_gsm_a_utra_csg_cells_reporting, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
3155     bit_offset = bit_offset + 1;
3156
3157     /*
3158      * <VAMOS Level : bit(2) >
3159      * Extract VAMOS Level
3160      */
3161     AVAILABLE_BITS_CHECK(2);
3162     proto_tree_add_bits_item(tree, hf_gsm_a_vamos_level, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
3163     bit_offset = bit_offset + 2;
3164
3165     /*
3166      * Release 10 starts here
3167      *
3168      * < TIGHTER Capability : bit(2) > -- Release 10 starts here.
3169      * Extract TIGHTER Capability
3170      */
3171     AVAILABLE_BITS_CHECK(2);
3172     proto_tree_add_bits_item(tree, hf_gsm_a_tighter_cap, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
3173     bit_offset = bit_offset + 2;
3174
3175     /*
3176      * < Selective Ciphering of Downlink SACCH : bit >
3177      * Extract Selective Ciphering of Downlink SACCH
3178      */
3179     AVAILABLE_BITS_CHECK(1);
3180     proto_tree_add_bits_item(tree, hf_gsm_a_selective_ciph_down_sacch, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
3181     bit_offset = bit_offset + 1;
3182
3183     /*
3184      * Release 11 starts here
3185      *
3186      * < CS to PS SRVCC from GERAN to UTRA : bit(2) > -- Release 11 starts here
3187      */
3188     AVAILABLE_BITS_CHECK(2);
3189     proto_tree_add_bits_item(tree, hf_gsm_a_cs_to_ps_srvcc_geran_to_utra, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
3190     bit_offset = bit_offset + 2;
3191
3192     /*
3193      * < CS to PS SRVCC from GERAN to E-UTRA : bit(2)>
3194      */
3195     AVAILABLE_BITS_CHECK(2);
3196     proto_tree_add_bits_item(tree, hf_gsm_a_cs_to_ps_srvcc_geran_to_eutra, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
3197     bit_offset = bit_offset + 2;
3198
3199     /*
3200      * < GERAN Network Sharing support : bit(1)>
3201      */
3202     AVAILABLE_BITS_CHECK(1);
3203     proto_tree_add_bits_item(tree, hf_gsm_a_geran_network_sharing_support, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
3204     bit_offset = bit_offset + 1;
3205
3206     /*
3207      * Add spare bits until we reach an octet boundary
3208      */
3209     bits_left = (((len + offset) << 3) - bit_offset) & 0x07;
3210     if (bits_left != 0)
3211     {
3212         proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, bit_offset, bits_left, ENC_BIG_ENDIAN);
3213         bit_offset += bits_left;
3214     }
3215
3216     /* translate to byte offset (we already know that we are on an octet boundary) */
3217     curr_offset = bit_offset >> 3;
3218     EXTRANEOUS_DATA_CHECK_EXPERT(len, curr_offset - offset, pinfo, &ei_gsm_a_extraneous_data);
3219
3220     return(len);
3221 }
3222 /*
3223  * [3] 10.5.1.8
3224  */
3225 guint16 de_spare_nibble(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3226 {
3227    guint32 curr_offset;
3228    gint    bit_offset;
3229
3230    curr_offset = offset;
3231    if (RIGHT_NIBBLE == len)
3232        bit_offset = 4;
3233    else
3234        bit_offset = 0;
3235
3236    proto_tree_add_bits_item(tree, hf_gsm_a_spare_nibble, tvb, (curr_offset<<3)+bit_offset, 4, ENC_BIG_ENDIAN);
3237    curr_offset = curr_offset + 1;
3238
3239    return(curr_offset - offset);
3240 }
3241
3242 /*
3243  * [3] 10.5.1.9 Descriptive group or broadcast call reference
3244  */
3245 guint16
3246 de_d_gb_call_ref(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3247 {
3248     guint8       oct;
3249     guint32      value;
3250     guint32      curr_offset;
3251     const gchar *str;
3252
3253     curr_offset = offset;
3254
3255     value = tvb_get_ntohl(tvb, curr_offset);
3256
3257     other_decode_bitfield_value(a_bigbuf, value, 0xffffffe0, 32);
3258     proto_tree_add_text(tree, tvb, curr_offset, 4,
3259         "%s = Group or Broadcast call reference: %u (0x%04x)",
3260         a_bigbuf,
3261         (value & 0xffffffe0) >> 5,
3262         (value & 0xffffffe0) >> 5);
3263
3264     other_decode_bitfield_value(a_bigbuf, value, 0x00000010, 32);
3265     proto_tree_add_text(tree, tvb, curr_offset, 4,
3266         "%s = SF Service Flag: %s",
3267         a_bigbuf,
3268         (value & 0x00000010) ?
3269         "VGCS (Group call reference)" : "VBS (Broadcast call reference)");
3270
3271     other_decode_bitfield_value(a_bigbuf, value, 0x00000008, 32);
3272     proto_tree_add_text(tree, tvb, curr_offset, 4,
3273         "%s = AF Acknowledgement Flag: acknowledgment is %srequired",
3274         a_bigbuf,
3275         (value & 0x00000008) ? "" : "not ");
3276
3277     switch (value & 0x00000007)
3278     {
3279     case 1: str = "call priority level 4"; break;
3280     case 2: str = "call priority level 3"; break;
3281     case 3: str = "call priority level 2"; break;
3282     case 4: str = "call priority level 1"; break;
3283     case 5: str = "call priority level 0"; break;
3284     case 6: str = "call priority level B"; break;
3285     case 7: str = "call priority level A"; break;
3286     default:
3287     str = "no priority applied";
3288     break;
3289     }
3290
3291     other_decode_bitfield_value(a_bigbuf, value, 0x00000007, 32);
3292     proto_tree_add_text(tree, tvb, curr_offset, 4,
3293         "%s = Call Priority: %s",
3294         a_bigbuf,
3295         str);
3296
3297     curr_offset += 4;
3298
3299     oct = tvb_get_guint8(tvb, curr_offset);
3300
3301     other_decode_bitfield_value(a_bigbuf, oct, 0xf0, 8);
3302     proto_tree_add_text(tree, tvb, curr_offset, 1,
3303         "%s = Ciphering Information",
3304         a_bigbuf);
3305
3306     proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, (curr_offset<<3)+4, 4, ENC_BIG_ENDIAN);
3307     curr_offset++;
3308
3309     /* no length check possible */
3310
3311     return(curr_offset - offset);
3312 }
3313
3314 /*
3315  * [3] 10.5.1.10a PD and SAPI $(CCBS)$
3316  */
3317 static guint16
3318 de_pd_sapi(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3319 {
3320     guint8       oct;
3321     guint32      curr_offset;
3322     proto_tree  *subtree;
3323     proto_item  *item;
3324     const gchar *str;
3325
3326     curr_offset = offset;
3327
3328     oct = tvb_get_guint8(tvb, curr_offset);
3329
3330     item =
3331     proto_tree_add_text(tree,
3332         tvb, curr_offset, 1, "%s",
3333         val_to_str_ext_const(DE_PD_SAPI, &gsm_dtap_elem_strings_ext, ""));
3334
3335     subtree = proto_item_add_subtree(item, ett_gsm_dtap_elem[DE_PD_SAPI]);
3336
3337     proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, curr_offset<<3, 2, ENC_BIG_ENDIAN);
3338
3339     switch ((oct & 0x30) >> 4)
3340     {
3341     case 0: str = "SAPI 0"; break;
3342     case 3: str = "SAPI 3"; break;
3343     default:
3344     str = "Reserved";
3345     break;
3346     }
3347
3348     other_decode_bitfield_value(a_bigbuf, oct, 0x30, 8);
3349     proto_tree_add_text(subtree, tvb, curr_offset, 1,
3350         "%s = SAPI (Service Access Point Identifier): %s",
3351         a_bigbuf,
3352         str);
3353
3354     proto_tree_add_item(tree, hf_gsm_a_L3_protocol_discriminator, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3355
3356     curr_offset++;
3357
3358     /* no length check possible */
3359
3360     return(curr_offset - offset);
3361 }
3362
3363 /*
3364  * [3] 10.5.1.11 Priority Level
3365  */
3366 static const value_string gsm_a_call_prio_vals[] = {
3367     { 0x00, "no priority applied" },
3368     { 0x01, "call priority level 4" },
3369     { 0x02, "call priority level 3" },
3370     { 0x03, "call priority level 2" },
3371     { 0x04, "call priority level 1" },
3372     { 0x05, "call priority level 0" },
3373     { 0x06, "call priority level B" },
3374     { 0x07, "call priority level A" },
3375     { 0,            NULL }
3376 };
3377
3378 static guint16
3379 de_prio(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3380 {
3381     guint32 curr_offset;
3382
3383     curr_offset = offset;
3384
3385     proto_tree_add_item(tree, hf_gsm_a_b8spare, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3386     proto_tree_add_bits_item(tree, hf_gsm_a_call_prio, tvb, (curr_offset<<3)+5, 3, ENC_BIG_ENDIAN);
3387     curr_offset++;
3388
3389     /* no length check possible */
3390
3391     return(curr_offset - offset);
3392 }
3393
3394 /*
3395  * [3] 10.5.1.12.1 CN Common GSM-MAP NAS system information
3396  */
3397 guint16
3398 de_cn_common_gsm_map_nas_sys_info(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
3399 {
3400     guint32 curr_offset;
3401
3402     curr_offset = offset;
3403
3404     proto_tree_add_item(tree, hf_gsm_a_lac, tvb, curr_offset, 2, ENC_BIG_ENDIAN);
3405     curr_offset += 2;
3406
3407     EXTRANEOUS_DATA_CHECK_EXPERT(len, curr_offset - offset, pinfo, &ei_gsm_a_extraneous_data);
3408
3409     return(curr_offset - offset);
3410 }
3411
3412 /*
3413  * [3] 10.5.1.12.2 CS domain specific system information
3414  */
3415 const true_false_string gsm_a_att_value = {
3416     "MSs shall apply IMSI attach and detach procedure",
3417     "MSs shall not apply IMSI attach and detach procedure"
3418 };
3419
3420 guint16
3421 de_cs_domain_spec_sys_info(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
3422 {
3423     guint32 curr_offset;
3424
3425     curr_offset = offset;
3426
3427     proto_tree_add_item(tree, hf_gsm_a_rr_t3212, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3428     curr_offset++;
3429     proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, (curr_offset<<3), 7, ENC_BIG_ENDIAN);
3430     proto_tree_add_item(tree, hf_gsm_a_att, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3431     curr_offset++;
3432
3433     EXTRANEOUS_DATA_CHECK_EXPERT(len, curr_offset - offset, pinfo, &ei_gsm_a_extraneous_data);
3434
3435     return(curr_offset - offset);
3436 }
3437
3438 /*
3439  * [3] 10.5.1.12.3 PS domain specific system information
3440  */
3441 const true_false_string gsm_a_nmo_1_value = {
3442     "Network Mode of Operation I is used for MS configured for NMO_I_Behaviour",
3443     "Network Mode of Operation indicated in Bit 1 (NMO) is used for MS configured for NMO_I_Behaviour"
3444 };
3445
3446 const true_false_string gsm_a_nmo_value = {
3447     "Network Mode of Operation II",
3448     "Network Mode of Operation I"
3449 };
3450
3451 guint16
3452 de_ps_domain_spec_sys_info(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
3453 {
3454     guint32 curr_offset;
3455
3456     curr_offset = offset;
3457
3458     proto_tree_add_item(tree, hf_gsm_a_gm_rac, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3459     curr_offset++;
3460     proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, (curr_offset<<3), 6, ENC_BIG_ENDIAN);
3461     proto_tree_add_item(tree, hf_gsm_a_nmo_1, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3462     proto_tree_add_item(tree, hf_gsm_a_nmo, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3463     curr_offset++;
3464
3465     EXTRANEOUS_DATA_CHECK_EXPERT(len, curr_offset - offset, pinfo, &ei_gsm_a_extraneous_data);
3466
3467     return(curr_offset - offset);
3468 }
3469
3470 /*
3471  * [3] 10.5.1.13 PLMN list
3472  */
3473 guint16
3474 de_plmn_list(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string, int string_len)
3475 {
3476     guint8  octs[3];
3477     guint32 curr_offset;
3478     gchar   mcc[4];
3479     gchar   mnc[4];
3480     guint8  num_plmn;
3481
3482     curr_offset = offset;
3483
3484     num_plmn = 0;
3485     while ((len - (curr_offset - offset)) >= 3)
3486     {
3487     octs[0] = tvb_get_guint8(tvb, curr_offset);
3488     octs[1] = tvb_get_guint8(tvb, curr_offset + 1);
3489     octs[2] = tvb_get_guint8(tvb, curr_offset + 2);
3490
3491     mcc_mnc_aux(octs, mcc, mnc);
3492
3493     proto_tree_add_text(tree,
3494         tvb, curr_offset, 3,
3495         "PLMN[%u]  Mobile Country Code (MCC): %s, Mobile Network Code (MNC): %s",
3496         num_plmn + 1,
3497         mcc,
3498         mnc);
3499
3500     curr_offset += 3;
3501
3502     num_plmn++;
3503     }
3504
3505     if (add_string)
3506     g_snprintf(add_string, string_len, " - %u PLMN%s",
3507         num_plmn, plurality(num_plmn, "", "s"));
3508
3509     EXTRANEOUS_DATA_CHECK_EXPERT(len, curr_offset - offset, pinfo, &ei_gsm_a_extraneous_data);
3510
3511     return(curr_offset - offset);
3512 }
3513
3514 /*
3515  * 10.5.1.14 NAS container for PS HO
3516  */
3517
3518 static const value_string gsm_a_pld_xid_vals[] = {
3519     { 0x00, "The MS shall perform a Reset of LLC and SNDCP without old XID indicator" },
3520     { 0x01, "The MS shall perform a Reset of LLC and SNDCP with old XID indicator" },
3521     { 0,            NULL }
3522 };
3523
3524 static guint16
3525 de_nas_cont_for_ps_ho(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_)
3526 {
3527     guint32 curr_offset;
3528
3529     curr_offset = offset;
3530
3531     /*     8     7     6     5     4     3     2      1
3532      *     0     0     0   old     0     Type of ciphering
3533      * spare  spare  spare XID  spare      algorithm
3534      */
3535     proto_tree_add_item(tree, hf_gsm_a_old_xid, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3536     proto_tree_add_item(tree, hf_gsm_a_type_of_ciph_alg, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
3537     curr_offset++;
3538
3539     /* IOV-UI value (octet 2 to 5)
3540      * The IOV-UI value consists of 32 bits, the format is defined in 3GPP TS 44.064 [78a].
3541      */
3542     proto_tree_add_item(tree, hf_gsm_a_iov_ui, tvb, curr_offset, 4, ENC_BIG_ENDIAN);
3543     curr_offset += 4;
3544
3545     EXTRANEOUS_DATA_CHECK_EXPERT(len, curr_offset - offset, pinfo, &ei_gsm_a_extraneous_data);
3546
3547     return(curr_offset - offset);
3548 }
3549
3550 /*
3551  * 10.5.1.15 MS network feature support
3552  */
3553 static const true_false_string gsm_a_ext_periodic_timers_value = {
3554     "MS supports the extended periodic timer in this domain",
3555     "MS does not support the extended periodic timer in this domain"
3556 };
3557
3558 static guint16
3559 de_ms_net_feat_sup(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_)
3560 {
3561     guint32 curr_offset, bit_offset;
3562
3563     curr_offset = offset;
3564     bit_offset  = (curr_offset<<3)+4;
3565
3566     proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, bit_offset, 3, ENC_BIG_ENDIAN);
3567     bit_offset += 3;
3568     proto_tree_add_bits_item(tree, hf_gsm_a_ext_periodic_timers, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
3569     curr_offset++;
3570
3571     return (curr_offset - offset);
3572 }
3573
3574
3575 guint16 (*common_elem_fcn[])(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string, int string_len) = {
3576     /* Common Information Elements 10.5.1 */
3577     de_cell_id,                        /* Cell Identity */
3578     de_ciph_key_seq_num,               /* Ciphering Key Sequence Number */
3579     de_lai,                            /* Location Area Identification */
3580     de_mid,                            /* Mobile Identity */
3581     de_ms_cm_1,                        /* Mobile Station Classmark 1 */
3582     de_ms_cm_2,                        /* Mobile Station Classmark 2 */
3583     de_ms_cm_3,                        /* Mobile Station Classmark 3 */
3584     de_spare_nibble,                   /* Spare Half Octet */
3585     de_d_gb_call_ref,                  /* Descriptive group or broadcast call reference */
3586     NULL       /* handled inline */,   /* Group Cipher Key Number */
3587     de_pd_sapi,                        /* PD and SAPI $(CCBS)$ */
3588     /* Pos 10 */
3589     de_prio    /* handled inline */,   /* Priority Level */
3590     de_cn_common_gsm_map_nas_sys_info, /* 10.5.1.12.1 CN Common GSM-MAP NAS system information */
3591     de_cs_domain_spec_sys_info,        /* 10.5.1.12.2 CS domain specific system information */
3592     de_ps_domain_spec_sys_info,        /* 10.5.1.12.2 PS domain specific system information */
3593     de_plmn_list,                      /* 10.5.1.13 PLMN list */
3594     de_nas_cont_for_ps_ho,             /* 10.5.1.14 NAS container for PS HO */
3595     de_ms_net_feat_sup,                /* 10.5.1.15 MS network feature support */
3596     NULL,                   /* NONE */
3597 };
3598
3599 /* Register the protocol with Wireshark */
3600 void
3601 proto_register_gsm_a_common(void)
3602 {
3603     guint   i;
3604     guint   last_offset;
3605
3606     /* Setup list of header fields */
3607     static hf_register_info hf[] =
3608     {
3609     { &hf_gsm_a_common_elem_id,
3610         { "Element ID", "gsm_a.common.elem_id",
3611         FT_UINT8, BASE_HEX, NULL, 0,
3612         NULL, HFILL }
3613     },
3614     { &hf_gsm_a_l_ext,
3615         { "ext",    "gsm_a.l_ext",
3616         FT_UINT8, BASE_DEC, NULL, 0x80,
3617         NULL, HFILL }
3618     },
3619     { &hf_gsm_a_imsi,
3620         { "IMSI",   "gsm_a.imsi",
3621         FT_STRING, BASE_NONE, 0, 0,
3622         NULL, HFILL }
3623     },
3624     { &hf_gsm_a_tmsi,
3625         { "TMSI/P-TMSI",    "gsm_a.tmsi",
3626         FT_UINT32, BASE_HEX, 0, 0x0,
3627         NULL, HFILL }
3628     },
3629     { &hf_gsm_a_imei,
3630         { "IMEI",   "gsm_a.imei",
3631         FT_STRING, BASE_NONE, 0, 0,
3632         NULL, HFILL }
3633     },
3634     { &hf_gsm_a_imeisv,
3635         { "IMEISV", "gsm_a.imeisv",
3636         FT_STRING, BASE_NONE, 0, 0,
3637         NULL, HFILL }
3638     },
3639     { &hf_gsm_a_MSC_rev,
3640         { "Revision Level", "gsm_a.MSC_rev",
3641         FT_UINT8, BASE_DEC, VALS(gsm_a_msc_rev_vals), 0x60,
3642         NULL, HFILL }
3643     },
3644     { &hf_gsm_a_ES_IND,
3645         { "ES IND", "gsm_a.ES_IND",
3646         FT_BOOLEAN, 8, TFS(&ES_IND_vals), 0x10,
3647             NULL, HFILL }
3648     },
3649     { &hf_gsm_a_A5_1_algorithm_sup,
3650         { "A5/1 algorithm supported", "gsm_a.A5_1_algorithm_sup",
3651         FT_BOOLEAN, 8, TFS(&A5_1_algorithm_sup_vals), 0x08,
3652         NULL, HFILL }
3653     },
3654     { &hf_gsm_a_RF_power_capability,
3655         { "RF Power Capability", "gsm_a.RF_power_capability",
3656         FT_UINT8, BASE_DEC, VALS(RF_power_capability_vals), 0x07,
3657         NULL, HFILL }
3658     },
3659     { &hf_gsm_a_ps_sup_cap,
3660         { "PS capability (pseudo-synchronization capability)", "gsm_a.ps_sup_cap",
3661         FT_BOOLEAN, 8, TFS(&ps_sup_cap_vals), 0x40,
3662         NULL, HFILL }
3663     },
3664     { &hf_gsm_a_SS_screening_indicator,
3665         { "SS Screening Indicator", "gsm_a.SS_screening_indicator",
3666         FT_UINT8, BASE_DEC, VALS(SS_screening_indicator_vals), 0x30,
3667         NULL, HFILL }
3668     },
3669     { &hf_gsm_a_SM_capability,
3670         { "SM capability (MT SMS pt to pt capability)", "gsm_a.SM_cap",
3671         FT_BOOLEAN, 8, TFS(&SM_capability_vals), 0x08,
3672         NULL, HFILL }
3673     },
3674     { &hf_gsm_a_VBS_notification_rec,
3675         { "VBS notification reception", "gsm_a.VBS_notification_rec",
3676         FT_BOOLEAN, 8, TFS(&VBS_notification_rec_vals), 0x04,
3677         NULL, HFILL }
3678     },
3679     { &hf_gsm_a_VGCS_notification_rec,
3680         { "VGCS notification reception", "gsm_a.VGCS_notification_rec",
3681         FT_BOOLEAN, 8, TFS(&VGCS_notification_rec_vals), 0x02,
3682         NULL, HFILL }
3683     },
3684     { &hf_gsm_a_FC_frequency_cap,
3685         { "FC Frequency Capability", "gsm_a.FC_frequency_cap",
3686         FT_BOOLEAN, 8, TFS(&FC_frequency_cap_vals), 0x01,
3687         NULL, HFILL }
3688     },
3689     { &hf_gsm_a_CM3,
3690         { "CM3", "gsm_a.CM3",
3691         FT_BOOLEAN, 8, TFS(&CM3_vals), 0x80,
3692         NULL, HFILL }
3693     },
3694     { &hf_gsm_a_LCS_VA_cap,
3695         { "LCS VA capability (LCS value added location request notification capability)", "gsm_a.LCS_VA_cap",
3696         FT_BOOLEAN, 8, TFS(&LCS_VA_cap_vals), 0x20,
3697         NULL, HFILL }
3698     },
3699     { &hf_gsm_a_UCS2_treatment,
3700         { "UCS2 treatment", "gsm_a.UCS2_treatment",
3701         FT_BOOLEAN, 8, TFS(&UCS2_treatment_vals), 0x10,
3702         NULL, HFILL }
3703     },
3704     { &hf_gsm_a_SoLSA,
3705         { "SoLSA", "gsm_a.SoLSA",
3706         FT_BOOLEAN, 8, TFS(&SoLSA_vals), 0x08,
3707         NULL, HFILL }
3708     },
3709     { &hf_gsm_a_CMSP,
3710         { "CMSP: CM Service Prompt", "gsm_a.CMSP",
3711         FT_BOOLEAN, 8, TFS(&CMSP_vals), 0x04,
3712         NULL, HFILL }
3713     },
3714     { &hf_gsm_a_A5_7_algorithm_sup,
3715         { "A5/7 algorithm supported", "gsm_a.A5_7_algorithm_sup",
3716         FT_BOOLEAN, BASE_NONE, TFS(&A5_7_algorithm_sup_vals), 0x0,
3717         NULL, HFILL }
3718     },
3719     { &hf_gsm_a_A5_6_algorithm_sup,
3720         { "A5/6 algorithm supported", "gsm_a.A5_6_algorithm_sup",
3721         FT_BOOLEAN, BASE_NONE, TFS(&A5_6_algorithm_sup_vals), 0x0,
3722         NULL, HFILL }
3723     },
3724     { &hf_gsm_a_A5_5_algorithm_sup,
3725         { "A5/5 algorithm supported", "gsm_a.A5_5_algorithm_sup",
3726         FT_BOOLEAN, BASE_NONE, TFS(&A5_5_algorithm_sup_vals), 0x0,
3727         NULL, HFILL }
3728     },
3729     { &hf_gsm_a_A5_4_algorithm_sup,
3730         { "A5/4 algorithm supported", "gsm_a.A5_4_algorithm_sup",
3731         FT_BOOLEAN, BASE_NONE, TFS(&A5_4_algorithm_sup_vals), 0x0,
3732         NULL, HFILL }
3733     },
3734     { &hf_gsm_a_A5_3_algorithm_sup,
3735         { "A5/3 algorithm supported", "gsm_a.A5_3_algorithm_sup",
3736         FT_BOOLEAN, 8, TFS(&A5_3_algorithm_sup_vals), 0x02,
3737         NULL, HFILL }
3738     },
3739     { &hf_gsm_a_A5_2_algorithm_sup,
3740         { "A5/2 algorithm supported", "gsm_a.A5_2_algorithm_sup",
3741         FT_BOOLEAN, 8, TFS(&A5_2_algorithm_sup_vals), 0x01,
3742         NULL, HFILL }
3743     },
3744     { &hf_gsm_a_mobile_identity_type,
3745         { "Mobile Identity Type", "gsm_a.ie.mobileid.type",
3746         FT_UINT8, BASE_DEC, VALS(mobile_identity_type_vals), 0x07,
3747         NULL, HFILL }
3748     },
3749     { &hf_gsm_a_odd_even_ind,
3750         { "Odd/even indication", "gsm_a.oddevenind",
3751         FT_BOOLEAN, 8, TFS(&oddevenind_vals), 0x08,
3752         NULL, HFILL }
3753     },
3754     { &hf_gsm_a_unused,
3755         { "Unused", "gsm_a.unused",
3756         FT_UINT8, BASE_HEX, NULL, 0xf0,
3757         NULL, HFILL }
3758     },
3759     { &hf_gsm_a_tmgi_mcc_mnc_ind,
3760         { "MCC/MNC indication", "gsm_a.tmgi_mcc_mnc_ind",
3761         FT_BOOLEAN, 8, TFS(&gsm_a_present_vals), 0x10,
3762         NULL, HFILL}
3763     },
3764     { &hf_gsm_a_mbs_ses_id_ind,
3765         { "MBMS Session Identity indication", "gsm_a.mbs_session_id_ind",
3766         FT_BOOLEAN, 8, TFS(&gsm_a_present_vals), 0x20,
3767         NULL, HFILL}
3768     },
3769     { &hf_gsm_a_mbs_service_id,
3770         { "MBMS Service ID", "gsm_a.mbs_service_id",
3771         FT_UINT24, BASE_HEX, NULL, 0x0,
3772         NULL, HFILL }
3773     },
3774     { &hf_gsm_a_mbs_session_id,
3775         { "MBMS Session ID", "gsm_a.mbs_session_id",
3776         FT_UINT8, BASE_HEX, NULL, 0x0,
3777         NULL, HFILL }
3778     },
3779     { &hf_gsm_a_length,
3780         { "Length",     "gsm_a.len",
3781         FT_UINT16, BASE_DEC, NULL, 0,
3782         NULL, HFILL }
3783     },
3784     { &hf_gsm_a_extension,
3785         { "Extension", "gsm_a.extension",
3786         FT_BOOLEAN, 8, TFS(&gsm_a_extension_value), 0x80,
3787         NULL, HFILL }
3788     },
3789     { &hf_gsm_a_L3_protocol_discriminator,
3790         { "Protocol discriminator", "gsm_a.L3_protocol_discriminator",
3791         FT_UINT8, BASE_HEX, VALS(protocol_discriminator_vals), 0x0f,
3792         NULL, HFILL }
3793     },
3794     { &hf_gsm_a_call_prio,
3795         { "Call priority", "gsm_a.call_prio",
3796         FT_UINT8, BASE_DEC, VALS(gsm_a_call_prio_vals), 0x00,
3797         NULL, HFILL }
3798     },
3799     { &hf_gsm_a_type_of_ciph_alg,
3800         { "Call priority", "gsm_a.call_prio",
3801         FT_UINT8, BASE_DEC, VALS(gsm_a_gm_type_of_ciph_alg_vals), 0x07,
3802         NULL, HFILL }
3803     },
3804     { &hf_gsm_a_att,
3805         { "ATT", "gsm_a.att",
3806         FT_BOOLEAN, 8, TFS(&gsm_a_att_value), 0x01,
3807         "ttach-detach allowed", HFILL }
3808     },
3809     { &hf_gsm_a_nmo_1,
3810         { "NMO I", "gsm_a.nmo_1",
3811         FT_BOOLEAN, 8, TFS(&gsm_a_nmo_1_value), 0x02,
3812         "Network Mode of Operation I", HFILL }
3813     },
3814     { &hf_gsm_a_nmo,
3815         { "NMO", "gsm_a.nmo",
3816         FT_BOOLEAN, 8, TFS(&gsm_a_nmo_value), 0x01,
3817         "Network Mode of Operation", HFILL }
3818     },
3819     { &hf_gsm_a_old_xid,
3820         { "Old XID", "gsm_a.old_xid",
3821         FT_UINT8, BASE_DEC, VALS(gsm_a_pld_xid_vals), 0x10,
3822         NULL, HFILL }
3823     },
3824     { &hf_gsm_a_iov_ui,
3825         { "IOV-UI", "gsm_a.iov_ui",
3826         FT_UINT32, BASE_HEX, NULL, 0x0,
3827         NULL, HFILL }
3828     },
3829     { &hf_gsm_a_ext_periodic_timers,
3830         { "Extended periodic timers", "gsm_a.ext_periodic_timers",
3831         FT_BOOLEAN, BASE_NONE, TFS(&gsm_a_ext_periodic_timers_value), 0x0,
3832         NULL, HFILL }
3833     },
3834     { &hf_gsm_a_skip_ind,
3835         { "Skip Indicator", "gsm_a.skip.ind",
3836         FT_UINT8, BASE_DEC, VALS(gsm_a_skip_ind_vals), 0xf0,
3837         NULL, HFILL }
3838     },
3839     { &hf_gsm_a_b7spare,
3840         { "Spare", "gsm_a.spareb7",
3841         FT_UINT8, BASE_DEC, NULL, 0x40,
3842         NULL, HFILL }
3843     },
3844     { &hf_gsm_a_b8spare,
3845         { "Spare", "gsm_a.spareb8",
3846         FT_UINT8, BASE_DEC, NULL, 0x80,
3847         NULL, HFILL }
3848     },
3849     { &hf_gsm_a_spare_bits,
3850         { "Spare bit(s)", "gsm_a.spare_bits",
3851         FT_UINT8, BASE_DEC, NULL, 0x0,
3852         NULL, HFILL }
3853     },
3854     { &hf_gsm_a_multi_bnd_sup_fields,
3855         { "Multiband supported field", "gsm_a.multi_bnd_sup_fields",
3856         FT_UINT8, BASE_DEC, NULL, 0x0,
3857         NULL, HFILL }
3858     },
3859     { &hf_gsm_a_pgsm_supported,
3860         { "P-GSM Supported", "gsm_a.classmark3.pgsmSupported",
3861         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x0,
3862         NULL, HFILL}
3863     },
3864     { &hf_gsm_a_egsm_supported,
3865         { "E-GSM or R-GSM Supported", "gsm_a.classmark3.egsmSupported",
3866         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x0,
3867         NULL, HFILL}
3868     },
3869     { &hf_gsm_a_gsm1800_supported,
3870         { "GSM 1800 Supported", "gsm_a.classmark3.gsm1800Supported",
3871         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x0,
3872         NULL, HFILL}
3873     },
3874     { &hf_gsm_a_ass_radio_cap1,
3875         { "Associated Radio Capability 1", "gsm_a.classmark3.ass_radio_cap1",
3876         FT_UINT8, BASE_DEC, NULL, 0x0,
3877         NULL, HFILL}
3878     },
3879     { &hf_gsm_a_ass_radio_cap2,
3880         { "Associated Radio Capability 2", "gsm_a.classmark3.ass_radio_cap2",
3881         FT_UINT8, BASE_DEC, NULL, 0x0,
3882         NULL, HFILL}
3883     },
3884     { &hf_gsm_a_cm3_A5_bits,
3885         { "A5 bits", "gsm_a.classmark3.a5_bits",
3886         FT_UINT8, BASE_HEX, NULL, 0x00,
3887         NULL, HFILL}
3888     },
3889     { &hf_gsm_a_rsupport,
3890         { "R Support", "gsm_a.classmark3.rsupport",
3891         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x0,
3892         NULL, HFILL}
3893     },
3894     { &hf_gsm_a_r_capabilities,
3895         { "R-GSM band Associated Radio Capability", "gsm_a.classmark3.r_capabilities",
3896         FT_UINT8, BASE_DEC, NULL, 0x0,
3897         NULL, HFILL}
3898     },
3899     { &hf_gsm_a_multislot_capabilities,
3900         { "HSCSD Multi Slot Capability", "gsm_a.classmark3.multislot_capabilities",
3901         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x0,
3902         NULL, HFILL}
3903     },
3904     { &hf_gsm_a_multislot_class,
3905         { "HSCSD Multi Slot Class", "gsm_a.classmark3.multislot_cap",
3906         FT_UINT8, BASE_DEC, NULL, 0x0,
3907         NULL, HFILL}
3908     },
3909     { &hf_gsm_a_ucs2_treatment,
3910         { "UCS2 treatment", "gsm_a.UCS2_treatment",
3911         FT_BOOLEAN, BASE_NONE, TFS(&UCS2_treatment_vals), 0x0,
3912         NULL, HFILL }
3913     },
3914     { &hf_gsm_a_extended_measurement_cap,
3915         { "Extended Measurement Capability", "gsm_a.classmark3.ext_meas_cap",
3916         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x0,
3917         NULL, HFILL}
3918     },
3919     { &hf_gsm_a_ms_measurement_capability,
3920         { "MS measurement capability", "gsm_a.classmark3.ms_measurement_capability",
3921         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x0,
3922         NULL, HFILL}
3923     },
3924     { &hf_gsm_a_sms_value,
3925         { "SMS_VALUE (Switch-Measure-Switch)", "gsm_a.classmark3.sms_value",
3926         FT_UINT8, BASE_DEC, VALS(gsm_a_sms_vals), 0x0,
3927         NULL, HFILL}
3928     },
3929     { &hf_gsm_a_sm_value,
3930         { "SM_VALUE (Switch-Measure)", "gsm_a.classmark3.sm_value",
3931         FT_UINT8, BASE_DEC, VALS(gsm_a_sms_vals), 0x0,
3932         NULL, HFILL}
3933     },
3934     { &hf_gsm_a_ms_pos_method_cap_present,
3935         { "MS Positioning Method Capability present", "gsm_a.classmark3.ms_pos_method_cap_present",
3936         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
3937         NULL, HFILL}
3938     },
3939     { &hf_gsm_a_ms_pos_method,
3940         { "MS Positioning Method", "gsm_a.classmark3.ms_pos_method",
3941         FT_UINT8, BASE_HEX, NULL, 0x00,
3942         NULL, HFILL}
3943     },
3944     { &hf_gsm_a_ms_assisted_e_otd,
3945         { "MS assisted E-OTD", "gsm_a.classmark3.ms_assisted_e_otd",
3946         FT_BOOLEAN, BASE_NONE, TFS(&ms_assisted_e_otd_vals), 0x0,
3947         NULL, HFILL}
3948     },
3949     { &hf_gsm_a_ms_based_e_otd,
3950         { "MS based E-OTD", "gsm_a.classmark3.ms_based_e_otd",
3951         FT_BOOLEAN, BASE_NONE, TFS(&ms_based_e_otd_vals), 0x0,
3952         NULL, HFILL}
3953     },
3954     { &hf_gsm_a_ms_assisted_gps,
3955         { "MS assisted GPS", "gsm_a.classmark3.ms_assisted_gps",
3956         FT_BOOLEAN, BASE_NONE, TFS(&ms_assisted_gps_vals), 0x0,
3957         NULL, HFILL}
3958     },
3959     { &hf_gsm_a_ms_based_gps,
3960         { "MS based GPS", "gsm_a.classmark3.ms_based_gps",
3961         FT_BOOLEAN, BASE_NONE, TFS(&ms_based_gps_vals), 0x0,
3962         NULL, HFILL}
3963     },
3964     { &hf_gsm_a_ms_conventional_gps,
3965         { "MS Conventional GPS", "gsm_a.classmark3.ms_conventional_gps",
3966         FT_BOOLEAN, BASE_NONE, TFS(&ms_conventional_gps_vals), 0x0,
3967         NULL, HFILL}
3968     },
3969     { &hf_gsm_a_ecsd_multi_slot_capability,
3970         { "ECSD Multi Slot Capability present", "gsm_a.classmark3.ecsd_multi_slot_capability",
3971         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
3972         NULL, HFILL}
3973     },
3974     { &hf_gsm_a_ecsd_multi_slot_class,
3975         { "ECSD Multi Slot Class", "gsm_a.classmark3.ecsd_multi_slot_class",
3976         FT_UINT8, BASE_DEC, NULL, 0x00,
3977         NULL, HFILL}
3978     },
3979     { &hf_gsm_a_8_psk_struct_present,
3980         { "8-PSK Struct present", "gsm_a.classmark3.8_psk_struct_present",
3981         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
3982         NULL, HFILL}
3983     },
3984     { &hf_gsm_a_8_psk_struct,
3985         { "8-PSK Struct", "gsm_a.classmark3.8_psk_struct",
3986         FT_UINT8, BASE_HEX, NULL, 0x00,
3987         NULL, HFILL}
3988     },
3989     { &hf_gsm_a_modulation_capability,
3990         { "Modulation Capability", "gsm_a.classmark3.modulation_capability",
3991         FT_BOOLEAN, BASE_NONE, TFS(&modulation_capability_vals), 0x00,
3992         NULL, HFILL}
3993     },
3994     { &hf_gsm_a_8_psk_rf_power_capability_1_present,
3995         { "8-PSK RF Power Capability 1 present", "gsm_a.classmark3.8_psk_rf_power_capability_1_present",
3996         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
3997         NULL, HFILL}
3998     },
3999     { &hf_gsm_a_8_psk_rf_power_capability_1,
4000         { "8-PSK RF Power Capability 1", "gsm_a.classmark3.8_psk_rf_power_capability_1",
4001         FT_UINT8, BASE_HEX, VALS(eight_psk_rf_power_capability_vals), 0x00,
4002         NULL, HFILL}
4003     },
4004     { &hf_gsm_a_8_psk_rf_power_capability_2_present,
4005         { "8-PSK RF Power Capability 2 present", "gsm_a.classmark3.8_psk_rf_power_capability_2_present",
4006         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
4007         NULL, HFILL}
4008     },
4009     { &hf_gsm_a_8_psk_rf_power_capability_2,
4010         { "8-PSK RF Power Capability 2", "gsm_a.classmark3.8_psk_rf_power_capability_2",
4011         FT_UINT8, BASE_HEX, VALS(eight_psk_rf_power_capability_vals), 0x00,
4012         NULL, HFILL}
4013     },
4014     { &hf_gsm_a_gsm_400_band_info_present,
4015         { "GSM 400 Band Information present", "gsm_a.classmark3.gsm_400_band_info_present",
4016         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
4017         NULL, HFILL}
4018     },
4019     { &hf_gsm_a_gsm_400_bands_supported,
4020         { "GSM 400 Bands Supported", "gsm_a.classmark3.gsm_400_bands_supported",
4021         FT_UINT8, BASE_HEX, VALS(gsm_400_bands_supported_vals), 0x00,
4022         NULL, HFILL}
4023     },
4024     { &hf_gsm_a_gsm_400_assoc_radio_cap,
4025         { "GSM 400 Associated Radio Capability", "gsm_a.classmark3.gsm_400_assoc_radio_cap",
4026         FT_UINT8, BASE_HEX, NULL, 0x00,
4027         NULL, HFILL}
4028     },
4029     { &hf_gsm_a_gsm_850_assoc_radio_cap_present,
4030         { "GSM 850 Associated Radio Capability present", "gsm_a.classmark3.gsm_850_assoc_radio_cap_present",
4031         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
4032         NULL, HFILL}
4033     },
4034     { &hf_gsm_a_gsm_850_assoc_radio_cap,
4035         { "GSM 850 Associated Radio Capability", "gsm_a.classmark3.gsm_850_assoc_radio_cap",
4036         FT_UINT8, BASE_HEX, NULL, 0x00,
4037         NULL, HFILL}
4038     },
4039     { &hf_gsm_a_gsm_1900_assoc_radio_cap_present,
4040         { "GSM 1900 Associated Radio Capability present", "gsm_a.classmark3.gsm_1900_assoc_radio_cap_present",
4041         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
4042         NULL, HFILL}
4043     },
4044     { &hf_gsm_a_gsm_1900_assoc_radio_cap,
4045         { "GSM 1900 Associated Radio Capability", "gsm_a.classmark3.gsm_1900_assoc_radio_cap",
4046         FT_UINT8, BASE_HEX, NULL, 0x00,
4047         NULL, HFILL}
4048     },
4049     { &hf_gsm_a_umts_fdd_rat_cap,
4050         { "UMTS FDD Radio Access Technology Capability", "gsm_a.classmark3.umts_fdd_rat_cap",
4051         FT_BOOLEAN, BASE_NONE, TFS(&umts_fdd_rat_cap_vals), 0x00,
4052         NULL, HFILL}
4053     },
4054     { &hf_gsm_a_umts_384_mcps_tdd_rat_cap,
4055         { "UMTS 3.84 Mcps TDD Radio Access Technology Capability", "gsm_a.classmark3.umts_384_mcps_tdd_rat_cap",
4056         FT_BOOLEAN, BASE_NONE, TFS(&umts_384_mcps_tdd_rat_cap_vals), 0x00,
4057         NULL, HFILL}
4058     },
4059     { &hf_gsm_a_cdma_2000_rat_cap,
4060         { "CDMA 2000 Radio Access Technology Capability", "gsm_a.classmark3.cdma_2000_rat_cap",
4061         FT_BOOLEAN, BASE_NONE, TFS(&cdma_2000_rat_cap_vals), 0x00,
4062         NULL, HFILL}
4063     },
4064     { &hf_gsm_a_dtm_e_gprs_multi_slot_info_present,
4065         { "DTM E/GPRS Multi Slot Information present", "gsm_a.classmark3.dtm_e_gprs_multi_slot_info_present",
4066         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
4067         NULL, HFILL}
4068     },
4069     { &hf_gsm_a_dtm_gprs_multi_slot_class,
4070         { "DTM GPRS Multi Slot Class", "gsm_a.classmark3.dtm_gprs_multi_slot_class",
4071         FT_UINT8, BASE_DEC, VALS(dtm_gprs_multi_slot_class_vals), 0x00,
4072         NULL, HFILL}
4073     },
4074     { &hf_gsm_a_single_slot_dtm,
4075         { "Single Slot DTM", "gsm_a.classmark3.single_slot_dtm_supported",
4076         FT_BOOLEAN, BASE_NONE, TFS(&single_slot_dtm_vals), 0x0,
4077         NULL, HFILL}
4078     },
4079     { &hf_gsm_a_dtm_egprs_multi_slot_class_present,
4080         { "DTM EGPRS Multi Slot Class present", "gsm_a.classmark3.dtm_egprs_multi_slot_class_present",
4081         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
4082         NULL, HFILL}
4083     },
4084     { &hf_gsm_a_dtm_egprs_multi_slot_class,
4085         { "DTM EGPRS Multi Slot Class", "gsm_a.classmark3.dtm_egprs_multi_slot_class",
4086         FT_UINT8, BASE_DEC, VALS(dtm_gprs_multi_slot_class_vals), 0x00,
4087         NULL, HFILL}
4088     },
4089     { &hf_gsm_a_single_band_support,
4090         { "Single Band Support", "gsm_a.classmark3.single_band_support",
4091         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
4092         NULL, HFILL}
4093     },
4094     { &hf_gsm_a_gsm_band,
4095         { "GSM Band", "gsm_a.classmark3.gsm_band",
4096         FT_UINT8, BASE_DEC, VALS(gsm_band_vals), 0x00,
4097         NULL, HFILL}
4098     },
4099     { &hf_gsm_a_gsm_750_assoc_radio_cap_present,
4100         { "GSM 750 Associated Radio Capability present", "gsm_a.classmark3.gsm_750_assoc_radio_cap_present",
4101         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
4102         NULL, HFILL}
4103     },
4104     { &hf_gsm_a_gsm_750_assoc_radio_cap,
4105         { "GSM 750 Associated Radio Capability", "gsm_a.classmark3.gsm_750_assoc_radio_cap",
4106         FT_UINT8, BASE_HEX, NULL, 0x00,
4107         NULL, HFILL}
4108     },
4109     { &hf_gsm_a_umts_128_mcps_tdd_rat_cap,
4110         { "UMTS 1.28 Mcps TDD Radio Access Technology Capability", "gsm_a.classmark3.umts_128_mcps_tdd_rat_cap",
4111         FT_BOOLEAN, BASE_NONE, TFS(&umts_128_mcps_tdd_rat_cap_vals), 0x00,
4112         NULL, HFILL}
4113     },
4114     { &hf_gsm_a_geran_feature_package_1,
4115         { "GERAN Feature Package 1", "gsm_a.classmark3.geran_feature_package_1",
4116         FT_BOOLEAN, BASE_NONE, TFS(&geran_feature_package_1_vals), 0x00,
4117         NULL, HFILL}
4118     },
4119     { &hf_gsm_a_ext_dtm_e_gprs_multi_slot_info_present,
4120         { "Extended DTM E/GPRS Multi Slot Information present", "gsm_a.classmark3.ext_dtm_e_gprs_info_present",
4121         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
4122         NULL, HFILL}
4123     },
4124     { &hf_gsm_a_ext_dtm_gprs_multi_slot_class,
4125         { "Extended DTM GPRS Multi Slot Class", "gsm_a.classmark3.ext_dtm_gprs_multi_slot_class",
4126         FT_UINT8, BASE_HEX, NULL, 0x00,
4127         NULL, HFILL}
4128     },
4129     { &hf_gsm_a_ext_dtm_egprs_multi_slot_class,
4130         { "Extended DTM EGPRS Multi Slot Class", "gsm_a.classmark3.ext_dtm_egprs_multi_slot_class",
4131         FT_UINT8, BASE_HEX, NULL, 0x00,
4132         NULL, HFILL}
4133     },
4134     { &hf_gsm_a_high_multislot_cap_present,
4135         { "High Multislot Capability present", "gsm_a.classmark3.high_multislot_cap_present",
4136         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
4137         NULL, HFILL}
4138     },
4139     { &hf_gsm_a_high_multislot_cap,
4140         { "High Multislot Capability", "gsm_a.classmark3.high_multislot_cap",
4141         FT_UINT8, BASE_HEX, NULL, 0x00,
4142         NULL, HFILL}
4143     },
4144     { &hf_gsm_a_geran_iu_mode_support,
4145         { "GERAN Iu Mode Support", "gsm_a.classmark3.geran_iu_mode_support",
4146         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
4147         NULL, HFILL}
4148     },
4149     { &hf_gsm_a_geran_iu_mode_cap,
4150         { "GERAN Iu Mode Capabilities", "gsm_a.classmark3.geran_iu_mode_cap",
4151         FT_UINT24, BASE_HEX, NULL, 0x00,
4152         NULL, HFILL}
4153     },
4154     { &hf_gsm_a_geran_iu_mode_cap_length,
4155         { "Length", "gsm_a.classmark3.geran_iu_mode_cap.length",
4156         FT_UINT8, BASE_DEC, NULL, 0x00,
4157         NULL, HFILL}
4158     },
4159     { &hf_gsm_a_flo_iu_cap,
4160         { "FLO Iu Capability", "gsm_a.classmark3.geran_iu_mode_cap.flo_iu_cap",
4161         FT_BOOLEAN, BASE_NONE, TFS(&flo_iu_cap_vals), 0x00,
4162         NULL, HFILL}
4163     },
4164     { &hf_gsm_a_geran_feature_package_2,
4165         { "GERAN Feature Package 2", "gsm_a.classmark3.geran_feature_package_2",
4166         FT_BOOLEAN, BASE_NONE, TFS(&geran_feature_package_2_vals), 0x00,
4167         NULL, HFILL}
4168     },
4169     { &hf_gsm_a_gmsk_multislot_power_prof,
4170         { "GMSK Multislot Power Profile", "gsm_a.classmark3.gmsk_multislot_power_prof",
4171         FT_UINT8, BASE_DEC, VALS(gmsk_multislot_power_prof_vals), 0x00,
4172         NULL, HFILL}
4173     },
4174     { &hf_gsm_a_8_psk_multislot_power_prof,
4175         { "8-PSK Multislot Power Profile", "gsm_a.classmark3.8_psk_multislot_power_prof",
4176         FT_UINT8, BASE_DEC, VALS(eight_psk_multislot_power_prof_vals), 0x00,
4177         NULL, HFILL}
4178     },
4179     { &hf_gsm_a_t_gsm_400_band_info_present,
4180         { "T-GSM 400 Band Information present", "gsm_a.classmark3.gsm_400_band_info_present",
4181         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
4182         NULL, HFILL}
4183     },
4184     { &hf_gsm_a_t_gsm_400_bands_supported,
4185         { "T-GSM 400 Bands Supported", "gsm_a.classmark3.t_gsm_400_bands_supported",
4186         FT_UINT8, BASE_HEX, VALS(t_gsm_400_bands_supported_vals), 0x00,
4187         NULL, HFILL}
4188     },
4189     { &hf_gsm_a_t_gsm_400_assoc_radio_cap,
4190         { "T-GSM 400 Associated Radio Capability", "gsm_a.classmark3.t_gsm_400_assoc_radio_cap",
4191         FT_UINT8, BASE_HEX, NULL, 0x00,
4192         NULL, HFILL}
4193     },
4194     { &hf_gsm_a_t_gsm_900_assoc_radio_cap_present,
4195         { "T-GSM 900 Associated Radio Capability present", "gsm_a.classmark3.t_gsm_900_assoc_radio_cap_present",
4196         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
4197         NULL, HFILL}
4198     },
4199     { &hf_gsm_a_t_gsm_900_assoc_radio_cap,
4200         { "T-GSM 900 Associated Radio Capability", "gsm_a.classmark3.t_gsm_900_assoc_radio_cap",
4201         FT_UINT8, BASE_HEX, NULL, 0x00,
4202         NULL, HFILL}
4203     },
4204     { &hf_gsm_a_downlink_adv_receiver_perf,
4205         { "Downlink Advanced Receiver Performance", "gsm_a.classmark3.downlink_adv_receiver_perf",
4206         FT_UINT8, BASE_DEC, VALS(downlink_adv_receiver_perf_vals), 0x00,
4207         NULL, HFILL}
4208     },
4209     { &hf_gsm_a_dtm_enhancements_cap,
4210         { "DTM Enhancements Capability", "gsm_a.classmark3.dtm_enhancements_capability",
4211         FT_BOOLEAN, BASE_NONE, TFS(&dtm_enhancements_cap_vals), 0x00,
4212         NULL, HFILL}
4213     },
4214     { &hf_gsm_a_dtm_e_gprs_high_multi_slot_info_present,
4215         { "DTM E/GPRS High Multi Slot Information present", "gsm_a.classmark3.dtm_e_gprs_high_mutli_slot_info_present",
4216         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
4217         NULL, HFILL}
4218     },
4219     { &hf_gsm_a_dtm_gprs_high_multi_slot_class,
4220         { "DTM GPRS Multi Slot Class", "gsm_a.classmark3.dtm_gprs_multi_slot_class",
4221         FT_UINT8, BASE_DEC, VALS(dtm_gprs_high_multi_slot_class_vals), 0x00,
4222         NULL, HFILL}
4223     },
4224     { &hf_gsm_a_offset_required,
4225         { "Offset required", "gsm_a.classmark3.offset_required",
4226         FT_BOOLEAN, BASE_NONE, TFS(&offset_required_vals), 0x0,
4227         NULL, HFILL}
4228     },
4229     { &hf_gsm_a_dtm_egprs_high_multi_slot_class_present,
4230         { "DTM EGPRS High Multi Slot Class present", "gsm_a.classmark3.dtm_egprs_high_multi_slot_class_present",
4231         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
4232         NULL, HFILL}
4233     },
4234     { &hf_gsm_a_dtm_egprs_high_multi_slot_class,
4235         { "DTM EGPRS High Multi Slot Class", "gsm_a.classmark3.dtm_egprs_high_multi_slot_class",
4236         FT_UINT8, BASE_DEC, VALS(dtm_gprs_high_multi_slot_class_vals), 0x00,
4237         NULL, HFILL}
4238     },
4239     { &hf_gsm_a_repeated_acch_cap,
4240         { "Repeated ACCH Capability", "gsm_a.classmark3.repeated_acch_cap",
4241         FT_BOOLEAN, BASE_NONE, TFS(&repeated_acch_cap_vals), 0x00,
4242         NULL, HFILL}
4243     },
4244     { &hf_gsm_a_gsm_710_assoc_radio_cap_present,
4245         { "GSM 710 Associated Radio Capability present", "gsm_a.classmark3.gsm_710_assoc_radio_cap_present",
4246         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
4247         NULL, HFILL}
4248     },
4249     { &hf_gsm_a_gsm_710_assoc_radio_cap,
4250         { "GSM 710 Associated Radio Capability", "gsm_a.classmark3.gsm_710_assoc_radio_cap",
4251         FT_UINT8, BASE_HEX, NULL, 0x00,
4252         NULL, HFILL}
4253     },
4254     { &hf_gsm_a_t_gsm_810_assoc_radio_cap_present,
4255         { "T-GSM 810 Associated Radio Capability present", "gsm_a.classmark3.t_gsm_810_assoc_radio_cap_present",
4256         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
4257         NULL, HFILL}
4258     },
4259     { &hf_gsm_a_t_gsm_810_assoc_radio_cap,
4260         { "T-GSM 810 Associated Radio Capability", "gsm_a.classmark3.t_gsm_810_assoc_radio_cap",
4261         FT_UINT8, BASE_HEX, NULL, 0x00,
4262         NULL, HFILL}
4263     },
4264     { &hf_gsm_a_ciphering_mode_setting_cap,
4265         { "Ciphering Mode Setting Capability", "gsm_a.classmark3.ciphering_mode_setting_cap",
4266         FT_BOOLEAN, BASE_NONE, TFS(&ciphering_mode_setting_cap_vals), 0x00,
4267         NULL, HFILL}
4268     },
4269     { &hf_gsm_a_additional_positioning_caps,
4270         { "Additional Positioning Capabilities", "gsm_a.classmark3.additional_positioning_caps",
4271         FT_BOOLEAN, BASE_NONE, TFS(&additional_positioning_caps_vals), 0x00,
4272         NULL, HFILL}
4273     },
4274     { &hf_gsm_a_e_utra_fdd_support,
4275         { "E-UTRA FDD support", "gsm_a.classmark3.e_utra_fdd_support",
4276         FT_BOOLEAN, BASE_NONE, TFS(&e_utra_fdd_support_vals), 0x00,
4277         NULL, HFILL}
4278     },
4279     { &hf_gsm_a_e_utra_tdd_support,
4280         { "E-UTRA TDD support", "gsm_a.classmark3.e_utra_tdd_support",
4281         FT_BOOLEAN, BASE_NONE, TFS(&e_utra_tdd_support_vals), 0x00,
4282         NULL, HFILL}
4283     },
4284     { &hf_gsm_a_e_utra_meas_and_report_support,
4285         { "E-UTRA Measurement and Reporting support", "gsm_a.classmark3.e_utra_meas_and_report_support",
4286         FT_BOOLEAN, BASE_NONE, TFS(&e_utra_meas_and_report_support_vals), 0x00,
4287         NULL, HFILL}
4288     },
4289     { &hf_gsm_a_prio_based_resel_support,
4290         { "Priority-based reselection support", "gsm_a.classmark3.prio_based_resel_support",
4291         FT_BOOLEAN, BASE_NONE, TFS(&prio_based_resel_support_vals), 0x00,
4292         NULL, HFILL}
4293     },
4294     { &hf_gsm_a_utra_csg_cells_reporting,
4295         { "UTRA CSG Cells Reporting", "gsm_a.classmark3.utra_csg_cells_reporting",
4296         FT_BOOLEAN, BASE_NONE, TFS(&utra_csg_cells_reporting_vals), 0x00,
4297         NULL, HFILL}
4298     },
4299     { &hf_gsm_a_vamos_level,
4300         { "VAMOS Level", "gsm_a.classmark3.vamos_level",
4301         FT_UINT8, BASE_DEC, VALS(vamos_level_vals), 0x00,
4302         NULL, HFILL}
4303     },
4304     { &hf_gsm_a_tighter_cap,
4305         { "TIGHTER Capability", "gsm_a.classmark3.tighter_cap",
4306         FT_UINT8, BASE_DEC, VALS(tighter_cap_level_vals), 0x00,
4307         NULL, HFILL}
4308     },
4309     { &hf_gsm_a_selective_ciph_down_sacch,
4310         { "Selective Ciphering of Downlink SACCH", "gsm_a.classmark3.selective_ciph_down_sacch",
4311         FT_BOOLEAN, BASE_NONE, TFS(&tfs_supported_not_supported), 0x00,
4312         NULL, HFILL}
4313     },
4314     { &hf_gsm_a_cs_to_ps_srvcc_geran_to_utra,
4315         { "CS to PS SRVCC from GERAN to UTRA", "gsm_a.classmark3.cs_to_ps_srvcc_geran_to_utra",
4316         FT_UINT8, BASE_DEC, VALS(cs_to_ps_srvcc_geran_to_utra_vals), 0x00,
4317         NULL, HFILL}
4318     },
4319     { &hf_gsm_a_cs_to_ps_srvcc_geran_to_eutra,
4320         { "CS to PS SRVCC from GERAN to E-UTRA", "gsm_a.classmark3.cs_to_ps_srvcc_geran_to_eutra",
4321         FT_UINT8, BASE_DEC, VALS(cs_to_ps_srvcc_geran_to_eutra_vals), 0x00,
4322         NULL, HFILL}
4323     },
4324     { &hf_gsm_a_geran_network_sharing_support,
4325         { "GERAN Network Sharing support", "gsm_a.classmark3.ggeran_network_sharing_support",
4326         FT_BOOLEAN, BASE_NONE, TFS(&true_false_vals), 0x00,
4327         NULL, HFILL}
4328     },
4329     { &hf_gsm_a_geo_loc_type_of_shape,
4330         { "Location estimate", "gsm_a.gad.location_estimate",
4331         FT_UINT8, BASE_DEC, VALS(type_of_shape_vals), 0xf0,
4332         NULL, HFILL }
4333     },
4334     { &hf_gsm_a_geo_loc_sign_of_lat,
4335         { "Sign of latitude", "gsm_a.gad.sign_of_latitude",
4336         FT_UINT8, BASE_DEC, VALS(sign_of_latitude_vals), 0x80,
4337         NULL, HFILL }
4338     },
4339     { &hf_gsm_a_geo_loc_deg_of_lat,
4340         { "Degrees of latitude", "gsm_a.gad.deg_of_latitude",
4341         FT_UINT24, BASE_DEC, NULL, 0x7fffff,
4342         NULL, HFILL }
4343     },
4344     { &hf_gsm_a_geo_loc_deg_of_long,
4345         { "Degrees of longitude", "gsm_a.gad.deg_of_longitude",
4346         FT_INT24, BASE_DEC, NULL, 0x0,
4347         NULL, HFILL }
4348     },
4349     { &hf_gsm_a_geo_loc_uncertainty_code,
4350         { "Uncertainty code", "gsm_a.gad.uncertainty_code",
4351         FT_UINT8, BASE_DEC, NULL, 0x7f,
4352         NULL, HFILL }
4353     },
4354     { &hf_gsm_a_geo_loc_uncertainty_semi_major,
4355         { "Uncertainty semi-major", "gsm_a.gad.uncertainty_semi_major",
4356         FT_UINT8, BASE_DEC, NULL, 0x7f,
4357         NULL, HFILL }
4358     },
4359     { &hf_gsm_a_geo_loc_uncertainty_semi_minor,
4360         { "Uncertainty semi-minor", "gsm_a.gad.uncertainty_semi_minor",
4361         FT_UINT8, BASE_DEC, NULL, 0x7f,
4362         NULL, HFILL }
4363     },
4364     { &hf_gsm_a_geo_loc_orientation_of_major_axis,
4365         { "Orientation of major axis", "gsm_a.gad.orientation_of_major_axis",
4366         FT_UINT8, BASE_DEC, NULL, 0x0,
4367         NULL, HFILL }
4368     },
4369     { &hf_gsm_a_geo_loc_uncertainty_altitude,
4370         { "Uncertainty Altitude", "gsm_a.gad.uncertainty_altitude",
4371         FT_UINT8, BASE_DEC, NULL, 0x7f,
4372         NULL, HFILL }
4373     },
4374     { &hf_gsm_a_geo_loc_confidence,
4375         { "Confidence(%)", "gsm_a.gad.confidence",
4376         FT_UINT8, BASE_DEC, NULL, 0x7f,
4377         NULL, HFILL }
4378     },
4379     { &hf_gsm_a_geo_loc_no_of_points,
4380         { "Number of points", "gsm_a.gad.no_of_points",
4381         FT_UINT8, BASE_DEC, NULL, 0x0f,
4382         NULL, HFILL }
4383     },
4384     { &hf_gsm_a_velocity_type,
4385         { "Number of points", "gsm_a.gad.velocity_type",
4386         FT_UINT8, BASE_DEC, VALS(gsm_a_velocity_type_vals), 0xf0,
4387         NULL, HFILL }
4388     },
4389     { &hf_gsm_a_bearing,
4390         { "Bearing", "gsm_a.gad.bearing",
4391         FT_UINT16, BASE_DEC, NULL, 0x0,
4392         NULL, HFILL }
4393     },
4394     { &hf_gsm_a_horizontal_speed,
4395         { "Horizontal Speed", "gsm_a.gad.horizontal_velocity",
4396         FT_UINT16, BASE_DEC, NULL, 0x0,
4397         NULL, HFILL }
4398     },
4399     { &hf_gsm_a_vertical_speed,
4400         { "Vertical Speed", "gsm_a.gad.vertical_speed",
4401         FT_UINT8, BASE_DEC, NULL, 0x0,
4402         NULL, HFILL }
4403     },
4404     { &hf_gsm_a_uncertainty_speed,
4405         { "Uncertainty Speed", "gsm_a.gad.uncertainty_speed",
4406         FT_UINT8, BASE_DEC, NULL, 0x0,
4407         NULL, HFILL }
4408     },
4409     { &hf_gsm_a_h_uncertainty_speed,
4410         { "Horizontal Uncertainty Speed", "gsm_a.gad.v_uncertainty_speed",
4411         FT_UINT8, BASE_DEC, NULL, 0x0,
4412         NULL, HFILL }
4413     },
4414     { &hf_gsm_a_v_uncertainty_speed,
4415         { "Vertical Uncertainty Speed", "gsm_a.gad.h_uncertainty_speed",
4416         FT_UINT8, BASE_DEC, NULL, 0x0,
4417         NULL, HFILL }
4418     },
4419     { &hf_gsm_a_d,
4420         { "Direction of Vertical Speed", "gsm_a.gad.d",
4421           FT_BOOLEAN, 8, TFS(&gsm_a_dir_of_ver_speed_vals), 0x08,
4422         NULL, HFILL}
4423     },
4424     { &hf_gsm_a_geo_loc_D,
4425         { "D: Direction of Altitude", "gsm_a.gad.D",
4426         FT_UINT16, BASE_DEC, VALS(dir_of_alt_vals), 0x8000,
4427         NULL, HFILL }
4428     },
4429     { &hf_gsm_a_geo_loc_altitude,
4430         { "Altitude in meters", "gsm_a.gad.altitude",
4431         FT_UINT16, BASE_DEC, NULL, 0x7fff,
4432         NULL, HFILL }
4433     },
4434     { &hf_gsm_a_geo_loc_inner_radius,
4435         { "Inner radius", "gsm_a.gad.altitude",
4436         FT_UINT16, BASE_DEC, NULL, 0x0,
4437         NULL, HFILL }
4438     },
4439     { &hf_gsm_a_geo_loc_uncertainty_radius,
4440         { "Uncertainty radius", "gsm_a.gad.no_of_points",
4441         FT_UINT8, BASE_DEC, NULL, 0x7f,
4442         NULL, HFILL }
4443     },
4444     { &hf_gsm_a_geo_loc_offset_angle,
4445         { "Offset angle", "gsm_a.gad.offset_angle",
4446         FT_UINT8, BASE_DEC, NULL, 0x0,
4447         NULL, HFILL }
4448     },
4449     { &hf_gsm_a_geo_loc_included_angle,
4450         { "Included angle", "gsm_a.gad.included_angle",
4451         FT_UINT8, BASE_DEC, NULL, 0x0,
4452         NULL, HFILL }
4453     },
4454     { &hf_gsm_a_key_seq,
4455         { "key sequence", "gsm_a.key_seq",
4456         FT_UINT8, BASE_DEC, VALS(gsm_a_key_seq_vals), 0x00,
4457         NULL, HFILL }
4458     },
4459     { &hf_gsm_a_lac,
4460         { "Location Area Code (LAC)", "gsm_a.lac",
4461         FT_UINT16, BASE_HEX_DEC, NULL, 0x00,
4462         NULL, HFILL }
4463     },
4464     { &hf_gsm_a_spare_nibble,
4465         { "Spare Nibble", "gsm_a.spare",
4466         FT_UINT8, BASE_DEC_HEX, NULL, 0x00,
4467         NULL, HFILL }
4468     },
4469     };
4470
4471     /* Setup protocol subtree array */
4472 #define NUM_INDIVIDUAL_ELEMS    0
4473     static gint *ett[NUM_INDIVIDUAL_ELEMS +
4474             NUM_GSM_COMMON_ELEM];
4475
4476     static ei_register_info ei[] = {
4477         { &ei_gsm_a_extraneous_data, { "gsm_a.extraneous_data", PI_PROTOCOL, PI_NOTE, "Extraneous Data, dissector bug or later version spec(report to wireshark.org)", EXPFILL }},
4478     };
4479
4480     expert_module_t* expert_a_common;
4481
4482     last_offset = NUM_INDIVIDUAL_ELEMS;
4483
4484     for (i=0; i < NUM_GSM_COMMON_ELEM; i++, last_offset++)
4485     {
4486         ett_gsm_common_elem[i] = -1;
4487         ett[last_offset]       = &ett_gsm_common_elem[i];
4488     }
4489
4490     /* Register the protocol name and description */
4491
4492     proto_a_common =
4493     proto_register_protocol("GSM A-I/F COMMON", "GSM COMMON", "gsm_a");
4494
4495     proto_register_field_array(proto_a_common, hf, array_length(hf));
4496
4497     proto_register_subtree_array(ett, array_length(ett));
4498     expert_a_common = expert_register_protocol(proto_a_common);
4499     expert_register_field_array(expert_a_common, ei, array_length(ei));
4500
4501
4502     gsm_a_tap = register_tap("gsm_a");
4503 }
4504