Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-ppi-gps.c
blob8eb1d3f012357bbde56e507efec4e0f4d07352a2
1 /* packet-ppi-gps.c
2 * Routines for PPI-GEOLOCATION-GPS dissection
3 * Copyright 2010, Harris Corp, jellch@harris.com
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * Copied from packet-radiotap.c
11 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include "config.h"
16 #include <epan/packet.h>
17 #include <epan/expert.h>
18 #include "packet-ppi-geolocation-common.h"
20 enum ppi_geotagging_type {
21 PPI_GEOTAG_GPSFLAGS = 0,
22 PPI_GEOTAG_LAT = 1,
23 PPI_GEOTAG_LON = 2,
24 PPI_GEOTAG_ALT = 3,
25 PPI_GEOTAG_ALT_G = 4,
26 PPI_GEOTAG_GPSTIME = 5,
27 PPI_GEOTAG_FRACTIONALTIME = 6,
28 PPI_GEOTAG_EPH = 7,
29 PPI_GEOTAG_EPV = 8,
30 PPI_GEOTAG_EPT = 9,
31 PPI_GEOTAG_DESCRIPTIONSTR = 28,
32 PPI_GEOTAG_APPID = 29,
33 PPI_GEOTAG_APPDATA = 30,
34 PPI_GEOTAG_EXT = 31
36 #define PPI_GPS_MAXTAGLEN 144 /* increase as fields are added */
38 #define PPI_GPS_MASK_GPSFLAGS 0x00000001
39 #define PPI_GPS_MASK_LAT 0x00000002
40 #define PPI_GPS_MASK_LON 0x00000004
41 #define PPI_GPS_MASK_ALT 0x00000008
42 #define PPI_GPS_MASK_ALT_G 0x00000010
44 #define PPI_GPS_MASK_GPSTIME 0x00000020
45 #define PPI_GPS_MASK_FRACTIME 0x00000040
46 #define PPI_GPS_MASK_EPH 0x00000080
47 #define PPI_GPS_MASK_EPV 0x00000100
48 #define PPI_GPS_MASK_EPT 0x00000200
50 #define PPI_GPS_MASK_DESCRSTR 0x10000000
51 #define PPI_GPS_MASK_APPID 0x20000000
52 #define PPI_GPS_MASK_APPDATA 0x40000000
53 #define PPI_GPS_MASK_EXT 0x80000000
56 void proto_register_ppi_gps(void);
58 /* protocol */
59 static int proto_ppi_gps;
61 static int hf_ppi_gps_version;
62 static int hf_ppi_gps_pad;
63 static int hf_ppi_gps_length;
64 static int hf_ppi_gps_present;
65 static int hf_ppi_gps_gpsflags_flags;
66 static int hf_ppi_gps_lon;
67 static int hf_ppi_gps_lat;
68 static int hf_ppi_gps_alt;
69 static int hf_ppi_gps_alt_gnd;
70 static int hf_ppi_gps_gpstime;
71 static int hf_ppi_gps_fractime;
72 static int hf_ppi_gps_eph;
73 static int hf_ppi_gps_epv;
74 static int hf_ppi_gps_ept;
75 static int hf_ppi_gps_descstr;
76 static int hf_ppi_gps_appspecific_num; /* 4-byte tag no */
77 static int hf_ppi_gps_appspecific_data; /* 60 byte arbitrary data */
78 /* "Present" flags, tese represent decoded-bits in the gui */
79 static int hf_ppi_gps_present_gpsflags_flags;
80 static int hf_ppi_gps_present_lon;
81 static int hf_ppi_gps_present_lat;
82 static int hf_ppi_gps_present_alt;
83 static int hf_ppi_gps_present_alt_gnd;
84 static int hf_ppi_gps_present_gpstime;
85 static int hf_ppi_gps_present_fractime;
86 static int hf_ppi_gps_present_eph;
87 static int hf_ppi_gps_present_epv;
88 static int hf_ppi_gps_present_ept;
89 static int hf_ppi_gps_present_descr;
90 static int hf_ppi_gps_present_appspecific_num;
91 static int hf_ppi_gps_present_appspecific_data;
92 static int hf_ppi_gps_present_ext;
94 /* Devicetype flags. not to be confused with "present" flags. These are optional */
95 static int hf_ppi_gps_gpsflags_flag0_nofix;
96 static int hf_ppi_gps_gpsflags_flag1_gpsfix;
97 static int hf_ppi_gps_gpsflags_flag2_diffgps;
98 static int hf_ppi_gps_gpsflags_flag3_PPS;
99 static int hf_ppi_gps_gpsflags_flag4_RTK;
100 static int hf_ppi_gps_gpsflags_flag5_floatRTK;
101 static int hf_ppi_gps_gpsflags_flag6_dead_reck;
102 static int hf_ppi_gps_gpsflags_flag7_manual;
103 static int hf_ppi_gps_gpsflags_flag8_sim;
105 /* These represent arrow-dropdownthings in the gui */
106 static int ett_ppi_gps;
107 static int ett_ppi_gps_present;
108 static int ett_ppi_gps_gpsflags_flags;
110 static expert_field ei_ppi_gps_present_bit;
111 static expert_field ei_ppi_gps_version;
112 static expert_field ei_ppi_gps_length;
114 static int
115 dissect_ppi_gps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
116 /* These are locals used for processing the current tvb */
117 unsigned length;
118 int length_remaining;
119 int offset = 0;
121 proto_tree *ppi_gps_tree = NULL;
123 proto_item *version_item, *length_item, *pt;
124 proto_item *gps_line = NULL;
126 static int * const ppi_gps_present_flags[] = {
127 &hf_ppi_gps_present_gpsflags_flags,
128 &hf_ppi_gps_present_lat,
129 &hf_ppi_gps_present_lon,
130 &hf_ppi_gps_present_alt,
131 &hf_ppi_gps_present_alt_gnd,
132 &hf_ppi_gps_present_gpstime,
133 &hf_ppi_gps_present_fractime,
134 &hf_ppi_gps_present_eph,
135 &hf_ppi_gps_present_epv,
136 &hf_ppi_gps_present_ept,
137 &hf_ppi_gps_present_descr,
138 &hf_ppi_gps_present_appspecific_num,
139 &hf_ppi_gps_present_appspecific_data,
140 &hf_ppi_gps_present_ext,
141 NULL
144 static int * const ppi_antenna_gps_flags[] = {
145 &hf_ppi_gps_gpsflags_flag0_nofix,
146 &hf_ppi_gps_gpsflags_flag1_gpsfix,
147 &hf_ppi_gps_gpsflags_flag2_diffgps,
148 &hf_ppi_gps_gpsflags_flag3_PPS,
149 &hf_ppi_gps_gpsflags_flag4_RTK,
150 &hf_ppi_gps_gpsflags_flag5_floatRTK,
151 &hf_ppi_gps_gpsflags_flag6_dead_reck,
152 &hf_ppi_gps_gpsflags_flag7_manual,
153 &hf_ppi_gps_gpsflags_flag8_sim,
154 NULL
157 /* bits */
158 int bit;
159 uint32_t present, next_present;
160 /* values actually read out, for displaying */
161 uint32_t version;
162 double lat, lon, alt, alt_gnd;
163 nstime_t gps_timestamp;
164 int gps_time_size, already_processed_fractime; /* we use this internally to track if this is a 4 or 8 byte wide timestamp */
165 double eph, epv, ept;
166 char *curr_str;
169 /* these are temporary intermediate values, used in the individual cases below */
170 uint32_t t_lat, t_lon, t_alt, t_alt_gnd;
171 uint32_t t_herr, t_verr, t_terr;
172 uint32_t t_appspecific_num;
173 /* initialize the timestamp value(s) */
174 gps_timestamp.secs = gps_timestamp.nsecs = already_processed_fractime = 0;
176 /* Clear out stuff in the info column */
177 col_clear(pinfo->cinfo,COL_INFO);
179 /* pull out the first three fields of the BASE-GEOTAG-HEADER */
180 version = tvb_get_uint8(tvb, offset);
181 length = tvb_get_letohs(tvb, offset+2);
182 present = tvb_get_letohl(tvb, offset+4);
184 /* Setup basic column info */
185 col_add_fstr(pinfo->cinfo, COL_INFO, "PPI_GPS Capture v%u, Length %u", version, length);
187 /* Create the basic dissection tree*/
188 gps_line = proto_tree_add_protocol_format(tree, proto_ppi_gps, tvb, 0, length, "GPS:");
189 ppi_gps_tree = proto_item_add_subtree(gps_line, ett_ppi_gps);
190 version_item = proto_tree_add_uint(ppi_gps_tree, hf_ppi_gps_version, tvb, offset, 1, version);
191 proto_tree_add_item(ppi_gps_tree, hf_ppi_gps_pad, tvb, offset + 1, 1, ENC_LITTLE_ENDIAN);
192 length_item = proto_tree_add_uint(ppi_gps_tree, hf_ppi_gps_length, tvb, offset + 2, 2, length);
194 /* We support v1 and v2 of GPS tags (identical) */
195 if (! (version == 1 || version == 2) ) {
196 expert_add_info_format(pinfo, version_item, &ei_ppi_gps_version, "Invalid version (got %d, expected 1 or 2)", version);
199 /* initialize the length of the actual tag contents */
200 length_remaining = length;
201 /* minimum length check, should atleast be a fixed-size geotagging-base header*/
202 if (length_remaining < PPI_GEOBASE_MIN_HEADER_LEN) {
204 * Base-geotag-header (Radiotap lookalike) is shorter than the fixed-length portion
205 * plus one "present" bitset.
207 expert_add_info_format(pinfo, length_item, &ei_ppi_gps_length, "Invalid PPI-GPS length - minimum length is 8");
208 return 2;
211 /* perform tag-specific max length sanity checking */
212 if (length > PPI_GPS_MAXTAGLEN ) {
213 expert_add_info_format(pinfo, length_item, &ei_ppi_gps_length, "Invalid PPI-GPS length (got %d, %d max\n)", length, PPI_GPS_MAXTAGLEN);
214 return 2;
217 /* Subtree for the "present flags" bitfield. */
218 pt = proto_tree_add_bitmask(ppi_gps_tree, tvb, offset + 4, hf_ppi_gps_present, ett_ppi_gps_present, ppi_gps_present_flags, ENC_LITTLE_ENDIAN);
220 offset += PPI_GEOBASE_MIN_HEADER_LEN;
221 length_remaining -= PPI_GEOBASE_MIN_HEADER_LEN;
223 /* The fixed BASE-GEOTAG-HEADER has been handled at this point. move on to the individual fields */
224 for (; present; present = next_present) {
225 /* clear the least significant bit that is set */
226 next_present = present & (present - 1);
227 /* extract the least significant bit that is set */
228 bit = BITNO_32(present ^ next_present);
229 switch (bit) {
230 case PPI_GEOTAG_GPSFLAGS:
231 if (length_remaining < 4)
232 break;
233 proto_tree_add_bitmask(ppi_gps_tree, tvb, offset, hf_ppi_gps_gpsflags_flags, ett_ppi_gps_gpsflags_flags, ppi_antenna_gps_flags, ENC_LITTLE_ENDIAN);
234 offset+=4;
235 length_remaining-=4;
236 break;
237 case PPI_GEOTAG_LAT:
238 if (length_remaining < 4)
239 break;
240 t_lat = tvb_get_letohl(tvb, offset);
241 lat = ppi_fixed3_7_to_double(t_lat);
242 if (tree)
244 proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_lat, tvb, offset, 4, lat);
245 proto_item_append_text(gps_line, " Lat:%f ", lat);
247 offset+=4;
248 length_remaining-=4;
249 break;
250 case PPI_GEOTAG_LON:
251 if (length_remaining < 4)
252 break;
253 t_lon = tvb_get_letohl(tvb, offset);
254 lon = ppi_fixed3_7_to_double(t_lon);
255 if (tree)
257 proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_lon, tvb, offset, 4, lon);
258 proto_item_append_text(gps_line, " Lon:%f ", lon);
260 offset+=4;
261 length_remaining-=4;
262 break;
263 case PPI_GEOTAG_ALT:
264 if (length_remaining < 4)
265 break;
266 t_alt = tvb_get_letohl(tvb, offset);
267 alt = ppi_fixed6_4_to_double(t_alt);
268 if (tree)
270 proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_alt, tvb, offset, 4, alt);
271 proto_item_append_text(gps_line, " Alt:%f ", alt);
273 offset+=4;
274 length_remaining-=4;
275 break;
276 case PPI_GEOTAG_ALT_G:
277 if (length_remaining < 4)
278 break;
279 t_alt_gnd = tvb_get_letohl(tvb, offset);
280 alt_gnd = ppi_fixed6_4_to_double(t_alt_gnd);
281 if (tree)
283 proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_alt_gnd, tvb, offset, 4, alt_gnd);
284 proto_item_append_text(gps_line, " Alt_g:%f ", alt_gnd);
286 offset+=4;
287 length_remaining-=4;
288 break;
289 case PPI_GEOTAG_GPSTIME:
290 if (length_remaining < 4)
291 break;
292 gps_timestamp.secs = tvb_get_letohl(tvb, offset);
293 gps_timestamp.nsecs = 0;
294 gps_time_size = 4;
295 /* This is somewhat tricky, inside the GPSTIME case we test if the optional fractional time */
296 /* is present. If so, we pull it out, and combine it with GPSTime. */
297 /* If we do this, we set already_processed_fractime to avoid hitting it below */
298 if (length_remaining < 8 && (present & PPI_GPS_MASK_FRACTIME))
299 break;
300 else if (present & PPI_GPS_MASK_FRACTIME) {
301 gps_timestamp.nsecs = tvb_get_letohl(tvb, offset + 4); /* manually offset seconds */
302 already_processed_fractime = 1;
303 gps_time_size = 8;
305 proto_tree_add_time(ppi_gps_tree, hf_ppi_gps_gpstime, tvb, offset, gps_time_size, &gps_timestamp);
306 offset += gps_time_size;
307 length_remaining -= gps_time_size;
308 break;
309 case PPI_GEOTAG_FRACTIONALTIME:
310 if (length_remaining < 4)
311 break;
312 if (already_processed_fractime)
313 break;
314 proto_tree_add_item(ppi_gps_tree, hf_ppi_gps_fractime, tvb, offset, 4, ENC_LITTLE_ENDIAN);
315 offset += 4;
316 length_remaining -= 4;
317 break;
318 case PPI_GEOTAG_EPH:
319 if (length_remaining < 4)
320 break;
321 t_herr = tvb_get_letohl(tvb, offset);
322 eph = ppi_fixed3_6_to_double(t_herr);
323 proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_eph, tvb, offset, 4, eph);
324 offset+=4;
325 length_remaining-=4;
326 break;
327 case PPI_GEOTAG_EPV:
328 if (length_remaining < 4)
329 break;
330 t_verr = tvb_get_letohl(tvb, offset);
331 epv = ppi_fixed3_6_to_double(t_verr);
332 proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_epv, tvb, offset, 4, epv);
333 offset+=4;
334 length_remaining-=4;
335 break;
336 case PPI_GEOTAG_EPT:
337 if (length_remaining < 4)
338 break;
339 t_terr = tvb_get_letohl(tvb, offset);
340 ept = ppi_ns_counter_to_double(t_terr);
341 proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_ept, tvb, offset, 4, ept);
342 offset+=4;
343 length_remaining-=4;
344 break;
345 case PPI_GEOTAG_DESCRIPTIONSTR:
346 if (length_remaining < 32)
347 break;
348 if (tree)
350 /* proto_tree_add_item(ppi_gps_tree, hf_ppi_gps_descstr, tvb, offset, 32, ENC_ASCII); */
351 curr_str = tvb_format_stringzpad(pinfo->pool, tvb, offset, 32); /* need to append_text this */
352 proto_tree_add_string(ppi_gps_tree, hf_ppi_gps_descstr, tvb, offset, 32, curr_str);
353 proto_item_append_text(gps_line, " (%s)", curr_str);
355 offset+=32;
356 length_remaining-=32;
357 break;
358 case PPI_GEOTAG_APPID:
359 if (length_remaining < 4)
360 break;
361 t_appspecific_num = tvb_get_letohl(tvb, offset); /* application specific parsers may switch on this later */
362 proto_tree_add_uint(ppi_gps_tree, hf_ppi_gps_appspecific_num, tvb, offset, 4, t_appspecific_num);
363 offset+=4;
364 length_remaining-=4;
365 break;
366 case PPI_GEOTAG_APPDATA:
367 if (length_remaining < 60)
368 break;
369 proto_tree_add_item(ppi_gps_tree, hf_ppi_gps_appspecific_data, tvb, offset, 60, ENC_NA);
370 offset+=60;
371 length_remaining-=60;
372 break;
375 * This indicates a field whose size we do not know, so we cannot proceed.
377 default:
378 next_present = 0; /* this will terminate the loop */
379 expert_add_info_format(pinfo, pt, &ei_ppi_gps_present_bit,
380 "Error: PPI-GEOLOCATION-GPS: unknown bit (%d) set in present field.", bit);
381 continue;
382 } /* switch (bit) */
384 } /* (for present..)*/
386 /* If there was any post processing of the elements, it could happen here. */
387 return tvb_captured_length(tvb);
390 void
391 proto_register_ppi_gps(void) {
392 /* The following array initializes those header fields declared above to the values displayed */
393 static hf_register_info hf[] = {
394 { &hf_ppi_gps_version,
395 { "Header revision", "ppi_gps.version",
396 FT_UINT8, BASE_DEC, NULL, 0x0,
397 "Version of ppi_gps header format", HFILL } },
398 { &hf_ppi_gps_pad,
399 { "Header pad", "ppi_gps.pad",
400 FT_UINT8, BASE_DEC, NULL, 0x0,
401 "Padding", HFILL } },
402 { &hf_ppi_gps_length,
403 { "Header length", "ppi_gps.length",
404 FT_UINT16, BASE_DEC, NULL, 0x0,
405 "Length of header including version, pad, length and data fields", HFILL } },
406 { &hf_ppi_gps_present, /* these flag fields are composed of a uint32 on the display */
407 { "Present", "ppi_gps.present",
408 FT_UINT32, BASE_HEX, NULL, 0x0,
409 "Bitmask indicating which fields are present", HFILL } },
411 /* Boolean 'present' flags */
412 { &hf_ppi_gps_present_gpsflags_flags, /* followed by a lot of booleans */
413 { "GPSFlags", "ppi_gps.present.gpsflagss",
414 FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_GPSFLAGS,
415 "32-bit bitmask indicating type of GPS fix (GPS/INS/software/etc)", HFILL } },
416 { &hf_ppi_gps_present_lat,
417 { "Lat", "ppi_gps.present.lat",
418 FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_LAT,
419 "Specifies if the latitude field is present", HFILL } },
421 { &hf_ppi_gps_present_lon,
422 { "Lon", "ppi_gps.present.lon",
423 FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_LON,
424 "Specifies if the longitude field is present", HFILL } },
426 { &hf_ppi_gps_present_alt,
427 { "Alt", "ppi_gps.present.alt",
428 FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_ALT,
429 "Specifies if the altitude field is present", HFILL } },
431 { &hf_ppi_gps_present_alt_gnd,
432 { "Alt-gnd", "ppi_gps.present.alt_gnd",
433 FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_ALT_G,
434 "Specifies if the altitude-g field is present", HFILL } },
436 { &hf_ppi_gps_present_gpstime,
437 { "GPStime", "ppi_gps.present.gpstime",
438 FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_GPSTIME,
439 "Specifies if the GPS time field is present", HFILL } },
442 { &hf_ppi_gps_present_fractime,
443 { "fractime", "ppi_gps.present.fractime",
444 FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_FRACTIME,
445 "Specifies if the fractional time field is present", HFILL } },
448 { &hf_ppi_gps_present_eph,
449 { "error_h", "ppi_gps.present.eph",
450 FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_EPH,
451 "Specifies if the horizontal error field is present (eph)", HFILL } },
453 { &hf_ppi_gps_present_epv,
454 { "error_v", "ppi_gps.present.epv",
455 FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_EPV,
456 "Specifies if the vertical error field present (epv)", HFILL } },
459 { &hf_ppi_gps_present_ept,
460 { "error_t", "ppi_gps.present.ept",
461 FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_EPT,
462 "Specifies if the estimated time error field is present (ept)", HFILL } },
464 { &hf_ppi_gps_present_descr,
465 { "Description", "ppi_gps.present.descr",
466 FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_DESCRSTR,
467 "Specifies if the (ASCII) description is present", HFILL } },
469 { &hf_ppi_gps_present_appspecific_num,
470 { "AppId", "ppi_gps.present.appid",
471 FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_APPID,
472 "Specifies if the application specific field id is present", HFILL } },
474 { &hf_ppi_gps_present_appspecific_data,
475 { "AppData", "ppi_gps.present.appdata",
476 FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_APPDATA,
477 "Specifies if the application specific data field is present", HFILL } },
479 { &hf_ppi_gps_present_ext,
480 { "Ext", "ppi_gps.present.ext",
481 FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_EXT,
482 "Specifies if there are any extensions to the header present", HFILL } },
484 /* ---Now we get to the actual data fields--- */
486 { &hf_ppi_gps_gpsflags_flags,
487 { "GPSFlags", "ppi_gps.gpsflags",
488 FT_UINT32, BASE_HEX, NULL, 0x0,
489 "Bitmask indicating GPS/INS/manual fix", HFILL } },
490 { &hf_ppi_gps_lat,
491 { "Latitude", "ppi_gps.lat",
492 FT_DOUBLE, BASE_NONE, NULL, 0x0,
493 "Latitude packet was received at", HFILL } },
494 { &hf_ppi_gps_lon,
495 { "Longitude", "ppi_gps.lon",
496 FT_DOUBLE, BASE_NONE, NULL, 0x0,
497 "Longitude packet was received at", HFILL } },
498 { &hf_ppi_gps_alt,
499 { "Altitude", "ppi_gps.alt",
500 FT_DOUBLE, BASE_NONE, NULL, 0x0,
501 "Altitude packet was received at", HFILL } },
502 { &hf_ppi_gps_alt_gnd,
503 { "Altitude_gnd", "ppi_gps.alt_gnd",
504 FT_DOUBLE, BASE_NONE, NULL, 0x0,
505 "Altitude packet was received at (relative to ground)", HFILL } },
506 { &hf_ppi_gps_gpstime,
507 { "GPSTimestamp", "ppi_gps.gpstime",
508 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0,
509 "GPSTimestamp packet was received at", HFILL } },
510 { &hf_ppi_gps_fractime,
511 { "fractional Timestamp", "ppi_gps.fractime",
512 FT_UINT32, BASE_DEC, NULL, 0x0,
513 "Fractional of GPSTimestamp packet was received at", HFILL } },
514 { &hf_ppi_gps_eph,
515 { "Horizontal Error (m)", "ppi_gps.eph",
516 FT_DOUBLE, BASE_NONE, NULL, 0x0,
517 "Horizontal margin of error (meters)", HFILL } },
518 { &hf_ppi_gps_epv,
519 { "Vertical Error (m)", "ppi_gps.epv",
520 FT_DOUBLE, BASE_NONE, NULL, 0x0,
521 "Vertical margin of error (meters)", HFILL } },
522 { &hf_ppi_gps_ept,
523 { "Time Error (s)", "ppi_gps.ept",
524 FT_DOUBLE, BASE_NONE, NULL, 0x0,
525 "Time margin of error (secs)", HFILL } },
526 { &hf_ppi_gps_descstr,
527 { "Description", "ppi_gps.descr",
528 FT_STRING, BASE_NONE, NULL, 0x0,
529 NULL, HFILL } },
530 { &hf_ppi_gps_appspecific_num,
531 { "Application Specific id", "ppi_gps.appid",
532 FT_UINT32, BASE_HEX, NULL, 0x0,
533 NULL, HFILL } },
534 { &hf_ppi_gps_appspecific_data,
535 { "Application specific data", "ppi_gps.appdata",
536 FT_BYTES, BASE_NONE, NULL, 0x0,
537 NULL, HFILL } },
539 /* --- moving on to the 'FixType' flags --- */
540 #define PPI_GPS_GPSFLAGS_FLAG0_NOFIX 0x00000001
541 #define PPI_GPS_GPSFLAGS_FLAG1_GPS 0x00000002
542 #define PPI_GPS_GPSFLAGS_FLAG2_DIFFGPS 0x00000004
543 #define PPI_GPS_GPSFLAGS_FLAG3_PPS 0x00000008
544 #define PPI_GPS_GPSFLAGS_FLAG4_RTK 0x00000010
545 #define PPI_GPS_GPSFLAGS_FLAG5_FLOATRTK 0x00000020
546 #define PPI_GPS_GPSFLAGS_FLAG6_DEAD_RECK 0x00000040
547 #define PPI_GPS_GPSFLAGS_FLAG7_MANUAL 0x00000080
548 #define PPI_GPS_GPSFLAGS_FLAG8_SIM 0x00000100
549 { &hf_ppi_gps_gpsflags_flag0_nofix, /* no fix available */
550 { "No fix available", "ppi_gps.gpsflagss.nofix",
551 FT_BOOLEAN, 32, NULL, PPI_GPS_GPSFLAGS_FLAG0_NOFIX,
552 NULL, HFILL } },
553 { &hf_ppi_gps_gpsflags_flag1_gpsfix, /* GPSfix available */
554 { "GPS provided fix", "ppi_gps.gpsflagss.gps",
555 FT_BOOLEAN, 32, NULL, PPI_GPS_GPSFLAGS_FLAG1_GPS,
556 NULL, HFILL } },
557 { &hf_ppi_gps_gpsflags_flag2_diffgps, /* Differential GPS fix available */
558 { "Differential GPS provided fix", "ppi_gps.gpsflagss.diffgps",
559 FT_BOOLEAN, 32, NULL, PPI_GPS_GPSFLAGS_FLAG2_DIFFGPS,
560 NULL, HFILL } },
561 { &hf_ppi_gps_gpsflags_flag3_PPS, /* PPS fix */
562 { "PPS fix", "ppi_gps.gpsflagss.pps",
563 FT_BOOLEAN, 32, NULL, PPI_GPS_GPSFLAGS_FLAG3_PPS,
564 NULL, HFILL } },
565 { &hf_ppi_gps_gpsflags_flag4_RTK, /* RTK fix*/
566 { "RTK fix", "ppi_gps.gpsflagss.rtk",
567 FT_BOOLEAN, 32, NULL, PPI_GPS_GPSFLAGS_FLAG4_RTK,
568 NULL, HFILL } },
569 { &hf_ppi_gps_gpsflags_flag5_floatRTK, /*float RTK */
570 { "floatRTK fix", "ppi_gps.gpsflagss.frtk",
571 FT_BOOLEAN, 32, NULL, PPI_GPS_GPSFLAGS_FLAG5_FLOATRTK,
572 NULL, HFILL } },
573 { &hf_ppi_gps_gpsflags_flag6_dead_reck, /*dead reckoning */
574 { "dead reckoning fix", "ppi_gps.gpsflagss.dead_reck",
575 FT_BOOLEAN, 32, NULL, PPI_GPS_GPSFLAGS_FLAG6_DEAD_RECK,
576 NULL, HFILL } },
577 { &hf_ppi_gps_gpsflags_flag7_manual, /* manual */
578 { "manual fix", "ppi_gps.gpsflagss.manual",
579 FT_BOOLEAN, 32, NULL, PPI_GPS_GPSFLAGS_FLAG7_MANUAL,
580 NULL, HFILL } },
581 { &hf_ppi_gps_gpsflags_flag8_sim, /* simulation */
582 { "simulated fix", "ppi_gps.gpsflagss.simulation",
583 FT_BOOLEAN, 32, NULL, PPI_GPS_GPSFLAGS_FLAG8_SIM,
584 NULL, HFILL } },
587 static int *ett[] = {
588 &ett_ppi_gps,
589 &ett_ppi_gps_present,
590 &ett_ppi_gps_gpsflags_flags
593 static ei_register_info ei[] = {
594 { &ei_ppi_gps_present_bit, { "ppi_gps.present.unknown_bit", PI_PROTOCOL, PI_WARN, "Error: PPI-GEOLOCATION-GPS: unknown bit set in present field.", EXPFILL }},
595 { &ei_ppi_gps_version, { "ppi_gps.version.unsupported", PI_PROTOCOL, PI_WARN, "Invalid version", EXPFILL }},
596 { &ei_ppi_gps_length, { "ppi_gps.length.invalid", PI_MALFORMED, PI_ERROR, "Invalid length", EXPFILL }},
599 expert_module_t* expert_ppi_gps;
601 proto_ppi_gps = proto_register_protocol("PPI Geotagging GPS tag decoder", "PPI GPS Decoder", "ppi_gps");
602 proto_register_field_array(proto_ppi_gps, hf, array_length(hf));
603 proto_register_subtree_array(ett, array_length(ett));
604 expert_ppi_gps = expert_register_protocol(proto_ppi_gps);
605 expert_register_field_array(expert_ppi_gps, ei, array_length(ei));
606 register_dissector("ppi_gps", dissect_ppi_gps, proto_ppi_gps);
610 * Editor modelines
612 * Local Variables:
613 * c-basic-offset: 4
614 * tab-width: 8
615 * indent-tabs-mode: nil
616 * End:
618 * ex: set shiftwidth=4 tabstop=8 expandtab:
619 * :indentSize=4:tabSize=8:noTabs=true: