MSWSP: add two more Property Sets
[wireshark-wip.git] / epan / dissectors / packet-ppi-gps.c
bloba161b619c2c317ae031b88f8ed5cec845565ed28
1 /* packet-ppi-gps.c
2 * Routines for PPI-GEOLOCATION-GPS dissection
3 * Copyright 2010, Harris Corp, jellch@harris.com
5 * $Id$
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.
28 #include "config.h"
30 #include <glib.h>
31 #include <epan/packet.h>
32 #include "packet-ppi-geolocation-common.h"
34 enum ppi_geotagging_type {
35 PPI_GEOTAG_GPSFLAGS = 0,
36 PPI_GEOTAG_LAT = 1,
37 PPI_GEOTAG_LON = 2,
38 PPI_GEOTAG_ALT = 3,
39 PPI_GEOTAG_ALT_G = 4,
40 PPI_GEOTAG_GPSTIME = 5,
41 PPI_GEOTAG_FRACTIONALTIME = 6,
42 PPI_GEOTAG_EPH = 7,
43 PPI_GEOTAG_EPV = 8,
44 PPI_GEOTAG_EPT = 9,
45 PPI_GEOTAG_DESCRIPTIONSTR = 28,
46 PPI_GEOTAG_APPID = 29,
47 PPI_GEOTAG_APPDATA = 30,
48 PPI_GEOTAG_EXT = 31
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
70 /* protocol */
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;
122 static void
123 dissect_ppi_gps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
124 /* These are locals used for processing the current tvb */
125 guint length;
126 gint length_remaining;
127 int offset = 0;
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;
137 /* bits */
138 int bit;
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;
146 gchar *curr_str;
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*/
168 if (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) ) {
179 if (tree)
180 proto_item_append_text(ti, "invalid version (got %d, expected 1 or 2)", version);
181 return;
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.
192 if (tree)
193 proto_item_append_text(ti, " (invalid - minimum length is 8)");
194 return;
197 /* perform tag-specific max length sanity checking */
198 if (length > PPI_GPS_MAXTAGLEN ) {
199 if (tree)
200 proto_item_append_text(ti, "Invalid PPI-GPS length (got %d, %d max\n)", length, PPI_GPS_MAXTAGLEN);
201 return;
204 /* Subtree for the "present flags" bitfield. */
205 if (tree) {
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);
233 switch (bit) {
234 case PPI_GEOTAG_GPSFLAGS:
235 if (length_remaining < 4)
236 break;
237 gpsflags_flags = tvb_get_letohl(tvb, offset); /* retrieve 32-bit gpsflags bitmask (-not- present bitmask) */
238 if (tree) {
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);
254 offset+=4;
255 length_remaining-=4;
256 break;
257 case PPI_GEOTAG_LAT:
258 if (length_remaining < 4)
259 break;
260 t_lat = tvb_get_letohl(tvb, offset);
261 lat = ppi_fixed3_7_to_gdouble(t_lat);
262 if (tree)
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);
267 offset+=4;
268 length_remaining-=4;
269 break;
270 case PPI_GEOTAG_LON:
271 if (length_remaining < 4)
272 break;
273 t_lon = tvb_get_letohl(tvb, offset);
274 lon = ppi_fixed3_7_to_gdouble(t_lon);
275 if (tree)
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);
280 offset+=4;
281 length_remaining-=4;
282 break;
283 case PPI_GEOTAG_ALT:
284 if (length_remaining < 4)
285 break;
286 t_alt = tvb_get_letohl(tvb, offset);
287 alt = ppi_fixed6_4_to_gdouble(t_alt);
288 if (tree)
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);
293 offset+=4;
294 length_remaining-=4;
295 break;
296 case PPI_GEOTAG_ALT_G:
297 if (length_remaining < 4)
298 break;
299 t_alt_gnd = tvb_get_letohl(tvb, offset);
300 alt_gnd = ppi_fixed6_4_to_gdouble(t_alt_gnd);
301 if (tree)
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);
306 offset+=4;
307 length_remaining-=4;
308 break;
309 case PPI_GEOTAG_GPSTIME:
310 if (length_remaining < 4)
311 break;
312 gps_timestamp.secs = tvb_get_letohl(tvb, offset);
313 gps_timestamp.nsecs = 0;
314 gps_time_size = 4;
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))
319 break;
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;
323 gps_time_size = 8;
325 if (tree) {
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;
330 break;
331 case PPI_GEOTAG_FRACTIONALTIME:
332 if (length_remaining < 4)
333 break;
334 if (already_processed_fractime)
335 break;
336 break;
337 case PPI_GEOTAG_EPH:
338 if (length_remaining < 4)
339 break;
340 t_herr = tvb_get_letohl(tvb, offset);
341 eph = ppi_fixed3_6_to_gdouble(t_herr);
342 if (tree)
343 proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_eph, tvb, offset, 4, eph);
344 offset+=4;
345 length_remaining-=4;
346 break;
347 case PPI_GEOTAG_EPV:
348 if (length_remaining < 4)
349 break;
350 t_verr = tvb_get_letohl(tvb, offset);
351 epv = ppi_fixed3_6_to_gdouble(t_verr);
352 if (tree)
353 proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_epv, tvb, offset, 4, epv);
354 offset+=4;
355 length_remaining-=4;
356 break;
357 case PPI_GEOTAG_EPT:
358 if (length_remaining < 4)
359 break;
360 t_terr = tvb_get_letohl(tvb, offset);
361 ept = ppi_ns_counter_to_gdouble(t_terr);
362 if (tree)
363 proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_ept, tvb, offset, 4, ept);
364 offset+=4;
365 length_remaining-=4;
366 break;
367 case PPI_GEOTAG_DESCRIPTIONSTR:
368 if (length_remaining < 32)
369 break;
370 if (tree)
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);
377 offset+=32;
378 length_remaining-=32;
379 break;
380 case PPI_GEOTAG_APPID:
381 if (length_remaining < 4)
382 break;
383 t_appspecific_num = tvb_get_letohl(tvb, offset); /* application specific parsers may switch on this later */
384 if (tree) {
385 proto_tree_add_uint(ppi_gps_tree, hf_ppi_gps_appspecific_num, tvb, offset, 4, t_appspecific_num);
387 offset+=4;
388 length_remaining-=4;
389 break;
390 case PPI_GEOTAG_APPDATA:
391 if (length_remaining < 60)
392 break;
393 if (tree) {
394 proto_tree_add_item(ppi_gps_tree, hf_ppi_gps_appspecific_data, tvb, offset, 60, ENC_NA);
396 offset+=60;
397 length_remaining-=60;
398 break;
401 * This indicates a field whose size we do not know, so we cannot proceed.
403 default:
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);
406 continue;
407 } /* switch (bit) */
409 } /* (for present..)*/
411 /* If there was any post processing of the elements, it could happen here. */
412 return;
415 void
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 } },
423 { &hf_ppi_gps_pad,
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 } },
515 { &hf_ppi_gps_lat,
516 { "Latitude", "ppi_gps.lat",
517 FT_DOUBLE, BASE_NONE, NULL, 0x0,
518 "Latitude packet was received at", HFILL } },
519 { &hf_ppi_gps_lon,
520 { "Longitude", "ppi_gps.lon",
521 FT_DOUBLE, BASE_NONE, NULL, 0x0,
522 "Longitude packet was received at", HFILL } },
523 { &hf_ppi_gps_alt,
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 } },
535 #if 0
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 } },
540 #endif
541 { &hf_ppi_gps_eph,
542 { "Horizontal Error (m)", "ppi_gps.eph",
543 FT_DOUBLE, BASE_NONE, NULL, 0x0,
544 "Horizontal margin of error (meters)", HFILL } },
545 { &hf_ppi_gps_epv,
546 { "Vertical Error (m)", "ppi_gps.epv",
547 FT_DOUBLE, BASE_NONE, NULL, 0x0,
548 "Vertical margin of error (meters)", HFILL } },
549 { &hf_ppi_gps_ept,
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,
556 NULL, HFILL } },
557 { &hf_ppi_gps_appspecific_num,
558 { "Application Specific id", "ppi_gps.appid",
559 FT_UINT32, BASE_HEX, NULL, 0x0,
560 NULL, HFILL } },
561 { &hf_ppi_gps_appspecific_data,
562 { "Application specific data", "ppi_gps.appdata",
563 FT_BYTES, BASE_NONE, NULL, 0x0,
564 NULL, HFILL } },
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,
579 NULL, HFILL } },
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,
583 NULL, HFILL } },
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,
587 NULL, HFILL } },
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,
591 NULL, HFILL } },
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,
595 NULL, HFILL } },
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,
599 NULL, HFILL } },
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,
603 NULL, HFILL } },
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,
607 NULL, HFILL } },
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,
611 NULL, HFILL } },
614 static gint *ett[] = {
615 &ett_ppi_gps,
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);
627 * Editor modelines
629 * Local Variables:
630 * c-basic-offset: 4
631 * tab-width: 8
632 * indent-tabs-mode: nil
633 * End:
635 * ex: set shiftwidth=4 tabstop=8 expandtab:
636 * :indentSize=4:tabSize=8:noTabs=true: