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
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,
26 PPI_GEOTAG_GPSTIME
= 5,
27 PPI_GEOTAG_FRACTIONALTIME
= 6,
31 PPI_GEOTAG_DESCRIPTIONSTR
= 28,
32 PPI_GEOTAG_APPID
= 29,
33 PPI_GEOTAG_APPDATA
= 30,
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);
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
;
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 */
118 int length_remaining
;
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
,
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
,
159 uint32_t present
, next_present
;
160 /* values actually read out, for displaying */
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
;
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");
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
);
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
);
230 case PPI_GEOTAG_GPSFLAGS
:
231 if (length_remaining
< 4)
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
);
238 if (length_remaining
< 4)
240 t_lat
= tvb_get_letohl(tvb
, offset
);
241 lat
= ppi_fixed3_7_to_double(t_lat
);
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
);
251 if (length_remaining
< 4)
253 t_lon
= tvb_get_letohl(tvb
, offset
);
254 lon
= ppi_fixed3_7_to_double(t_lon
);
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
);
264 if (length_remaining
< 4)
266 t_alt
= tvb_get_letohl(tvb
, offset
);
267 alt
= ppi_fixed6_4_to_double(t_alt
);
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
);
276 case PPI_GEOTAG_ALT_G
:
277 if (length_remaining
< 4)
279 t_alt_gnd
= tvb_get_letohl(tvb
, offset
);
280 alt_gnd
= ppi_fixed6_4_to_double(t_alt_gnd
);
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
);
289 case PPI_GEOTAG_GPSTIME
:
290 if (length_remaining
< 4)
292 gps_timestamp
.secs
= tvb_get_letohl(tvb
, offset
);
293 gps_timestamp
.nsecs
= 0;
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
))
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;
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
;
309 case PPI_GEOTAG_FRACTIONALTIME
:
310 if (length_remaining
< 4)
312 if (already_processed_fractime
)
314 proto_tree_add_item(ppi_gps_tree
, hf_ppi_gps_fractime
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
316 length_remaining
-= 4;
319 if (length_remaining
< 4)
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
);
328 if (length_remaining
< 4)
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
);
337 if (length_remaining
< 4)
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
);
345 case PPI_GEOTAG_DESCRIPTIONSTR
:
346 if (length_remaining
< 32)
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
);
356 length_remaining
-=32;
358 case PPI_GEOTAG_APPID
:
359 if (length_remaining
< 4)
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
);
366 case PPI_GEOTAG_APPDATA
:
367 if (length_remaining
< 60)
369 proto_tree_add_item(ppi_gps_tree
, hf_ppi_gps_appspecific_data
, tvb
, offset
, 60, ENC_NA
);
371 length_remaining
-=60;
375 * This indicates a field whose size we do not know, so we cannot proceed.
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
);
384 } /* (for present..)*/
386 /* If there was any post processing of the elements, it could happen here. */
387 return tvb_captured_length(tvb
);
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
} },
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
} },
491 { "Latitude", "ppi_gps.lat",
492 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
493 "Latitude packet was received at", HFILL
} },
495 { "Longitude", "ppi_gps.lon",
496 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
497 "Longitude packet was received at", HFILL
} },
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
} },
515 { "Horizontal Error (m)", "ppi_gps.eph",
516 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
517 "Horizontal margin of error (meters)", HFILL
} },
519 { "Vertical Error (m)", "ppi_gps.epv",
520 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
521 "Vertical margin of error (meters)", HFILL
} },
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,
530 { &hf_ppi_gps_appspecific_num
,
531 { "Application Specific id", "ppi_gps.appid",
532 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
534 { &hf_ppi_gps_appspecific_data
,
535 { "Application specific data", "ppi_gps.appdata",
536 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
587 static int *ett
[] = {
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
);
615 * indent-tabs-mode: nil
618 * ex: set shiftwidth=4 tabstop=8 expandtab:
619 * :indentSize=4:tabSize=8:noTabs=true: