Coverage Report

Created: 2025-08-04 07:15

/src/wireshark/epan/dissectors/packet-ansi_801.c
Line
Count
Source (jump to first uncovered line)
1
/* packet-ansi_801.c
2
 * Routines for ANSI IS-801 (Location Services (PLD)) dissection
3
 *
4
 *   Location Services (Position Determination Service)
5
 *      3GPP2 C.S0022-0 v1.0  IS-801
6
 *
7
 *   Location Services (Position Determination Service)
8
 *      3GPP2 C.S0022-0-1 v1.0  IS-801 Addendum
9
 *
10
 * Copyright 2004, Michael Lum <mlum [AT] telostech.com>
11
 * In association with Telos Technology Inc.
12
 * Copyright 2007, Michael Lum <michael.lum [AT] utstar.com>
13
 * In association with UTStarcom Inc.
14
 *
15
 * Wireshark - Network traffic analyzer
16
 * By Gerald Combs <gerald@wireshark.org>
17
 * Copyright 1998 Gerald Combs
18
 *
19
 * SPDX-License-Identifier: GPL-2.0-or-later
20
 */
21
22
#include "config.h"
23
24
#include <math.h>
25
26
#include <epan/packet.h>
27
#include <epan/expert.h>
28
#include <epan/tfs.h>
29
#include <epan/unit_strings.h>
30
#include <wsutil/array.h>
31
32
void proto_register_ansi_801(void);
33
void proto_reg_handoff_ansi_801(void);
34
35
static const char *ansi_proto_name = "ANSI IS-801 (Location Services (PLD))";
36
static const char *ansi_proto_name_short = "IS-801";
37
38
28
#define ANSI_801_FORWARD  0
39
28
#define ANSI_801_REVERSE  1
40
41
42
/* Initialize the subtree pointers */
43
static int ett_ansi_801;
44
static int ett_gps;
45
static int ett_loc;
46
47
/* Initialize the protocol and registered fields */
48
static int proto_ansi_801;
49
static int hf_ansi_801_for_req_type;
50
static int hf_ansi_801_for_rsp_type;
51
static int hf_ansi_801_rev_req_type;
52
static int hf_ansi_801_rev_rsp_type;
53
static int hf_ansi_801_for_sess_tag;
54
static int hf_ansi_801_rev_sess_tag;
55
static int hf_ansi_801_sess_tag;
56
57
static int hf_ansi_801_time_ref_cdma;
58
static int hf_ansi_801_lat;
59
static int hf_ansi_801_long;
60
static int hf_ansi_801_loc_uncrtnty_ang;
61
static int hf_ansi_801_loc_uncrtnty_a;
62
static int hf_ansi_801_loc_uncrtnty_p;
63
static int hf_ansi_801_fix_type;
64
static int hf_ansi_801_velocity_incl;
65
static int hf_ansi_801_velocity_hor;
66
static int hf_ansi_801_heading;
67
static int hf_ansi_801_velocity_ver;
68
static int hf_ansi_801_clock_incl;
69
static int hf_ansi_801_clock_bias;
70
static int hf_ansi_801_clock_drift;
71
static int hf_ansi_801_height_incl;
72
static int hf_ansi_801_height;
73
static int hf_ansi_801_loc_uncrtnty_v;
74
static int hf_ansi_801_reserved_bits;
75
76
static int hf_ansi_801_bad_sv_present;
77
static int hf_ansi_801_num_bad_sv;
78
static int hf_ansi_801_bad_sv_prn_num;
79
static int hf_ansi_801_dopp_req;
80
static int hf_ansi_801_add_dopp_req;
81
static int hf_ansi_801_code_ph_par_req;
82
static int hf_ansi_801_az_el_req;
83
84
static int hf_ansi_801_pref_resp_qual;
85
static int hf_ansi_801_num_fixes;
86
static int hf_ansi_801_t_betw_fixes;
87
static int hf_ansi_801_offset_req;
88
89
/* Generated from convert_proto_tree_add_text.pl */
90
static int hf_ansi_801_for_message_number_responsesF0;
91
static int hf_ansi_801_apdc_id;
92
static int hf_ansi_801_num_sv_p32;
93
static int hf_ansi_801_regulatory_services_indicator;
94
static int hf_ansi_801_session_source;
95
static int hf_ansi_801_reserved8_E0;
96
static int hf_ansi_801_action_time;
97
static int hf_ansi_801_rev_message_number_responsesF0;
98
static int hf_ansi_801_reserved24_3;
99
static int hf_ansi_801_cancellation_type;
100
static int hf_ansi_801_gps_navigation_message_bits;
101
static int hf_ansi_801_num_dr_p;
102
static int hf_ansi_801_rev_message_number_requests8;
103
static int hf_ansi_801_reserved8_F0;
104
static int hf_ansi_801_for_req_loc_clock_correction_for_gps_time;
105
static int hf_ansi_801_for_response_length;
106
static int hf_ansi_801_session_end;
107
static int hf_ansi_801_reserved8_1F;
108
static int hf_ansi_801_part_num;
109
static int hf_ansi_801_dr_size;
110
static int hf_ansi_801_reserved_24_700;
111
static int hf_ansi_801_for_message_number_responses0F;
112
static int hf_ansi_801_rev_message_number_requests16;
113
static int hf_ansi_801_lcc_capable_using_location_assistance_spherical;
114
static int hf_ansi_801_part_num32;
115
static int hf_ansi_801_part_num16;
116
static int hf_ansi_801_reserved8_07;
117
static int hf_ansi_801_reserved24_1;
118
static int hf_ansi_801_reserved_24_F80000;
119
static int hf_ansi_801_extended_base_station_almanac;
120
static int hf_ansi_801_no_outstanding_request_element;
121
static int hf_ansi_801_for_request_length;
122
static int hf_ansi_801_week_num;
123
static int hf_ansi_801_total_parts16;
124
static int hf_ansi_801_pd_message_type;
125
static int hf_ansi_801_total_parts32;
126
static int hf_ansi_801_alpha_and_beta_parameters;
127
static int hf_ansi_801_lcc_using_gps_ephemeris_assistance;
128
static int hf_ansi_801_rev_request_length;
129
static int hf_ansi_801_reserved8_7F;
130
static int hf_ansi_801_unsolicited_response_indicator;
131
static int hf_ansi_801_autonomous_location_calculation_capable;
132
static int hf_ansi_801_gps_almanac_correction;
133
static int hf_ansi_801_total_parts;
134
static int hf_ansi_801_session_start;
135
static int hf_ansi_801_ref_bit_num;
136
static int hf_ansi_801_aflt_lcc;
137
static int hf_ansi_801_reject_reason;
138
static int hf_ansi_801_gps_ephemeris;
139
static int hf_ansi_801_pre_programmed_location;
140
static int hf_ansi_801_rev_response_length;
141
static int hf_ansi_801_afltc_id;
142
static int hf_ansi_801_rev_req_loc_height_information;
143
static int hf_ansi_801_reserved8_01;
144
static int hf_ansi_801_pilot_ph_cap;
145
static int hf_ansi_801_gps_acquisition_assistance;
146
static int hf_ansi_801_coordinate_type_requested;
147
static int hf_ansi_801_gps_almanac;
148
static int hf_ansi_801_rev_req_loc_velocity_information;
149
static int hf_ansi_801_gps_autonomous_acquisition_capable;
150
static int hf_ansi_801_num_sv_p16;
151
static int hf_ansi_801_mob_sys_t_offset;
152
static int hf_ansi_801_desired_pilot_phase_resolution;
153
static int hf_ansi_801_for_req_loc_velocity_information;
154
static int hf_ansi_801_reserved8_0F;
155
static int hf_ansi_801_hybrid_gps_and_aflt_lcc;
156
static int hf_ansi_801_gps_acq_cap;
157
static int hf_ansi_801_gps_sensitivity_assistance;
158
static int hf_ansi_801_ms_ls_rev;
159
static int hf_ansi_801_reject_request_type;
160
static int hf_ansi_801_ms_mode;
161
static int hf_ansi_801_bs_ls_rev;
162
static int hf_ansi_801_ref_pn;
163
static int hf_ansi_801_rev_message_number_responses0F;
164
static int hf_ansi_801_for_req_loc_height_information;
165
static int hf_ansi_801_gps_capability_indicator;
166
static int hf_ansi_801_rev_req_loc_clock_correction_for_gps_time;
167
static int hf_ansi_801_data_records;
168
static int hf_ansi_801_for_message_number_requests8;
169
static int hf_ansi_801_subframes_4_and_5;
170
static int hf_ansi_801_use_action_time_indicator;
171
static int hf_ansi_801_lcc_using_gps_almanac_assistance;
172
static int hf_ansi_801_lcc_using_gps_almanac_correction;
173
static int hf_ansi_801_pd_message_len;
174
static int hf_ansi_801_lcc_using_location_assistance_cartesian;
175
static int hf_ansi_801_for_message_number_requests16;
176
static int hf_ansi_801_reserved_24_7;
177
static int hf_ansi_801_loc_calc_cap;
178
static int hf_ansi_801_toa;
179
static int hf_ansi_801_data;
180
static int hf_ansi_801_proprietary_data;
181
static int hf_ansi_801_time_ref_ms;
182
static int hf_ansi_801_time_of_almanac;
183
static int hf_ansi_801_gps_week_number;
184
185
186
static expert_field ei_ansi_801_extraneous_data;
187
static expert_field ei_ansi_801_short_data;
188
static expert_field ei_ansi_801_unexpected_length;
189
190
191
static dissector_handle_t ansi_801_handle;
192
193
/* PARAM FUNCTIONS */
194
195
#define EXTRANEOUS_DATA_CHECK(edc_len, edc_max_len)     \
196
0
  if ((edc_len) > (edc_max_len))         \
197
0
  {               \
198
0
    proto_tree_add_expert(tree, pinfo, &ei_ansi_801_extraneous_data, tvb, \
199
0
            offset, (edc_len) - (edc_max_len)); \
200
0
  }
201
202
#define SHORT_DATA_CHECK(sdc_len, sdc_min_len)        \
203
0
  if ((sdc_len) < (sdc_min_len))         \
204
0
  {               \
205
0
    proto_tree_add_expert(tree, pinfo, &ei_ansi_801_short_data, tvb,  \
206
0
            offset, (sdc_len)); \
207
0
    return;             \
208
0
  }
209
210
#define EXACT_DATA_CHECK(edc_len, edc_eq_len)       \
211
  if ((edc_len) != (edc_eq_len))          \
212
  {               \
213
    proto_tree_add_expert(tree, pinfo, &ei_ansi_801_unexpected_length, tvb, \
214
            offset, (edc_len)); \
215
    return;             \
216
  }
217
218
219
/*
220
 * Table 3.2-4 for PD_MSG_TYPE = '0000000'
221
 */
222
static const value_string for_req_type_strings[] = {
223
  { 0,  "Reserved" },
224
  { 1,  "Request Location Response" },
225
  { 2,  "Request MS Information" },
226
  { 3,  "Request Autonomous Measurement Weighting Factors" },
227
  { 4,  "Request Pseudorange Measurement" },
228
  { 5,  "Request Pilot Phase Measurement" },
229
  { 6,  "Request Time Offset Measurement" },
230
  { 7,  "Request Cancellation" },
231
  { 0, NULL },
232
};
233
140
#define NUM_FOR_REQ_TYPE array_length(for_req_type_strings)
234
static int ett_for_req_type[NUM_FOR_REQ_TYPE];
235
236
static const value_string for_rsp_type_strings[] = {
237
  { 0,  "Reject" },
238
  { 2,  "Provide BS Capabilities" },
239
  { 4,  "Provide GPS Acquisition Assistance" },
240
  { 6,  "Provide GPS Location Assistance Spherical Coordinates" },
241
  { 7,  "Provide GPS Location Assistance Cartesian Coordinates" },
242
  { 5,  "Provide GPS Sensitivity Assistance" },
243
  { 3,  "Provide Base Station Almanac" },
244
  { 8,  "Provide GPS Almanac" },
245
  { 9,  "Provide GPS Ephemeris" },
246
  { 10, "Provide GPS Navigation Message Bits" },
247
  { 1,  "Provide Location Response" },
248
  { 11, "Provide GPS Almanac Correction" },
249
  { 12, "Provide GPS Satellite Health Information" },
250
  { 0, NULL },
251
};
252
210
#define NUM_FOR_RSP_TYPE array_length(for_rsp_type_strings)
253
static int ett_for_rsp_type[NUM_FOR_RSP_TYPE];
254
255
256
static const value_string rev_rsp_type_strings[] = {
257
  { 0,  "Reject" },
258
  { 2,  "Provide MS Information" },
259
  { 3,  "Provide Autonomous Measurement Weighting Factors" },
260
  { 4,  "Provide Pseudorange Measurement" },
261
  { 5,  "Provide Pilot Phase Measurement" },
262
  { 1,  "Provide Location Response" },
263
  { 6,  "Provide Time Offset Measurement" },
264
  { 7,  "Provide Cancellation Acknowledgement" },
265
  { 0, NULL },
266
};
267
140
#define NUM_REV_RSP_TYPE array_length(rev_rsp_type_strings)
268
static int ett_rev_rsp_type[NUM_REV_RSP_TYPE];
269
270
/*
271
 * Table 2.2-5 for PD_MSG_TYPE = '0000000'
272
 */
273
static const value_string rev_req_type_strings[] = {
274
  { 0,  "Reserved" },
275
  { 2,  "Request BS Capabilities" },
276
  { 4,  "Request GPS Acquisition Assistance" },
277
  { 6,  "Request GPS Location Assistance" },
278
  { 7,  "Reserved" },
279
  { 5,  "Request GPS Sensitivity Assistance" },
280
  { 3,  "Request Base Station Almanac" },
281
  { 8,  "Request GPS Almanac" },
282
  { 9,  "Request GPS Ephemeris" },
283
  { 10, "Request GPS Navigation Message Bits" },
284
  { 1,  "Request Location Response" },
285
  { 11, "Request GPS Almanac Correction" },
286
  { 12, "Request GPS Satellite Health Information" },
287
  { 0, NULL },
288
};
289
210
#define NUM_REV_REQ_TYPE array_length(rev_req_type_strings)
290
static int ett_rev_req_type[NUM_REV_REQ_TYPE];
291
292
static const value_string regulatory_services_indicator_vals[] = {
293
  { 0,  "No Regulatory service" },
294
  { 1,  "Emergency service" },
295
  { 2,  "Reserved" },
296
  { 3,  "Reserved" },
297
  { 0, NULL },
298
};
299
300
static const true_false_string tfs_desired_pilot_phase_resolution = { "at least 1/8th PN chip resolution", "at least 1 PN chip resolution" };
301
static const true_false_string tfs_spherical_cartesian = { "Spherical", "Cartesian" };
302
303
static const unit_name_string units_time_of_almanac = { " (in units of 4096 seconds)", NULL };
304
static const unit_name_string units_gps_week_number = { " (8 least significant bits)", NULL };
305
306
static void
307
for_req_pseudo_meas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset)
308
0
{
309
0
  uint32_t  saved_offset = offset;
310
311
0
  SHORT_DATA_CHECK(len, 3);
312
313
  /* PREF_RESP_QUAL */
314
0
  proto_tree_add_item(tree, hf_ansi_801_pref_resp_qual, tvb, offset, 3, ENC_BIG_ENDIAN);
315
0
  proto_tree_add_item(tree, hf_ansi_801_num_fixes, tvb, offset, 3, ENC_BIG_ENDIAN);
316
0
  proto_tree_add_item(tree, hf_ansi_801_t_betw_fixes, tvb, offset, 3, ENC_BIG_ENDIAN);
317
0
  proto_tree_add_item(tree, hf_ansi_801_offset_req, tvb, offset, 3, ENC_BIG_ENDIAN);
318
0
  proto_tree_add_item(tree, hf_ansi_801_reserved_24_7, tvb, offset, 3, ENC_BIG_ENDIAN);
319
0
  offset += 3;
320
321
0
  EXTRANEOUS_DATA_CHECK(len, offset - saved_offset);
322
323
0
}
324
325
static void
326
for_req_pilot_ph_meas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset)
327
0
{
328
0
  uint32_t  saved_offset;
329
330
0
  SHORT_DATA_CHECK(len, 3);
331
332
0
  saved_offset = offset;
333
334
0
  proto_tree_add_item(tree, hf_ansi_801_pref_resp_qual, tvb, offset, 3, ENC_BIG_ENDIAN);
335
0
  proto_tree_add_item(tree, hf_ansi_801_num_fixes, tvb, offset, 3, ENC_BIG_ENDIAN);
336
0
  proto_tree_add_item(tree, hf_ansi_801_t_betw_fixes, tvb, offset, 3, ENC_BIG_ENDIAN);
337
0
  proto_tree_add_item(tree, hf_ansi_801_offset_req, tvb, offset, 3, ENC_BIG_ENDIAN);
338
0
  proto_tree_add_item(tree, hf_ansi_801_desired_pilot_phase_resolution, tvb, offset, 3, ENC_BIG_ENDIAN);
339
0
  proto_tree_add_item(tree, hf_ansi_801_reserved_24_7, tvb, offset, 3, ENC_BIG_ENDIAN);
340
0
  offset += 3;
341
342
0
  EXTRANEOUS_DATA_CHECK(len, offset - saved_offset);
343
0
}
344
345
static void
346
for_req_loc_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset)
347
0
{
348
0
  uint32_t  saved_offset;
349
350
0
  SHORT_DATA_CHECK(len, 3);
351
352
0
  saved_offset = offset;
353
354
0
  proto_tree_add_item(tree, hf_ansi_801_pref_resp_qual, tvb, offset, 3, ENC_BIG_ENDIAN);
355
0
  proto_tree_add_item(tree, hf_ansi_801_num_fixes, tvb, offset, 3, ENC_BIG_ENDIAN);
356
0
  proto_tree_add_item(tree, hf_ansi_801_t_betw_fixes, tvb, offset, 3, ENC_BIG_ENDIAN);
357
0
  proto_tree_add_item(tree, hf_ansi_801_for_req_loc_height_information, tvb, offset, 3, ENC_BIG_ENDIAN);
358
0
  proto_tree_add_item(tree, hf_ansi_801_for_req_loc_clock_correction_for_gps_time, tvb, offset, 3, ENC_BIG_ENDIAN);
359
0
  proto_tree_add_item(tree, hf_ansi_801_for_req_loc_velocity_information, tvb, offset, 3, ENC_BIG_ENDIAN);
360
0
  proto_tree_add_item(tree, hf_ansi_801_reserved24_3, tvb, offset, 3, ENC_BIG_ENDIAN);
361
0
  offset += 3;
362
363
0
  EXTRANEOUS_DATA_CHECK(len, offset - saved_offset);
364
0
}
365
366
static void
367
for_req_time_off_meas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset)
368
0
{
369
0
  uint8_t oct;
370
0
  uint32_t  saved_offset;
371
372
0
  SHORT_DATA_CHECK(len, 1);
373
374
0
  saved_offset = offset;
375
376
0
  oct = tvb_get_uint8(tvb, offset);
377
378
0
  proto_tree_add_item(tree, hf_ansi_801_use_action_time_indicator, tvb, offset, 1, ENC_NA);
379
380
0
  if (oct & 0x80)
381
0
  {
382
0
    proto_tree_add_item(tree, hf_ansi_801_action_time, tvb, offset, 1, ENC_BIG_ENDIAN);
383
0
    proto_tree_add_item(tree, hf_ansi_801_reserved8_01, tvb, offset, 1, ENC_BIG_ENDIAN);
384
0
  }
385
0
  else
386
0
  {
387
0
    proto_tree_add_item(tree, hf_ansi_801_reserved8_7F, tvb, offset, 1, ENC_BIG_ENDIAN);
388
0
  }
389
0
  offset++;
390
391
0
  EXTRANEOUS_DATA_CHECK(len, offset - saved_offset);
392
0
}
393
394
static void
395
for_req_cancel(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset)
396
0
{
397
0
  uint8_t      oct;
398
0
  uint32_t     saved_offset;
399
0
  const char *str = NULL;
400
401
0
  SHORT_DATA_CHECK(len, 1);
402
403
0
  saved_offset = offset;
404
405
0
  oct = tvb_get_uint8(tvb, offset);
406
407
0
  str = val_to_str_const((oct & 0xf0) >> 4, for_req_type_strings, "Reserved");
408
0
  proto_tree_add_uint_format_value(tree, hf_ansi_801_cancellation_type, tvb, offset, 1,
409
0
          oct, "(%u) %s", (oct & 0xf0) >> 4, str);
410
411
0
  proto_tree_add_item(tree, hf_ansi_801_reserved8_0F, tvb, offset, 1, ENC_BIG_ENDIAN);
412
0
  offset++;
413
414
0
  EXTRANEOUS_DATA_CHECK(len, offset - saved_offset);
415
0
}
416
417
static void
418
for_reject(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset)
419
0
{
420
0
  uint8_t      oct;
421
0
  uint32_t     saved_offset;
422
0
  const char *str = NULL;
423
424
0
  saved_offset = offset;
425
426
0
  SHORT_DATA_CHECK(len, 1);
427
428
0
  oct = tvb_get_uint8(tvb, offset);
429
0
  str = val_to_str_const((oct & 0xf0) >> 4, rev_req_type_strings, "Reserved");
430
431
0
  proto_tree_add_uint_format_value(tree, hf_ansi_801_reject_request_type, tvb, offset, 1, oct,
432
0
          "(%u) %s", (oct & 0xf0) >> 4, str);
433
434
0
  switch ((oct & 0x0e) >> 1)
435
0
  {
436
0
  case 0x00: str = "Capability not supported by the base station"; break;
437
0
  case 0x01: str = "Capability normally supported by the base station but temporarily not available or not enabled"; break;
438
0
  default: str = "Reserved"; break;
439
0
  }
440
441
0
  proto_tree_add_uint_format_value(tree, hf_ansi_801_reject_reason, tvb, offset, 1, oct, "%s", str);
442
0
  proto_tree_add_item(tree, hf_ansi_801_reserved8_01, tvb, offset, 1, ENC_BIG_ENDIAN);
443
0
  offset++;
444
445
0
  EXTRANEOUS_DATA_CHECK(len, offset - saved_offset);
446
0
}
447
448
static void
449
for_pr_bs_cap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset)
450
0
{
451
0
  uint8_t oct;
452
0
  uint32_t  saved_offset;
453
454
0
  saved_offset = offset;
455
456
0
  SHORT_DATA_CHECK(len, 2);
457
458
0
  proto_tree_add_item(tree, hf_ansi_801_bs_ls_rev, tvb, offset, 1, ENC_BIG_ENDIAN);
459
0
  proto_tree_add_item(tree, hf_ansi_801_gps_capability_indicator, tvb, offset, 1, ENC_BIG_ENDIAN);
460
0
  proto_tree_add_item(tree, hf_ansi_801_afltc_id, tvb, offset, 1, ENC_BIG_ENDIAN);
461
0
  offset++;
462
463
0
  oct = tvb_get_uint8(tvb, offset);
464
0
  if (oct == 0x00)
465
0
  {
466
0
    proto_tree_add_uint_format(tree, hf_ansi_801_apdc_id, tvb, offset, 1, 0,
467
0
            "APDC_ID: Autonomous position determination capability indicator: None");
468
0
  }
469
0
  else
470
0
  {
471
0
    proto_tree_add_item(tree, hf_ansi_801_apdc_id, tvb, offset, 1, ENC_BIG_ENDIAN);
472
0
  }
473
474
0
  offset++;
475
476
0
  EXTRANEOUS_DATA_CHECK(len, offset - saved_offset);
477
0
}
478
479
static void
480
for_pr_gps_sense_ass(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset)
481
0
{
482
0
  uint32_t  saved_offset;
483
484
0
  saved_offset = offset;
485
486
0
  SHORT_DATA_CHECK(len, 4);
487
488
0
  proto_tree_add_item(tree, hf_ansi_801_ref_bit_num, tvb, offset, 2, ENC_BIG_ENDIAN);
489
0
  proto_tree_add_item(tree, hf_ansi_801_num_dr_p, tvb, offset, 2, ENC_BIG_ENDIAN);
490
0
  offset += 2;
491
492
0
  proto_tree_add_item(tree, hf_ansi_801_dr_size, tvb, offset, 3, ENC_BIG_ENDIAN);
493
0
  offset++;
494
495
0
  proto_tree_add_item(tree, hf_ansi_801_part_num, tvb, offset, 2, ENC_BIG_ENDIAN);
496
0
  proto_tree_add_item(tree, hf_ansi_801_total_parts, tvb, offset, 2, ENC_BIG_ENDIAN);
497
0
  proto_tree_add_item(tree, hf_ansi_801_data_records, tvb, offset, 2, ENC_BIG_ENDIAN);
498
0
  offset++;
499
500
0
  EXTRANEOUS_DATA_CHECK(len, offset - saved_offset);
501
0
}
502
503
static void
504
for_pr_gps_almanac(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset)
505
0
{
506
0
  uint32_t  saved_offset = offset;
507
0
  int * const fields[] = {
508
0
    &hf_ansi_801_num_sv_p32,
509
0
    &hf_ansi_801_week_num,
510
0
    &hf_ansi_801_toa,
511
0
    &hf_ansi_801_part_num32,
512
0
    &hf_ansi_801_total_parts32,
513
0
    NULL
514
0
  };
515
516
0
  SHORT_DATA_CHECK(len, 4);
517
518
0
    proto_tree_add_bitmask_list(tree, tvb, offset, 4, fields, ENC_BIG_ENDIAN);
519
0
  offset += 4;
520
521
0
  EXTRANEOUS_DATA_CHECK(len, offset - saved_offset);
522
0
}
523
524
static void
525
for_pr_gps_nav_msg_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset)
526
0
{
527
0
  uint32_t  saved_offset = offset;
528
0
  int * const fields[] = {
529
0
    &hf_ansi_801_num_sv_p16,
530
0
    &hf_ansi_801_part_num16,
531
0
    &hf_ansi_801_total_parts16,
532
0
    NULL
533
0
  };
534
535
0
  SHORT_DATA_CHECK(len, 2);
536
537
0
    proto_tree_add_bitmask_list(tree, tvb, offset, 2, fields, ENC_BIG_ENDIAN);
538
0
  offset += 2;
539
540
0
  EXTRANEOUS_DATA_CHECK(len, offset - saved_offset);
541
0
}
542
543
/*
544
 * shared for both forward/reverse directions
545
 */
546
static const true_false_string ansi_801_fix_type_vals = {
547
  "3D",
548
  "2D"
549
};
550
551
static void
552
pr_loc_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset)
553
0
{
554
0
  uint32_t     bit_offset, spare_bits;
555
0
  uint32_t     value;
556
0
  float        fl_value;
557
0
  uint32_t     saved_offset;
558
0
  uint64_t     fix_type, velocity_incl, clock_incl, height_incl;
559
0
  const char *str = NULL;
560
561
0
  SHORT_DATA_CHECK(len, 11);
562
0
  saved_offset = offset;
563
0
  bit_offset   = offset << 3;
564
565
  /* TIME_REF_CDMA */
566
0
  value = tvb_get_bits16(tvb, bit_offset, 14, ENC_BIG_ENDIAN);
567
0
  proto_tree_add_uint_bits_format_value(tree, hf_ansi_801_time_ref_cdma, tvb, bit_offset, 14, value * 50,
568
0
                ENC_BIG_ENDIAN, "%u frames (0x%04x)", value * 50, value);
569
0
  bit_offset += 14;
570
571
  /* LAT */
572
0
  value = tvb_get_bits32(tvb, bit_offset, 25, ENC_BIG_ENDIAN);
573
0
  fl_value = (float)(-90.0 + ((float)value * 180 / 33554432));
574
0
  proto_tree_add_float_bits_format_value(tree, hf_ansi_801_lat, tvb, bit_offset, 25, fl_value, ENC_BIG_ENDIAN,
575
0
                 "%.5f degrees %s (0x%08x)", fabs(fl_value), fl_value < 0 ? "South" : "North", value);
576
0
  bit_offset += 25;
577
578
  /* LONG */
579
0
  value    = tvb_get_bits32(tvb, bit_offset, 26, ENC_BIG_ENDIAN);
580
0
  fl_value = (float)(-180.0 + ((float)value * 180 / 33554432));
581
0
  proto_tree_add_float_bits_format_value(tree, hf_ansi_801_long, tvb, bit_offset, 26, fl_value, ENC_BIG_ENDIAN,
582
0
                 "%.5f degrees %s (0x%08x)", fabs(fl_value), fl_value < 0 ? "West" : "East", value);
583
0
  bit_offset += 26;
584
585
  /* LOC_UNCRTNTY_ANG */
586
0
  value    = tvb_get_bits8(tvb, bit_offset, 4);
587
0
  fl_value = (float)(5.625 * value);
588
0
  proto_tree_add_float_bits_format_value(tree, hf_ansi_801_loc_uncrtnty_ang, tvb, bit_offset, 4, fl_value,
589
0
                 ENC_BIG_ENDIAN, "%.5f degrees (0x%02x)", fl_value, value);
590
0
  bit_offset += 4;
591
592
  /* LOC_UNCRTNTY_A */
593
0
  value = tvb_get_bits8(tvb, bit_offset, 5);
594
0
  switch (value)
595
0
  {
596
0
  case 0x1e: str = "> 12288.00 meters"; break;
597
0
  case 0x1f: str = "Not computable"; break;
598
0
  default:
599
0
    fl_value = (float)(0.5f * (1 << (value >> 1)));
600
0
    if (value & 0x01)
601
0
      fl_value *= 1.5f;
602
0
    str = wmem_strdup_printf(pinfo->pool, "%.2f meters", fl_value);
603
0
  }
604
0
  proto_tree_add_uint_bits_format_value(tree, hf_ansi_801_loc_uncrtnty_a, tvb, bit_offset, 5, value,
605
0
                ENC_BIG_ENDIAN, "%s (0x%02x)", str, value);
606
0
  bit_offset += 5;
607
608
  /* LOC_UNCRTNTY_P */
609
0
  value = tvb_get_bits8(tvb, bit_offset, 5);
610
0
  switch (value)
611
0
  {
612
0
  case 0x1e: str = "> 12288.00 meters"; break;
613
0
  case 0x1f: str = "Not computable"; break;
614
0
  default:
615
0
    fl_value = (float)(0.5f * (1 << (value >> 1)));
616
0
    if (value & 0x01)
617
0
      fl_value *= 1.5f;
618
0
    str = wmem_strdup_printf(pinfo->pool, "%.2f meters", fl_value);
619
0
  }
620
0
  proto_tree_add_uint_bits_format_value(tree, hf_ansi_801_loc_uncrtnty_p, tvb, bit_offset, 5, value,
621
0
                ENC_BIG_ENDIAN, "%s (0x%02x)", str, value);
622
0
  bit_offset += 5;
623
624
  /* FIX_TYPE */
625
0
  proto_tree_add_bits_ret_val(tree, hf_ansi_801_fix_type, tvb, bit_offset++, 1, &fix_type, ENC_BIG_ENDIAN);
626
627
  /* VELOCITY_INCL */
628
0
  proto_tree_add_bits_ret_val(tree, hf_ansi_801_velocity_incl, tvb, bit_offset++, 1, &velocity_incl, ENC_BIG_ENDIAN);
629
630
631
0
  if(velocity_incl)
632
0
  {
633
    /* VELOCITY_HOR */
634
0
    value = tvb_get_bits16(tvb, bit_offset, 9, ENC_BIG_ENDIAN);
635
0
    fl_value = (float)(0.25 * value);
636
0
    proto_tree_add_float_bits_format_value(tree, hf_ansi_801_velocity_hor, tvb, bit_offset, 9, fl_value,
637
0
                   ENC_BIG_ENDIAN, "%.2f m/s (0x%04x)", fl_value, value);
638
0
    bit_offset += 9;
639
640
    /* HEADING */
641
0
    value = tvb_get_bits16(tvb, bit_offset, 10, ENC_BIG_ENDIAN);
642
0
    fl_value = (float)value * 360 / 1024;
643
0
    proto_tree_add_float_bits_format_value(tree, hf_ansi_801_heading, tvb, bit_offset, 10, fl_value,
644
0
                   ENC_BIG_ENDIAN, "%.3f degrees (0x%04x)", fl_value, value);
645
0
    bit_offset += 10;
646
647
0
    if(fix_type)
648
0
    {
649
      /* VELOCITY_VER */
650
0
      value = tvb_get_bits8(tvb, bit_offset, 8);
651
0
      fl_value = (float)(-64 + 0.5 * value);
652
0
      proto_tree_add_float_bits_format_value(tree, hf_ansi_801_velocity_ver, tvb, bit_offset, 8, fl_value,
653
0
                     ENC_BIG_ENDIAN, "%.1f m/s (0x%02x)", fl_value, value);
654
0
      bit_offset += 8;
655
0
    }
656
0
  }
657
658
  /* CLOCK_INCL */
659
0
  proto_tree_add_bits_ret_val(tree, hf_ansi_801_clock_incl, tvb, bit_offset++, 1, &clock_incl, ENC_BIG_ENDIAN);
660
661
0
  if(clock_incl)
662
0
  {
663
    /* CLOCK_BIAS */
664
0
    value = tvb_get_bits32(tvb, bit_offset, 18, ENC_BIG_ENDIAN);
665
0
    proto_tree_add_int_bits_format_value(tree, hf_ansi_801_clock_bias, tvb, bit_offset, 18, (int32_t)value - 13000,
666
0
                 ENC_BIG_ENDIAN, "%d ns (0x%06x)", (int32_t)value - 13000, value);
667
0
    bit_offset += 18;
668
669
    /* CLOCK_DRIFT */
670
0
    value = tvb_get_bits16(tvb, bit_offset, 16, ENC_BIG_ENDIAN);
671
0
    proto_tree_add_int_bits_format_value(tree, hf_ansi_801_clock_drift, tvb, bit_offset, 16, (int16_t)value,
672
0
                 ENC_BIG_ENDIAN, "%d ppb (ns/s) (0x%04x)", (int16_t)value, value);
673
0
    bit_offset += 16;
674
0
  }
675
676
  /* HEIGHT_INCL */
677
0
  proto_tree_add_bits_ret_val(tree, hf_ansi_801_height_incl, tvb, bit_offset++, 1, &height_incl, ENC_BIG_ENDIAN);
678
679
0
  if(height_incl)
680
0
  {
681
    /* HEIGHT */
682
0
    value = tvb_get_bits16(tvb, bit_offset, 14, ENC_BIG_ENDIAN);
683
0
    proto_tree_add_int_bits_format_value(tree, hf_ansi_801_height, tvb, bit_offset, 14, (int32_t)value - 500,
684
0
                 ENC_BIG_ENDIAN, "%d m (0x%04x)", (int32_t)value - 500, value);
685
0
    bit_offset += 14;
686
687
    /* LOC_UNCRTNTY_V */
688
0
    value = tvb_get_bits8(tvb, bit_offset, 5);
689
0
    switch (value)
690
0
    {
691
0
    case 0x1e: str = "> 12288.00 meters"; break;
692
0
    case 0x1f: str = "Not computable"; break;
693
0
    default:
694
0
      fl_value = (float)(0.5f * (1 << (value >> 1)));
695
0
      if (value & 0x01)
696
0
        fl_value *= 1.5f;
697
0
      str = wmem_strdup_printf(pinfo->pool, "%.2f meters", fl_value);
698
0
    }
699
0
    proto_tree_add_uint_bits_format_value(tree, hf_ansi_801_loc_uncrtnty_v, tvb, bit_offset, 5, value,
700
0
                  ENC_BIG_ENDIAN, "%s (0x%02x)", str, value);
701
0
    bit_offset += 5;
702
0
  }
703
704
0
  if(bit_offset & 0x07)
705
0
  {
706
0
    spare_bits = 8 - (bit_offset & 0x07);
707
0
    proto_tree_add_bits_item(tree, hf_ansi_801_reserved_bits, tvb, bit_offset, spare_bits, ENC_BIG_ENDIAN);
708
0
    bit_offset += spare_bits;
709
0
  }
710
711
0
  offset = bit_offset >> 3;
712
713
0
  EXTRANEOUS_DATA_CHECK(len, offset - saved_offset);
714
0
}
715
716
static void
717
for_pr_loc_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset)
718
0
{
719
0
  pr_loc_response(tvb, pinfo, tree, len, offset);
720
0
}
721
722
static void
723
for_pr_gps_sat_health(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset)
724
0
{
725
0
  uint32_t  bit_offset, spare_bits;
726
0
  uint32_t  i;
727
0
  uint32_t  saved_offset, num_bad_sv, bad_sv_prn_num;
728
0
  uint64_t  bad_sv_present;
729
730
0
  SHORT_DATA_CHECK(len, 1);
731
0
  saved_offset = offset;
732
0
  bit_offset   = offset << 3;
733
734
  /* BAD_SV_PRESENT */
735
0
  proto_tree_add_bits_ret_val(tree, hf_ansi_801_bad_sv_present, tvb, bit_offset++, 1, &bad_sv_present, ENC_BIG_ENDIAN);
736
737
0
  if (bad_sv_present)
738
0
  {
739
    /* NUM_BAD_SV */
740
0
    num_bad_sv = tvb_get_bits8(tvb, bit_offset, 4) + 1;
741
0
    proto_tree_add_uint_bits_format_value(tree, hf_ansi_801_num_bad_sv, tvb, bit_offset, 4, num_bad_sv,
742
0
                  ENC_BIG_ENDIAN, "%u", num_bad_sv);
743
0
    bit_offset += 4;
744
745
0
    for (i=0; i < num_bad_sv; i++)
746
0
    {
747
      /* BAD_SV_PRN_NUM */
748
0
      bad_sv_prn_num = tvb_get_bits8(tvb, bit_offset, 5) + 1;
749
0
      proto_tree_add_uint_bits_format_value(tree, hf_ansi_801_bad_sv_prn_num, tvb, bit_offset, 5, bad_sv_prn_num,
750
0
                    ENC_BIG_ENDIAN, "%u", bad_sv_prn_num);
751
0
      bit_offset += 5;
752
0
    }
753
0
  }
754
755
0
  if(bit_offset & 0x07)
756
0
  {
757
0
    spare_bits = 8 - (bit_offset & 0x07);
758
0
    proto_tree_add_bits_item(tree, hf_ansi_801_reserved_bits, tvb, bit_offset, spare_bits, ENC_BIG_ENDIAN);
759
0
    bit_offset += spare_bits;
760
0
  }
761
762
0
  offset = bit_offset >> 3;
763
764
0
  EXTRANEOUS_DATA_CHECK(len, offset - saved_offset);
765
0
}
766
767
static void
768
rev_req_gps_acq_ass(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset)
769
0
{
770
0
  uint32_t  saved_offset;
771
0
  uint32_t  bit_offset;
772
773
0
  SHORT_DATA_CHECK(len, 1);
774
0
  saved_offset = offset;
775
0
  bit_offset   = offset << 3;
776
777
0
  proto_tree_add_bits_item(tree, hf_ansi_801_dopp_req, tvb, bit_offset++, 1, ENC_BIG_ENDIAN);
778
0
  proto_tree_add_bits_item(tree, hf_ansi_801_add_dopp_req, tvb, bit_offset++, 1, ENC_BIG_ENDIAN);
779
0
  proto_tree_add_bits_item(tree, hf_ansi_801_code_ph_par_req, tvb, bit_offset++, 1, ENC_BIG_ENDIAN);
780
0
  proto_tree_add_bits_item(tree, hf_ansi_801_az_el_req, tvb, bit_offset++, 1, ENC_BIG_ENDIAN);
781
0
  proto_tree_add_bits_item(tree, hf_ansi_801_reserved_bits, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
782
0
  offset++;
783
784
0
  EXTRANEOUS_DATA_CHECK(len, offset - saved_offset);
785
0
}
786
787
static void
788
rev_req_gps_loc_ass(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset)
789
0
{
790
0
  uint32_t saved_offset;
791
792
0
  SHORT_DATA_CHECK(len, 1);
793
794
0
  saved_offset = offset;
795
796
0
  proto_tree_add_item(tree, hf_ansi_801_coordinate_type_requested, tvb, offset, 1, ENC_NA);
797
0
  proto_tree_add_item(tree, hf_ansi_801_reserved8_7F, tvb, offset, 1, ENC_BIG_ENDIAN);
798
0
  offset++;
799
800
0
  EXTRANEOUS_DATA_CHECK(len, offset - saved_offset);
801
0
}
802
803
static void
804
rev_req_bs_alm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset)
805
0
{
806
0
  uint32_t saved_offset;
807
808
0
  SHORT_DATA_CHECK(len, 1);
809
810
0
  saved_offset = offset;
811
812
0
  proto_tree_add_item(tree, hf_ansi_801_extended_base_station_almanac, tvb, offset, 1, ENC_NA);
813
0
  proto_tree_add_item(tree, hf_ansi_801_reserved8_7F, tvb, offset, 1, ENC_BIG_ENDIAN);
814
0
  offset++;
815
816
0
  EXTRANEOUS_DATA_CHECK(len, offset - saved_offset);
817
0
}
818
819
static void
820
rev_req_gps_ephemeris(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset)
821
0
{
822
0
  uint32_t saved_offset;
823
824
0
  SHORT_DATA_CHECK(len, 1);
825
826
0
  saved_offset = offset;
827
828
0
  proto_tree_add_item(tree, hf_ansi_801_alpha_and_beta_parameters, tvb, offset, 1, ENC_NA);
829
0
  proto_tree_add_item(tree, hf_ansi_801_reserved8_7F, tvb, offset, 1, ENC_BIG_ENDIAN);
830
0
  offset++;
831
832
0
  EXTRANEOUS_DATA_CHECK(len, offset - saved_offset);
833
0
}
834
835
static void
836
rev_req_gps_nav_msg_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset)
837
0
{
838
0
  uint32_t saved_offset;
839
840
0
  SHORT_DATA_CHECK(len, 1);
841
842
0
  saved_offset = offset;
843
844
0
  proto_tree_add_item(tree, hf_ansi_801_subframes_4_and_5, tvb, offset, 1, ENC_NA);
845
0
  proto_tree_add_item(tree, hf_ansi_801_reserved8_7F, tvb, offset, 1, ENC_BIG_ENDIAN);
846
847
0
  offset++;
848
849
0
  EXTRANEOUS_DATA_CHECK(len, offset - saved_offset);
850
0
}
851
852
static void
853
rev_req_loc_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset)
854
0
{
855
0
  uint32_t saved_offset;
856
857
0
  SHORT_DATA_CHECK(len, 1);
858
859
0
  saved_offset = offset;
860
861
0
  proto_tree_add_item(tree, hf_ansi_801_rev_req_loc_height_information, tvb, offset, 1, ENC_NA);
862
0
  proto_tree_add_item(tree, hf_ansi_801_rev_req_loc_clock_correction_for_gps_time, tvb, offset, 1, ENC_NA);
863
0
  proto_tree_add_item(tree, hf_ansi_801_rev_req_loc_velocity_information, tvb, offset, 1, ENC_NA);
864
0
  proto_tree_add_item(tree, hf_ansi_801_reserved8_1F, tvb, offset, 1, ENC_BIG_ENDIAN);
865
0
  offset++;
866
867
0
  EXTRANEOUS_DATA_CHECK(len, offset - saved_offset);
868
0
}
869
870
static void
871
rev_req_gps_alm_correction(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset)
872
0
{
873
0
  uint32_t  saved_offset;
874
875
0
  SHORT_DATA_CHECK(len, 2);
876
877
0
  saved_offset = offset;
878
879
0
  proto_tree_add_item(tree, hf_ansi_801_time_of_almanac, tvb, offset, 1, ENC_NA);
880
881
0
  offset++;
882
0
  proto_tree_add_item(tree, hf_ansi_801_gps_week_number, tvb, offset, 1, ENC_NA);
883
884
0
  offset++;
885
886
0
  EXTRANEOUS_DATA_CHECK(len, offset - saved_offset);
887
0
}
888
889
static void
890
rev_reject(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset)
891
0
{
892
0
  uint8_t      oct;
893
0
  uint32_t     saved_offset;
894
0
  const char *str = NULL;
895
896
0
  saved_offset = offset;
897
898
0
  SHORT_DATA_CHECK(len, 1);
899
900
0
  oct = tvb_get_uint8(tvb, offset);
901
902
0
  str = val_to_str_const((oct & 0xf0) >> 4, for_req_type_strings, "Reserved");
903
904
0
  proto_tree_add_uint_format_value(tree, hf_ansi_801_reject_request_type, tvb, offset, 1, oct,
905
0
          "(%u) %s", (oct & 0xf0) >> 4, str);
906
907
0
  switch ((oct & 0x0e) >> 1)
908
0
  {
909
0
  case 0x00: str = "Capability not supported by the mobile station"; break;
910
0
  case 0x01: str = "Capability normally supported by the mobile station but temporarily not available or not enabled"; break;
911
0
  default: str = "Reserved"; break;
912
0
  }
913
914
0
  proto_tree_add_uint_format_value(tree, hf_ansi_801_reject_reason, tvb, offset, 1,
915
0
          oct, "%s", str);
916
917
0
  proto_tree_add_item(tree, hf_ansi_801_reserved8_01, tvb, offset, 1, ENC_BIG_ENDIAN);
918
0
  offset++;
919
920
0
  EXTRANEOUS_DATA_CHECK(len, offset - saved_offset);
921
0
}
922
923
static void
924
rev_pr_ms_information(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset)
925
0
{
926
0
  uint32_t     value;
927
0
  uint32_t     saved_offset;
928
0
  const char *str = NULL;
929
0
  proto_item* ti;
930
0
  proto_tree *gps_tree, *loc_tree;
931
932
0
  saved_offset = offset;
933
934
0
  SHORT_DATA_CHECK(len, 5);
935
936
0
  value = tvb_get_ntohs(tvb, offset);
937
938
0
  proto_tree_add_item(tree, hf_ansi_801_ms_ls_rev, tvb, offset, 2, ENC_BIG_ENDIAN);
939
940
0
  proto_tree_add_item(tree, hf_ansi_801_ms_mode, tvb, offset, 2, ENC_BIG_ENDIAN);
941
942
0
  switch (value & 0x003f)
943
0
  {
944
0
  case 0x00: str = "Full Chip Measurement Capability"; break;
945
0
  case 0x01: str = "Half Chip Measurement Capability"; break;
946
0
  case 0x02: str = "Quarter Chip Measurement Capability"; break;
947
0
  case 0x03: str = "Eighth Chip Measurement Capability"; break;
948
0
  case 0x04: str = "One Sixteenth Chip Measurement Capability"; break;
949
0
  default: str = "Reserved"; break;
950
0
  }
951
952
0
  proto_tree_add_uint_format_value(tree, hf_ansi_801_pilot_ph_cap, tvb, offset, 2,
953
0
          value, "(%u) %s", value & 0x3f, str);
954
0
  offset += 2;
955
956
0
  ti = proto_tree_add_item(tree, hf_ansi_801_gps_acq_cap, tvb, offset, 3, ENC_BIG_ENDIAN);
957
0
  gps_tree = proto_item_add_subtree(ti, ett_gps);
958
959
0
  proto_tree_add_item(gps_tree, hf_ansi_801_reserved_24_F80000, tvb, offset, 3, ENC_BIG_ENDIAN);
960
0
  proto_tree_add_item(gps_tree, hf_ansi_801_gps_autonomous_acquisition_capable, tvb, offset, 3, ENC_BIG_ENDIAN);
961
0
  proto_tree_add_item(gps_tree, hf_ansi_801_gps_almanac_correction, tvb, offset, 3, ENC_BIG_ENDIAN);
962
0
  proto_tree_add_item(gps_tree, hf_ansi_801_gps_navigation_message_bits, tvb, offset, 3, ENC_BIG_ENDIAN);
963
0
  proto_tree_add_item(gps_tree, hf_ansi_801_gps_ephemeris, tvb, offset, 3, ENC_BIG_ENDIAN);
964
0
  proto_tree_add_item(gps_tree, hf_ansi_801_gps_almanac, tvb, offset, 3, ENC_BIG_ENDIAN);
965
0
  proto_tree_add_item(gps_tree, hf_ansi_801_gps_sensitivity_assistance, tvb, offset, 3, ENC_BIG_ENDIAN);
966
0
  proto_tree_add_item(gps_tree, hf_ansi_801_gps_acquisition_assistance, tvb, offset, 3, ENC_BIG_ENDIAN);
967
968
0
  ti = proto_tree_add_item(tree, hf_ansi_801_loc_calc_cap, tvb, offset, 3, ENC_BIG_ENDIAN);
969
0
  loc_tree = proto_item_add_subtree(ti, ett_loc);
970
971
0
  proto_tree_add_item(loc_tree, hf_ansi_801_pre_programmed_location, tvb, offset, 3, ENC_BIG_ENDIAN);
972
0
  proto_tree_add_item(loc_tree, hf_ansi_801_reserved_24_700, tvb, offset, 3, ENC_BIG_ENDIAN);
973
0
  proto_tree_add_item(loc_tree, hf_ansi_801_hybrid_gps_and_aflt_lcc, tvb, offset, 3, ENC_BIG_ENDIAN);
974
0
  proto_tree_add_item(loc_tree, hf_ansi_801_autonomous_location_calculation_capable, tvb, offset, 3, ENC_BIG_ENDIAN);
975
0
  proto_tree_add_item(loc_tree, hf_ansi_801_lcc_using_gps_almanac_correction, tvb, offset, 3, ENC_BIG_ENDIAN);
976
0
  proto_tree_add_item(loc_tree, hf_ansi_801_lcc_using_gps_ephemeris_assistance, tvb, offset, 3, ENC_BIG_ENDIAN);
977
0
  proto_tree_add_item(loc_tree, hf_ansi_801_lcc_using_gps_almanac_assistance, tvb, offset, 3, ENC_BIG_ENDIAN);
978
0
  proto_tree_add_item(loc_tree, hf_ansi_801_aflt_lcc, tvb, offset, 3, ENC_BIG_ENDIAN);
979
0
  proto_tree_add_item(loc_tree, hf_ansi_801_lcc_using_location_assistance_cartesian, tvb, offset, 3, ENC_BIG_ENDIAN);
980
0
  proto_tree_add_item(loc_tree, hf_ansi_801_lcc_capable_using_location_assistance_spherical, tvb, offset, 3, ENC_BIG_ENDIAN);
981
0
  offset += 3;
982
983
0
  EXTRANEOUS_DATA_CHECK(len, offset - saved_offset);
984
0
}
985
986
static void
987
rev_pr_loc_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset)
988
0
{
989
0
  pr_loc_response(tvb, pinfo, tree, len, offset);
990
0
}
991
992
static void
993
rev_pr_time_off_meas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset)
994
0
{
995
0
  uint32_t  saved_offset;
996
997
0
  saved_offset = offset;
998
999
0
  SHORT_DATA_CHECK(len, 6);
1000
1001
0
  proto_tree_add_uint_format_value(tree, hf_ansi_801_time_ref_ms, tvb, offset, 3, tvb_get_ntoh24(tvb, offset),
1002
0
          "The time of validity of the parameters reported in this response element.");
1003
0
  offset += 3;
1004
1005
0
  proto_tree_add_item(tree, hf_ansi_801_ref_pn, tvb, offset, 3, ENC_BIG_ENDIAN);
1006
0
  proto_tree_add_item(tree, hf_ansi_801_mob_sys_t_offset, tvb, offset, 3, ENC_BIG_ENDIAN);
1007
0
  proto_tree_add_item(tree, hf_ansi_801_reserved24_1, tvb, offset, 3, ENC_BIG_ENDIAN);
1008
0
  offset += 3;
1009
1010
0
  EXTRANEOUS_DATA_CHECK(len, offset - saved_offset);
1011
0
}
1012
1013
static void
1014
rev_pr_can_ack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset)
1015
0
{
1016
0
  uint8_t      oct;
1017
0
  uint32_t     saved_offset;
1018
0
  const char *str;
1019
1020
0
  saved_offset = offset;
1021
1022
0
  SHORT_DATA_CHECK(len, 1);
1023
1024
0
  oct = tvb_get_uint8(tvb, offset);
1025
1026
0
  str = val_to_str_const((oct & 0xf0) >> 4, for_req_type_strings, "Reserved");
1027
0
  proto_tree_add_uint_format_value(tree, hf_ansi_801_cancellation_type, tvb, offset, 1, oct,
1028
0
          "(%u) %s", (oct & 0xf0) >> 4, str);
1029
1030
0
  proto_tree_add_item(tree, hf_ansi_801_no_outstanding_request_element, tvb, offset, 1, ENC_NA);
1031
0
  proto_tree_add_item(tree, hf_ansi_801_reserved8_07, tvb, offset, 1, ENC_BIG_ENDIAN);
1032
0
  offset++;
1033
1034
0
  EXTRANEOUS_DATA_CHECK(len, offset - saved_offset);
1035
0
}
1036
1037
static void (*for_req_type_fcn[])(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset) = {
1038
  NULL, /* Reserved */
1039
  NULL, /* no data */ /* Request MS Information */
1040
  NULL, /* no data */ /* Request Autonomous Measurement Weighting Factors */
1041
  for_req_pseudo_meas,  /* Request Pseudorange Measurement */
1042
  for_req_pilot_ph_meas,  /* Request Pilot Phase Measurement */
1043
  for_req_loc_response, /* Request Location Response */
1044
  for_req_time_off_meas,  /* Request Time Offset Measurement */
1045
  for_req_cancel,   /* Request Cancellation */
1046
  NULL, /* NONE */
1047
};
1048
1049
static void (*for_rsp_type_fcn[])(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset) = {
1050
  for_reject,              /* Reject */
1051
  for_pr_bs_cap,           /* Provide BS Capabilities */
1052
  NULL,                    /* Provide GPS Acquisition Assistance */
1053
  NULL,                    /* Provide GPS Location Assistance Spherical Coordinates */
1054
  NULL,                    /* Provide GPS Location Assistance Cartesian Coordinates */
1055
  for_pr_gps_sense_ass,    /* Provide GPS Sensitivity Assistance */
1056
  NULL,                    /* Provide Base Station Almanac */
1057
  for_pr_gps_almanac,      /* Provide GPS Almanac */
1058
  NULL,                    /* Provide GPS Ephemeris */
1059
  for_pr_gps_nav_msg_bits, /* Provide GPS Navigation Message Bits */
1060
  for_pr_loc_response,     /* Provide Location Response */
1061
  NULL,                    /* Provide GPS Almanac Correction */
1062
  for_pr_gps_sat_health,   /* Provide GPS Satellite Health Information */
1063
  NULL,                    /* NONE */
1064
};
1065
1066
static void (*rev_req_type_fcn[])(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset) = {
1067
  NULL, /* Reserved */
1068
  NULL,   /* no data */   /* Request BS Capabilities */
1069
  rev_req_gps_acq_ass,    /* Request GPS Acquisition Assistance */
1070
  rev_req_gps_loc_ass,    /* Request GPS Location Assistance */
1071
  NULL, /* Reserved */
1072
  NULL,   /* no data */   /* Request GPS Sensitivity Assistance */
1073
  rev_req_bs_alm,     /* Request Base Station Almanac */
1074
  NULL,   /* no data */   /* Request GPS Almanac */
1075
  rev_req_gps_ephemeris,    /* Request GPS Ephemeris */
1076
  rev_req_gps_nav_msg_bits, /* Request GPS Navigation Message Bits */
1077
  rev_req_loc_response,   /* Request Location Response */
1078
  rev_req_gps_alm_correction, /* Request GPS Almanac Correction */
1079
  NULL,   /* no data */   /* Request GPS Satellite Health Information */
1080
  NULL, /* NONE */
1081
};
1082
1083
static void (*rev_rsp_type_fcn[])(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset) = {
1084
  rev_reject,            /* Reject */
1085
  rev_pr_ms_information, /* Provide MS Information */
1086
  NULL,                  /* Provide Autonomous Measurement Weighting Factors */
1087
  NULL,                  /* Provide Pseudorange Measurement */
1088
  NULL,                  /* Provide Pilot Phase Measurement */
1089
  rev_pr_loc_response,   /* Provide Location Response */
1090
  rev_pr_time_off_meas,  /* Provide Time Offset Measurement */
1091
  rev_pr_can_ack,        /* Provide Cancellation Acknowledgement */
1092
  NULL,                  /* NONE */
1093
};
1094
1095
static void
1096
for_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t *offset_p, uint8_t pd_msg_type)
1097
0
{
1098
0
  uint32_t     offset;
1099
0
  uint8_t      oct;
1100
0
  const char *str = NULL;
1101
0
  int          idx;
1102
0
  proto_tree  *subtree;
1103
0
  proto_item  *item;
1104
1105
0
  offset = *offset_p;
1106
0
  oct    = tvb_get_uint8(tvb, offset);
1107
1108
0
  if (pd_msg_type == 0x00)
1109
0
  {
1110
0
    proto_tree_add_item(tree, hf_ansi_801_reserved8_F0, tvb, offset, 1, ENC_BIG_ENDIAN);
1111
1112
0
    str = try_val_to_str_idx(oct & 0x0f, for_req_type_strings, &idx);
1113
0
    if (str == NULL)
1114
0
    {
1115
0
      return;
1116
0
    }
1117
1118
0
    item = proto_tree_add_uint_format_value(tree, hf_ansi_801_for_req_type, tvb, offset, 1,
1119
0
              oct & 0x0f, "%s (%u)", str, oct & 0x0f);
1120
0
  }
1121
0
  else
1122
0
  {
1123
    /* TBD */
1124
    /*
1125
     * It is unclear from TIA-801-A how this was meant to be decoded.
1126
     * Are the elements supposed to be byte aligned?
1127
     */
1128
0
    return;
1129
0
  }
1130
1131
0
  subtree = proto_item_add_subtree(item, ett_for_req_type[idx]);
1132
1133
0
  offset++;
1134
0
  oct = tvb_get_uint8(tvb, offset);
1135
1136
0
  proto_tree_add_item(subtree, hf_ansi_801_for_request_length, tvb, offset, 1, ENC_BIG_ENDIAN);
1137
0
  offset++;
1138
1139
0
  if (oct > 0)
1140
0
  {
1141
0
    if (for_req_type_fcn[idx] != NULL)
1142
0
    {
1143
0
      (*for_req_type_fcn[idx])(tvb, pinfo, subtree, oct, offset);
1144
0
    }
1145
0
    else
1146
0
    {
1147
0
      proto_tree_add_item(subtree, hf_ansi_801_data, tvb, offset, oct, ENC_NA);
1148
0
    }
1149
0
  }
1150
1151
0
  *offset_p = offset + oct;
1152
0
}
1153
1154
static void
1155
for_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t *offset_p)
1156
0
{
1157
0
  uint32_t     offset;
1158
0
  uint8_t      oct;
1159
0
  const char *str = NULL;
1160
0
  int          idx;
1161
0
  proto_tree  *subtree;
1162
0
  proto_item  *item;
1163
1164
0
  offset = *offset_p;
1165
0
  oct    = tvb_get_uint8(tvb, offset);
1166
1167
0
  proto_tree_add_item(tree, hf_ansi_801_reserved8_E0, tvb, offset, 1, ENC_BIG_ENDIAN);
1168
0
  proto_tree_add_item(tree, hf_ansi_801_unsolicited_response_indicator, tvb, offset, 1, ENC_NA);
1169
1170
0
  str = try_val_to_str_idx(oct & 0x0f, for_rsp_type_strings, &idx);
1171
1172
0
  if (str == NULL)
1173
0
  {
1174
0
    return;
1175
0
  }
1176
1177
0
  item = proto_tree_add_uint_format_value(tree, hf_ansi_801_for_rsp_type, tvb, offset, 1,
1178
0
            oct & 0x0f, "%s (%u)", str, oct & 0x0f);
1179
0
  subtree = proto_item_add_subtree(item, ett_for_rsp_type[idx]);
1180
1181
0
  offset++;
1182
0
  oct = tvb_get_uint8(tvb, offset);
1183
1184
0
  proto_tree_add_item(subtree, hf_ansi_801_for_response_length, tvb, offset, 1, ENC_BIG_ENDIAN);
1185
1186
0
  offset++;
1187
1188
0
  if (for_rsp_type_fcn[idx] != NULL)
1189
0
  {
1190
0
    (*for_rsp_type_fcn[idx])(tvb, pinfo, subtree, oct, offset);
1191
0
  }
1192
0
  else
1193
0
  {
1194
0
    proto_tree_add_item(subtree, hf_ansi_801_data, tvb, offset, oct, ENC_NA);
1195
0
  }
1196
1197
0
  *offset_p = offset + oct;
1198
0
}
1199
1200
static void
1201
rev_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t *offset_p, uint8_t pd_msg_type)
1202
0
{
1203
0
  uint32_t     offset;
1204
0
  uint8_t      oct;
1205
0
  const char *str = NULL;
1206
0
  int          idx;
1207
0
  proto_tree  *subtree;
1208
0
  proto_item  *item;
1209
1210
0
  offset = *offset_p;
1211
0
  oct    = tvb_get_uint8(tvb, offset);
1212
1213
0
  if (pd_msg_type == 0x00)
1214
0
  {
1215
0
    proto_tree_add_item(tree, hf_ansi_801_reserved8_F0, tvb, offset, 1, ENC_BIG_ENDIAN);
1216
1217
0
    str = try_val_to_str_idx(oct & 0x0f, rev_req_type_strings, &idx);
1218
0
    if (str == NULL)
1219
0
    {
1220
0
      return;
1221
0
    }
1222
1223
0
    item = proto_tree_add_uint_format_value(tree, hf_ansi_801_rev_req_type, tvb, offset, 1,
1224
0
              oct & 0x0f, "%s (%u)", str, oct & 0x0f);
1225
0
  }
1226
0
  else
1227
0
  {
1228
    /* TBD */
1229
    /*
1230
     * It is unclear from TIA-801-A how this was meant to be decoded.
1231
     * Are the elements supposed to be byte aligned?
1232
     */
1233
0
    return;
1234
0
  }
1235
1236
0
  subtree = proto_item_add_subtree(item, ett_rev_req_type[idx]);
1237
1238
0
  offset++;
1239
0
  oct = tvb_get_uint8(tvb, offset);
1240
1241
0
  proto_tree_add_item(subtree, hf_ansi_801_rev_request_length, tvb, offset, 1, ENC_BIG_ENDIAN);
1242
1243
0
  offset++;
1244
1245
0
  if (rev_req_type_fcn[idx] != NULL)
1246
0
  {
1247
0
    (*rev_req_type_fcn[idx])(tvb, pinfo, subtree, oct, offset);
1248
0
  }
1249
0
  else
1250
0
  {
1251
0
    proto_tree_add_item(subtree, hf_ansi_801_data, tvb, offset, oct, ENC_NA);
1252
0
  }
1253
1254
0
  *offset_p = offset + oct;
1255
0
}
1256
1257
static void
1258
rev_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t *offset_p)
1259
0
{
1260
0
  uint32_t     offset;
1261
0
  uint8_t      oct;
1262
0
  const char *str = NULL;
1263
0
  int          idx;
1264
0
  proto_tree  *subtree;
1265
0
  proto_item  *item;
1266
1267
0
  offset = *offset_p;
1268
0
  oct    = tvb_get_uint8(tvb, offset);
1269
1270
0
  proto_tree_add_item(tree, hf_ansi_801_reserved8_E0, tvb, offset, 1, ENC_BIG_ENDIAN);
1271
0
  proto_tree_add_item(tree, hf_ansi_801_unsolicited_response_indicator, tvb, offset, 1, ENC_NA);
1272
1273
0
  str = try_val_to_str_idx(oct & 0x0f, rev_rsp_type_strings, &idx);
1274
1275
0
  if (str == NULL)
1276
0
  {
1277
0
    return;
1278
0
  }
1279
1280
0
  item = proto_tree_add_uint_format_value(tree, hf_ansi_801_rev_rsp_type, tvb, offset, 1,
1281
0
            oct & 0x0f, "%s (%u)", str, oct & 0x0f);
1282
0
  subtree = proto_item_add_subtree(item, ett_rev_rsp_type[idx]);
1283
0
  offset++;
1284
1285
0
  oct = tvb_get_uint8(tvb, offset);
1286
1287
0
  proto_tree_add_item(subtree, hf_ansi_801_rev_response_length, tvb, offset, 1, ENC_BIG_ENDIAN);
1288
1289
0
  offset++;
1290
1291
0
  if (rev_rsp_type_fcn[idx] != NULL)
1292
0
  {
1293
0
    (*rev_rsp_type_fcn[idx])(tvb, pinfo, subtree, oct, offset);
1294
0
  }
1295
0
  else
1296
0
  {
1297
0
    proto_tree_add_item(subtree, hf_ansi_801_data, tvb, offset, oct, ENC_NA);
1298
0
  }
1299
1300
0
  *offset_p = offset + oct;
1301
0
}
1302
1303
static void
1304
dissect_ansi_801_for_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1305
0
{
1306
0
  uint32_t     value;
1307
0
  uint32_t     offset;
1308
0
  uint8_t      oct, num_req, num_rsp, pd_msg_type;
1309
0
  unsigned     rem_len;
1310
0
  const char *str = NULL;
1311
0
  proto_item  *hidden_item;
1312
1313
0
  offset = 0;
1314
1315
0
  proto_tree_add_item(tree, hf_ansi_801_session_start, tvb, offset, 1, ENC_NA);
1316
0
  proto_tree_add_item(tree, hf_ansi_801_session_end, tvb, offset, 1, ENC_NA);
1317
0
  proto_tree_add_item(tree, hf_ansi_801_session_source, tvb, offset, 1, ENC_NA);
1318
0
  proto_tree_add_item(tree, hf_ansi_801_for_sess_tag, tvb, offset, 1, ENC_BIG_ENDIAN);
1319
1320
0
  hidden_item = proto_tree_add_item(tree, hf_ansi_801_sess_tag, tvb, offset, 1, ENC_BIG_ENDIAN);
1321
0
  proto_item_set_hidden(hidden_item);
1322
1323
0
  offset++;
1324
0
  oct = tvb_get_uint8(tvb, offset);
1325
0
  pd_msg_type = oct;
1326
1327
0
  switch (pd_msg_type)
1328
0
  {
1329
0
  case 0x00: str = "Position Determination Data Message"; break;
1330
0
  case 0x01: str = "Position Determination Data Message"; break;
1331
0
  case 0xff: str = "Reserved"; break;
1332
0
  default:
1333
0
    if (pd_msg_type < 0xc0)
1334
0
    {
1335
0
      str = "Reserved for future standardization";
1336
0
    }
1337
0
    else
1338
0
    {
1339
0
      str = "Available for manufacturer-specific Position Determination "
1340
0
          "Data Message definition as specified in TSB-58";
1341
0
    }
1342
0
    break;
1343
0
  }
1344
1345
0
  proto_tree_add_uint_format_value(tree, hf_ansi_801_pd_message_type, tvb, offset, 1, pd_msg_type,
1346
0
          "%s (%u)", str, pd_msg_type);
1347
1348
0
  offset++;
1349
1350
0
  if ((pd_msg_type != 0x00) &&
1351
0
      (pd_msg_type != 0x01))
1352
0
  {
1353
0
    proto_tree_add_item(tree, hf_ansi_801_proprietary_data, tvb, offset, -1, ENC_NA);
1354
0
    return;
1355
0
  }
1356
1357
0
  if (pd_msg_type == 0x01)
1358
0
  {
1359
0
    value = tvb_get_ntohs(tvb, offset);
1360
1361
0
    proto_tree_add_item(tree, hf_ansi_801_pd_message_len, tvb, offset, 2, ENC_BIG_ENDIAN);
1362
0
    proto_tree_add_item(tree, hf_ansi_801_regulatory_services_indicator, tvb, offset, 2, ENC_BIG_ENDIAN);
1363
1364
0
    num_req = value & 0x000f;
1365
1366
0
    proto_tree_add_item(tree, hf_ansi_801_for_message_number_requests16, tvb, offset, 2, ENC_BIG_ENDIAN);
1367
0
    offset += 2;
1368
1369
0
    oct = tvb_get_uint8(tvb, offset);
1370
0
    num_rsp = oct & 0xf0;
1371
1372
0
    proto_tree_add_item(tree, hf_ansi_801_for_message_number_responsesF0, tvb, offset, 1, ENC_BIG_ENDIAN);
1373
0
    offset++;
1374
0
  }
1375
0
  else
1376
0
  {
1377
0
    oct = tvb_get_uint8(tvb, offset);
1378
1379
0
    num_req = (oct & 0xf0) >> 4;
1380
0
    num_rsp = oct & 0x0f;
1381
1382
0
    proto_tree_add_item(tree, hf_ansi_801_for_message_number_requests8, tvb, offset, 1, ENC_BIG_ENDIAN);
1383
0
    proto_tree_add_item(tree, hf_ansi_801_for_message_number_responses0F, tvb, offset, 1, ENC_BIG_ENDIAN);
1384
0
  }
1385
1386
0
  offset++;
1387
0
  rem_len = tvb_reported_length_remaining(tvb, offset);
1388
1389
0
  while ((num_req > 0) &&
1390
0
         (rem_len >= 2))
1391
0
  {
1392
0
    for_request(tvb, pinfo, tree, &offset, pd_msg_type);
1393
1394
0
    rem_len = tvb_reported_length_remaining(tvb, offset);
1395
0
    num_req--;
1396
0
  }
1397
1398
0
  if (num_req != 0)
1399
0
  {
1400
0
    proto_tree_add_expert(tree, pinfo, &ei_ansi_801_short_data, tvb, offset, -1);
1401
0
    return;
1402
0
  }
1403
1404
0
  while ((num_rsp > 0) &&
1405
0
         (rem_len >= 2))
1406
0
  {
1407
0
    for_response(tvb, pinfo, tree, &offset);
1408
1409
0
    rem_len = tvb_reported_length_remaining(tvb, offset);
1410
0
    num_rsp--;
1411
0
  }
1412
1413
0
  if (num_rsp != 0)
1414
0
  {
1415
0
    proto_tree_add_expert(tree, pinfo, &ei_ansi_801_short_data, tvb, offset, -1);
1416
0
    return;
1417
0
  }
1418
1419
0
  if (rem_len > 0)
1420
0
  {
1421
0
    proto_tree_add_expert(tree, pinfo, &ei_ansi_801_extraneous_data, tvb, offset, rem_len);
1422
0
  }
1423
0
}
1424
1425
static void
1426
dissect_ansi_801_rev_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1427
0
{
1428
0
  uint32_t     value;
1429
0
  uint32_t     offset;
1430
0
  uint8_t      oct, num_req, num_rsp, pd_msg_type;
1431
0
  unsigned     rem_len;
1432
0
  const char *str = NULL;
1433
0
  proto_item  *hidden_item;
1434
1435
0
  offset = 0;
1436
1437
0
  proto_tree_add_item(tree, hf_ansi_801_session_start, tvb, offset, 1, ENC_NA);
1438
0
  proto_tree_add_item(tree, hf_ansi_801_session_end, tvb, offset, 1, ENC_NA);
1439
0
  proto_tree_add_item(tree, hf_ansi_801_session_source, tvb, offset, 1, ENC_NA);
1440
0
  proto_tree_add_item(tree, hf_ansi_801_rev_sess_tag, tvb, offset, 1, ENC_BIG_ENDIAN);
1441
1442
0
  hidden_item = proto_tree_add_item(tree, hf_ansi_801_sess_tag, tvb, offset, 1, ENC_BIG_ENDIAN);
1443
0
  proto_item_set_hidden(hidden_item);
1444
1445
0
  offset++;
1446
0
  oct = tvb_get_uint8(tvb, offset);
1447
0
  pd_msg_type = oct;
1448
1449
0
  switch (pd_msg_type)
1450
0
  {
1451
0
  case 0x00: str = "Position Determination Data Message"; break;
1452
0
  case 0x01: str = "Position Determination Data Message"; break;
1453
0
  case 0xff: str = "Reserved"; break;
1454
0
  default:
1455
0
    if (pd_msg_type < 0xc0)
1456
0
    {
1457
0
      str = "Reserved for future standardization";
1458
0
    }
1459
0
    else
1460
0
    {
1461
0
      str = "Available for manufacturer-specific Position Determination "
1462
0
        "Data Message definition as specified in TSB-58";
1463
0
    }
1464
0
    break;
1465
0
  }
1466
1467
0
  proto_tree_add_uint_format_value(tree, hf_ansi_801_pd_message_type, tvb, offset, 1, pd_msg_type,
1468
0
          "%s (%u)", str, pd_msg_type);
1469
0
  offset++;
1470
1471
0
  if ((pd_msg_type != 0x00) &&
1472
0
      (pd_msg_type != 0x01))
1473
0
  {
1474
0
    proto_tree_add_item(tree, hf_ansi_801_proprietary_data, tvb, offset, -1, ENC_NA);
1475
0
    return;
1476
0
  }
1477
1478
0
  if (pd_msg_type == 0x01)
1479
0
  {
1480
0
    value = tvb_get_ntohs(tvb, offset);
1481
1482
0
    proto_tree_add_item(tree, hf_ansi_801_pd_message_len, tvb, offset, 2, ENC_BIG_ENDIAN);
1483
0
    proto_tree_add_item(tree, hf_ansi_801_regulatory_services_indicator, tvb, offset, 2, ENC_BIG_ENDIAN);
1484
1485
0
    num_req = value & 0x000f;
1486
1487
0
    proto_tree_add_item(tree, hf_ansi_801_rev_message_number_requests16, tvb, offset, 2, ENC_BIG_ENDIAN);
1488
0
    offset += 2;
1489
1490
0
    oct = tvb_get_uint8(tvb, offset);
1491
0
    num_rsp = oct & 0xf0;
1492
1493
0
    proto_tree_add_item(tree, hf_ansi_801_rev_message_number_responsesF0, tvb, offset, 1, ENC_BIG_ENDIAN);
1494
0
    offset++;
1495
0
  }
1496
0
  else
1497
0
  {
1498
0
    oct = tvb_get_uint8(tvb, offset);
1499
1500
0
    num_req = (oct & 0xf0) >> 4;
1501
0
    num_rsp = oct & 0x0f;
1502
1503
0
    proto_tree_add_item(tree, hf_ansi_801_rev_message_number_requests8, tvb, offset, 1, ENC_BIG_ENDIAN);
1504
0
    proto_tree_add_item(tree, hf_ansi_801_rev_message_number_responses0F, tvb, offset, 1, ENC_BIG_ENDIAN);
1505
0
    offset++;
1506
0
  }
1507
1508
0
  rem_len = tvb_reported_length_remaining(tvb, offset);
1509
1510
0
  while ((num_req > 0) &&
1511
0
         (rem_len >= 2))
1512
0
  {
1513
0
    rev_request(tvb, pinfo, tree, &offset, pd_msg_type);
1514
1515
0
    rem_len = tvb_reported_length_remaining(tvb, offset);
1516
0
    num_req--;
1517
0
  }
1518
1519
0
  if (num_req != 0)
1520
0
  {
1521
0
    proto_tree_add_expert(tree, pinfo, &ei_ansi_801_short_data, tvb, offset, -1);
1522
0
    return;
1523
0
  }
1524
1525
0
  while ((num_rsp > 0) &&
1526
0
         (rem_len >= 2))
1527
0
  {
1528
0
    rev_response(tvb, pinfo, tree, &offset);
1529
1530
0
    rem_len = tvb_reported_length_remaining(tvb, offset);
1531
0
    num_rsp--;
1532
0
  }
1533
1534
0
  if (num_rsp != 0)
1535
0
  {
1536
0
    proto_tree_add_expert(tree, pinfo, &ei_ansi_801_short_data, tvb, offset, -1);
1537
0
    return;
1538
0
  }
1539
1540
0
  if (rem_len > 0)
1541
0
  {
1542
0
    proto_tree_add_expert(tree, pinfo, &ei_ansi_801_extraneous_data, tvb, offset, rem_len);
1543
0
  }
1544
0
}
1545
1546
static int
1547
dissect_ansi_801(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1548
0
{
1549
0
  proto_item *ansi_801_item;
1550
0
  proto_tree *ansi_801_tree = NULL;
1551
1552
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, ansi_proto_name_short);
1553
1554
  /* In the interest of speed, if "tree" is NULL, don't do any work not
1555
   * necessary to generate protocol tree items.
1556
   */
1557
0
  if (tree)
1558
0
  {
1559
    /*
1560
     * create the ansi_801 protocol tree
1561
     */
1562
0
    ansi_801_item =
1563
0
      proto_tree_add_protocol_format(tree, proto_ansi_801, tvb, 0, -1,
1564
0
                   "%s %s Link",
1565
0
                   ansi_proto_name,
1566
0
                   (pinfo->match_uint == ANSI_801_FORWARD) ? "Forward" : "Reverse");
1567
1568
0
    ansi_801_tree =
1569
0
      proto_item_add_subtree(ansi_801_item, ett_ansi_801);
1570
1571
0
    if (pinfo->match_uint == ANSI_801_FORWARD)
1572
0
    {
1573
0
      dissect_ansi_801_for_message(tvb, pinfo, ansi_801_tree);
1574
0
    }
1575
0
    else
1576
0
    {
1577
0
      dissect_ansi_801_rev_message(tvb, pinfo, ansi_801_tree);
1578
0
    }
1579
0
  }
1580
0
  return tvb_captured_length(tvb);
1581
0
}
1582
1583
1584
/* Register the protocol with Wireshark */
1585
void
1586
proto_register_ansi_801(void)
1587
14
{
1588
14
  unsigned i;
1589
14
  int   last_offset;
1590
1591
  /* Setup list of header fields */
1592
14
  static hf_register_info hf[] = {
1593
14
    { &hf_ansi_801_for_req_type,
1594
14
      { "Forward Request Type", "ansi_801.for_req_type",
1595
14
        FT_UINT8, BASE_DEC, NULL, 0,
1596
14
        NULL, HFILL }
1597
14
    },
1598
14
    { &hf_ansi_801_for_rsp_type,
1599
14
      { "Forward Response Type", "ansi_801.for_rsp_type",
1600
14
        FT_UINT8, BASE_DEC, NULL, 0,
1601
14
        NULL, HFILL }
1602
14
    },
1603
14
    { &hf_ansi_801_rev_req_type,
1604
14
      { "Reverse Request Type", "ansi_801.rev_req_type",
1605
14
        FT_UINT8, BASE_DEC, NULL, 0,
1606
14
        NULL, HFILL }
1607
14
    },
1608
14
    { &hf_ansi_801_rev_rsp_type,
1609
14
      { "Reverse Response Type", "ansi_801.rev_rsp_type",
1610
14
        FT_UINT8, BASE_DEC, NULL, 0,
1611
14
        NULL, HFILL }
1612
14
    },
1613
14
    { &hf_ansi_801_for_sess_tag,
1614
14
      { "Forward Session Tag", "ansi_801.for_sess_tag",
1615
14
        FT_UINT8, BASE_DEC, NULL, 0x1f,
1616
14
        NULL, HFILL }
1617
14
    },
1618
14
    { &hf_ansi_801_rev_sess_tag,
1619
14
      { "Reverse Session Tag", "ansi_801.rev_sess_tag",
1620
14
        FT_UINT8, BASE_DEC, NULL, 0x1f,
1621
14
        NULL, HFILL }
1622
14
    },
1623
14
    { &hf_ansi_801_sess_tag,
1624
14
      { "Session Tag", "ansi_801.sess_tag",
1625
14
        FT_UINT8, BASE_DEC, NULL, 0x1f,
1626
14
        NULL, HFILL }
1627
14
    },
1628
14
    { &hf_ansi_801_time_ref_cdma,
1629
14
      { "CDMA system time at the time the solution is valid (TIME_REF_CDMA)", "ansi_801.time_ref_cdma",
1630
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1631
14
        NULL, HFILL }
1632
14
    },
1633
14
    { &hf_ansi_801_lat,
1634
14
      { "Latitude (LAT)", "ansi_801.lat",
1635
14
        FT_FLOAT, BASE_NONE, NULL, 0x00,
1636
14
        NULL, HFILL }
1637
14
    },
1638
14
    { &hf_ansi_801_long,
1639
14
      { "Longitude (LONG)", "ansi_801.long",
1640
14
        FT_FLOAT, BASE_NONE, NULL, 0x00,
1641
14
        NULL, HFILL }
1642
14
    },
1643
14
    { &hf_ansi_801_loc_uncrtnty_ang,
1644
14
      { "Angle of axis with respect to True North for pos uncertainty (LOC_UNCRTNTY_ANG)", "ansi_801.loc_uncrtnty_ang",
1645
14
        FT_FLOAT, BASE_NONE, NULL, 0x00,
1646
14
        NULL, HFILL }
1647
14
    },
1648
14
    { &hf_ansi_801_loc_uncrtnty_a,
1649
14
      { "Std dev of axis along angle specified for pos uncertainty (LOC_UNCRTNTY_A)", "ansi_801.loc_uncrtnty_a",
1650
14
        FT_UINT8, BASE_DEC, NULL, 0x00,
1651
14
        NULL, HFILL }
1652
14
    },
1653
14
    { &hf_ansi_801_loc_uncrtnty_p,
1654
14
      { "Std dev of axis perpendicular to angle specified for pos uncertainty (LOC_UNCRTNTY_P)", "ansi_801.loc_uncrtnty_p",
1655
14
        FT_UINT8, BASE_DEC, NULL, 0x00,
1656
14
        NULL, HFILL }
1657
14
    },
1658
14
    { &hf_ansi_801_fix_type,
1659
14
      { "Fix type (FIX_TYPE)", "ansi_801.fix_type",
1660
14
        FT_BOOLEAN, BASE_NONE, TFS(&ansi_801_fix_type_vals), 0x00,
1661
14
        NULL, HFILL }
1662
14
    },
1663
14
    { &hf_ansi_801_velocity_incl,
1664
14
      { "Velocity information included (VELOCITY_INCL)", "ansi_801.velocity_incl",
1665
14
        FT_BOOLEAN, BASE_NONE, NULL, 0x00,
1666
14
        NULL, HFILL }
1667
14
    },
1668
14
    { &hf_ansi_801_velocity_hor,
1669
14
      { "Horizontal velocity magnitude (VELOCITY_HOR)", "ansi_801.velocity_hor",
1670
14
        FT_FLOAT, BASE_NONE, NULL, 0x00,
1671
14
        NULL, HFILL }
1672
14
    },
1673
14
    { &hf_ansi_801_heading,
1674
14
      { "Heading (HEADING)", "ansi_801.heading",
1675
14
        FT_FLOAT, BASE_NONE, NULL, 0x00,
1676
14
        NULL, HFILL }
1677
14
    },
1678
14
    { &hf_ansi_801_velocity_ver,
1679
14
      { "Vertical velocity (VELOCITY_VER)", "ansi_801.velocity_ver",
1680
14
        FT_FLOAT, BASE_NONE, NULL, 0x00,
1681
14
        NULL, HFILL }
1682
14
    },
1683
14
    { &hf_ansi_801_clock_incl,
1684
14
      { "Clock information included (CLOCK_INCL)", "ansi_801.clock_incl",
1685
14
        FT_BOOLEAN, BASE_NONE, NULL, 0x00,
1686
14
        NULL, HFILL }
1687
14
    },
1688
14
    { &hf_ansi_801_clock_bias,
1689
14
      { "Clock bias (CLOCK_BIAS)", "ansi_801.clock_bias",
1690
14
        FT_INT24, BASE_DEC, NULL, 0x00,
1691
14
        NULL, HFILL }
1692
14
    },
1693
14
    { &hf_ansi_801_clock_drift,
1694
14
      { "Clock drift (CLOCK_DRIFT)", "ansi_801.clock_drift",
1695
14
        FT_INT16, BASE_DEC, NULL, 0x00,
1696
14
        NULL, HFILL }
1697
14
    },
1698
14
    { &hf_ansi_801_height_incl,
1699
14
      { "Height information included (HEIGHT_INCL)", "ansi_801.height_incl",
1700
14
        FT_BOOLEAN, BASE_NONE, NULL, 0x00,
1701
14
        NULL, HFILL }
1702
14
    },
1703
14
    { &hf_ansi_801_height,
1704
14
      { "Height (HEIGHT)", "ansi_801.height",
1705
14
        FT_INT16, BASE_DEC, NULL, 0x00,
1706
14
        NULL, HFILL }
1707
14
    },
1708
14
    { &hf_ansi_801_loc_uncrtnty_v,
1709
14
      { "Std dev of vertical error for pos uncertainty (LOC_UNCRTNTY_V)", "ansi_801.loc_uncrtnty_v",
1710
14
        FT_UINT8, BASE_DEC, NULL, 0x00,
1711
14
        NULL, HFILL }
1712
14
    },
1713
14
    { &hf_ansi_801_reserved_bits,
1714
14
      { "Reserved bit(s)","ansi_801.reserved_bits",
1715
14
        FT_UINT8,BASE_DEC, NULL, 0x0,
1716
14
        NULL, HFILL }
1717
14
    },
1718
14
    { &hf_ansi_801_bad_sv_present,
1719
14
      { "Bad GPS satellites present (BAD_SV_PRESENT)", "ansi_801.bad_sv_present",
1720
14
        FT_BOOLEAN, BASE_NONE, NULL, 0x00,
1721
14
        NULL, HFILL }
1722
14
    },
1723
14
    { &hf_ansi_801_num_bad_sv,
1724
14
      { "Number of bad GPS satellites (NUM_BAD_SV)", "ansi_801.num_bad_sv",
1725
14
        FT_UINT8, BASE_DEC, NULL, 0x00,
1726
14
        NULL, HFILL }
1727
14
    },
1728
14
    { &hf_ansi_801_bad_sv_prn_num,
1729
14
      { "Satellite PRN number (SV_PRN_NUM)", "ansi_801.bad_sv_prn_num",
1730
14
        FT_UINT8, BASE_DEC, NULL, 0x00,
1731
14
        NULL, HFILL }
1732
14
    },
1733
14
    { &hf_ansi_801_dopp_req,
1734
14
      { "Doppler (0th order) term requested (DOPP_REQ)", "ansi_801.dopp_req",
1735
14
        FT_BOOLEAN, BASE_NONE, NULL, 0x00,
1736
14
        NULL, HFILL }
1737
14
    },
1738
14
    { &hf_ansi_801_add_dopp_req,
1739
14
      { "Additional Doppler terms requested (ADD_DOPP_REQ)", "ansi_801.add_dopp_req",
1740
14
        FT_BOOLEAN, BASE_NONE, NULL, 0x00,
1741
14
        NULL, HFILL }
1742
14
    },
1743
14
    { &hf_ansi_801_code_ph_par_req,
1744
14
      { "Code phase parameters requested (CODE_PH_PAR_REQ)", "ansi_801.code_ph_par_req",
1745
14
        FT_BOOLEAN, BASE_NONE, NULL, 0x00,
1746
14
        NULL, HFILL }
1747
14
    },
1748
14
    { &hf_ansi_801_az_el_req,
1749
14
      { "Azimuth and elevation angle requested (AZ_EL_REQ)", "ansi_801.az_el_req",
1750
14
        FT_BOOLEAN, BASE_NONE, NULL, 0x00,
1751
14
        NULL, HFILL }
1752
14
    },
1753
14
    { &hf_ansi_801_pref_resp_qual,
1754
14
      { "Preferred response quality (PREF_RESP_QUAL)", "ansi_801.pref_resp_qual",
1755
14
        FT_UINT24, BASE_DEC, NULL, 0xe00000,
1756
14
        NULL, HFILL }
1757
14
    },
1758
14
    { &hf_ansi_801_num_fixes,
1759
14
      { "Number of fixes (NUM_FIXES)", "ansi_801.num_fixes",
1760
14
        FT_UINT24, BASE_DEC, NULL, 0x1fe000,
1761
14
        NULL, HFILL }
1762
14
    },
1763
14
    { &hf_ansi_801_t_betw_fixes,
1764
14
      { "Time between fixes (T_BETW_FIXES) (in seconds)", "ansi_801.t_betw_fixes",
1765
14
        FT_UINT24, BASE_DEC, NULL, 0x001fe0,
1766
14
        NULL, HFILL }
1767
14
    },
1768
14
    { &hf_ansi_801_offset_req,
1769
14
      { "Offset requested (OFFSET_REQ)", "ansi_801.offset_req",
1770
14
        FT_BOOLEAN, 24, TFS(&tfs_requested_not_requested), 0x000010,
1771
14
        NULL, HFILL }
1772
14
    },
1773
1774
    /* Generated from convert_proto_tree_add_text.pl */
1775
14
    { &hf_ansi_801_desired_pilot_phase_resolution,
1776
14
      { "Desired pilot phase resolution", "ansi_801.desired_pilot_phase_resolution",
1777
14
        FT_BOOLEAN, 24, TFS(&tfs_desired_pilot_phase_resolution), 0x000008,
1778
14
        NULL, HFILL }
1779
14
    },
1780
14
    { &hf_ansi_801_reserved_24_7,
1781
14
      { "Reserved", "ansi_801.reserved",
1782
14
        FT_UINT24, BASE_HEX, NULL, 0x07,
1783
14
        NULL, HFILL }
1784
14
    },
1785
14
    { &hf_ansi_801_for_req_loc_height_information,
1786
14
      { "Height information", "ansi_801.height_incl",
1787
14
        FT_BOOLEAN, 24, TFS(&tfs_requested_not_requested), 0x000010,
1788
14
        NULL, HFILL }
1789
14
    },
1790
14
    { &hf_ansi_801_for_req_loc_clock_correction_for_gps_time,
1791
14
      { "Clock correction for GPS time", "ansi_801.clock_correction_for_gps_time",
1792
14
        FT_BOOLEAN, 24, TFS(&tfs_requested_not_requested), 0x000008,
1793
14
        NULL, HFILL }
1794
14
    },
1795
14
    { &hf_ansi_801_for_req_loc_velocity_information,
1796
14
      { "Velocity information", "ansi_801.velocity_information",
1797
14
        FT_BOOLEAN, 24, TFS(&tfs_requested_not_requested), 0x000004,
1798
14
        NULL, HFILL }
1799
14
    },
1800
14
    { &hf_ansi_801_reserved24_3,
1801
14
      { "Reserved", "ansi_801.reserved",
1802
14
        FT_UINT24, BASE_HEX, NULL, 0x000003,
1803
14
        NULL, HFILL }
1804
14
    },
1805
14
    { &hf_ansi_801_use_action_time_indicator,
1806
14
      { "Use action time indicator", "ansi_801.use_action_time_indicator",
1807
14
        FT_BOOLEAN, 8, NULL, 0x80,
1808
14
        NULL, HFILL }
1809
14
    },
1810
14
    { &hf_ansi_801_action_time,
1811
14
      { "Action time", "ansi_801.action_time",
1812
14
        FT_UINT8, BASE_DEC, NULL, 0x7E,
1813
14
        NULL, HFILL }
1814
14
    },
1815
14
    { &hf_ansi_801_reserved8_7F,
1816
14
      { "Reserved", "ansi_801.reserved",
1817
14
        FT_UINT8, BASE_HEX, NULL, 0x7F,
1818
14
        NULL, HFILL }
1819
14
    },
1820
14
    { &hf_ansi_801_cancellation_type,
1821
14
      { "Cancellation Type", "ansi_801.cancellation_type",
1822
14
        FT_UINT8, BASE_DEC, VALS(for_req_type_strings), 0xF0,
1823
14
        NULL, HFILL }
1824
14
    },
1825
14
    { &hf_ansi_801_reserved8_0F,
1826
14
      { "Reserved", "ansi_801.reserved",
1827
14
        FT_UINT8, BASE_HEX, NULL, 0x0F,
1828
14
        NULL, HFILL }
1829
14
    },
1830
14
    { &hf_ansi_801_reject_request_type,
1831
14
      { "Reject request type", "ansi_801.reject_request_type",
1832
14
        FT_UINT8, BASE_DEC, VALS(rev_req_type_strings), 0xF0,
1833
14
        NULL, HFILL }
1834
14
    },
1835
14
    { &hf_ansi_801_reject_reason,
1836
14
      { "Reject reason", "ansi_801.reject_reason",
1837
14
        FT_UINT8, BASE_DEC, NULL, 0x0E,
1838
14
        NULL, HFILL }
1839
14
    },
1840
14
    { &hf_ansi_801_reserved8_01,
1841
14
      { "Reserved", "ansi_801.reserved",
1842
14
        FT_UINT8, BASE_HEX, NULL, 0x01,
1843
14
        NULL, HFILL }
1844
14
    },
1845
14
    { &hf_ansi_801_bs_ls_rev,
1846
14
      { "BS_LS_REV", "ansi_801.bs_ls_rev",
1847
14
        FT_UINT8, BASE_HEX, NULL, 0xfc,
1848
14
        NULL, HFILL }
1849
14
    },
1850
14
    { &hf_ansi_801_gps_capability_indicator,
1851
14
      { "GPSC_ID: GPS capability indicator", "ansi_801.gps_capability_indicator",
1852
14
        FT_UINT8, BASE_DEC, NULL, 0x02,
1853
14
        NULL, HFILL }
1854
14
    },
1855
14
    { &hf_ansi_801_afltc_id,
1856
14
      { "AFLTC_ID: Advanced forward link trilateration capability indicator", "ansi_801.afltc_id",
1857
14
        FT_UINT8, BASE_DEC, NULL, 0x01,
1858
14
        NULL, HFILL }
1859
14
    },
1860
14
    { &hf_ansi_801_apdc_id,
1861
14
      { "APDC_ID: Autonomous position determination capability indicator: Autonomous Location Technology Identifier", "ansi_801.apdc_id",
1862
14
        FT_UINT8, BASE_DEC, NULL, 0x0,
1863
14
        NULL, HFILL }
1864
14
    },
1865
14
    { &hf_ansi_801_ref_bit_num,
1866
14
      { "REF_BIT_NUM", "ansi_801.ref_bit_num",
1867
14
        FT_UINT16, BASE_DEC, NULL, 0xffe0,
1868
14
        NULL, HFILL }
1869
14
    },
1870
14
    { &hf_ansi_801_num_dr_p,
1871
14
      { "NUM_DR_P: Number of data records in this part", "ansi_801.num_dr_p",
1872
14
        FT_UINT16, BASE_DEC, NULL, 0x001e,
1873
14
        NULL, HFILL }
1874
14
    },
1875
14
    { &hf_ansi_801_dr_size,
1876
14
      { "DR_SIZE: Data record size", "ansi_801.dr_size",
1877
14
        FT_UINT24, BASE_DEC, NULL, 0x0001FE,
1878
14
        NULL, HFILL }
1879
14
    },
1880
14
    { &hf_ansi_801_part_num,
1881
14
      { "PART_NUM: The part number", "ansi_801.part_num",
1882
14
        FT_UINT16, BASE_DEC, NULL, 0x01c0,
1883
14
        NULL, HFILL }
1884
14
    },
1885
14
    { &hf_ansi_801_total_parts,
1886
14
      { "TOTAL_PARTS: Total number of parts", "ansi_801.total_parts",
1887
14
        FT_UINT16, BASE_DEC, NULL, 0x38,
1888
14
        NULL, HFILL }
1889
14
    },
1890
14
    { &hf_ansi_801_data_records,
1891
14
      { "Data records", "ansi_801.data_records",
1892
14
        FT_UINT16, BASE_DEC, NULL, 0x07,
1893
14
        NULL, HFILL }
1894
14
    },
1895
14
    { &hf_ansi_801_num_sv_p32,
1896
14
      { "NUM_SV_P: Number of satellites in this part", "ansi_801.num_sv_p",
1897
14
        FT_UINT32, BASE_DEC, NULL, 0xfc000000,
1898
14
        NULL, HFILL }
1899
14
    },
1900
14
    { &hf_ansi_801_week_num,
1901
14
      { "WEEK_NUM: The GPS week number of the almanac", "ansi_801.week_num",
1902
14
        FT_UINT32, BASE_DEC, NULL, 0x03fc0000,
1903
14
        NULL, HFILL }
1904
14
    },
1905
14
    { &hf_ansi_801_toa,
1906
14
      { "TOA: The reference time of the almanac", "ansi_801.toa",
1907
14
        FT_UINT32, BASE_DEC, NULL, 0x0003fc00,
1908
14
        NULL, HFILL }
1909
14
    },
1910
14
    { &hf_ansi_801_part_num32,
1911
14
      { "PART_NUM: The part number", "ansi_801.part_num",
1912
14
        FT_UINT32, BASE_DEC, NULL, 0x000003e0,
1913
14
        NULL, HFILL }
1914
14
    },
1915
14
    { &hf_ansi_801_total_parts32,
1916
14
      { "TOTAL_PARTS: The total number of parts", "ansi_801.total_parts",
1917
14
        FT_UINT32, BASE_DEC, NULL, 0x0000001f,
1918
14
        NULL, HFILL }
1919
14
    },
1920
14
    { &hf_ansi_801_num_sv_p16,
1921
14
      { "NUM_SV_P: Number of satellites in this part", "ansi_801.num_sv_p",
1922
14
        FT_UINT16, BASE_DEC, NULL, 0xfc00,
1923
14
        NULL, HFILL }
1924
14
    },
1925
14
    { &hf_ansi_801_part_num16,
1926
14
      { "PART_NUM: The part number", "ansi_801.part_num",
1927
14
        FT_UINT16, BASE_DEC, NULL, 0x03e0,
1928
14
        NULL, HFILL }
1929
14
    },
1930
14
    { &hf_ansi_801_total_parts16,
1931
14
      { "TOTAL_PARTS: The total number of parts", "ansi_801.total_parts",
1932
14
        FT_UINT16, BASE_DEC, NULL, 0x001f,
1933
14
        NULL, HFILL }
1934
14
    },
1935
14
    { &hf_ansi_801_coordinate_type_requested,
1936
14
      { "Coordinate type requested", "ansi_801.coordinate_type_requested",
1937
14
        FT_BOOLEAN, 8, TFS(&tfs_spherical_cartesian), 0x80,
1938
14
        NULL, HFILL }
1939
14
    },
1940
14
    { &hf_ansi_801_extended_base_station_almanac,
1941
14
      { "Extended base station almanac", "ansi_801.extended_base_station_almanac",
1942
14
        FT_BOOLEAN, 8, TFS(&tfs_requested_not_requested), 0x80,
1943
14
        NULL, HFILL }
1944
14
    },
1945
14
    { &hf_ansi_801_alpha_and_beta_parameters,
1946
14
      { "Alpha and Beta parameters", "ansi_801.alpha_and_beta_parameters",
1947
14
        FT_BOOLEAN, 8, TFS(&tfs_requested_not_requested), 0x80,
1948
14
        NULL, HFILL }
1949
14
    },
1950
14
    { &hf_ansi_801_subframes_4_and_5,
1951
14
      { "Subframes 4 and 5", "ansi_801.subframes_4_and_5",
1952
14
        FT_BOOLEAN, 8, TFS(&tfs_requested_not_requested), 0x80,
1953
14
        NULL, HFILL }
1954
14
    },
1955
14
    { &hf_ansi_801_rev_req_loc_height_information,
1956
14
      { "Height information", "ansi_801.height_information",
1957
14
        FT_BOOLEAN, 8, TFS(&tfs_requested_not_requested), 0x80,
1958
14
        NULL, HFILL }
1959
14
    },
1960
14
    { &hf_ansi_801_rev_req_loc_clock_correction_for_gps_time,
1961
14
      { "Clock correction for GPS time", "ansi_801.clock_correction_for_gps_time",
1962
14
        FT_BOOLEAN, 8, TFS(&tfs_requested_not_requested), 0x40,
1963
14
        NULL, HFILL }
1964
14
    },
1965
14
    { &hf_ansi_801_rev_req_loc_velocity_information,
1966
14
      { "Velocity information", "ansi_801.velocity_information",
1967
14
        FT_BOOLEAN, 8, TFS(&tfs_requested_not_requested), 0x20,
1968
14
        NULL, HFILL }
1969
14
    },
1970
14
    { &hf_ansi_801_reserved8_1F,
1971
14
      { "Reserved", "ansi_801.reserved",
1972
14
        FT_UINT8, BASE_HEX, NULL, 0x1F,
1973
14
        NULL, HFILL }
1974
14
    },
1975
14
    { &hf_ansi_801_ms_ls_rev,
1976
14
      { "MS_LS_REV", "ansi_801.ms_ls_rev",
1977
14
        FT_UINT16, BASE_DEC, NULL, 0xfc00,
1978
14
        NULL, HFILL }
1979
14
    },
1980
14
    { &hf_ansi_801_ms_mode,
1981
14
      { "MS_MODE", "ansi_801.ms_mode",
1982
14
        FT_UINT16, BASE_DEC, NULL, 0x03c0,
1983
14
        NULL, HFILL }
1984
14
    },
1985
14
    { &hf_ansi_801_pilot_ph_cap,
1986
14
      { "PILOT_PH_CAP", "ansi_801.pilot_ph_cap",
1987
14
        FT_UINT16, BASE_DEC, NULL, 0x003f,
1988
14
        NULL, HFILL }
1989
14
    },
1990
14
    { &hf_ansi_801_gps_acq_cap,
1991
14
      { "GPS_ACQ_CAP", "ansi_801.gps_acq_cap",
1992
14
        FT_UINT24, BASE_HEX, NULL, 0x000FFF,
1993
14
        NULL, HFILL }
1994
14
    },
1995
14
    { &hf_ansi_801_reserved_24_F80000,
1996
14
      { "Reserved", "ansi_801.reserved",
1997
14
        FT_UINT24, BASE_HEX, NULL, 0xf80000,
1998
14
        NULL, HFILL }
1999
14
    },
2000
14
    { &hf_ansi_801_gps_autonomous_acquisition_capable,
2001
14
      { "GPS Autonomous Acquisition Capable", "ansi_801.gps_autonomous_acquisition_capable",
2002
14
        FT_BOOLEAN, 24, NULL, 0x040000,
2003
14
        NULL, HFILL }
2004
14
    },
2005
14
    { &hf_ansi_801_gps_almanac_correction,
2006
14
      { "GPS Almanac Correction", "ansi_801.gps_almanac_correction",
2007
14
        FT_BOOLEAN, 24, NULL, 0x020000,
2008
14
        NULL, HFILL }
2009
14
    },
2010
14
    { &hf_ansi_801_gps_navigation_message_bits,
2011
14
      { "GPS Navigation Message Bits", "ansi_801.gps_navigation_message_bits",
2012
14
        FT_BOOLEAN, 24, NULL, 0x010000,
2013
14
        NULL, HFILL }
2014
14
    },
2015
14
    { &hf_ansi_801_gps_ephemeris,
2016
14
      { "GPS Ephemeris", "ansi_801.gps_ephemeris",
2017
14
        FT_BOOLEAN, 24, NULL, 0x008000,
2018
14
        NULL, HFILL }
2019
14
    },
2020
14
    { &hf_ansi_801_gps_almanac,
2021
14
      { "GPS Almanac", "ansi_801.gps_almanac",
2022
14
        FT_BOOLEAN, 24, NULL, 0x004000,
2023
14
        NULL, HFILL }
2024
14
    },
2025
14
    { &hf_ansi_801_gps_sensitivity_assistance,
2026
14
      { "GPS Sensitivity Assistance", "ansi_801.gps_sensitivity_assistance",
2027
14
        FT_BOOLEAN, 24, NULL, 0x002000,
2028
14
        NULL, HFILL }
2029
14
    },
2030
14
    { &hf_ansi_801_gps_acquisition_assistance,
2031
14
      { "GPS Acquisition Assistance", "ansi_801.gps_acquisition_assistance",
2032
14
        FT_BOOLEAN, 24, NULL, 0x001000,
2033
14
        NULL, HFILL }
2034
14
    },
2035
14
    { &hf_ansi_801_loc_calc_cap,
2036
14
      { "LOC_CALC_CAP", "ansi_801.loc_calc_cap",
2037
14
        FT_UINT24, BASE_HEX, NULL, 0x000FFF,
2038
14
        NULL, HFILL }
2039
14
    },
2040
14
    { &hf_ansi_801_pre_programmed_location,
2041
14
      { "Pre-programmed Location", "ansi_801.pre_programmed_location",
2042
14
        FT_BOOLEAN, 24, NULL, 0x000800,
2043
14
        NULL, HFILL }
2044
14
    },
2045
14
    { &hf_ansi_801_reserved_24_700,
2046
14
      { "Reserved", "ansi_801.reserved",
2047
14
        FT_UINT24, BASE_HEX, NULL, 0x000700,
2048
14
        NULL, HFILL }
2049
14
    },
2050
14
    { &hf_ansi_801_hybrid_gps_and_aflt_lcc,
2051
14
      { "Hybrid GPS and AFLT Location Calculation Capable", "ansi_801.hybrid_gps_and_aflt_lcc",
2052
14
        FT_BOOLEAN, 24, NULL, 0x000080,
2053
14
        NULL, HFILL }
2054
14
    },
2055
14
    { &hf_ansi_801_autonomous_location_calculation_capable,
2056
14
      { "Autonomous Location Calculation Capable", "ansi_801.autonomous_lcc",
2057
14
        FT_BOOLEAN, 24, NULL, 0x000040,
2058
14
        NULL, HFILL }
2059
14
    },
2060
14
    { &hf_ansi_801_lcc_using_gps_almanac_correction,
2061
14
      { "Location Calculation Capable using GPS Almanac Correction", "ansi_801.lcc_using_gps_almanac_correction",
2062
14
        FT_BOOLEAN, 24, NULL, 0x000020,
2063
14
        NULL, HFILL }
2064
14
    },
2065
14
    { &hf_ansi_801_lcc_using_gps_ephemeris_assistance,
2066
14
      { "Location Calculation Capable using GPS Ephemeris Assistance", "ansi_801.lcc_using_gps_ephemeris_assistance",
2067
14
        FT_BOOLEAN, 24, NULL, 0x000010,
2068
14
        NULL, HFILL }
2069
14
    },
2070
14
    { &hf_ansi_801_lcc_using_gps_almanac_assistance,
2071
14
      { "Location Calculation Capable using GPS Almanac Assistance", "ansi_801.lcc_using_gps_almanac_assistance",
2072
14
        FT_BOOLEAN, 24, NULL, 0x000008,
2073
14
        NULL, HFILL }
2074
14
    },
2075
14
    { &hf_ansi_801_aflt_lcc,
2076
14
      { "Advanced Forward Link Trilateration (AFLT) Location Calculation Capable", "ansi_801.aflt_lcc",
2077
14
        FT_BOOLEAN, 24, NULL, 0x000004,
2078
14
        NULL, HFILL }
2079
14
    },
2080
14
    { &hf_ansi_801_lcc_using_location_assistance_cartesian,
2081
14
      { "Location Calculation Capable using Location Assistance - Cartesian", "ansi_801.lcc_using_location_assistance.cartesian",
2082
14
        FT_BOOLEAN, 24, NULL, 0x000002,
2083
14
        NULL, HFILL }
2084
14
    },
2085
14
    { &hf_ansi_801_lcc_capable_using_location_assistance_spherical,
2086
14
      { "Location Calculation Capable using Location Assistance - Spherical", "ansi_801.lcc_using_location_assistance.spherical",
2087
14
        FT_BOOLEAN, 24, NULL, 0x000001,
2088
14
        NULL, HFILL }
2089
14
    },
2090
14
    { &hf_ansi_801_ref_pn,
2091
14
      { "REF_PN", "ansi_801.ref_pn",
2092
14
        FT_UINT24, BASE_DEC, NULL, 0xff8000,
2093
14
        NULL, HFILL }
2094
14
    },
2095
14
    { &hf_ansi_801_mob_sys_t_offset,
2096
14
      { "MOB_SYS_T_OFFSET", "ansi_801.mob_sys_t_offset",
2097
14
        FT_UINT24, BASE_DEC, NULL, 0x007ffe,
2098
14
        NULL, HFILL }
2099
14
    },
2100
14
    { &hf_ansi_801_reserved24_1,
2101
14
      { "Reserved", "ansi_801.reserved",
2102
14
        FT_UINT24, BASE_HEX, NULL, 0x000001,
2103
14
        NULL, HFILL }
2104
14
    },
2105
14
    { &hf_ansi_801_no_outstanding_request_element,
2106
14
      { "No outstanding request element", "ansi_801.no_outstanding_request_element",
2107
14
        FT_BOOLEAN, 8, NULL, 0x08,
2108
14
        NULL, HFILL }
2109
14
    },
2110
14
    { &hf_ansi_801_reserved8_07,
2111
14
      { "Reserved", "ansi_801.reserved",
2112
14
        FT_UINT8, BASE_HEX, NULL, 0x07,
2113
14
        NULL, HFILL }
2114
14
    },
2115
14
    { &hf_ansi_801_reserved8_F0,
2116
14
      { "Reserved", "ansi_801.reserved",
2117
14
        FT_UINT8, BASE_HEX, NULL, 0xF0,
2118
14
        NULL, HFILL }
2119
14
    },
2120
14
    { &hf_ansi_801_for_request_length,
2121
14
      { "Length", "ansi_801.for_request_length",
2122
14
        FT_UINT8, BASE_DEC, NULL, 0x0,
2123
14
        NULL, HFILL }
2124
14
    },
2125
14
    { &hf_ansi_801_reserved8_E0,
2126
14
      { "Reserved", "ansi_801.reserved",
2127
14
        FT_UINT8, BASE_HEX, NULL, 0xE0,
2128
14
        NULL, HFILL }
2129
14
    },
2130
14
    { &hf_ansi_801_unsolicited_response_indicator,
2131
14
      { "Unsolicited response indicator", "ansi_801.unsolicited_response_indicator",
2132
14
        FT_BOOLEAN, 8, NULL, 0x10,
2133
14
        NULL, HFILL }
2134
14
    },
2135
14
    { &hf_ansi_801_for_response_length,
2136
14
      { "Length", "ansi_801.for_response_length",
2137
14
        FT_UINT8, BASE_DEC, NULL, 0x0,
2138
14
        NULL, HFILL }
2139
14
    },
2140
14
    { &hf_ansi_801_rev_request_length,
2141
14
      { "Length", "ansi_801.rev_request_length",
2142
14
        FT_UINT8, BASE_DEC, NULL, 0x0,
2143
14
        NULL, HFILL }
2144
14
    },
2145
14
    { &hf_ansi_801_rev_response_length,
2146
14
      { "Length", "ansi_801.rev_response_length",
2147
14
        FT_UINT8, BASE_DEC, NULL, 0x0,
2148
14
        NULL, HFILL }
2149
14
    },
2150
14
    { &hf_ansi_801_session_start,
2151
14
      { "Session Start", "ansi_801.session_start",
2152
14
        FT_BOOLEAN, 8, NULL, 0x80,
2153
14
        NULL, HFILL }
2154
14
    },
2155
14
    { &hf_ansi_801_session_end,
2156
14
      { "Session End", "ansi_801.session_end",
2157
14
        FT_BOOLEAN, 8, NULL, 0x40,
2158
14
        NULL, HFILL }
2159
14
    },
2160
14
    { &hf_ansi_801_session_source,
2161
14
      { "Session Source", "ansi_801.session_source",
2162
14
        FT_BOOLEAN, 8, NULL, 0x20,
2163
14
        NULL, HFILL }
2164
14
    },
2165
14
    { &hf_ansi_801_pd_message_type,
2166
14
      { "PD Message Type", "ansi_801.pd_message_type",
2167
14
        FT_UINT8, BASE_DEC, NULL, 0x0,
2168
14
        NULL, HFILL }
2169
14
    },
2170
14
    { &hf_ansi_801_pd_message_len,
2171
14
      { "PD Message Length", "ansi_801.pd_message_len",
2172
14
        FT_UINT16, BASE_DEC, NULL, 0xffc0,
2173
14
        NULL, HFILL }
2174
14
    },
2175
14
    { &hf_ansi_801_regulatory_services_indicator,
2176
14
      { "Regulatory Services Indicator", "ansi_801.regulatory_services_indicator",
2177
14
        FT_UINT16, BASE_DEC, VALS(regulatory_services_indicator_vals), 0x0030,
2178
14
        NULL, HFILL }
2179
14
    },
2180
14
    { &hf_ansi_801_for_message_number_requests16,
2181
14
      { "Number Requests", "ansi_801.for_message_number_requests",
2182
14
        FT_UINT16, BASE_DEC, NULL, 0x0F,
2183
14
        NULL, HFILL }
2184
14
    },
2185
14
    { &hf_ansi_801_for_message_number_responsesF0,
2186
14
      { "Number Responses", "ansi_801.for_message_number_responses",
2187
14
        FT_UINT8, BASE_DEC, NULL, 0xF0,
2188
14
        NULL, HFILL }
2189
14
    },
2190
14
    { &hf_ansi_801_for_message_number_requests8,
2191
14
      { "Number Requests", "ansi_801.for_message_number_requests",
2192
14
        FT_UINT8, BASE_DEC, NULL, 0xF0,
2193
14
        NULL, HFILL }
2194
14
    },
2195
14
    { &hf_ansi_801_for_message_number_responses0F,
2196
14
      { "Number Responses", "ansi_801.for_message_number_responses",
2197
14
        FT_UINT8, BASE_DEC, NULL, 0x0F,
2198
14
        NULL, HFILL }
2199
14
    },
2200
14
    { &hf_ansi_801_rev_message_number_requests16,
2201
14
      { "Number Requests", "ansi_801.rev_message_number_requests",
2202
14
        FT_UINT16, BASE_DEC, NULL, 0x0F,
2203
14
        NULL, HFILL }
2204
14
    },
2205
14
    { &hf_ansi_801_rev_message_number_responsesF0,
2206
14
      { "Number Responses", "ansi_801.rev_message_number_responses",
2207
14
        FT_UINT8, BASE_DEC, NULL, 0xF0,
2208
14
        NULL, HFILL }
2209
14
    },
2210
14
    { &hf_ansi_801_rev_message_number_requests8,
2211
14
      { "Number Requests", "ansi_801.rev_message_number_requests",
2212
14
        FT_UINT8, BASE_DEC, NULL, 0xF0,
2213
14
        NULL, HFILL }
2214
14
    },
2215
14
    { &hf_ansi_801_rev_message_number_responses0F,
2216
14
      { "Number Responses", "ansi_801.rev_message_number_responses",
2217
14
        FT_UINT8, BASE_DEC, NULL, 0x0F,
2218
14
        NULL, HFILL }
2219
14
    },
2220
14
    { &hf_ansi_801_data,
2221
14
      { "Data", "ansi_801.data",
2222
14
        FT_BYTES, BASE_NONE, NULL, 0x0,
2223
14
        NULL, HFILL }
2224
14
    },
2225
14
    { &hf_ansi_801_proprietary_data,
2226
14
      { "Reserved/Proprietary/Future Data", "ansi_801.proprietary_data",
2227
14
        FT_BYTES, BASE_NONE, NULL, 0x0,
2228
14
        NULL, HFILL }
2229
14
    },
2230
14
    { &hf_ansi_801_time_ref_ms,
2231
14
      { "TIME_REF_MS", "ansi_801.time_ref_ms",
2232
14
        FT_UINT24, BASE_DEC, NULL, 0x0,
2233
14
        NULL, HFILL }
2234
14
    },
2235
14
    { &hf_ansi_801_time_of_almanac,
2236
14
      { "Time of almanac", "ansi_801.time_of_almanac",
2237
14
        FT_UINT8, BASE_DEC|BASE_UNIT_STRING, UNS(&units_time_of_almanac), 0x0,
2238
14
        NULL, HFILL }
2239
14
    },
2240
14
    { &hf_ansi_801_gps_week_number,
2241
14
      { "GPS week number", "ansi_801.gps_week_number",
2242
14
        FT_UINT8, BASE_DEC|BASE_UNIT_STRING, UNS(&units_gps_week_number), 0x0,
2243
14
        NULL, HFILL }
2244
14
    },
2245
14
  };
2246
2247
  /* Setup protocol subtree array */
2248
14
#define NUM_INDIVIDUAL_PARAMS 3
2249
14
  int *ett[NUM_INDIVIDUAL_PARAMS+NUM_FOR_REQ_TYPE+NUM_FOR_RSP_TYPE+NUM_REV_REQ_TYPE+NUM_REV_RSP_TYPE];
2250
2251
2252
14
  static ei_register_info ei[] = {
2253
14
    { &ei_ansi_801_extraneous_data, { "ansi_801.extraneous_data", PI_PROTOCOL, PI_NOTE, "Extraneous Data, dissector bug or later version spec (report to wireshark.org)", EXPFILL }},
2254
14
    { &ei_ansi_801_short_data, { "ansi_801.short_data", PI_PROTOCOL, PI_NOTE, "Short Data (?) - try checking decoder variant preference or dissector bug/later version spec (report to wireshark.org)", EXPFILL }},
2255
14
    { &ei_ansi_801_unexpected_length, { "ansi_801.unexpected_length", PI_PROTOCOL, PI_WARN, "Unexpected Data Length - try checking decoder variant preference or dissector bug/later version spec (report to wireshark.org)", EXPFILL }},
2256
14
  };
2257
2258
14
  expert_module_t* expert_ansi_801;
2259
2260
14
  ett[0] = &ett_ansi_801;
2261
14
  ett[1] = &ett_gps;
2262
14
  ett[2] = &ett_loc;
2263
2264
14
  last_offset = NUM_INDIVIDUAL_PARAMS;
2265
2266
140
  for (i=0; i < NUM_FOR_REQ_TYPE; i++, last_offset++)
2267
126
  {
2268
126
    ett[last_offset] = &ett_for_req_type[i];
2269
126
  }
2270
2271
210
  for (i=0; i < NUM_FOR_RSP_TYPE; i++, last_offset++)
2272
196
  {
2273
196
    ett[last_offset] = &ett_for_rsp_type[i];
2274
196
  }
2275
2276
210
  for (i=0; i < NUM_REV_REQ_TYPE; i++, last_offset++)
2277
196
  {
2278
196
    ett[last_offset] = &ett_rev_req_type[i];
2279
196
  }
2280
2281
140
  for (i=0; i < NUM_REV_RSP_TYPE; i++, last_offset++)
2282
126
  {
2283
126
    ett[last_offset] = &ett_rev_rsp_type[i];
2284
126
  }
2285
2286
  /* Register the protocol name and description */
2287
14
  proto_ansi_801 =
2288
14
    proto_register_protocol(ansi_proto_name, "ANSI IS-801 (Location Services (PLD))", "ansi_801");
2289
2290
  /* Required function calls to register the header fields and subtrees used */
2291
14
  proto_register_field_array(proto_ansi_801, hf, array_length(hf));
2292
14
  proto_register_subtree_array(ett, array_length(ett));
2293
14
  expert_ansi_801 = expert_register_protocol(proto_ansi_801);
2294
14
  expert_register_field_array(expert_ansi_801, ei, array_length(ei));
2295
2296
  /* subdissector code */
2297
14
  ansi_801_handle = register_dissector("ansi_801", dissect_ansi_801, proto_ansi_801);
2298
14
}
2299
2300
2301
void
2302
proto_reg_handoff_ansi_801(void)
2303
14
{
2304
14
  dissector_add_uint("ansi_map.pld", ANSI_801_FORWARD, ansi_801_handle);
2305
14
  dissector_add_uint("ansi_map.pld", ANSI_801_REVERSE, ansi_801_handle);
2306
14
  dissector_add_uint("ansi_a.pld",   ANSI_801_FORWARD, ansi_801_handle);
2307
14
  dissector_add_uint("ansi_a.pld",   ANSI_801_REVERSE, ansi_801_handle);
2308
14
}
2309
2310
/*
2311
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
2312
 *
2313
 * Local variables:
2314
 * c-basic-offset: 8
2315
 * tab-width: 8
2316
 * indent-tabs-mode: t
2317
 * End:
2318
 *
2319
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2320
 * :indentSize=8:tabSize=8:noTabs=false:
2321
 */