2 * Routines for PPI-GEOLOCATION-VECTOR dissection
3 * Copyright 2010, Harris Corp, jellch@harris.com
7 * http://new.11mercenary.net/~johnycsh/ppi_geolocation_spec/
13 * Wireshark - Network traffic analyzer
14 * By Gerald Combs <gerald@wireshark.org>
15 * Copyright 1998 Gerald Combs
17 * Copied from packet-radiotap.c
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License along
30 * with this program; if not, write to the Free Software Foundation, Inc.,
31 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
40 #include <epan/packet.h>
41 #include "packet-ppi-geolocation-common.h"
43 enum ppi_vector_type {
44 PPI_VECTOR_VFLAGS = 0,
45 PPI_VECTOR_VCHARS = 1,
56 PPI_VECTOR_VEL_U = 10,
57 PPI_VECTOR_VEL_T = 11,
58 PPI_VECTOR_ACC_R = 12,
59 PPI_VECTOR_ACC_F = 13,
60 PPI_VECTOR_ACC_U = 14,
61 PPI_VECTOR_ACC_T = 15,
68 PPI_VECTOR_ERR_ROT = 16,
69 PPI_VECTOR_ERR_OFF = 17,
72 PPI_VECTOR_ERR_VEL = 18,
73 PPI_VECTOR_ERR_ACC = 19,
75 PPI_VECTOR_DESCSTR = 28,
76 PPI_VECTOR_APPID = 29,
77 PPI_VECTOR_APPDATA = 30,
80 #define PPI_VECTOR_MAXTAGLEN 144 /* increase as fields are added */
82 /* There are currently eight vector characteristics.
83 * These are purely descriptive (no mathematical importance)
85 #define PPI_VECTOR_VCHARS_ANTENNA 0x00000001
86 #define PPI_VECTOR_VCHARS_DIR_OF_TRAVEL 0x00000002
87 #define PPI_VECTOR_VCHARS_FRONT_OF_VEH 0x00000004
88 #define PPI_VECTOR_VCHARS_AOA 0x00000008
89 #define PPI_VECTOR_VCHARS_TRANSMITTER_POS 0x00000010
91 #define PPI_VECTOR_VCHARS_GPS_DERIVED 0x00000100
92 #define PPI_VECTOR_VCHARS_INS_DERIVED 0x00000200
93 #define PPI_VECTOR_VCHARS_COMPASS_DERIVED 0x00000400
94 #define PPI_VECTOR_VCHARS_ACCELEROMETER_DERIVED 0x00000800
95 #define PPI_VECTOR_VCHARS_HUMAN_DERIVED 0x00001000
97 #define PPI_VECTOR_MASK_VFLAGS 0x00000001
98 #define PPI_VECTOR_MASK_VCHARS 0x00000002
99 #define PPI_VECTOR_MASK_ROTX 0x00000004
100 #define PPI_VECTOR_MASK_ROTY 0x00000008
101 #define PPI_VECTOR_MASK_ROTZ 0x00000010
104 #define PPI_VECTOR_MASK_OFF_R 0x00000020
105 #define PPI_VECTOR_MASK_OFF_F 0x00000040
106 #define PPI_VECTOR_MASK_OFF_U 0x00000080
107 #define PPI_VECTOR_MASK_VEL_R 0x00000100
108 #define PPI_VECTOR_MASK_VEL_F 0x00000200
109 #define PPI_VECTOR_MASK_VEL_U 0x00000400
110 #define PPI_VECTOR_MASK_VEL_T 0x00000800
111 #define PPI_VECTOR_MASK_ACC_R 0x00001000
112 #define PPI_VECTOR_MASK_ACC_F 0x00002000
113 #define PPI_VECTOR_MASK_ACC_U 0x00004000
114 #define PPI_VECTOR_MASK_ACC_T 0x00008000
117 #define PPI_VECTOR_MASK_OFF_X 0x00000020
118 #define PPI_VECTOR_MASK_OFF_Y 0x00000040
119 #define PPI_VECTOR_MASK_OFF_Z 0x00000080
121 #define PPI_VECTOR_MASK_ERR_ROT 0x00010000
122 #define PPI_VECTOR_MASK_ERR_OFF 0x00020000
125 #define PPI_VECTOR_MASK_ERR_VEL 0x00040000
126 #define PPI_VECTOR_MASK_ERR_ACC 0x00080000
128 #define PPI_VECTOR_MASK_DESCSTR 0x10000000 /* 28 */
129 #define PPI_VECTOR_MASK_APPID 0x20000000 /* 29 */
130 #define PPI_VECTOR_MASK_APPDATA 0x40000000 /* 30 */
131 #define PPI_VECTOR_MASK_EXT 0x80000000 /* 31 */
133 /* There are currently only three vector flags.
134 * These control the units/interpreration of a vector
136 #define PPI_VECTOR_VFLAGS_DEFINES_FORWARD 0x00000001
139 #define PPI_VECTOR_VFLAGS_ROTS_ABSOLUTE 0x00000002
140 #define PPI_VECTOR_VFLAGS_OFFSETS_FROM_GPS 0x00000004
143 #define PPI_VECTOR_VFLAGS_RELATIVE_TO 0x00000006 /* 2 bits */
145 /* Values for the two-bit RelativeTo subfield of vflags */
146 static const value_string relativeto_string[] = {
156 static int proto_ppi_vector = -1;
158 /* "top" level fields */
159 static int hf_ppi_vector_version = -1;
160 static int hf_ppi_vector_pad = -1;
161 static int hf_ppi_vector_length = -1;
162 static int hf_ppi_vector_present = -1;
163 static int hf_ppi_vector_vflags = -1;
164 static int hf_ppi_vector_vchars = -1;
165 static int hf_ppi_vector_rot_x = -1;
166 static int hf_ppi_vector_rot_y = -1;
167 static int hf_ppi_vector_rot_z = -1;
170 static int hf_ppi_vector_off_r = -1;
171 static int hf_ppi_vector_off_f = -1;
172 static int hf_ppi_vector_off_u = -1;
173 static int hf_ppi_vector_vel_r = -1;
174 static int hf_ppi_vector_vel_f = -1;
175 static int hf_ppi_vector_vel_u = -1;
176 static int hf_ppi_vector_vel_t = -1;
177 static int hf_ppi_vector_acc_r = -1;
178 static int hf_ppi_vector_acc_f = -1;
179 static int hf_ppi_vector_acc_u = -1;
180 static int hf_ppi_vector_acc_t = -1;
183 static int hf_ppi_vector_off_x = -1;
184 static int hf_ppi_vector_off_y = -1;
185 static int hf_ppi_vector_off_z = -1;
187 static int hf_ppi_vector_err_rot= -1;
188 static int hf_ppi_vector_err_off= -1;
191 static int hf_ppi_vector_err_vel= -1;
192 static int hf_ppi_vector_err_acc= -1;
194 static int hf_ppi_vector_descstr= -1;
195 static int hf_ppi_vector_appspecific_num = -1;
196 static int hf_ppi_vector_appspecific_data = -1;
198 /* "Present" flags */
199 static int hf_ppi_vector_present_vflags = -1;
200 static int hf_ppi_vector_present_vchars = -1;
201 static int hf_ppi_vector_present_val_x = -1;
202 static int hf_ppi_vector_present_val_y = -1;
203 static int hf_ppi_vector_present_val_z = -1;
206 static int hf_ppi_vector_present_off_r = -1;
207 static int hf_ppi_vector_present_off_f = -1;
208 static int hf_ppi_vector_present_off_u = -1;
209 static int hf_ppi_vector_present_vel_r = -1;
210 static int hf_ppi_vector_present_vel_f = -1;
211 static int hf_ppi_vector_present_vel_u = -1;
212 static int hf_ppi_vector_present_vel_t = -1;
213 static int hf_ppi_vector_present_acc_r = -1;
214 static int hf_ppi_vector_present_acc_f = -1;
215 static int hf_ppi_vector_present_acc_u = -1;
216 static int hf_ppi_vector_present_acc_t = -1;
219 static int hf_ppi_vector_present_off_x = -1;
220 static int hf_ppi_vector_present_off_y = -1;
221 static int hf_ppi_vector_present_off_z = -1;
223 static int hf_ppi_vector_present_err_rot = -1;
224 static int hf_ppi_vector_present_err_off = -1;
227 static int hf_ppi_vector_present_err_vel = -1;
228 static int hf_ppi_vector_present_err_acc = -1;
230 static int hf_ppi_vector_present_descstr= -1;
231 static int hf_ppi_vector_presenappsecific_num = -1;
232 static int hf_ppi_vector_present_appspecific_data = -1;
233 static int hf_ppi_vector_present_ext = -1;
235 /* VectorFlags bits */
236 /* There are currently only three bits and two fields defined in vector flags.
237 * These control the units/interpretation of a vector
239 static int hf_ppi_vector_vflags_defines_forward = -1; /* bit 0 */
242 static int hf_ppi_vector_vflags_rots_absolute = -1; /* different ways to display the same bit, hi or low */
243 static int hf_ppi_vector_vflags_offsets_from_gps = -1; /* these are different ways to display the same bit, hi or low */
246 static int hf_ppi_vector_vflags_relative_to= -1; /* bits 1 and 2 */
248 /* There are currently eight vector characteristics.
249 * These are purely descriptive (no mathematical importance)
251 static int hf_ppi_vector_vchars_antenna = -1;
252 static int hf_ppi_vector_vchars_dir_of_travel = -1;
253 static int hf_ppi_vector_vchars_front_of_veh = -1;
256 static int hf_ppi_vector_vchars_angle_of_arrival= -1;
257 static int hf_ppi_vector_vchars_transmitter_pos= -1;
259 static int hf_ppi_vector_vchars_gps_derived = -1;
260 static int hf_ppi_vector_vchars_ins_derived = -1;
261 static int hf_ppi_vector_vchars_compass_derived = -1;
262 static int hf_ppi_vector_vchars_accelerometer_derived = -1;
263 static int hf_ppi_vector_vchars_human_derived = -1;
265 /*These represent arrow-dropdownthings in the gui */
266 static gint ett_ppi_vector = -1;
267 static gint ett_ppi_vector_present = -1;
268 static gint ett_ppi_vectorflags= -1;
269 static gint ett_ppi_vectorchars= -1;
272 /* We want to abbreviate this field into a single line. Does so without any string maniuplation */
274 annotate_vector_chars(guint32 chars, proto_tree *my_pt)
276 if (chars & PPI_VECTOR_VCHARS_ANTENNA)
277 proto_item_append_text(my_pt, " (Antenna)");
278 if (chars & PPI_VECTOR_VCHARS_DIR_OF_TRAVEL)
279 proto_item_append_text(my_pt, " (DOT)");
280 if (chars & PPI_VECTOR_VCHARS_FRONT_OF_VEH)
281 proto_item_append_text(my_pt, " (Front_of_veh)");
282 if (chars & PPI_VECTOR_VCHARS_AOA)
283 proto_item_append_text(my_pt, " (AOA)");
284 if (chars & PPI_VECTOR_VCHARS_TRANSMITTER_POS)
285 proto_item_append_text(my_pt, " (TRANSMITTER_POS)");
289 dissect_ppi_vector_v1(tvbuff_t *tvb, int offset, gint length_remaining, proto_tree *ppi_vector_tree)
291 proto_tree *vectorflags_tree = NULL;
292 proto_tree *vectorchars_tree = NULL;
293 proto_tree *my_pt, *pt, *present_tree = NULL;
298 guint32 present, next_present;
299 /* values actually read out, for displaying */
300 gdouble rot_x, rot_y, rot_z;
301 gdouble off_r, off_f, off_u;
302 gdouble vel_r, vel_f, vel_u, vel_t;
303 gdouble acc_r, acc_f, acc_u, acc_t = 0;
304 gdouble err_rot, err_off, err_vel, err_acc;
305 guint32 appsecific_num; /* appdata parser should add a subtree based on this value */
306 guint32 flags=0, chars=0;
308 /* temporary, conversion values */
311 present = tvb_get_letohl(tvb, offset+4);
312 /* Subtree for the "present flags" bitfield. */
313 if (ppi_vector_tree) {
314 pt = proto_tree_add_uint(ppi_vector_tree, hf_ppi_vector_present,
315 tvb, offset + 4, 4, present);
316 present_tree = proto_item_add_subtree(pt, ett_ppi_vector_present);
318 proto_tree_add_item(present_tree, hf_ppi_vector_present_vflags, tvb, 4, 4, ENC_LITTLE_ENDIAN);
319 proto_tree_add_item(present_tree, hf_ppi_vector_present_vchars, tvb, 4, 4, ENC_LITTLE_ENDIAN);
320 proto_tree_add_item(present_tree, hf_ppi_vector_present_val_x, tvb, 4, 4, ENC_LITTLE_ENDIAN);
321 proto_tree_add_item(present_tree, hf_ppi_vector_present_val_y, tvb, 4, 4, ENC_LITTLE_ENDIAN);
322 proto_tree_add_item(present_tree, hf_ppi_vector_present_val_z, tvb, 4, 4, ENC_LITTLE_ENDIAN);
323 proto_tree_add_item(present_tree, hf_ppi_vector_present_off_r, tvb, 4, 4, ENC_LITTLE_ENDIAN);
324 proto_tree_add_item(present_tree, hf_ppi_vector_present_off_f, tvb, 4, 4, ENC_LITTLE_ENDIAN);
325 proto_tree_add_item(present_tree, hf_ppi_vector_present_off_u, tvb, 4, 4, ENC_LITTLE_ENDIAN);
326 proto_tree_add_item(present_tree, hf_ppi_vector_present_vel_r, tvb, 4, 4, ENC_LITTLE_ENDIAN);
327 proto_tree_add_item(present_tree, hf_ppi_vector_present_vel_f, tvb, 4, 4, ENC_LITTLE_ENDIAN);
328 proto_tree_add_item(present_tree, hf_ppi_vector_present_vel_u, tvb, 4, 4, ENC_LITTLE_ENDIAN);
329 proto_tree_add_item(present_tree, hf_ppi_vector_present_vel_t, tvb, 4, 4, ENC_LITTLE_ENDIAN);
330 proto_tree_add_item(present_tree, hf_ppi_vector_present_acc_r, tvb, 4, 4, ENC_LITTLE_ENDIAN);
331 proto_tree_add_item(present_tree, hf_ppi_vector_present_acc_f, tvb, 4, 4, ENC_LITTLE_ENDIAN);
332 proto_tree_add_item(present_tree, hf_ppi_vector_present_acc_u, tvb, 4, 4, ENC_LITTLE_ENDIAN);
333 proto_tree_add_item(present_tree, hf_ppi_vector_present_acc_t, tvb, 4, 4, ENC_LITTLE_ENDIAN);
334 proto_tree_add_item(present_tree, hf_ppi_vector_present_err_rot, tvb, 4, 4, ENC_LITTLE_ENDIAN);
335 proto_tree_add_item(present_tree, hf_ppi_vector_present_err_off, tvb, 4, 4, ENC_LITTLE_ENDIAN);
336 proto_tree_add_item(present_tree, hf_ppi_vector_present_err_vel, tvb, 4, 4, ENC_LITTLE_ENDIAN);
337 proto_tree_add_item(present_tree, hf_ppi_vector_present_err_acc, tvb, 4, 4, ENC_LITTLE_ENDIAN);
338 proto_tree_add_item(present_tree, hf_ppi_vector_present_descstr, tvb, 4, 4, ENC_LITTLE_ENDIAN);
339 proto_tree_add_item(present_tree, hf_ppi_vector_presenappsecific_num, tvb, 4, 4, ENC_LITTLE_ENDIAN);
340 proto_tree_add_item(present_tree, hf_ppi_vector_present_appspecific_data, tvb, 4, 4, ENC_LITTLE_ENDIAN);
341 proto_tree_add_item(present_tree, hf_ppi_vector_present_ext, tvb, 4, 4, ENC_LITTLE_ENDIAN);
343 offset += PPI_GEOBASE_MIN_HEADER_LEN;
344 length_remaining -= PPI_GEOBASE_MIN_HEADER_LEN;
347 /* Now all of the fixed length, fixed location stuff is over. Loop over the bits */
348 for (; present; present = next_present) {
349 /* clear the least significant bit that is set */
350 next_present = present & (present - 1);
351 /* extract the least significant bit that is set */
352 bit = BITNO_32(present ^ next_present);
354 case PPI_VECTOR_VFLAGS:
355 if (length_remaining < 4)
357 flags = tvb_get_letohl(tvb, offset);
358 if (ppi_vector_tree) {
359 my_pt = proto_tree_add_uint(ppi_vector_tree, hf_ppi_vector_vflags, tvb, offset , 4, flags);
360 vectorflags_tree= proto_item_add_subtree(my_pt, ett_ppi_vectorflags);
362 proto_tree_add_item(vectorflags_tree, hf_ppi_vector_vflags_defines_forward, tvb, offset, 4, ENC_LITTLE_ENDIAN);
363 proto_tree_add_item(vectorflags_tree, hf_ppi_vector_vflags_rots_absolute, tvb, offset, 4, ENC_LITTLE_ENDIAN);
364 proto_tree_add_item(vectorflags_tree, hf_ppi_vector_vflags_offsets_from_gps, tvb, offset, 4, ENC_LITTLE_ENDIAN);
369 case PPI_VECTOR_VCHARS:
370 if (length_remaining < 4)
372 chars = tvb_get_letohl(tvb, offset);
373 if (ppi_vector_tree) {
374 my_pt = proto_tree_add_uint(ppi_vector_tree, hf_ppi_vector_vchars, tvb, offset , 4, chars);
375 vectorchars_tree= proto_item_add_subtree(my_pt, ett_ppi_vectorchars);
377 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_antenna, tvb, offset, 4, ENC_LITTLE_ENDIAN);
378 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_dir_of_travel, tvb, offset, 4, ENC_LITTLE_ENDIAN);
379 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_front_of_veh, tvb, offset, 4, ENC_LITTLE_ENDIAN);
380 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_gps_derived, tvb, offset, 4, ENC_LITTLE_ENDIAN);
381 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_ins_derived, tvb, offset, 4, ENC_LITTLE_ENDIAN);
382 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_compass_derived, tvb, offset, 4, ENC_LITTLE_ENDIAN);
383 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_accelerometer_derived, tvb, offset, 4, ENC_LITTLE_ENDIAN);
384 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_human_derived, tvb, offset, 4, ENC_LITTLE_ENDIAN);
389 case PPI_VECTOR_ROTX:
390 if (length_remaining < 4)
392 t_val = tvb_get_letohl(tvb, offset);
393 rot_x = ppi_fixed3_6_to_gdouble(t_val);
394 if (ppi_vector_tree) {
395 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_rot_x, tvb, offset, 4, rot_x);
396 if (flags & PPI_VECTOR_VFLAGS_ROTS_ABSOLUTE)
397 proto_item_append_text(ti, " Degrees (Absolute)");
399 proto_item_append_text(ti, " Degrees (Rel to forward)");
404 case PPI_VECTOR_ROTY:
405 if (length_remaining < 4)
407 t_val = tvb_get_letohl(tvb, offset);
408 rot_y = ppi_fixed3_6_to_gdouble(t_val);
409 if (ppi_vector_tree) {
410 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_rot_y, tvb, offset, 4, rot_y);
411 if (flags & PPI_VECTOR_VFLAGS_ROTS_ABSOLUTE)
412 proto_item_append_text(ti, " Degrees (Absolute)");
414 proto_item_append_text(ti, " Degrees (Rel to forward)");
419 case PPI_VECTOR_ROTZ:
420 if (length_remaining < 4)
422 t_val = tvb_get_letohl(tvb, offset);
423 rot_z = ppi_fixed3_6_to_gdouble(t_val);
424 if (ppi_vector_tree) {
425 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_rot_z, tvb, offset, 4, rot_z);
426 if (flags & PPI_VECTOR_VFLAGS_ROTS_ABSOLUTE)
427 proto_item_append_text(ti, " Degrees (Absolute) ");
429 proto_item_append_text(ti, " Degrees (Rel to forward)");
434 case PPI_VECTOR_OFF_R:
435 if (length_remaining < 4)
437 t_val = tvb_get_letohl(tvb, offset);
438 off_r = ppi_fixed6_4_to_gdouble(t_val);
439 if (ppi_vector_tree) {
440 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_off_r, tvb, offset, 4, off_r);
441 if (flags & PPI_VECTOR_VFLAGS_OFFSETS_FROM_GPS)
442 proto_item_append_text(ti, " m from Curr_GPS");
444 proto_item_append_text(ti, " m from Curr_Pos");
449 case PPI_VECTOR_OFF_F:
450 if (length_remaining < 4)
452 t_val = tvb_get_letohl(tvb, offset);
453 off_f = ppi_fixed6_4_to_gdouble(t_val);
454 if (ppi_vector_tree) {
455 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_off_f, tvb, offset, 4, off_f);
456 if (flags & PPI_VECTOR_VFLAGS_OFFSETS_FROM_GPS)
457 proto_item_append_text(ti, " m from Curr_GPS");
459 proto_item_append_text(ti, " m from Curr_Pos");
464 case PPI_VECTOR_OFF_U:
465 if (length_remaining < 4)
467 t_val = tvb_get_letohl(tvb, offset);
468 off_u = ppi_fixed6_4_to_gdouble(t_val);
469 if (ppi_vector_tree) {
470 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_off_u, tvb, offset, 4, off_u);
471 if (flags & PPI_VECTOR_VFLAGS_OFFSETS_FROM_GPS)
472 proto_item_append_text(ti, " m from Curr_GPS");
474 proto_item_append_text(ti, " m from Curr_Pos");
479 case PPI_VECTOR_VEL_R:
480 if (length_remaining < 4)
482 t_val = tvb_get_letohl(tvb, offset);
483 vel_r = ppi_fixed6_4_to_gdouble(t_val);
484 if (ppi_vector_tree) {
485 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_vel_r, tvb, offset, 4, vel_r);
486 proto_item_append_text(ti, " m/s");
491 case PPI_VECTOR_VEL_F:
492 if (length_remaining < 4)
494 t_val = tvb_get_letohl(tvb, offset);
495 vel_f = ppi_fixed6_4_to_gdouble(t_val);
496 if (ppi_vector_tree) {
497 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_vel_f, tvb, offset, 4, vel_f);
498 proto_item_append_text(ti, " m/s");
503 case PPI_VECTOR_VEL_U:
504 if (length_remaining < 4)
506 t_val = tvb_get_letohl(tvb, offset);
507 vel_u = ppi_fixed6_4_to_gdouble(t_val);
508 if (ppi_vector_tree) {
509 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_vel_u, tvb, offset, 4, vel_u);
510 proto_item_append_text(ti, " m/s");
515 case PPI_VECTOR_VEL_T:
516 if (length_remaining < 4)
518 t_val = tvb_get_letohl(tvb, offset);
519 vel_t = ppi_fixed6_4_to_gdouble(t_val);
520 if (ppi_vector_tree) {
521 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_vel_t, tvb, offset, 4, vel_t);
522 proto_item_append_text(ti, " m/s");
527 case PPI_VECTOR_ACC_R:
528 if (length_remaining < 4)
530 t_val = tvb_get_letohl(tvb, offset);
531 acc_r = ppi_fixed6_4_to_gdouble(t_val);
532 if (ppi_vector_tree) {
533 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_acc_r, tvb, offset, 4, acc_r);
534 proto_item_append_text(ti, " (m/s)/s");
539 case PPI_VECTOR_ACC_F:
540 if (length_remaining < 4)
542 t_val = tvb_get_letohl(tvb, offset);
543 acc_f = ppi_fixed6_4_to_gdouble(t_val);
544 if (ppi_vector_tree) {
545 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_acc_f, tvb, offset, 4, acc_f);
546 proto_item_append_text(ti, " (m/s)/s");
551 case PPI_VECTOR_ACC_U:
552 if (length_remaining < 4)
554 t_val = tvb_get_letohl(tvb, offset);
555 acc_u = ppi_fixed6_4_to_gdouble(t_val);
556 if (ppi_vector_tree) {
557 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_acc_u, tvb, offset, 4, acc_u);
558 proto_item_append_text(ti, " (m/s)/s");
563 case PPI_VECTOR_ACC_T:
564 if (length_remaining < 4)
566 t_val = tvb_get_letohl(tvb, offset);
567 acc_t = ppi_fixed6_4_to_gdouble(t_val);
568 if (ppi_vector_tree) {
569 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_acc_t, tvb, offset, 4, acc_t);
570 proto_item_append_text(ti, " (m/s)/s");
575 case PPI_VECTOR_ERR_ROT:
576 if (length_remaining < 4)
578 t_val = tvb_get_letohl(tvb, offset);
579 err_rot = ppi_fixed3_6_to_gdouble(t_val);
580 if (ppi_vector_tree) {
581 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_err_rot, tvb, offset, 4, err_rot);
582 proto_item_append_text(ti, " degrees");
587 case PPI_VECTOR_ERR_OFF:
588 if (length_remaining < 4)
590 t_val = tvb_get_letohl(tvb, offset);
591 err_off = ppi_fixed6_4_to_gdouble(t_val);
592 if (ppi_vector_tree) {
593 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_err_off, tvb, offset, 4, err_off);
594 proto_item_append_text(ti, " meters");
599 case PPI_VECTOR_ERR_VEL:
600 if (length_remaining < 4)
602 t_val = tvb_get_letohl(tvb, offset);
603 err_vel = ppi_fixed6_4_to_gdouble(t_val);
604 if (ppi_vector_tree) {
605 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_err_vel, tvb, offset, 4, err_vel);
606 proto_item_append_text(ti, "m/s");
611 case PPI_VECTOR_ERR_ACC:
612 if (length_remaining < 4)
614 t_val = tvb_get_letohl(tvb, offset);
615 err_acc = ppi_fixed6_4_to_gdouble(t_val);
616 if (ppi_vector_tree) {
617 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_err_acc, tvb, offset, 4, err_acc);
618 proto_item_append_text(ti, " (m/s)/s");
623 case PPI_VECTOR_DESCSTR:
624 if (length_remaining < 32)
626 proto_tree_add_item(ppi_vector_tree, hf_ppi_vector_descstr, tvb, offset, 32, ENC_NA);
628 length_remaining-=32;
630 case PPI_VECTOR_APPID:
631 if (length_remaining < 4)
633 appsecific_num = tvb_get_letohl(tvb, offset); /* application specific parsers may switch on this later */
634 if (ppi_vector_tree) {
635 proto_tree_add_uint(ppi_vector_tree, hf_ppi_vector_appspecific_num, tvb, offset, 4, appsecific_num);
640 case PPI_VECTOR_APPDATA:
641 if (length_remaining < 60)
643 if (ppi_vector_tree) {
644 proto_tree_add_item(ppi_vector_tree, hf_ppi_vector_appspecific_data, tvb, offset, 60, ENC_NA);
647 length_remaining-=60;
652 * This indicates a field whose size we do not
653 * know, so we cannot proceed.
655 proto_tree_add_text(ppi_vector_tree, tvb, offset, 0, "Error: PPI-VECTOR: unknown bit (%d) set in present field.\n", bit);
664 dissect_ppi_vector_v2(tvbuff_t *tvb, int offset, gint length_remaining, proto_tree *ppi_vector_tree, proto_item *vector_line)
666 proto_tree *vectorflags_tree = NULL;
667 proto_tree *vectorchars_tree = NULL;
668 proto_tree *my_pt, *pt, *present_tree = NULL;
673 guint32 present, next_present;
675 /* values actually read out, for displaying */
678 /* these are used to specially handle RelativeTo: */
679 guint32 relativeto_int;
680 const gchar *relativeto_str= "RelativeTo: Forward"; /* default if vflags is not present*/
683 guint32 flags=0, chars=0;
684 gdouble rot_x, rot_y, rot_z;
685 gdouble off_x, off_y, off_z;
686 gdouble err_rot, err_off;
687 guint32 appsecific_num; /* appdata parser should add a subtree based on this value */
689 /* temporary, conversion values */
692 present = tvb_get_letohl(tvb, offset+4);
693 /* Subtree for the "present flags" bitfield. */
694 if (ppi_vector_tree) {
695 pt = proto_tree_add_uint(ppi_vector_tree, hf_ppi_vector_present,
696 tvb, offset + 4, 4, present);
697 present_tree = proto_item_add_subtree(pt, ett_ppi_vector_present);
699 proto_tree_add_item(present_tree, hf_ppi_vector_present_vflags, tvb, 4, 4, ENC_LITTLE_ENDIAN);
700 proto_tree_add_item(present_tree, hf_ppi_vector_present_vchars, tvb, 4, 4, ENC_LITTLE_ENDIAN);
701 proto_tree_add_item(present_tree, hf_ppi_vector_present_val_x, tvb, 4, 4, ENC_LITTLE_ENDIAN);
702 proto_tree_add_item(present_tree, hf_ppi_vector_present_val_y, tvb, 4, 4, ENC_LITTLE_ENDIAN);
703 proto_tree_add_item(present_tree, hf_ppi_vector_present_val_z, tvb, 4, 4, ENC_LITTLE_ENDIAN);
704 proto_tree_add_item(present_tree, hf_ppi_vector_present_off_x, tvb, 4, 4, ENC_LITTLE_ENDIAN);
705 proto_tree_add_item(present_tree, hf_ppi_vector_present_off_y, tvb, 4, 4, ENC_LITTLE_ENDIAN);
706 proto_tree_add_item(present_tree, hf_ppi_vector_present_off_z, tvb, 4, 4, ENC_LITTLE_ENDIAN);
707 proto_tree_add_item(present_tree, hf_ppi_vector_present_err_rot, tvb, 4, 4, ENC_LITTLE_ENDIAN);
708 proto_tree_add_item(present_tree, hf_ppi_vector_present_err_off, tvb, 4, 4, ENC_LITTLE_ENDIAN);
709 proto_tree_add_item(present_tree, hf_ppi_vector_present_descstr, tvb, 4, 4, ENC_LITTLE_ENDIAN);
710 proto_tree_add_item(present_tree, hf_ppi_vector_presenappsecific_num, tvb, 4, 4, ENC_LITTLE_ENDIAN);
711 proto_tree_add_item(present_tree, hf_ppi_vector_present_appspecific_data, tvb, 4, 4, ENC_LITTLE_ENDIAN);
712 proto_tree_add_item(present_tree, hf_ppi_vector_present_ext, tvb, 4, 4, ENC_LITTLE_ENDIAN);
714 offset += PPI_GEOBASE_MIN_HEADER_LEN;
715 length_remaining -= PPI_GEOBASE_MIN_HEADER_LEN;
717 /* Before we process any fields, we check what this vector is RelativeTo. */
718 /* We do this so this up front so that it displays prominently in the summary line */
719 /* Another reason to do this up here is that vflags may not be present (in which case it defaults to 0) */
720 /* It also saves us from repeating this logic in any of the individual fields */
721 if ( (present & PPI_VECTOR_MASK_VFLAGS) && length_remaining >= 4)
723 /*vflags is the first field, */
724 flags = tvb_get_letohl(tvb, offset);
725 relativeto_int = (flags & (PPI_VECTOR_VFLAGS_RELATIVE_TO)); /* mask out all other bits */
726 relativeto_int = relativeto_int >> 1; /*scoot over 1 bit to align with the type string */
727 relativeto_str = val_to_str_const (relativeto_int, relativeto_string, "Reserved"); /*re-use that type string up top */
728 /* We will append this text to the vector line once all the other fields have processed */
730 /* this is important enough to put in vector line */
731 if (flags & PPI_VECTOR_VFLAGS_DEFINES_FORWARD)
732 proto_item_append_text(vector_line, " (Forward)");
734 /* Intentionally dont upset offset, length_remaining. This is taken care of in the normal vflags parser below*/
736 else /* No vflags means vlfags defaults to zero. RelativeTo: Forward */
738 relativeto_str = " RelativeTo: Forward";
741 * vchars is another field that we want to pre-process simillar to vflags and for the same reasons.
742 * we perform seperate length checks depending on if vector_flags is present (which would precede vector_chars)
744 if ( ( (present & PPI_VECTOR_MASK_VFLAGS)) && (present & PPI_VECTOR_MASK_VCHARS) && length_remaining >= 8)
745 chars = tvb_get_letohl(tvb, offset + 4);
746 else if ( (!(present & PPI_VECTOR_MASK_VFLAGS)) && (present & PPI_VECTOR_MASK_VCHARS) && length_remaining >= 4)
747 chars = tvb_get_letohl(tvb, offset );
751 /* Mark the most interesting characteristics on the vector dropdown line */
752 annotate_vector_chars(chars, vector_line);
753 /* Intentionally dont update offset, length_remaining. This is taken care of in the normal vchars parser below*/
756 /* Now all of the fixed length, fixed location stuff is over. Loop over the bits */
757 for (; present; present = next_present) {
758 /* clear the least significant bit that is set */
759 next_present = present & (present - 1);
760 /* extract the least significant bit that is set */
761 bit = BITNO_32(present ^ next_present);
763 case PPI_VECTOR_VFLAGS:
764 if (length_remaining < 4)
766 /* flags = tvb_get_letohl(tvb, offset); */ /* Usually we read this in, but vflags is a special case handled above */
767 if (ppi_vector_tree) {
768 my_pt = proto_tree_add_uint(ppi_vector_tree, hf_ppi_vector_vflags, tvb, offset , 4, flags);
769 vectorflags_tree= proto_item_add_subtree(my_pt, ett_ppi_vectorflags);
771 proto_tree_add_item(vectorflags_tree, hf_ppi_vector_vflags_defines_forward, tvb, offset, 4, ENC_LITTLE_ENDIAN);
772 proto_tree_add_item(vectorflags_tree, hf_ppi_vector_vflags_relative_to, tvb, offset, 4, ENC_LITTLE_ENDIAN);
774 if (flags & PPI_VECTOR_VFLAGS_DEFINES_FORWARD)
775 proto_item_append_text(vectorflags_tree, " (Forward)");
777 proto_item_append_text (vectorflags_tree, " RelativeTo: %s", relativeto_str);
782 case PPI_VECTOR_VCHARS:
783 if (length_remaining < 4)
785 /* chars = tvb_get_letohl(tvb, offset); */ /*Usually we read this in, but vchars specially handled above */
786 if (ppi_vector_tree) {
787 my_pt = proto_tree_add_uint(ppi_vector_tree, hf_ppi_vector_vchars, tvb, offset , 4, chars);
788 vectorchars_tree= proto_item_add_subtree(my_pt, ett_ppi_vectorchars);
790 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_antenna, tvb, offset, 4, ENC_LITTLE_ENDIAN);
791 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_dir_of_travel, tvb, offset, 4, ENC_LITTLE_ENDIAN);
792 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_front_of_veh, tvb, offset, 4, ENC_LITTLE_ENDIAN);
793 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_angle_of_arrival, tvb, offset, 4, ENC_LITTLE_ENDIAN);
794 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_transmitter_pos, tvb, offset, 4, ENC_LITTLE_ENDIAN);
795 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_gps_derived, tvb, offset, 4, ENC_LITTLE_ENDIAN);
796 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_ins_derived, tvb, offset, 4, ENC_LITTLE_ENDIAN);
797 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_compass_derived, tvb, offset, 4, ENC_LITTLE_ENDIAN);
798 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_accelerometer_derived, tvb, offset, 4, ENC_LITTLE_ENDIAN);
799 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_human_derived, tvb, offset, 4, ENC_LITTLE_ENDIAN);
801 annotate_vector_chars(chars, my_pt);
806 case PPI_VECTOR_ROTX:
807 if (length_remaining < 4)
809 t_val = tvb_get_letohl(tvb, offset);
810 rot_x = ppi_fixed3_6_to_gdouble(t_val);
811 if (ppi_vector_tree) {
812 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_rot_x, tvb, offset, 4, rot_x);
813 proto_item_append_text(ti, " Degrees RelativeTo: %s", relativeto_str);
814 proto_item_append_text(vector_line, " Pitch:%3f ", rot_x);
819 case PPI_VECTOR_ROTY:
820 if (length_remaining < 4)
822 t_val = tvb_get_letohl(tvb, offset);
823 rot_y = ppi_fixed3_6_to_gdouble(t_val);
824 if (ppi_vector_tree) {
825 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_rot_y, tvb, offset, 4, rot_y);
826 proto_item_append_text(ti, " Degrees RelativeTo: %s", relativeto_str);
827 proto_item_append_text(vector_line, " Roll:%3f ", rot_y);
832 case PPI_VECTOR_ROTZ:
833 if (length_remaining < 4)
835 t_val = tvb_get_letohl(tvb, offset);
836 rot_z = ppi_fixed3_6_to_gdouble(t_val);
837 if (ppi_vector_tree) {
838 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_rot_z, tvb, offset, 4, rot_z);
839 proto_item_append_text(ti, " Degrees RelativeTo: %s", relativeto_str);
840 proto_item_append_text(vector_line, " Heading:%3f ", rot_z);
845 case PPI_VECTOR_OFF_X:
846 if (length_remaining < 4)
848 t_val = tvb_get_letohl(tvb, offset);
849 off_x = ppi_fixed6_4_to_gdouble(t_val);
850 if (ppi_vector_tree) {
851 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_off_x, tvb, offset, 4, off_x);
852 proto_item_append_text(ti, " Meters RelativeTo: %s", relativeto_str);
853 proto_item_append_text(vector_line, " Off-X:%3f ", off_x);
858 case PPI_VECTOR_OFF_Y:
859 if (length_remaining < 4)
861 t_val = tvb_get_letohl(tvb, offset);
862 off_y = ppi_fixed6_4_to_gdouble(t_val);
863 if (ppi_vector_tree) {
864 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_off_y, tvb, offset, 4, off_y);
865 proto_item_append_text(ti, " Meters RelativeTo: %s", relativeto_str);
866 proto_item_append_text(vector_line, " Off-Y:%3f ", off_y);
871 case PPI_VECTOR_OFF_Z:
872 if (length_remaining < 4)
874 t_val = tvb_get_letohl(tvb, offset);
875 off_z = ppi_fixed6_4_to_gdouble(t_val);
876 if (ppi_vector_tree) {
877 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_off_z, tvb, offset, 4, off_z);
878 proto_item_append_text(ti, " Meters RelativeTo: %s", relativeto_str);
879 proto_item_append_text(vector_line, " Off-Z:%3f ", off_z);
884 case PPI_VECTOR_ERR_ROT:
885 if (length_remaining < 4)
887 t_val = tvb_get_letohl(tvb, offset);
888 err_rot = ppi_fixed3_6_to_gdouble(t_val);
889 if (ppi_vector_tree) {
890 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_err_rot, tvb, offset, 4, err_rot);
891 proto_item_append_text(ti, " Degrees");
896 case PPI_VECTOR_ERR_OFF:
897 if (length_remaining < 4)
899 t_val = tvb_get_letohl(tvb, offset);
900 err_off = ppi_fixed6_4_to_gdouble(t_val);
901 if (ppi_vector_tree) {
902 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_err_off, tvb, offset, 4, err_off);
903 proto_item_append_text(ti, " Meters");
909 case PPI_VECTOR_DESCSTR:
910 if (length_remaining < 32)
914 /* proto_tree_add_item(ppi_vector_tree, hf_ppi_vector_descstr, tvb, offset, 32, ENC_NA); */
915 curr_str = tvb_format_stringzpad(tvb, offset, 32); /* need to append_text this */
916 proto_tree_add_string(ppi_vector_tree, hf_ppi_vector_descstr, tvb, offset, 32, curr_str);
917 proto_item_append_text(vector_line, " (%s)", curr_str);
920 length_remaining-=32;
922 case PPI_VECTOR_APPID:
923 if (length_remaining < 4)
925 appsecific_num = tvb_get_letohl(tvb, offset); /* application specific parsers may switch on this later */
926 if (ppi_vector_tree) {
927 proto_tree_add_uint(ppi_vector_tree, hf_ppi_vector_appspecific_num, tvb, offset, 4, appsecific_num);
932 case PPI_VECTOR_APPDATA:
933 if (length_remaining < 60)
935 if (ppi_vector_tree) {
936 proto_tree_add_item(ppi_vector_tree, hf_ppi_vector_appspecific_data, tvb, offset, 60, ENC_NA);
939 length_remaining-=60;
944 * This indicates a field whose size we do not
945 * know, so we cannot proceed.
947 proto_tree_add_text(ppi_vector_tree, tvb, offset, 0, "Error: PPI-VECTOR: unknown bit (%d) set in present field.\n", bit);
952 /* Append the RelativeTo string we computed up top */
953 proto_item_append_text (vector_line, " RelativeTo: %s", relativeto_str);
957 dissect_ppi_vector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
959 proto_tree *ppi_vector_tree = NULL;
960 proto_item *ti = NULL;
961 proto_item *vector_line = NULL;
962 gint length_remaining;
965 /* values actually read out, for displaying */
969 /* Clear out stuff in the info column */
970 col_clear(pinfo->cinfo,COL_INFO);
972 /* pull out the first three fields of the BASE-GEOTAG-HEADER */
973 version = tvb_get_guint8(tvb, offset);
974 length = tvb_get_letohs(tvb, offset+2);
976 /* Setup basic column info */
977 if (check_col(pinfo->cinfo, COL_INFO))
978 col_add_fstr(pinfo->cinfo, COL_INFO, "PPI_Vector Capture v%u, Length %u",
981 /* Create the basic dissection tree*/
983 ti = proto_tree_add_protocol_format(tree, proto_ppi_vector, tvb, 0, length, "Vector:");
984 vector_line = ti; /*save this for later, we will replace it with something more useful*/
985 ppi_vector_tree= proto_item_add_subtree(ti, ett_ppi_vector);
986 proto_tree_add_uint(ppi_vector_tree, hf_ppi_vector_version,
987 tvb, offset, 1, version);
988 proto_tree_add_item(ppi_vector_tree, hf_ppi_vector_pad,
989 tvb, offset + 1, 1, ENC_NA);
990 ti = proto_tree_add_uint(ppi_vector_tree, hf_ppi_vector_length,
991 tvb, offset + 2, 2, length);
994 /* initialize remaining length */
995 length_remaining = length;
996 /* minimum length check, should atleast be a fixed-size geotagging-base header*/
997 if (length_remaining < PPI_GEOBASE_MIN_HEADER_LEN) {
999 * Base-geotag-header (Radiotap lookalike) is shorter than the fixed-length portion
1000 * plus one "present" bitset.
1003 proto_item_append_text(ti, " (invalid - minimum length is %d)", PPI_GEOBASE_MIN_HEADER_LEN);
1010 dissect_ppi_vector_v1(tvb, offset, length_remaining, ppi_vector_tree);
1014 /* perform max length sanity checking */
1015 if (length > PPI_VECTOR_MAXTAGLEN ) {
1017 proto_item_append_text(ti, " (invalid - maximum length is %d\n)", PPI_VECTOR_MAXTAGLEN);
1020 dissect_ppi_vector_v2(tvb, offset, length_remaining, ppi_vector_tree, vector_line);
1025 proto_tree_add_text(ppi_vector_tree, tvb, offset + 4, -1,
1026 "Data for unknown version");
1033 proto_register_ppi_vector(void)
1035 /* The following array initializes those header fields declared above to the values displayed */
1036 static hf_register_info hf[] = {
1037 { &hf_ppi_vector_version,
1038 { "Header revision", "ppi_vector.version",
1039 FT_UINT8, BASE_DEC, NULL, 0x0,
1040 "Version of ppi_vector header format", HFILL } },
1041 { &hf_ppi_vector_pad,
1042 { "Header pad", "ppi_vector.pad",
1043 FT_UINT8, BASE_DEC, NULL, 0x0,
1044 "Padding", HFILL } },
1045 { &hf_ppi_vector_length,
1046 { "Header length", "ppi_vector.length",
1047 FT_UINT16, BASE_DEC, NULL, 0x0,
1048 "Length of header including version, pad, length and data fields", HFILL } },
1049 { &hf_ppi_vector_present,
1050 { "Present", "ppi_vector.present",
1051 FT_UINT32, BASE_HEX, NULL, 0x0,
1052 "Bitmask indicating which fields are present", HFILL } },
1054 /* Boolean 'present' flags */
1055 { &hf_ppi_vector_present_vflags,
1056 { "Vector flags", "ppi_vector.present.flags",
1057 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_VFLAGS,
1058 "Specifies if the Vector flags bitfield is present", HFILL } },
1060 { &hf_ppi_vector_present_vchars,
1061 { "Vector chararacteristics", "ppi_vector.present.chars",
1062 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_VCHARS,
1063 "Specifies if the Vector chars bitfield is present", HFILL } },
1065 { &hf_ppi_vector_present_val_x,
1066 { "Pitch", "ppi_vector.present.pitch",
1067 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ROTX,
1068 "Specifies if the rotate-x field (pitch) is present", HFILL } },
1070 { &hf_ppi_vector_present_val_y,
1071 { "Roll", "ppi_vector.present.roll",
1072 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ROTY,
1073 "Specifies if the rotate-y field (roll) is present", HFILL } },
1075 { &hf_ppi_vector_present_val_z,
1076 { "Heading", "ppi_vector.present.heading",
1077 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ROTZ,
1078 "Specifies if the rotate-z field (heading) is present", HFILL } },
1082 { &hf_ppi_vector_present_off_r,
1083 { "Offset_R", "ppi_vector.present.off_r",
1084 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_OFF_R,
1085 "Specifies if the offset-right field is present", HFILL } },
1087 { &hf_ppi_vector_present_off_f,
1088 { "Offset_F", "ppi_vector.present.off_f",
1089 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_OFF_F,
1090 "Specifies if the offset-forward field is present", HFILL } },
1092 { &hf_ppi_vector_present_off_u,
1093 { "Offset_U", "ppi_vector.present.off_u",
1094 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_OFF_U,
1095 "Specifies if the offset-up field is present", HFILL } },
1097 { &hf_ppi_vector_present_vel_r,
1098 { "Velocity_R", "ppi_vector.present.vel_r",
1099 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_VEL_R,
1100 "Specifies if the velocity-right field is present", HFILL } },
1102 { &hf_ppi_vector_present_vel_f,
1103 { "Velocity_F", "ppi_vector.present.vel_f",
1104 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_VEL_F,
1105 "Specifies if the velocity-forward field is present", HFILL } },
1107 { &hf_ppi_vector_present_vel_u,
1108 { "Velocity_U", "ppi_vector.present.vel_u",
1109 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_VEL_U,
1110 "Specifies if the velocity-up field is present", HFILL } },
1111 { &hf_ppi_vector_present_vel_t,
1112 { "Velocity_T", "ppi_vector.present.vel_t",
1113 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_VEL_T,
1114 "Specifies if the total velocity field is present", HFILL } },
1116 { &hf_ppi_vector_present_acc_r,
1117 { "Acceleration_R", "ppi_vector.present.acc_r",
1118 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ACC_R,
1119 "Specifies if the accel-right field is present", HFILL } },
1121 { &hf_ppi_vector_present_acc_f,
1122 { "Acceleration_F", "ppi_vector.present.acc_f",
1123 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ACC_F,
1124 "Specifies if the accel-forward field is present", HFILL } },
1126 { &hf_ppi_vector_present_acc_u,
1127 { "Acceleration_U", "ppi_vector.present.acc_u",
1128 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ACC_U,
1129 "Specifies if the accel-up field is present", HFILL } },
1130 { &hf_ppi_vector_present_acc_t,
1131 { "Acceleration_T", "ppi_vector.present.acc_t",
1132 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ACC_T,
1133 "Specifies if the total acceleration field is present", HFILL } },
1136 { &hf_ppi_vector_present_off_x,
1137 { "Offset_R", "ppi_vector.present.off_x",
1138 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_OFF_X,
1139 "Specifies if the offset-x (right/east) field is present", HFILL } },
1141 { &hf_ppi_vector_present_off_y,
1142 { "Offset_F", "ppi_vector.present.off_y",
1143 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_OFF_Y,
1144 "Specifies if the offset-y (forward/north) field is present", HFILL } },
1146 { &hf_ppi_vector_present_off_z,
1147 { "Offset_U", "ppi_vector.present.off_z",
1148 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_OFF_Z,
1149 "Specifies if the offset-z (up) field is present", HFILL } },
1152 { &hf_ppi_vector_present_err_rot,
1153 { "err_rot", "ppi_vector.present.err_rot",
1154 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ERR_ROT,
1155 "Specifies if the rotation error field is present", HFILL } },
1157 { &hf_ppi_vector_present_err_off,
1158 { "err_off", "ppi_vector.present.err_off",
1159 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ERR_OFF,
1160 "Specifies if the offset error field is present", HFILL } },
1164 { &hf_ppi_vector_present_err_vel,
1165 { "err_vel", "ppi_vector.present.err_vel",
1166 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ERR_VEL,
1167 "Specifies if the velocity error field is present", HFILL } },
1169 { &hf_ppi_vector_present_err_acc,
1170 { "err_acc", "ppi_vector.present.err_acc",
1171 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ERR_ACC,
1172 "Specifies if the acceleration error field is present", HFILL } },
1175 { &hf_ppi_vector_present_descstr,
1176 { "descstr", "ppi_vector.present.descstr",
1177 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_DESCSTR,
1178 "Specifies if the acceleration error field is present", HFILL } },
1180 { &hf_ppi_vector_presenappsecific_num,
1181 { "appid", "ppi_vector.present.appid",
1182 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_APPID,
1183 "Specifies if the application specific field id is present", HFILL } },
1185 { &hf_ppi_vector_present_appspecific_data,
1186 { "appdata", "ppi_vector.present.appdata",
1187 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_APPDATA,
1188 "Specifies if the application specific data field is present", HFILL } },
1190 { &hf_ppi_vector_present_ext,
1191 { "Ext", "ppi_vector.present.ext",
1192 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_EXT,
1193 "Specifies if there are any extensions to the header present", HFILL } },
1195 /* Now we get to the actual data fields */
1196 /* This setups the "Vector fflags" hex dropydown thing */
1197 { &hf_ppi_vector_vflags,
1198 { "Vector flags", "ppi_vector.vector_flags",
1199 FT_UINT32, BASE_HEX, NULL, 0x0,
1200 "Bitmask indicating coordinate sys, among others, etc", HFILL } },
1201 { &hf_ppi_vector_vchars,
1202 { "Vector chars", "ppi_vector.vector_chars",
1203 FT_UINT32, BASE_HEX, NULL, 0x0,
1204 "Bitmask indicating if vector tracks antenna, vehicle, motion, etc", HFILL } },
1205 { &hf_ppi_vector_rot_x,
1206 { "Pitch ", "ppi_vector.pitch", /*extra spaces intentional. casuses field values to align*/
1207 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1208 "Pitch (Rotation x) packet was received at", HFILL } },
1209 { &hf_ppi_vector_rot_y,
1210 { "Roll ", "ppi_vector.roll", /*extra spaces intentional. casuses field values to align*/
1211 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1212 "Roll (Rotation y) packet was received at", HFILL } },
1213 { &hf_ppi_vector_rot_z,
1214 { "Heading ", "ppi_vector.heading", /*extra spaces intentional. casuses field values to align*/
1215 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1216 "Heading (Rotation z) packet was received at", HFILL } },
1219 { &hf_ppi_vector_off_r,
1220 { "Off-r", "ppi_vector.off_r",
1221 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1222 "Offset right", HFILL } },
1223 { &hf_ppi_vector_off_f,
1224 { "Off-f", "ppi_vector.off_f",
1225 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1226 "Offation forward", HFILL } },
1227 { &hf_ppi_vector_off_u,
1228 { "Off-u", "ppi_vector.off_u",
1229 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1230 "Offset up", HFILL } },
1231 { &hf_ppi_vector_vel_r,
1232 { "Vel-r", "ppi_vector.vel_r",
1233 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1234 "Velocity-right", HFILL } },
1235 { &hf_ppi_vector_vel_f,
1236 { "Vel-f", "ppi_vector.vel_f",
1237 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1238 "Velocity-forward", HFILL } },
1239 { &hf_ppi_vector_vel_u,
1240 { "Vel-u", "ppi_vector.vel_u",
1241 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1242 "Velocity-up", HFILL } },
1243 { &hf_ppi_vector_vel_t,
1244 { "Vel-t", "ppi_vector.vel_t",
1245 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1246 "Velocity-Total", HFILL } },
1248 { &hf_ppi_vector_acc_r,
1249 { "Accel-r", "ppi_vector.acc_r",
1250 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1251 "Acceleration-right", HFILL } },
1252 { &hf_ppi_vector_acc_f,
1253 { "Accel-f", "ppi_vector.acc_f",
1254 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1255 "Acceleration-forward", HFILL } },
1256 { &hf_ppi_vector_acc_u,
1257 { "Accel-u", "ppi_vector.acc_u",
1258 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1259 "Acceleration-up", HFILL } },
1260 { &hf_ppi_vector_acc_t,
1261 { "Accel-t", "ppi_vector.acc_t",
1262 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1263 "Acceleration-Total", HFILL } },
1266 { &hf_ppi_vector_off_x,
1267 { "Off-x", "ppi_vector.off_x",
1268 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1269 "Offset-x (right/east)", HFILL } },
1270 { &hf_ppi_vector_off_y,
1271 { "Off-y", "ppi_vector.off_y",
1272 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1273 "Offset-y (forward/north)", HFILL } },
1274 { &hf_ppi_vector_off_z,
1275 { "Off-z", "ppi_vector.off_z",
1276 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1277 "Offset-z (up)", HFILL } },
1279 { &hf_ppi_vector_err_rot,
1280 { "Err-Rot", "ppi_vector.err_rot",
1281 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1282 "Rotation margin of error", HFILL } },
1283 { &hf_ppi_vector_err_off,
1284 { "Err-Off", "ppi_vector.err_off",
1285 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1286 "Offset margin of error", HFILL } },
1289 { &hf_ppi_vector_err_vel,
1290 { "Err-Vel", "ppi_vector.err_vel",
1291 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1292 "Velocity margin of error", HFILL } },
1293 { &hf_ppi_vector_err_acc,
1294 { "Err-Accel", "ppi_vector.err_acc",
1295 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1296 "Acceleration margin of error", HFILL } },
1298 { &hf_ppi_vector_descstr,
1299 { "Description", "ppi_vector.descr",
1300 FT_STRING, BASE_NONE, NULL, 0x0,
1302 { &hf_ppi_vector_appspecific_num,
1303 { "Application Specific id", "ppi_vector.appid",
1304 FT_UINT32, BASE_HEX, NULL, 0x0,
1305 "Application-specific identifier", HFILL } },
1306 { &hf_ppi_vector_appspecific_data,
1307 { "Application specific data", "ppi_vector.appdata",
1308 FT_BYTES, BASE_NONE, NULL, 0x0,
1309 "Application-specific data", HFILL } },
1311 /* Boolean vector flags */
1312 { &hf_ppi_vector_vflags_defines_forward,
1313 { "Defines forward", "ppi_vector.vflags.forward",
1314 FT_BOOLEAN, 32, NULL, PPI_VECTOR_VFLAGS_DEFINES_FORWARD,
1315 "Current vector indicates forward frame of reference", HFILL } },
1318 { &hf_ppi_vector_vflags_rots_absolute,
1319 { "Absolute (E/N/U) rotations", "ppi_vector.vflags.abs_rots",
1320 FT_BOOLEAN, 32, NULL, PPI_VECTOR_VFLAGS_ROTS_ABSOLUTE,
1321 "Rotations are in East/North/Up coord. sys", HFILL } },
1322 { &hf_ppi_vector_vflags_offsets_from_gps,
1323 { "Offsets from prev GPS TAG", "ppi_vector.vflags.offsets_from_gps",
1324 FT_BOOLEAN, 32, NULL, PPI_VECTOR_VFLAGS_OFFSETS_FROM_GPS,
1325 "Offsets fied rel. to Curr_Gps", HFILL } },
1328 { &hf_ppi_vector_vflags_relative_to,
1329 { "RelativeTo", "ppi_vector.vflags.relative_to", FT_UINT32, BASE_HEX, VALS(&relativeto_string), PPI_VECTOR_VFLAGS_RELATIVE_TO,
1330 "Reference frame vectors are RelativeTo:", HFILL } },
1332 /* Boolean vector chars */
1333 { &hf_ppi_vector_vchars_antenna,
1334 { "Antenna", "ppi_vector.chars.antenna",
1335 FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_ANTENNA,
1336 "Vector represents: Antenna", HFILL } },
1338 { &hf_ppi_vector_vchars_dir_of_travel,
1339 { "Dir of travel", "ppi_vector.chars.dir_of_travel",
1340 FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_DIR_OF_TRAVEL,
1341 "Vector represents: Direction of travel", HFILL } },
1343 { &hf_ppi_vector_vchars_front_of_veh,
1344 { "Front of vehicle", "ppi_vector.chars.front_of_veh",
1345 FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_FRONT_OF_VEH,
1346 "Vector represents: Front of vehicle", HFILL } },
1349 { &hf_ppi_vector_vchars_angle_of_arrival,
1350 { "Angle of arrival", "ppi_vector.chars.angle_of_arr",
1351 FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_AOA,
1352 "Vector represents: Angle of Arrival", HFILL } },
1353 { &hf_ppi_vector_vchars_transmitter_pos,
1354 { "Transmitter Position", "ppi_vector.chars.transmitter_pos",
1355 FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_TRANSMITTER_POS,
1356 "Vector position represents computed transmitter location", HFILL } },
1358 { &hf_ppi_vector_vchars_gps_derived,
1359 { "GPS Derived", "ppi_vector.vflags.gps_derived",
1360 FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_GPS_DERIVED,
1361 "Vector derived from: gps", HFILL } },
1363 { &hf_ppi_vector_vchars_ins_derived,
1364 { "INS Derived", "ppi_vector.vflags.ins_derived",
1365 FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_INS_DERIVED,
1366 "Vector derived from: inertial nav system", HFILL } },
1368 { &hf_ppi_vector_vchars_compass_derived,
1369 { "Compass derived", "ppi_vector.vflags.compass_derived",
1370 FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_COMPASS_DERIVED,
1371 "Vector derived from: compass", HFILL } },
1373 { &hf_ppi_vector_vchars_accelerometer_derived,
1374 { "Accelerometer derived", "ppi_vector.vflags.accelerometer_derived",
1375 FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_ACCELEROMETER_DERIVED,
1376 "Vector derived from: accelerometer", HFILL } },
1378 { &hf_ppi_vector_vchars_human_derived,
1379 { "Human derived", "ppi_vector.vflags.human_derived",
1380 FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_HUMAN_DERIVED,
1381 "Vector derived from: human", HFILL } },
1384 static gint *ett[] = {
1386 &ett_ppi_vector_present,
1387 &ett_ppi_vectorflags,
1388 &ett_ppi_vectorchars
1391 proto_ppi_vector = proto_register_protocol("PPI vector decoder", "PPI vector Decoder", "ppi_vector");
1392 proto_register_field_array(proto_ppi_vector, hf, array_length(hf));
1393 proto_register_subtree_array(ett, array_length(ett));
1394 register_dissector("ppi_vector", dissect_ppi_vector, proto_ppi_vector);
1404 * indent-tabs-mode: nil
1407 * ex: set shiftwidth=4 tabstop=8 expandtab:
1408 * :indentSize=4:tabSize=8:noTabs=true: