2 * Routines for PPI-GEOLOCATION-GPS dissection
3 * Copyright 2010, Harris Corp, jellch@harris.com
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * Copied from packet-radiotap.c
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 #include <epan/packet.h>
32 #include "packet-ppi-geolocation-common.h"
34 enum ppi_geotagging_type
{
35 PPI_GEOTAG_GPSFLAGS
= 0,
40 PPI_GEOTAG_GPSTIME
= 5,
41 PPI_GEOTAG_FRACTIONALTIME
= 6,
45 PPI_GEOTAG_DESCRIPTIONSTR
= 28,
46 PPI_GEOTAG_APPID
= 29,
47 PPI_GEOTAG_APPDATA
= 30,
50 #define PPI_GPS_MAXTAGLEN 144 /* increase as fields are added */
52 #define PPI_GPS_MASK_GPSFLAGS 0x00000001
53 #define PPI_GPS_MASK_LAT 0x00000002
54 #define PPI_GPS_MASK_LON 0x00000004
55 #define PPI_GPS_MASK_ALT 0x00000008
56 #define PPI_GPS_MASK_ALT_G 0x00000010
58 #define PPI_GPS_MASK_GPSTIME 0x00000020
59 #define PPI_GPS_MASK_FRACTIME 0x00000040
60 #define PPI_GPS_MASK_EPH 0x00000080
61 #define PPI_GPS_MASK_EPV 0x00000100
62 #define PPI_GPS_MASK_EPT 0x00000200
64 #define PPI_GPS_MASK_DESCRSTR 0x10000000
65 #define PPI_GPS_MASK_APPID 0x20000000
66 #define PPI_GPS_MASK_APPDATA 0x40000000
67 #define PPI_GPS_MASK_EXT 0x80000000
71 static int proto_ppi_gps
= -1;
73 static int hf_ppi_gps_version
= -1;
74 static int hf_ppi_gps_pad
= -1;
75 static int hf_ppi_gps_length
= -1;
76 static int hf_ppi_gps_present
= -1;
77 static int hf_ppi_gps_gpsflags_flags
= -1;
78 static int hf_ppi_gps_lon
= -1;
79 static int hf_ppi_gps_lat
= -1;
80 static int hf_ppi_gps_alt
= -1;
81 static int hf_ppi_gps_alt_gnd
= -1;
82 static int hf_ppi_gps_gpstime
= -1;
83 /* static int hf_ppi_gps_fractime = -1; */
84 static int hf_ppi_gps_eph
= -1;
85 static int hf_ppi_gps_epv
= -1;
86 static int hf_ppi_gps_ept
= -1;
87 static int hf_ppi_gps_descstr
= -1;
88 static int hf_ppi_gps_appspecific_num
= -1; /* 4-byte tag no */
89 static int hf_ppi_gps_appspecific_data
= -1; /* 60 byte arbitrary data */
90 /* "Present" flags, tese represent decoded-bits in the gui */
91 static int hf_ppi_gps_present_gpsflags_flags
= -1;
92 static int hf_ppi_gps_present_lon
= -1;
93 static int hf_ppi_gps_present_lat
= -1;
94 static int hf_ppi_gps_present_alt
= -1;
95 static int hf_ppi_gps_present_alt_gnd
= -1;
96 static int hf_ppi_gps_present_gpstime
= -1;
97 static int hf_ppi_gps_present_fractime
= -1;
98 static int hf_ppi_gps_present_eph
= -1;
99 static int hf_ppi_gps_present_epv
= -1;
100 static int hf_ppi_gps_present_ept
= -1;
101 static int hf_ppi_gps_present_descr
= -1;
102 static int hf_ppi_gps_present_appspecific_num
= -1;
103 static int hf_ppi_gps_present_appspecific_data
= -1;
104 static int hf_ppi_gps_present_ext
= -1;
106 /* Devicetype flags. not to be confused with "present" flags. These are optional */
107 static int hf_ppi_gps_gpsflags_flag0_nofix
= -1;
108 static int hf_ppi_gps_gpsflags_flag1_gpsfix
= -1;
109 static int hf_ppi_gps_gpsflags_flag2_diffgps
= -1;
110 static int hf_ppi_gps_gpsflags_flag3_PPS
= -1;
111 static int hf_ppi_gps_gpsflags_flag4_RTK
= -1;
112 static int hf_ppi_gps_gpsflags_flag5_floatRTK
= -1;
113 static int hf_ppi_gps_gpsflags_flag6_dead_reck
= -1;
114 static int hf_ppi_gps_gpsflags_flag7_manual
= -1;
115 static int hf_ppi_gps_gpsflags_flag8_sim
= -1;
117 /* These represent arrow-dropdownthings in the gui */
118 static gint ett_ppi_gps
= -1;
119 static gint ett_ppi_gps_present
= -1;
120 static gint ett_ppi_gps_gpsflags_flags
= -1;
123 dissect_ppi_gps(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
) {
124 /* These are locals used for processing the current tvb */
126 gint length_remaining
;
129 proto_tree
*ppi_gps_tree
= NULL
;
130 proto_tree
*pt
, *present_tree
= NULL
;
131 proto_tree
*my_pt
, *gpsflags_flags_tree
= NULL
; /* used for DeviceType bitmask stuff */
133 proto_item
*ti
= NULL
;
134 proto_item
*gps_line
= NULL
;
139 guint32 present
, next_present
;
140 /* values actually read out, for displaying */
141 guint32 version
, gpsflags_flags
;
142 gdouble lat
, lon
, alt
, alt_gnd
;
143 nstime_t gps_timestamp
;
144 int gps_time_size
, already_processed_fractime
; /* we use this internally to track if this is a 4 or 8 byte wide timestamp */
145 gdouble eph
, epv
, ept
;
149 /* these are temporary intermediate values, used in the individual cases below */
150 guint32 t_lat
, t_lon
, t_alt
, t_alt_gnd
;
151 guint32 t_herr
, t_verr
, t_terr
;
152 guint32 t_appspecific_num
;
153 /* initialize the timestamp value(s) */
154 gps_timestamp
.secs
= gps_timestamp
.nsecs
= already_processed_fractime
= 0;
156 /* Clear out stuff in the info column */
157 col_clear(pinfo
->cinfo
,COL_INFO
);
159 /* pull out the first three fields of the BASE-GEOTAG-HEADER */
160 version
= tvb_get_guint8(tvb
, offset
);
161 length
= tvb_get_letohs(tvb
, offset
+2);
162 present
= tvb_get_letohl(tvb
, offset
+4);
164 /* Setup basic column info */
165 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "PPI_GPS Capture v%u, Length %u", version
, length
);
167 /* Create the basic dissection tree*/
169 ti
= proto_tree_add_protocol_format(tree
, proto_ppi_gps
, tvb
, 0, length
, "GPS:");
170 gps_line
= ti
; /*we will make this more useful if we hit lon/lat later */
171 ppi_gps_tree
= proto_item_add_subtree(ti
, ett_ppi_gps
);
172 proto_tree_add_uint(ppi_gps_tree
, hf_ppi_gps_version
, tvb
, offset
, 1, version
);
173 proto_tree_add_item(ppi_gps_tree
, hf_ppi_gps_pad
, tvb
, offset
+ 1, 1, ENC_NA
);
174 ti
= proto_tree_add_uint(ppi_gps_tree
, hf_ppi_gps_length
, tvb
, offset
+ 2, 2, length
);
177 /* We support v1 and v2 of GPS tags (identical) */
178 if (! (version
== 1 || version
== 2) ) {
180 proto_item_append_text(ti
, "invalid version (got %d, expected 1 or 2)", version
);
184 /* initialize the length of the actual tag contents */
185 length_remaining
= length
;
186 /* minimum length check, should atleast be a fixed-size geotagging-base header*/
187 if (length_remaining
< PPI_GEOBASE_MIN_HEADER_LEN
) {
189 * Base-geotag-header (Radiotap lookalike) is shorter than the fixed-length portion
190 * plus one "present" bitset.
193 proto_item_append_text(ti
, " (invalid - minimum length is 8)");
197 /* perform tag-specific max length sanity checking */
198 if (length
> PPI_GPS_MAXTAGLEN
) {
200 proto_item_append_text(ti
, "Invalid PPI-GPS length (got %d, %d max\n)", length
, PPI_GPS_MAXTAGLEN
);
204 /* Subtree for the "present flags" bitfield. */
206 pt
= proto_tree_add_uint(ppi_gps_tree
, hf_ppi_gps_present
, tvb
, offset
+ 4, 4, present
);
207 present_tree
= proto_item_add_subtree(pt
, ett_ppi_gps_present
);
209 proto_tree_add_item(present_tree
, hf_ppi_gps_present_gpsflags_flags
, tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
210 proto_tree_add_item(present_tree
, hf_ppi_gps_present_lat
, tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
211 proto_tree_add_item(present_tree
, hf_ppi_gps_present_lon
, tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
212 proto_tree_add_item(present_tree
, hf_ppi_gps_present_alt
, tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
213 proto_tree_add_item(present_tree
, hf_ppi_gps_present_alt_gnd
, tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
214 proto_tree_add_item(present_tree
, hf_ppi_gps_present_gpstime
, tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
215 proto_tree_add_item(present_tree
, hf_ppi_gps_present_fractime
, tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
216 proto_tree_add_item(present_tree
, hf_ppi_gps_present_eph
, tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
217 proto_tree_add_item(present_tree
, hf_ppi_gps_present_epv
, tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
218 proto_tree_add_item(present_tree
, hf_ppi_gps_present_ept
, tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
219 proto_tree_add_item(present_tree
, hf_ppi_gps_present_descr
, tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
220 proto_tree_add_item(present_tree
, hf_ppi_gps_present_appspecific_num
, tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
221 proto_tree_add_item(present_tree
, hf_ppi_gps_present_appspecific_data
, tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
222 proto_tree_add_item(present_tree
, hf_ppi_gps_present_ext
, tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
224 offset
+= PPI_GEOBASE_MIN_HEADER_LEN
;
225 length_remaining
-= PPI_GEOBASE_MIN_HEADER_LEN
;
227 /* The fixed BASE-GEOTAG-HEADER has been handled at this point. move on to the individual fields */
228 for (; present
; present
= next_present
) {
229 /* clear the least significant bit that is set */
230 next_present
= present
& (present
- 1);
231 /* extract the least significant bit that is set */
232 bit
= BITNO_32(present
^ next_present
);
234 case PPI_GEOTAG_GPSFLAGS
:
235 if (length_remaining
< 4)
237 gpsflags_flags
= tvb_get_letohl(tvb
, offset
); /* retrieve 32-bit gpsflags bitmask (-not- present bitmask) */
239 /* first we add the hex flags line */
240 my_pt
= proto_tree_add_uint(ppi_gps_tree
, hf_ppi_gps_gpsflags_flags
, tvb
, offset
, 4, gpsflags_flags
);
241 /* then we add a subtree */
242 gpsflags_flags_tree
= proto_item_add_subtree(my_pt
, ett_ppi_gps_gpsflags_flags
);
243 /* to pin the individual bits on */
244 proto_tree_add_item(gpsflags_flags_tree
, hf_ppi_gps_gpsflags_flag0_nofix
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
245 proto_tree_add_item(gpsflags_flags_tree
, hf_ppi_gps_gpsflags_flag1_gpsfix
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
246 proto_tree_add_item(gpsflags_flags_tree
, hf_ppi_gps_gpsflags_flag2_diffgps
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
247 proto_tree_add_item(gpsflags_flags_tree
, hf_ppi_gps_gpsflags_flag3_PPS
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
248 proto_tree_add_item(gpsflags_flags_tree
, hf_ppi_gps_gpsflags_flag4_RTK
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
249 proto_tree_add_item(gpsflags_flags_tree
, hf_ppi_gps_gpsflags_flag5_floatRTK
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
250 proto_tree_add_item(gpsflags_flags_tree
, hf_ppi_gps_gpsflags_flag6_dead_reck
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
251 proto_tree_add_item(gpsflags_flags_tree
, hf_ppi_gps_gpsflags_flag7_manual
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
252 proto_tree_add_item(gpsflags_flags_tree
, hf_ppi_gps_gpsflags_flag8_sim
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
258 if (length_remaining
< 4)
260 t_lat
= tvb_get_letohl(tvb
, offset
);
261 lat
= ppi_fixed3_7_to_gdouble(t_lat
);
264 proto_tree_add_double(ppi_gps_tree
, hf_ppi_gps_lat
, tvb
, offset
, 4, lat
);
265 proto_item_append_text(gps_line
, " Lat:%f ", lat
);
271 if (length_remaining
< 4)
273 t_lon
= tvb_get_letohl(tvb
, offset
);
274 lon
= ppi_fixed3_7_to_gdouble(t_lon
);
277 proto_tree_add_double(ppi_gps_tree
, hf_ppi_gps_lon
, tvb
, offset
, 4, lon
);
278 proto_item_append_text(gps_line
, " Lon:%f ", lon
);
284 if (length_remaining
< 4)
286 t_alt
= tvb_get_letohl(tvb
, offset
);
287 alt
= ppi_fixed6_4_to_gdouble(t_alt
);
290 proto_tree_add_double(ppi_gps_tree
, hf_ppi_gps_alt
, tvb
, offset
, 4, alt
);
291 proto_item_append_text(gps_line
, " Alt:%f ", alt
);
296 case PPI_GEOTAG_ALT_G
:
297 if (length_remaining
< 4)
299 t_alt_gnd
= tvb_get_letohl(tvb
, offset
);
300 alt_gnd
= ppi_fixed6_4_to_gdouble(t_alt_gnd
);
303 proto_tree_add_double(ppi_gps_tree
, hf_ppi_gps_alt_gnd
, tvb
, offset
, 4, alt_gnd
);
304 proto_item_append_text(gps_line
, " Alt_g:%f ", alt_gnd
);
309 case PPI_GEOTAG_GPSTIME
:
310 if (length_remaining
< 4)
312 gps_timestamp
.secs
= tvb_get_letohl(tvb
, offset
);
313 gps_timestamp
.nsecs
= 0;
315 /* This is somewhat tricky, inside the GPSTIME case we test if the optional fractional time */
316 /* is present. If so, we pull it out, and combine it with GPSTime. */
317 /* If we do this, we set already_processed_fractime to avoid hitting it below */
318 if (length_remaining
< 4 && (present
& PPI_GPS_MASK_FRACTIME
))
320 else if (present
& PPI_GPS_MASK_FRACTIME
) {
321 gps_timestamp
.nsecs
= tvb_get_letohl(tvb
, offset
+ 4); /* manually offset seconds */
322 already_processed_fractime
= 1;
326 proto_tree_add_time(ppi_gps_tree
, hf_ppi_gps_gpstime
, tvb
, offset
, gps_time_size
, &gps_timestamp
);
328 offset
+= gps_time_size
;
329 length_remaining
-= gps_time_size
;
331 case PPI_GEOTAG_FRACTIONALTIME
:
332 if (length_remaining
< 4)
334 if (already_processed_fractime
)
338 if (length_remaining
< 4)
340 t_herr
= tvb_get_letohl(tvb
, offset
);
341 eph
= ppi_fixed3_6_to_gdouble(t_herr
);
343 proto_tree_add_double(ppi_gps_tree
, hf_ppi_gps_eph
, tvb
, offset
, 4, eph
);
348 if (length_remaining
< 4)
350 t_verr
= tvb_get_letohl(tvb
, offset
);
351 epv
= ppi_fixed3_6_to_gdouble(t_verr
);
353 proto_tree_add_double(ppi_gps_tree
, hf_ppi_gps_epv
, tvb
, offset
, 4, epv
);
358 if (length_remaining
< 4)
360 t_terr
= tvb_get_letohl(tvb
, offset
);
361 ept
= ppi_ns_counter_to_gdouble(t_terr
);
363 proto_tree_add_double(ppi_gps_tree
, hf_ppi_gps_ept
, tvb
, offset
, 4, ept
);
367 case PPI_GEOTAG_DESCRIPTIONSTR
:
368 if (length_remaining
< 32)
372 /* proto_tree_add_item(ppi_gps_tree, hf_ppi_gps_descstr, tvb, offset, 32, ENC_ASCII|ENC_NA); */
373 curr_str
= tvb_format_stringzpad(tvb
, offset
, 32); /* need to append_text this */
374 proto_tree_add_string(ppi_gps_tree
, hf_ppi_gps_descstr
, tvb
, offset
, 32, curr_str
);
375 proto_item_append_text(gps_line
, " (%s)", curr_str
);
378 length_remaining
-=32;
380 case PPI_GEOTAG_APPID
:
381 if (length_remaining
< 4)
383 t_appspecific_num
= tvb_get_letohl(tvb
, offset
); /* application specific parsers may switch on this later */
385 proto_tree_add_uint(ppi_gps_tree
, hf_ppi_gps_appspecific_num
, tvb
, offset
, 4, t_appspecific_num
);
390 case PPI_GEOTAG_APPDATA
:
391 if (length_remaining
< 60)
394 proto_tree_add_item(ppi_gps_tree
, hf_ppi_gps_appspecific_data
, tvb
, offset
, 60, ENC_NA
);
397 length_remaining
-=60;
401 * This indicates a field whose size we do not know, so we cannot proceed.
404 next_present
= 0; /* this will terminate the loop */
405 proto_tree_add_text(ppi_gps_tree
, tvb
, offset
, 0, "Error: PPI-GEOLOCATION-GPS: unknown bit (%d) set in present field.\n", bit
);
409 } /* (for present..)*/
411 /* If there was any post processing of the elements, it could happen here. */
416 proto_register_ppi_gps(void) {
417 /* The following array initializes those header fields declared above to the values displayed */
418 static hf_register_info hf
[] = {
419 { &hf_ppi_gps_version
,
420 { "Header revision", "ppi_gps.version",
421 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
422 "Version of ppi_gps header format", HFILL
} },
424 { "Header pad", "ppi_gps.pad",
425 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
426 "Padding", HFILL
} },
427 { &hf_ppi_gps_length
,
428 { "Header length", "ppi_gps.length",
429 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
430 "Length of header including version, pad, length and data fields", HFILL
} },
431 { &hf_ppi_gps_present
, /* these flag fields are composed of a uint32 on the display */
432 { "Present", "ppi_gps.present",
433 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
434 "Bitmask indicating which fields are present", HFILL
} },
436 /* Boolean 'present' flags */
437 { &hf_ppi_gps_present_gpsflags_flags
, /* followed by a lot of booleans */
438 { "GPSFlags", "ppi_gps.present.gpsflagss",
439 FT_BOOLEAN
, 32, NULL
, PPI_GPS_MASK_GPSFLAGS
,
440 "32-bit bitmask indicating type of GPS fix (GPS/INS/software/etc)", HFILL
} },
441 { &hf_ppi_gps_present_lat
,
442 { "Lat", "ppi_gps.present.lat",
443 FT_BOOLEAN
, 32, NULL
, PPI_GPS_MASK_LAT
,
444 "Specifies if the latitude field is present", HFILL
} },
446 { &hf_ppi_gps_present_lon
,
447 { "Lon", "ppi_gps.present.lon",
448 FT_BOOLEAN
, 32, NULL
, PPI_GPS_MASK_LON
,
449 "Specifies if the longitude field is present", HFILL
} },
451 { &hf_ppi_gps_present_alt
,
452 { "Alt", "ppi_gps.present.alt",
453 FT_BOOLEAN
, 32, NULL
, PPI_GPS_MASK_ALT
,
454 "Specifies if the altitude field is present", HFILL
} },
456 { &hf_ppi_gps_present_alt_gnd
,
457 { "Alt-gnd", "ppi_gps.present.alt_gnd",
458 FT_BOOLEAN
, 32, NULL
, PPI_GPS_MASK_ALT_G
,
459 "Specifies if the altitude-g field is present", HFILL
} },
461 { &hf_ppi_gps_present_gpstime
,
462 { "GPStime", "ppi_gps.present.gpstime",
463 FT_BOOLEAN
, 32, NULL
, PPI_GPS_MASK_GPSTIME
,
464 "Specifies if the GPS time field is present", HFILL
} },
467 { &hf_ppi_gps_present_fractime
,
468 { "fractime", "ppi_gps.present.fractime",
469 FT_BOOLEAN
, 32, NULL
, PPI_GPS_MASK_FRACTIME
,
470 "Specifies if the fractional time field is present", HFILL
} },
473 { &hf_ppi_gps_present_eph
,
474 { "error_h", "ppi_gps.present.eph",
475 FT_BOOLEAN
, 32, NULL
, PPI_GPS_MASK_EPH
,
476 "Specifies if the horizontal error field is present (eph)", HFILL
} },
478 { &hf_ppi_gps_present_epv
,
479 { "error_v", "ppi_gps.present.epv",
480 FT_BOOLEAN
, 32, NULL
, PPI_GPS_MASK_EPV
,
481 "Specifies if the vertical error field present (epv)", HFILL
} },
484 { &hf_ppi_gps_present_ept
,
485 { "error_t", "ppi_gps.present.ept",
486 FT_BOOLEAN
, 32, NULL
, PPI_GPS_MASK_EPT
,
487 "Specifies if the estimed time error field is present (ept)", HFILL
} },
489 { &hf_ppi_gps_present_descr
,
490 { "Description", "ppi_gps.present.descr",
491 FT_BOOLEAN
, 32, NULL
, PPI_GPS_MASK_DESCRSTR
,
492 "Specifies if the (ASCII) description is present", HFILL
} },
494 { &hf_ppi_gps_present_appspecific_num
,
495 { "AppId", "ppi_gps.present.appid",
496 FT_BOOLEAN
, 32, NULL
, PPI_GPS_MASK_APPID
,
497 "Specifies if the application specific field id is present", HFILL
} },
499 { &hf_ppi_gps_present_appspecific_data
,
500 { "AppData", "ppi_gps.present.appdata",
501 FT_BOOLEAN
, 32, NULL
, PPI_GPS_MASK_APPDATA
,
502 "Specifies if the application specific data field is present", HFILL
} },
504 { &hf_ppi_gps_present_ext
,
505 { "Ext", "ppi_gps.present.ext",
506 FT_BOOLEAN
, 32, NULL
, PPI_GPS_MASK_EXT
,
507 "Specifies if there are any extensions to the header present", HFILL
} },
509 /* ---Now we get to the actual data fields--- */
511 { &hf_ppi_gps_gpsflags_flags
,
512 { "GPSFlags", "ppi_gps.gpsflags",
513 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
514 "Bitmask indicating GPS/INS/manual fix", HFILL
} },
516 { "Latitude", "ppi_gps.lat",
517 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
518 "Latitude packet was received at", HFILL
} },
520 { "Longitude", "ppi_gps.lon",
521 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
522 "Longitude packet was received at", HFILL
} },
524 { "Altitude", "ppi_gps.alt",
525 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
526 "Altitude packet was received at", HFILL
} },
527 { &hf_ppi_gps_alt_gnd
,
528 { "Altitude_gnd", "ppi_gps.alt_gnd",
529 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
530 "Altitude packet was received at (relative to ground)", HFILL
} },
531 { &hf_ppi_gps_gpstime
,
532 { "GPSTimestamp", "ppi_gps.gpstime",
533 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_UTC
, NULL
, 0x0,
534 "GPSTimestamp packet was received at", HFILL
} },
536 { &hf_ppi_gps_fractime
,
537 { "fractional Timestamp", "ppi_gps.fractime",
538 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
539 "fractional GPSTimestamp packet was received at", HFILL
} },
542 { "Horizontal Error (m)", "ppi_gps.eph",
543 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
544 "Horizontal margin of error (meters)", HFILL
} },
546 { "Vertical Error (m)", "ppi_gps.epv",
547 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
548 "Vertical margin of error (meters)", HFILL
} },
550 { "Time Error (s)", "ppi_gps.ept",
551 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
552 "Time margin of error (secs)", HFILL
} },
553 { &hf_ppi_gps_descstr
,
554 { "Description", "ppi_gps.descr",
555 FT_STRING
, BASE_NONE
, NULL
, 0x0,
557 { &hf_ppi_gps_appspecific_num
,
558 { "Application Specific id", "ppi_gps.appid",
559 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
561 { &hf_ppi_gps_appspecific_data
,
562 { "Application specific data", "ppi_gps.appdata",
563 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
566 /* --- moving on to the 'FixType' flags --- */
567 #define PPI_GPS_GPSFLAGS_FLAG0_NOFIX 0x00000001
568 #define PPI_GPS_GPSFLAGS_FLAG1_GPS 0x00000002
569 #define PPI_GPS_GPSFLAGS_FLAG2_DIFFGPS 0x00000004
570 #define PPI_GPS_GPSFLAGS_FLAG3_PPS 0x00000008
571 #define PPI_GPS_GPSFLAGS_FLAG4_RTK 0x00000010
572 #define PPI_GPS_GPSFLAGS_FLAG5_FLOATRTK 0x00000020
573 #define PPI_GPS_GPSFLAGS_FLAG6_DEAD_RECK 0x00000040
574 #define PPI_GPS_GPSFLAGS_FLAG7_MANUAL 0x00000080
575 #define PPI_GPS_GPSFLAGS_FLAG8_SIM 0x00000100
576 { &hf_ppi_gps_gpsflags_flag0_nofix
, /* no fix available */
577 { "No fix available", "ppi_gps.gpsflagss.nofix",
578 FT_BOOLEAN
, 32, NULL
, PPI_GPS_GPSFLAGS_FLAG0_NOFIX
,
580 { &hf_ppi_gps_gpsflags_flag1_gpsfix
, /* GPSfix available */
581 { "GPS provided fix", "ppi_gps.gpsflagss.gps",
582 FT_BOOLEAN
, 32, NULL
, PPI_GPS_GPSFLAGS_FLAG1_GPS
,
584 { &hf_ppi_gps_gpsflags_flag2_diffgps
, /* Differential GPS fix available */
585 { "Differential GPS provided fix", "ppi_gps.gpsflagss.diffgps",
586 FT_BOOLEAN
, 32, NULL
, PPI_GPS_GPSFLAGS_FLAG2_DIFFGPS
,
588 { &hf_ppi_gps_gpsflags_flag3_PPS
, /* PPS fix */
589 { "PPS fix", "ppi_gps.gpsflagss.pps",
590 FT_BOOLEAN
, 32, NULL
, PPI_GPS_GPSFLAGS_FLAG3_PPS
,
592 { &hf_ppi_gps_gpsflags_flag4_RTK
, /* RTK fix*/
593 { "RTK fix", "ppi_gps.gpsflagss.rtk",
594 FT_BOOLEAN
, 32, NULL
, PPI_GPS_GPSFLAGS_FLAG4_RTK
,
596 { &hf_ppi_gps_gpsflags_flag5_floatRTK
, /*float RTK */
597 { "floatRTK fix", "ppi_gps.gpsflagss.frtk",
598 FT_BOOLEAN
, 32, NULL
, PPI_GPS_GPSFLAGS_FLAG5_FLOATRTK
,
600 { &hf_ppi_gps_gpsflags_flag6_dead_reck
, /*dead reckoning */
601 { "dead reckoning fix", "ppi_gps.gpsflagss.dead_reck",
602 FT_BOOLEAN
, 32, NULL
, PPI_GPS_GPSFLAGS_FLAG6_DEAD_RECK
,
604 { &hf_ppi_gps_gpsflags_flag7_manual
, /* manual */
605 { "manual fix", "ppi_gps.gpsflagss.manual",
606 FT_BOOLEAN
, 32, NULL
, PPI_GPS_GPSFLAGS_FLAG7_MANUAL
,
608 { &hf_ppi_gps_gpsflags_flag8_sim
, /* simulation */
609 { "simulated fix", "ppi_gps.gpsflagss.simulation",
610 FT_BOOLEAN
, 32, NULL
, PPI_GPS_GPSFLAGS_FLAG8_SIM
,
614 static gint
*ett
[] = {
616 &ett_ppi_gps_present
,
617 &ett_ppi_gps_gpsflags_flags
620 proto_ppi_gps
= proto_register_protocol("PPI Geotagging GPS tag decoder", "PPI GPS Decoder", "ppi_gps");
621 proto_register_field_array(proto_ppi_gps
, hf
, array_length(hf
));
622 proto_register_subtree_array(ett
, array_length(ett
));
623 register_dissector("ppi_gps", dissect_ppi_gps
, proto_ppi_gps
);
632 * indent-tabs-mode: nil
635 * ex: set shiftwidth=4 tabstop=8 expandtab:
636 * :indentSize=4:tabSize=8:noTabs=true: