Coverage Report

Created: 2026-08-14 06:45

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