Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-ppi-vector.c
blob80355af5aa15eabc018581fce9b9f90280460142
1 /* packet-ppi-vector.c
2 * Routines for PPI-GEOLOCATION-VECTOR dissection
3 * Copyright 2010, Harris Corp, jellch@harris.com
5 * See
7 * http://new.11mercenary.net/~johnycsh/ppi_geolocation_spec/
9 * for specifications.
11 * Wireshark - Network traffic analyzer
12 * By Gerald Combs <gerald@wireshark.org>
13 * Copyright 1998 Gerald Combs
15 * Copied from packet-radiotap.c
17 * SPDX-License-Identifier: GPL-2.0-or-later
20 #include "config.h"
22 #include <epan/packet.h>
23 #include <epan/expert.h>
24 #include <epan/unit_strings.h>
25 #include "packet-ppi-geolocation-common.h"
27 enum ppi_vector_type {
28 PPI_VECTOR_VFLAGS = 0,
29 PPI_VECTOR_VCHARS = 1,
30 PPI_VECTOR_ROTX = 2,
31 PPI_VECTOR_ROTY = 3,
32 PPI_VECTOR_ROTZ = 4,
34 /* V1 */
35 PPI_VECTOR_OFF_R = 5,
36 PPI_VECTOR_OFF_F = 6,
37 PPI_VECTOR_OFF_U = 7,
38 PPI_VECTOR_VEL_R = 8,
39 PPI_VECTOR_VEL_F = 9,
40 PPI_VECTOR_VEL_U = 10,
41 PPI_VECTOR_VEL_T = 11,
42 PPI_VECTOR_ACC_R = 12,
43 PPI_VECTOR_ACC_F = 13,
44 PPI_VECTOR_ACC_U = 14,
45 PPI_VECTOR_ACC_T = 15,
47 /* V2 */
48 PPI_VECTOR_OFF_X = 5,
49 PPI_VECTOR_OFF_Y = 6,
50 PPI_VECTOR_OFF_Z = 7,
52 PPI_VECTOR_ERR_ROT = 16,
53 PPI_VECTOR_ERR_OFF = 17,
55 /* V1 only */
56 PPI_VECTOR_ERR_VEL = 18,
57 PPI_VECTOR_ERR_ACC = 19,
59 PPI_VECTOR_DESCSTR = 28,
60 PPI_VECTOR_APPID = 29,
61 PPI_VECTOR_APPDATA = 30,
62 PPI_VECTOR_EXT = 31
64 #define PPI_VECTOR_MAXTAGLEN 144 /* increase as fields are added */
66 /* There are currently eight vector characteristics.
67 * These are purely descriptive (no mathematical importance)
69 #define PPI_VECTOR_VCHARS_ANTENNA 0x00000001
70 #define PPI_VECTOR_VCHARS_DIR_OF_TRAVEL 0x00000002
71 #define PPI_VECTOR_VCHARS_FRONT_OF_VEH 0x00000004
72 #define PPI_VECTOR_VCHARS_AOA 0x00000008
73 #define PPI_VECTOR_VCHARS_TRANSMITTER_POS 0x00000010
75 #define PPI_VECTOR_VCHARS_GPS_DERIVED 0x00000100
76 #define PPI_VECTOR_VCHARS_INS_DERIVED 0x00000200
77 #define PPI_VECTOR_VCHARS_COMPASS_DERIVED 0x00000400
78 #define PPI_VECTOR_VCHARS_ACCELEROMETER_DERIVED 0x00000800
79 #define PPI_VECTOR_VCHARS_HUMAN_DERIVED 0x00001000
81 #define PPI_VECTOR_MASK_VFLAGS 0x00000001
82 #define PPI_VECTOR_MASK_VCHARS 0x00000002
83 #define PPI_VECTOR_MASK_ROTX 0x00000004
84 #define PPI_VECTOR_MASK_ROTY 0x00000008
85 #define PPI_VECTOR_MASK_ROTZ 0x00000010
87 /* V1 */
88 #define PPI_VECTOR_MASK_OFF_R 0x00000020
89 #define PPI_VECTOR_MASK_OFF_F 0x00000040
90 #define PPI_VECTOR_MASK_OFF_U 0x00000080
91 #define PPI_VECTOR_MASK_VEL_R 0x00000100
92 #define PPI_VECTOR_MASK_VEL_F 0x00000200
93 #define PPI_VECTOR_MASK_VEL_U 0x00000400
94 #define PPI_VECTOR_MASK_VEL_T 0x00000800
95 #define PPI_VECTOR_MASK_ACC_R 0x00001000
96 #define PPI_VECTOR_MASK_ACC_F 0x00002000
97 #define PPI_VECTOR_MASK_ACC_U 0x00004000
98 #define PPI_VECTOR_MASK_ACC_T 0x00008000
100 /* V2 */
101 #define PPI_VECTOR_MASK_OFF_X 0x00000020
102 #define PPI_VECTOR_MASK_OFF_Y 0x00000040
103 #define PPI_VECTOR_MASK_OFF_Z 0x00000080
105 #define PPI_VECTOR_MASK_ERR_ROT 0x00010000
106 #define PPI_VECTOR_MASK_ERR_OFF 0x00020000
108 /* V1 only */
109 #define PPI_VECTOR_MASK_ERR_VEL 0x00040000
110 #define PPI_VECTOR_MASK_ERR_ACC 0x00080000
112 #define PPI_VECTOR_MASK_DESCSTR 0x10000000 /* 28 */
113 #define PPI_VECTOR_MASK_APPID 0x20000000 /* 29 */
114 #define PPI_VECTOR_MASK_APPDATA 0x40000000 /* 30 */
115 #define PPI_VECTOR_MASK_EXT 0x80000000 /* 31 */
117 /* There are currently only three vector flags.
118 * These control the units/interpretation of a vector
120 #define PPI_VECTOR_VFLAGS_DEFINES_FORWARD 0x00000001
122 /* V1 */
123 #define PPI_VECTOR_VFLAGS_ROTS_ABSOLUTE 0x00000002
124 #define PPI_VECTOR_VFLAGS_OFFSETS_FROM_GPS 0x00000004
126 /* V2 */
127 #define PPI_VECTOR_VFLAGS_RELATIVE_TO 0x00000006 /* 2 bits */
129 /* Values for the two-bit RelativeTo subfield of vflags */
130 static const value_string relativeto_string[] = {
131 { 0x00, "Forward"},
132 { 0x01, "Earth"},
133 { 0x02, "Current"},
134 { 0x03, "Reserved"},
135 { 0x00, NULL}
138 void proto_register_ppi_vector(void);
140 /* protocol */
141 static int proto_ppi_vector;
143 /* "top" level fields */
144 static int hf_ppi_vector_version;
145 static int hf_ppi_vector_pad;
146 static int hf_ppi_vector_length;
147 static int hf_ppi_vector_present;
148 static int hf_ppi_vector_vflags;
149 static int hf_ppi_vector_vchars;
150 static int hf_ppi_vector_rot_x;
151 static int hf_ppi_vector_rot_y;
152 static int hf_ppi_vector_rot_z;
154 /* V1 */
155 static int hf_ppi_vector_off_r;
156 static int hf_ppi_vector_off_f;
157 static int hf_ppi_vector_off_u;
158 static int hf_ppi_vector_vel_r;
159 static int hf_ppi_vector_vel_f;
160 static int hf_ppi_vector_vel_u;
161 static int hf_ppi_vector_vel_t;
162 static int hf_ppi_vector_acc_r;
163 static int hf_ppi_vector_acc_f;
164 static int hf_ppi_vector_acc_u;
165 static int hf_ppi_vector_acc_t;
167 /* V2 */
168 static int hf_ppi_vector_off_x;
169 static int hf_ppi_vector_off_y;
170 static int hf_ppi_vector_off_z;
172 static int hf_ppi_vector_err_rot;
173 static int hf_ppi_vector_err_off;
175 /* V1 only */
176 static int hf_ppi_vector_err_vel;
177 static int hf_ppi_vector_err_acc;
179 static int hf_ppi_vector_descstr;
180 static int hf_ppi_vector_appspecific_num;
181 static int hf_ppi_vector_appspecific_data;
183 /* "Present" flags */
184 static int hf_ppi_vector_present_vflags;
185 static int hf_ppi_vector_present_vchars;
186 static int hf_ppi_vector_present_val_x;
187 static int hf_ppi_vector_present_val_y;
188 static int hf_ppi_vector_present_val_z;
190 /* V1 */
191 static int hf_ppi_vector_present_off_r;
192 static int hf_ppi_vector_present_off_f;
193 static int hf_ppi_vector_present_off_u;
194 static int hf_ppi_vector_present_vel_r;
195 static int hf_ppi_vector_present_vel_f;
196 static int hf_ppi_vector_present_vel_u;
197 static int hf_ppi_vector_present_vel_t;
198 static int hf_ppi_vector_present_acc_r;
199 static int hf_ppi_vector_present_acc_f;
200 static int hf_ppi_vector_present_acc_u;
201 static int hf_ppi_vector_present_acc_t;
203 /* V2 */
204 static int hf_ppi_vector_present_off_x;
205 static int hf_ppi_vector_present_off_y;
206 static int hf_ppi_vector_present_off_z;
208 static int hf_ppi_vector_present_err_rot;
209 static int hf_ppi_vector_present_err_off;
211 /* V1 only */
212 static int hf_ppi_vector_present_err_vel;
213 static int hf_ppi_vector_present_err_acc;
215 static int hf_ppi_vector_present_descstr;
216 static int hf_ppi_vector_presenappsecific_num;
217 static int hf_ppi_vector_present_appspecific_data;
218 static int hf_ppi_vector_present_ext;
220 /* VectorFlags bits */
221 /* There are currently only three bits and two fields defined in vector flags.
222 * These control the units/interpretation of a vector
224 static int hf_ppi_vector_vflags_defines_forward; /* bit 0 */
226 /* V1 */
227 static int hf_ppi_vector_vflags_rots_absolute; /* different ways to display the same bit, hi or low */
228 static int hf_ppi_vector_vflags_offsets_from_gps; /* these are different ways to display the same bit, hi or low */
230 /* V2 */
231 static int hf_ppi_vector_vflags_relative_to; /* bits 1 and 2 */
233 /* There are currently eight vector characteristics.
234 * These are purely descriptive (no mathematical importance)
236 static int hf_ppi_vector_vchars_antenna;
237 static int hf_ppi_vector_vchars_dir_of_travel;
238 static int hf_ppi_vector_vchars_front_of_veh;
240 /* V2 only */
241 static int hf_ppi_vector_vchars_angle_of_arrival;
242 static int hf_ppi_vector_vchars_transmitter_pos;
244 static int hf_ppi_vector_vchars_gps_derived;
245 static int hf_ppi_vector_vchars_ins_derived;
246 static int hf_ppi_vector_vchars_compass_derived;
247 static int hf_ppi_vector_vchars_accelerometer_derived;
248 static int hf_ppi_vector_vchars_human_derived;
249 static int hf_ppi_vector_unknown_data;
251 /*These represent arrow-dropdownthings in the gui */
252 static int ett_ppi_vector;
253 static int ett_ppi_vector_present;
254 static int ett_ppi_vectorflags;
255 static int ett_ppi_vectorchars;
257 static expert_field ei_ppi_vector_present_bit;
258 static expert_field ei_ppi_vector_length;
261 /* We want to abbreviate this field into a single line. Does so without any string manipulation */
262 static void
263 annotate_vector_chars(uint32_t chars, proto_tree *my_pt)
265 if (chars & PPI_VECTOR_VCHARS_ANTENNA)
266 proto_item_append_text(my_pt, " (Antenna)");
267 if (chars & PPI_VECTOR_VCHARS_DIR_OF_TRAVEL)
268 proto_item_append_text(my_pt, " (DOT)");
269 if (chars & PPI_VECTOR_VCHARS_FRONT_OF_VEH)
270 proto_item_append_text(my_pt, " (Front_of_veh)");
271 if (chars & PPI_VECTOR_VCHARS_AOA)
272 proto_item_append_text(my_pt, " (AOA)");
273 if (chars & PPI_VECTOR_VCHARS_TRANSMITTER_POS)
274 proto_item_append_text(my_pt, " (TRANSMITTER_POS)");
277 static void
278 dissect_ppi_vector_v1(tvbuff_t *tvb, packet_info *pinfo, int offset, int length_remaining, proto_tree *ppi_vector_tree)
280 proto_tree *vectorflags_tree = NULL;
281 proto_tree *vectorchars_tree = NULL;
282 proto_tree *my_pt, *pt;
283 proto_item *ti;
285 /* bits */
286 int bit;
287 uint32_t present, next_present;
288 /* values actually read out, for displaying */
289 double rot_x, rot_y, rot_z;
290 double off_r, off_f, off_u;
291 double vel_r, vel_f, vel_u, vel_t;
292 double acc_r, acc_f, acc_u, acc_t = 0;
293 double err_rot, err_off, err_vel, err_acc;
294 uint32_t appsecific_num; /* appdata parser should add a subtree based on this value */
295 uint32_t flags=0, chars=0;
297 static int * const ppi_vector_present_flags[] = {
298 &hf_ppi_vector_present_vflags,
299 &hf_ppi_vector_present_vchars,
300 &hf_ppi_vector_present_val_x,
301 &hf_ppi_vector_present_val_y,
302 &hf_ppi_vector_present_val_z,
303 &hf_ppi_vector_present_off_r,
304 &hf_ppi_vector_present_off_f,
305 &hf_ppi_vector_present_off_u,
306 &hf_ppi_vector_present_vel_r,
307 &hf_ppi_vector_present_vel_f,
308 &hf_ppi_vector_present_vel_u,
309 &hf_ppi_vector_present_vel_t,
310 &hf_ppi_vector_present_acc_r,
311 &hf_ppi_vector_present_acc_f,
312 &hf_ppi_vector_present_acc_u,
313 &hf_ppi_vector_present_acc_t,
314 &hf_ppi_vector_present_err_rot,
315 &hf_ppi_vector_present_err_off,
316 &hf_ppi_vector_present_err_vel,
317 &hf_ppi_vector_present_err_acc,
318 &hf_ppi_vector_present_descstr,
319 &hf_ppi_vector_presenappsecific_num,
320 &hf_ppi_vector_present_appspecific_data,
321 &hf_ppi_vector_present_ext,
322 NULL
325 /* temporary, conversion values */
326 uint32_t t_val;
328 present = tvb_get_letohl(tvb, offset+4);
329 /* Subtree for the "present flags" bitfield. */
330 pt = proto_tree_add_bitmask(ppi_vector_tree, tvb, offset + 4, hf_ppi_vector_present, ett_ppi_vector_present, ppi_vector_present_flags, ENC_LITTLE_ENDIAN);
332 offset += PPI_GEOBASE_MIN_HEADER_LEN;
333 length_remaining -= PPI_GEOBASE_MIN_HEADER_LEN;
336 /* Now all of the fixed length, fixed location stuff is over. Loop over the bits */
337 for (; present; present = next_present) {
338 /* clear the least significant bit that is set */
339 next_present = present & (present - 1);
340 /* extract the least significant bit that is set */
341 bit = BITNO_32(present ^ next_present);
342 switch (bit) {
343 case PPI_VECTOR_VFLAGS:
344 if (length_remaining < 4)
345 break;
346 flags = tvb_get_letohl(tvb, offset);
347 if (ppi_vector_tree) {
348 my_pt = proto_tree_add_uint(ppi_vector_tree, hf_ppi_vector_vflags, tvb, offset , 4, flags);
349 vectorflags_tree= proto_item_add_subtree(my_pt, ett_ppi_vectorflags);
351 proto_tree_add_item(vectorflags_tree, hf_ppi_vector_vflags_defines_forward, tvb, offset, 4, ENC_LITTLE_ENDIAN);
352 proto_tree_add_item(vectorflags_tree, hf_ppi_vector_vflags_rots_absolute, tvb, offset, 4, ENC_LITTLE_ENDIAN);
353 proto_tree_add_item(vectorflags_tree, hf_ppi_vector_vflags_offsets_from_gps, tvb, offset, 4, ENC_LITTLE_ENDIAN);
355 offset+=4;
356 length_remaining-=4;
357 break;
358 case PPI_VECTOR_VCHARS:
359 if (length_remaining < 4)
360 break;
361 chars = tvb_get_letohl(tvb, offset);
362 if (ppi_vector_tree) {
363 my_pt = proto_tree_add_uint(ppi_vector_tree, hf_ppi_vector_vchars, tvb, offset , 4, chars);
364 vectorchars_tree= proto_item_add_subtree(my_pt, ett_ppi_vectorchars);
366 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_antenna, tvb, offset, 4, ENC_LITTLE_ENDIAN);
367 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_dir_of_travel, tvb, offset, 4, ENC_LITTLE_ENDIAN);
368 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_front_of_veh, tvb, offset, 4, ENC_LITTLE_ENDIAN);
369 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_gps_derived, tvb, offset, 4, ENC_LITTLE_ENDIAN);
370 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_ins_derived, tvb, offset, 4, ENC_LITTLE_ENDIAN);
371 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_compass_derived, tvb, offset, 4, ENC_LITTLE_ENDIAN);
372 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_accelerometer_derived, tvb, offset, 4, ENC_LITTLE_ENDIAN);
373 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_human_derived, tvb, offset, 4, ENC_LITTLE_ENDIAN);
375 offset+=4;
376 length_remaining-=4;
377 break;
378 case PPI_VECTOR_ROTX:
379 if (length_remaining < 4)
380 break;
381 t_val = tvb_get_letohl(tvb, offset);
382 rot_x = ppi_fixed3_6_to_double(t_val);
383 if (ppi_vector_tree) {
384 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_rot_x, tvb, offset, 4, rot_x);
385 if (flags & PPI_VECTOR_VFLAGS_ROTS_ABSOLUTE)
386 proto_item_append_text(ti, " Degrees (Absolute)");
387 else
388 proto_item_append_text(ti, " Degrees (Rel to forward)");
390 offset+=4;
391 length_remaining-=4;
392 break;
393 case PPI_VECTOR_ROTY:
394 if (length_remaining < 4)
395 break;
396 t_val = tvb_get_letohl(tvb, offset);
397 rot_y = ppi_fixed3_6_to_double(t_val);
398 if (ppi_vector_tree) {
399 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_rot_y, tvb, offset, 4, rot_y);
400 if (flags & PPI_VECTOR_VFLAGS_ROTS_ABSOLUTE)
401 proto_item_append_text(ti, " Degrees (Absolute)");
402 else
403 proto_item_append_text(ti, " Degrees (Rel to forward)");
405 offset+=4;
406 length_remaining-=4;
407 break;
408 case PPI_VECTOR_ROTZ:
409 if (length_remaining < 4)
410 break;
411 t_val = tvb_get_letohl(tvb, offset);
412 rot_z = ppi_fixed3_6_to_double(t_val);
413 if (ppi_vector_tree) {
414 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_rot_z, tvb, offset, 4, rot_z);
415 if (flags & PPI_VECTOR_VFLAGS_ROTS_ABSOLUTE)
416 proto_item_append_text(ti, " Degrees (Absolute) ");
417 else
418 proto_item_append_text(ti, " Degrees (Rel to forward)");
420 offset+=4;
421 length_remaining-=4;
422 break;
423 case PPI_VECTOR_OFF_R:
424 if (length_remaining < 4)
425 break;
426 t_val = tvb_get_letohl(tvb, offset);
427 off_r = ppi_fixed6_4_to_double(t_val);
428 if (ppi_vector_tree) {
429 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_off_r, tvb, offset, 4, off_r);
430 if (flags & PPI_VECTOR_VFLAGS_OFFSETS_FROM_GPS)
431 proto_item_append_text(ti, " m from Curr_GPS");
432 else
433 proto_item_append_text(ti, " m from Curr_Pos");
435 offset+=4;
436 length_remaining-=4;
437 break;
438 case PPI_VECTOR_OFF_F:
439 if (length_remaining < 4)
440 break;
441 t_val = tvb_get_letohl(tvb, offset);
442 off_f = ppi_fixed6_4_to_double(t_val);
443 if (ppi_vector_tree) {
444 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_off_f, tvb, offset, 4, off_f);
445 if (flags & PPI_VECTOR_VFLAGS_OFFSETS_FROM_GPS)
446 proto_item_append_text(ti, " m from Curr_GPS");
447 else
448 proto_item_append_text(ti, " m from Curr_Pos");
450 offset+=4;
451 length_remaining-=4;
452 break;
453 case PPI_VECTOR_OFF_U:
454 if (length_remaining < 4)
455 break;
456 t_val = tvb_get_letohl(tvb, offset);
457 off_u = ppi_fixed6_4_to_double(t_val);
458 if (ppi_vector_tree) {
459 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_off_u, tvb, offset, 4, off_u);
460 if (flags & PPI_VECTOR_VFLAGS_OFFSETS_FROM_GPS)
461 proto_item_append_text(ti, " m from Curr_GPS");
462 else
463 proto_item_append_text(ti, " m from Curr_Pos");
465 offset+=4;
466 length_remaining-=4;
467 break;
468 case PPI_VECTOR_VEL_R:
469 if (length_remaining < 4)
470 break;
471 t_val = tvb_get_letohl(tvb, offset);
472 vel_r = ppi_fixed6_4_to_double(t_val);
473 proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_vel_r, tvb, offset, 4, vel_r);
474 offset+=4;
475 length_remaining-=4;
476 break;
477 case PPI_VECTOR_VEL_F:
478 if (length_remaining < 4)
479 break;
480 t_val = tvb_get_letohl(tvb, offset);
481 vel_f = ppi_fixed6_4_to_double(t_val);
482 proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_vel_f, tvb, offset, 4, vel_f);
483 offset+=4;
484 length_remaining-=4;
485 break;
486 case PPI_VECTOR_VEL_U:
487 if (length_remaining < 4)
488 break;
489 t_val = tvb_get_letohl(tvb, offset);
490 vel_u = ppi_fixed6_4_to_double(t_val);
491 proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_vel_u, tvb, offset, 4, vel_u);
492 offset+=4;
493 length_remaining-=4;
494 break;
495 case PPI_VECTOR_VEL_T:
496 if (length_remaining < 4)
497 break;
498 t_val = tvb_get_letohl(tvb, offset);
499 vel_t = ppi_fixed6_4_to_double(t_val);
500 proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_vel_t, tvb, offset, 4, vel_t);
501 offset+=4;
502 length_remaining-=4;
503 break;
504 case PPI_VECTOR_ACC_R:
505 if (length_remaining < 4)
506 break;
507 t_val = tvb_get_letohl(tvb, offset);
508 acc_r = ppi_fixed6_4_to_double(t_val);
509 proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_acc_r, tvb, offset, 4, acc_r);
510 offset+=4;
511 length_remaining-=4;
512 break;
513 case PPI_VECTOR_ACC_F:
514 if (length_remaining < 4)
515 break;
516 t_val = tvb_get_letohl(tvb, offset);
517 acc_f = ppi_fixed6_4_to_double(t_val);
518 proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_acc_f, tvb, offset, 4, acc_f);
519 offset+=4;
520 length_remaining-=4;
521 break;
522 case PPI_VECTOR_ACC_U:
523 if (length_remaining < 4)
524 break;
525 t_val = tvb_get_letohl(tvb, offset);
526 acc_u = ppi_fixed6_4_to_double(t_val);
527 proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_acc_u, tvb, offset, 4, acc_u);
528 offset+=4;
529 length_remaining-=4;
530 break;
531 case PPI_VECTOR_ACC_T:
532 if (length_remaining < 4)
533 break;
534 t_val = tvb_get_letohl(tvb, offset);
535 acc_t = ppi_fixed6_4_to_double(t_val);
536 proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_acc_t, tvb, offset, 4, acc_t);
537 offset+=4;
538 length_remaining-=4;
539 break;
540 case PPI_VECTOR_ERR_ROT:
541 if (length_remaining < 4)
542 break;
543 t_val = tvb_get_letohl(tvb, offset);
544 err_rot = ppi_fixed3_6_to_double(t_val);
545 proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_err_rot, tvb, offset, 4, err_rot);
546 offset+=4;
547 length_remaining-=4;
548 break;
549 case PPI_VECTOR_ERR_OFF:
550 if (length_remaining < 4)
551 break;
552 t_val = tvb_get_letohl(tvb, offset);
553 err_off = ppi_fixed6_4_to_double(t_val);
554 proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_err_off, tvb, offset, 4, err_off);
555 offset+=4;
556 length_remaining-=4;
557 break;
558 case PPI_VECTOR_ERR_VEL:
559 if (length_remaining < 4)
560 break;
561 t_val = tvb_get_letohl(tvb, offset);
562 err_vel = ppi_fixed6_4_to_double(t_val);
563 proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_err_vel, tvb, offset, 4, err_vel);
564 offset+=4;
565 length_remaining-=4;
566 break;
567 case PPI_VECTOR_ERR_ACC:
568 if (length_remaining < 4)
569 break;
570 t_val = tvb_get_letohl(tvb, offset);
571 err_acc = ppi_fixed6_4_to_double(t_val);
572 if (ppi_vector_tree) {
573 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_err_acc, tvb, offset, 4, err_acc);
574 proto_item_append_text(ti, " (m/s)/s");
576 offset+=4;
577 length_remaining-=4;
578 break;
579 case PPI_VECTOR_DESCSTR:
580 if (length_remaining < 32)
581 break;
582 proto_tree_add_item(ppi_vector_tree, hf_ppi_vector_descstr, tvb, offset, 32, ENC_ASCII);
583 offset+=32;
584 length_remaining-=32;
585 break;
586 case PPI_VECTOR_APPID:
587 if (length_remaining < 4)
588 break;
589 appsecific_num = tvb_get_letohl(tvb, offset); /* application specific parsers may switch on this later */
590 proto_tree_add_uint(ppi_vector_tree, hf_ppi_vector_appspecific_num, tvb, offset, 4, appsecific_num);
591 offset+=4;
592 length_remaining-=4;
593 break;
594 case PPI_VECTOR_APPDATA:
595 if (length_remaining < 60)
596 break;
597 proto_tree_add_item(ppi_vector_tree, hf_ppi_vector_appspecific_data, tvb, offset, 60, ENC_NA);
598 offset+=60;
599 length_remaining-=60;
600 break;
602 default:
604 * This indicates a field whose size we do not
605 * know, so we cannot proceed.
607 expert_add_info_format(pinfo, pt, &ei_ppi_vector_present_bit, "Error: PPI-VECTOR: unknown bit (%d) set in present field.", bit);
608 next_present = 0;
609 continue;
615 static void
616 dissect_ppi_vector_v2(tvbuff_t *tvb, packet_info *pinfo, int offset, int length_remaining, proto_tree *ppi_vector_tree, proto_item *vector_line)
618 proto_tree *vectorflags_tree = NULL;
619 proto_tree *vectorchars_tree = NULL;
620 proto_tree *my_pt, *pt;
621 proto_item *ti;
623 /* bits */
624 int bit;
625 uint32_t present, next_present;
627 /* values actually read out, for displaying */
628 char *curr_str;
630 /* these are used to specially handle RelativeTo: */
631 uint32_t relativeto_int;
632 const char *relativeto_str;
634 /* normal fields*/
635 uint32_t flags=0, chars=0;
636 double rot_x, rot_y, rot_z;
637 double off_x, off_y, off_z;
638 double err_rot, err_off;
639 uint32_t appsecific_num; /* appdata parser should add a subtree based on this value */
641 static int * const ppi_vector_present_flags[] = {
642 &hf_ppi_vector_present_vflags,
643 &hf_ppi_vector_present_vchars,
644 &hf_ppi_vector_present_val_x,
645 &hf_ppi_vector_present_val_y,
646 &hf_ppi_vector_present_val_z,
647 &hf_ppi_vector_present_off_x,
648 &hf_ppi_vector_present_off_y,
649 &hf_ppi_vector_present_off_z,
650 &hf_ppi_vector_present_err_rot,
651 &hf_ppi_vector_present_err_off,
652 &hf_ppi_vector_present_descstr,
653 &hf_ppi_vector_presenappsecific_num,
654 &hf_ppi_vector_present_appspecific_data,
655 &hf_ppi_vector_present_ext,
656 NULL
659 /* temporary, conversion values */
660 uint32_t t_val;
662 present = tvb_get_letohl(tvb, offset+4);
663 /* Subtree for the "present flags" bitfield. */
664 pt = proto_tree_add_bitmask(ppi_vector_tree, tvb, offset + 4, hf_ppi_vector_present, ett_ppi_vector_present, ppi_vector_present_flags, ENC_LITTLE_ENDIAN);
666 offset += PPI_GEOBASE_MIN_HEADER_LEN;
667 length_remaining -= PPI_GEOBASE_MIN_HEADER_LEN;
669 /* Before we process any fields, we check what this vector is RelativeTo. */
670 /* We do this so this up front so that it displays prominently in the summary line */
671 /* Another reason to do this up here is that vflags may not be present (in which case it defaults to 0) */
672 /* It also saves us from repeating this logic in any of the individual fields */
673 if ( (present & PPI_VECTOR_MASK_VFLAGS) && length_remaining >= 4)
675 /*vflags is the first field, */
676 flags = tvb_get_letohl(tvb, offset);
677 relativeto_int = (flags & (PPI_VECTOR_VFLAGS_RELATIVE_TO)); /* mask out all other bits */
678 relativeto_int = relativeto_int >> 1; /*scoot over 1 bit to align with the type string */
679 relativeto_str = val_to_str_const (relativeto_int, relativeto_string, "Reserved"); /*re-use that type string up top */
680 /* We will append this text to the vector line once all the other fields have processed */
682 /* this is important enough to put in vector line */
683 if (flags & PPI_VECTOR_VFLAGS_DEFINES_FORWARD)
684 proto_item_append_text(vector_line, " (Forward)");
686 /* Intentionally don't upset offset, length_remaining. This is taken care of in the normal vflags parser below*/
688 else /* No vflags means vlfags defaults to zero. RelativeTo: Forward */
690 relativeto_str = " RelativeTo: Forward";
693 * vchars is another field that we want to pre-process similar to vflags and for the same reasons.
694 * we perform separate length checks depending on if vector_flags is present (which would precede vector_chars)
696 if ( ( (present & PPI_VECTOR_MASK_VFLAGS)) && (present & PPI_VECTOR_MASK_VCHARS) && length_remaining >= 8)
697 chars = tvb_get_letohl(tvb, offset + 4);
698 else if ( (!(present & PPI_VECTOR_MASK_VFLAGS)) && (present & PPI_VECTOR_MASK_VCHARS) && length_remaining >= 4)
699 chars = tvb_get_letohl(tvb, offset );
701 if (chars)
703 /* Mark the most interesting characteristics on the vector dropdown line */
704 annotate_vector_chars(chars, vector_line);
705 /* Intentionally don't update offset, length_remaining. This is taken care of in the normal vchars parser below*/
708 /* Now all of the fixed length, fixed location stuff is over. Loop over the bits */
709 for (; present; present = next_present) {
710 /* clear the least significant bit that is set */
711 next_present = present & (present - 1);
712 /* extract the least significant bit that is set */
713 bit = BITNO_32(present ^ next_present);
714 switch (bit) {
715 case PPI_VECTOR_VFLAGS:
716 if (length_remaining < 4)
717 break;
718 /* flags = tvb_get_letohl(tvb, offset); */ /* Usually we read this in, but vflags is a special case handled above */
719 if (ppi_vector_tree) {
720 my_pt = proto_tree_add_uint(ppi_vector_tree, hf_ppi_vector_vflags, tvb, offset , 4, flags);
721 vectorflags_tree= proto_item_add_subtree(my_pt, ett_ppi_vectorflags);
723 proto_tree_add_item(vectorflags_tree, hf_ppi_vector_vflags_defines_forward, tvb, offset, 4, ENC_LITTLE_ENDIAN);
724 proto_tree_add_item(vectorflags_tree, hf_ppi_vector_vflags_relative_to, tvb, offset, 4, ENC_LITTLE_ENDIAN);
726 if (flags & PPI_VECTOR_VFLAGS_DEFINES_FORWARD)
727 proto_item_append_text(vectorflags_tree, " (Forward)");
729 proto_item_append_text (vectorflags_tree, " RelativeTo: %s", relativeto_str);
731 offset+=4;
732 length_remaining-=4;
733 break;
734 case PPI_VECTOR_VCHARS:
735 if (length_remaining < 4)
736 break;
737 /* chars = tvb_get_letohl(tvb, offset); */ /*Usually we read this in, but vchars specially handled above */
738 if (ppi_vector_tree) {
739 my_pt = proto_tree_add_uint(ppi_vector_tree, hf_ppi_vector_vchars, tvb, offset , 4, chars);
740 vectorchars_tree= proto_item_add_subtree(my_pt, ett_ppi_vectorchars);
742 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_antenna, tvb, offset, 4, ENC_LITTLE_ENDIAN);
743 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_dir_of_travel, tvb, offset, 4, ENC_LITTLE_ENDIAN);
744 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_front_of_veh, tvb, offset, 4, ENC_LITTLE_ENDIAN);
745 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_angle_of_arrival, tvb, offset, 4, ENC_LITTLE_ENDIAN);
746 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_transmitter_pos, tvb, offset, 4, ENC_LITTLE_ENDIAN);
747 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_gps_derived, tvb, offset, 4, ENC_LITTLE_ENDIAN);
748 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_ins_derived, tvb, offset, 4, ENC_LITTLE_ENDIAN);
749 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_compass_derived, tvb, offset, 4, ENC_LITTLE_ENDIAN);
750 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_accelerometer_derived, tvb, offset, 4, ENC_LITTLE_ENDIAN);
751 proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_human_derived, tvb, offset, 4, ENC_LITTLE_ENDIAN);
753 annotate_vector_chars(chars, my_pt);
755 offset+=4;
756 length_remaining-=4;
757 break;
758 case PPI_VECTOR_ROTX:
759 if (length_remaining < 4)
760 break;
761 t_val = tvb_get_letohl(tvb, offset);
762 rot_x = ppi_fixed3_6_to_double(t_val);
763 if (ppi_vector_tree) {
764 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_rot_x, tvb, offset, 4, rot_x);
765 proto_item_append_text(ti, " Degrees RelativeTo: %s", relativeto_str);
766 proto_item_append_text(vector_line, " Pitch:%3f ", rot_x);
768 offset+=4;
769 length_remaining-=4;
770 break;
771 case PPI_VECTOR_ROTY:
772 if (length_remaining < 4)
773 break;
774 t_val = tvb_get_letohl(tvb, offset);
775 rot_y = ppi_fixed3_6_to_double(t_val);
776 if (ppi_vector_tree) {
777 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_rot_y, tvb, offset, 4, rot_y);
778 proto_item_append_text(ti, " Degrees RelativeTo: %s", relativeto_str);
779 proto_item_append_text(vector_line, " Roll:%3f ", rot_y);
781 offset+=4;
782 length_remaining-=4;
783 break;
784 case PPI_VECTOR_ROTZ:
785 if (length_remaining < 4)
786 break;
787 t_val = tvb_get_letohl(tvb, offset);
788 rot_z = ppi_fixed3_6_to_double(t_val);
789 if (ppi_vector_tree) {
790 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_rot_z, tvb, offset, 4, rot_z);
791 proto_item_append_text(ti, " Degrees RelativeTo: %s", relativeto_str);
792 proto_item_append_text(vector_line, " Heading:%3f ", rot_z);
794 offset+=4;
795 length_remaining-=4;
796 break;
797 case PPI_VECTOR_OFF_X:
798 if (length_remaining < 4)
799 break;
800 t_val = tvb_get_letohl(tvb, offset);
801 off_x = ppi_fixed6_4_to_double(t_val);
802 if (ppi_vector_tree) {
803 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_off_x, tvb, offset, 4, off_x);
804 proto_item_append_text(ti, " Meters RelativeTo: %s", relativeto_str);
805 proto_item_append_text(vector_line, " Off-X:%3f ", off_x);
807 offset+=4;
808 length_remaining-=4;
809 break;
810 case PPI_VECTOR_OFF_Y:
811 if (length_remaining < 4)
812 break;
813 t_val = tvb_get_letohl(tvb, offset);
814 off_y = ppi_fixed6_4_to_double(t_val);
815 if (ppi_vector_tree) {
816 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_off_y, tvb, offset, 4, off_y);
817 proto_item_append_text(ti, " Meters RelativeTo: %s", relativeto_str);
818 proto_item_append_text(vector_line, " Off-Y:%3f ", off_y);
820 offset+=4;
821 length_remaining-=4;
822 break;
823 case PPI_VECTOR_OFF_Z:
824 if (length_remaining < 4)
825 break;
826 t_val = tvb_get_letohl(tvb, offset);
827 off_z = ppi_fixed6_4_to_double(t_val);
828 if (ppi_vector_tree) {
829 ti = proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_off_z, tvb, offset, 4, off_z);
830 proto_item_append_text(ti, " Meters RelativeTo: %s", relativeto_str);
831 proto_item_append_text(vector_line, " Off-Z:%3f ", off_z);
833 offset+=4;
834 length_remaining-=4;
835 break;
836 case PPI_VECTOR_ERR_ROT:
837 if (length_remaining < 4)
838 break;
839 t_val = tvb_get_letohl(tvb, offset);
840 err_rot = ppi_fixed3_6_to_double(t_val);
841 proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_err_rot, tvb, offset, 4, err_rot);
842 offset+=4;
843 length_remaining-=4;
844 break;
845 case PPI_VECTOR_ERR_OFF:
846 if (length_remaining < 4)
847 break;
848 t_val = tvb_get_letohl(tvb, offset);
849 err_off = ppi_fixed6_4_to_double(t_val);
850 proto_tree_add_double(ppi_vector_tree, hf_ppi_vector_err_off, tvb, offset, 4, err_off);
851 offset+=4;
852 length_remaining-=4;
853 break;
855 case PPI_VECTOR_DESCSTR:
856 if (length_remaining < 32)
857 break;
858 if (ppi_vector_tree)
860 /* proto_tree_add_item(ppi_vector_tree, hf_ppi_vector_descstr, tvb, offset, 32, ENC_ASCII); */
861 curr_str = tvb_format_stringzpad(pinfo->pool, tvb, offset, 32); /* need to append_text this */
862 proto_tree_add_string(ppi_vector_tree, hf_ppi_vector_descstr, tvb, offset, 32, curr_str);
863 proto_item_append_text(vector_line, " (%s)", curr_str);
865 offset+=32;
866 length_remaining-=32;
867 break;
868 case PPI_VECTOR_APPID:
869 if (length_remaining < 4)
870 break;
871 appsecific_num = tvb_get_letohl(tvb, offset); /* application specific parsers may switch on this later */
872 if (ppi_vector_tree) {
873 proto_tree_add_uint(ppi_vector_tree, hf_ppi_vector_appspecific_num, tvb, offset, 4, appsecific_num);
875 offset+=4;
876 length_remaining-=4;
877 break;
878 case PPI_VECTOR_APPDATA:
879 if (length_remaining < 60)
880 break;
881 if (ppi_vector_tree) {
882 proto_tree_add_item(ppi_vector_tree, hf_ppi_vector_appspecific_data, tvb, offset, 60, ENC_NA);
884 offset+=60;
885 length_remaining-=60;
886 break;
888 default:
890 * This indicates a field whose size we do not
891 * know, so we cannot proceed.
893 expert_add_info_format(pinfo, pt, &ei_ppi_vector_present_bit, "Error: PPI-VECTOR: unknown bit (%d) set in present field.\n", bit);
894 next_present = 0;
895 continue;
898 /* Append the RelativeTo string we computed up top */
899 proto_item_append_text (vector_line, " RelativeTo: %s", relativeto_str);
902 static int
903 dissect_ppi_vector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
905 proto_tree *ppi_vector_tree;
906 proto_item *ti, *vector_line;
907 int length_remaining;
908 int offset = 0;
910 /* values actually read out, for displaying */
911 uint32_t version;
912 unsigned length;
914 /* Clear out stuff in the info column */
915 col_clear(pinfo->cinfo,COL_INFO);
917 /* pull out the first three fields of the BASE-GEOTAG-HEADER */
918 version = tvb_get_uint8(tvb, offset);
919 length = tvb_get_letohs(tvb, offset+2);
921 /* Setup basic column info */
922 col_add_fstr(pinfo->cinfo, COL_INFO, "PPI_Vector Capture v%u, Length %u",
923 version, length);
925 /* Create the basic dissection tree*/
926 vector_line = proto_tree_add_protocol_format(tree, proto_ppi_vector, tvb, 0, length, "Vector:");
927 ppi_vector_tree = proto_item_add_subtree(vector_line, ett_ppi_vector);
928 proto_tree_add_uint(ppi_vector_tree, hf_ppi_vector_version,
929 tvb, offset, 1, version);
930 proto_tree_add_item(ppi_vector_tree, hf_ppi_vector_pad,
931 tvb, offset + 1, 1, ENC_LITTLE_ENDIAN);
932 ti = proto_tree_add_uint(ppi_vector_tree, hf_ppi_vector_length,
933 tvb, offset + 2, 2, length);
935 /* initialize remaining length */
936 length_remaining = length;
937 /* minimum length check, should atleast be a fixed-size geotagging-base header*/
938 if (length_remaining < PPI_GEOBASE_MIN_HEADER_LEN) {
940 * Base-geotag-header (Radiotap lookalike) is shorter than the fixed-length portion
941 * plus one "present" bitset.
943 expert_add_info_format(pinfo, ti, &ei_ppi_vector_length, "Invalid PPI-Vector length - minimum length is %d", PPI_GEOBASE_MIN_HEADER_LEN);
944 return 2;
947 switch (version) {
949 case 1:
950 dissect_ppi_vector_v1(tvb, pinfo, offset, length_remaining, ppi_vector_tree);
951 break;
953 case 2:
954 /* perform max length sanity checking */
955 if (length > PPI_VECTOR_MAXTAGLEN ) {
956 expert_add_info_format(pinfo, ti, &ei_ppi_vector_length, "Invalid PPI-Vector length (got %d, %d max\n)", length, PPI_VECTOR_MAXTAGLEN);
957 return 2;
959 dissect_ppi_vector_v2(tvb, pinfo, offset, length_remaining, ppi_vector_tree, vector_line);
960 break;
962 default:
963 proto_tree_add_item(ppi_vector_tree, hf_ppi_vector_unknown_data, tvb, offset + 4, -1, ENC_NA);
964 break;
966 return tvb_captured_length(tvb);
969 void
970 proto_register_ppi_vector(void)
972 /* The following array initializes those header fields declared above to the values displayed */
973 static hf_register_info hf[] = {
974 { &hf_ppi_vector_version,
975 { "Header revision", "ppi_vector.version",
976 FT_UINT8, BASE_DEC, NULL, 0x0,
977 "Version of ppi_vector header format", HFILL } },
978 { &hf_ppi_vector_pad,
979 { "Header pad", "ppi_vector.pad",
980 FT_UINT8, BASE_DEC, NULL, 0x0,
981 "Padding", HFILL } },
982 { &hf_ppi_vector_length,
983 { "Header length", "ppi_vector.length",
984 FT_UINT16, BASE_DEC, NULL, 0x0,
985 "Length of header including version, pad, length and data fields", HFILL } },
986 { &hf_ppi_vector_present,
987 { "Present", "ppi_vector.present",
988 FT_UINT32, BASE_HEX, NULL, 0x0,
989 "Bitmask indicating which fields are present", HFILL } },
991 /* Boolean 'present' flags */
992 { &hf_ppi_vector_present_vflags,
993 { "Vector flags", "ppi_vector.present.flags",
994 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_VFLAGS,
995 "Specifies if the Vector flags bitfield is present", HFILL } },
997 { &hf_ppi_vector_present_vchars,
998 { "Vector characteristics", "ppi_vector.present.chars",
999 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_VCHARS,
1000 "Specifies if the Vector chars bitfield is present", HFILL } },
1002 { &hf_ppi_vector_present_val_x,
1003 { "Pitch", "ppi_vector.present.pitch",
1004 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ROTX,
1005 "Specifies if the rotate-x field (pitch) is present", HFILL } },
1007 { &hf_ppi_vector_present_val_y,
1008 { "Roll", "ppi_vector.present.roll",
1009 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ROTY,
1010 "Specifies if the rotate-y field (roll) is present", HFILL } },
1012 { &hf_ppi_vector_present_val_z,
1013 { "Heading", "ppi_vector.present.heading",
1014 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ROTZ,
1015 "Specifies if the rotate-z field (heading) is present", HFILL } },
1018 /* V1 */
1019 { &hf_ppi_vector_present_off_r,
1020 { "Offset_R", "ppi_vector.present.off_r",
1021 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_OFF_R,
1022 "Specifies if the offset-right field is present", HFILL } },
1024 { &hf_ppi_vector_present_off_f,
1025 { "Offset_F", "ppi_vector.present.off_f",
1026 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_OFF_F,
1027 "Specifies if the offset-forward field is present", HFILL } },
1029 { &hf_ppi_vector_present_off_u,
1030 { "Offset_U", "ppi_vector.present.off_u",
1031 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_OFF_U,
1032 "Specifies if the offset-up field is present", HFILL } },
1034 { &hf_ppi_vector_present_vel_r,
1035 { "Velocity_R", "ppi_vector.present.vel_r",
1036 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_VEL_R,
1037 "Specifies if the velocity-right field is present", HFILL } },
1039 { &hf_ppi_vector_present_vel_f,
1040 { "Velocity_F", "ppi_vector.present.vel_f",
1041 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_VEL_F,
1042 "Specifies if the velocity-forward field is present", HFILL } },
1044 { &hf_ppi_vector_present_vel_u,
1045 { "Velocity_U", "ppi_vector.present.vel_u",
1046 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_VEL_U,
1047 "Specifies if the velocity-up field is present", HFILL } },
1048 { &hf_ppi_vector_present_vel_t,
1049 { "Velocity_T", "ppi_vector.present.vel_t",
1050 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_VEL_T,
1051 "Specifies if the total velocity field is present", HFILL } },
1053 { &hf_ppi_vector_present_acc_r,
1054 { "Acceleration_R", "ppi_vector.present.acc_r",
1055 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ACC_R,
1056 "Specifies if the accel-right field is present", HFILL } },
1058 { &hf_ppi_vector_present_acc_f,
1059 { "Acceleration_F", "ppi_vector.present.acc_f",
1060 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ACC_F,
1061 "Specifies if the accel-forward field is present", HFILL } },
1063 { &hf_ppi_vector_present_acc_u,
1064 { "Acceleration_U", "ppi_vector.present.acc_u",
1065 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ACC_U,
1066 "Specifies if the accel-up field is present", HFILL } },
1067 { &hf_ppi_vector_present_acc_t,
1068 { "Acceleration_T", "ppi_vector.present.acc_t",
1069 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ACC_T,
1070 "Specifies if the total acceleration field is present", HFILL } },
1072 /* V2 */
1073 { &hf_ppi_vector_present_off_x,
1074 { "Offset_R", "ppi_vector.present.off_x",
1075 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_OFF_X,
1076 "Specifies if the offset-x (right/east) field is present", HFILL } },
1078 { &hf_ppi_vector_present_off_y,
1079 { "Offset_F", "ppi_vector.present.off_y",
1080 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_OFF_Y,
1081 "Specifies if the offset-y (forward/north) field is present", HFILL } },
1083 { &hf_ppi_vector_present_off_z,
1084 { "Offset_U", "ppi_vector.present.off_z",
1085 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_OFF_Z,
1086 "Specifies if the offset-z (up) field is present", HFILL } },
1089 { &hf_ppi_vector_present_err_rot,
1090 { "err_rot", "ppi_vector.present.err_rot",
1091 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ERR_ROT,
1092 "Specifies if the rotation error field is present", HFILL } },
1094 { &hf_ppi_vector_present_err_off,
1095 { "err_off", "ppi_vector.present.err_off",
1096 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ERR_OFF,
1097 "Specifies if the offset error field is present", HFILL } },
1100 /* V1 only */
1101 { &hf_ppi_vector_present_err_vel,
1102 { "err_vel", "ppi_vector.present.err_vel",
1103 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ERR_VEL,
1104 "Specifies if the velocity error field is present", HFILL } },
1106 { &hf_ppi_vector_present_err_acc,
1107 { "err_acc", "ppi_vector.present.err_acc",
1108 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ERR_ACC,
1109 "Specifies if the acceleration error field is present", HFILL } },
1112 { &hf_ppi_vector_present_descstr,
1113 { "descstr", "ppi_vector.present.descstr",
1114 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_DESCSTR,
1115 "Specifies if the acceleration error field is present", HFILL } },
1117 { &hf_ppi_vector_presenappsecific_num,
1118 { "appid", "ppi_vector.present.appid",
1119 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_APPID,
1120 "Specifies if the application specific field id is present", HFILL } },
1122 { &hf_ppi_vector_present_appspecific_data,
1123 { "appdata", "ppi_vector.present.appdata",
1124 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_APPDATA,
1125 "Specifies if the application specific data field is present", HFILL } },
1127 { &hf_ppi_vector_present_ext,
1128 { "Ext", "ppi_vector.present.ext",
1129 FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_EXT,
1130 "Specifies if there are any extensions to the header present", HFILL } },
1132 /* Now we get to the actual data fields */
1133 /* This setups the "Vector fflags" hex dropydown thing */
1134 { &hf_ppi_vector_vflags,
1135 { "Vector flags", "ppi_vector.vector_flags",
1136 FT_UINT32, BASE_HEX, NULL, 0x0,
1137 "Bitmask indicating coordinate sys, among others, etc", HFILL } },
1138 { &hf_ppi_vector_vchars,
1139 { "Vector chars", "ppi_vector.vector_chars",
1140 FT_UINT32, BASE_HEX, NULL, 0x0,
1141 "Bitmask indicating if vector tracks antenna, vehicle, motion, etc", HFILL } },
1142 { &hf_ppi_vector_rot_x,
1143 { "Pitch", "ppi_vector.pitch",
1144 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1145 "Pitch (Rotation x) packet was received at", HFILL } },
1146 { &hf_ppi_vector_rot_y,
1147 { "Roll", "ppi_vector.roll",
1148 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1149 "Roll (Rotation y) packet was received at", HFILL } },
1150 { &hf_ppi_vector_rot_z,
1151 { "Heading", "ppi_vector.heading",
1152 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1153 "Heading (Rotation z) packet was received at", HFILL } },
1155 /* V1 */
1156 { &hf_ppi_vector_off_r,
1157 { "Off-r", "ppi_vector.off_r",
1158 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1159 "Offset right", HFILL } },
1160 { &hf_ppi_vector_off_f,
1161 { "Off-f", "ppi_vector.off_f",
1162 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1163 "Offation forward", HFILL } },
1164 { &hf_ppi_vector_off_u,
1165 { "Off-u", "ppi_vector.off_u",
1166 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1167 "Offset up", HFILL } },
1168 { &hf_ppi_vector_vel_r,
1169 { "Vel-r", "ppi_vector.vel_r",
1170 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_meter_sec), 0x0,
1171 "Velocity-right", HFILL } },
1172 { &hf_ppi_vector_vel_f,
1173 { "Vel-f", "ppi_vector.vel_f",
1174 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_meter_sec), 0x0,
1175 "Velocity-forward", HFILL } },
1176 { &hf_ppi_vector_vel_u,
1177 { "Vel-u", "ppi_vector.vel_u",
1178 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_meter_sec), 0x0,
1179 "Velocity-up", HFILL } },
1180 { &hf_ppi_vector_vel_t,
1181 { "Vel-t", "ppi_vector.vel_t",
1182 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_meter_sec), 0x0,
1183 "Velocity-Total", HFILL } },
1185 { &hf_ppi_vector_acc_r,
1186 { "Accel-r", "ppi_vector.acc_r",
1187 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_meter_sec_squared), 0x0,
1188 "Acceleration-right", HFILL } },
1189 { &hf_ppi_vector_acc_f,
1190 { "Accel-f", "ppi_vector.acc_f",
1191 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_meter_sec_squared), 0x0,
1192 "Acceleration-forward", HFILL } },
1193 { &hf_ppi_vector_acc_u,
1194 { "Accel-u", "ppi_vector.acc_u",
1195 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_meter_sec_squared), 0x0,
1196 "Acceleration-up", HFILL } },
1197 { &hf_ppi_vector_acc_t,
1198 { "Accel-t", "ppi_vector.acc_t",
1199 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_meter_sec_squared), 0x0,
1200 "Acceleration-Total", HFILL } },
1202 /* V2 */
1203 { &hf_ppi_vector_off_x,
1204 { "Off-x", "ppi_vector.off_x",
1205 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1206 "Offset-x (right/east)", HFILL } },
1207 { &hf_ppi_vector_off_y,
1208 { "Off-y", "ppi_vector.off_y",
1209 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1210 "Offset-y (forward/north)", HFILL } },
1211 { &hf_ppi_vector_off_z,
1212 { "Off-z", "ppi_vector.off_z",
1213 FT_DOUBLE, BASE_NONE, NULL, 0x0,
1214 "Offset-z (up)", HFILL } },
1216 { &hf_ppi_vector_err_rot,
1217 { "Err-Rot", "ppi_vector.err_rot",
1218 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_degree_degrees), 0x0,
1219 "Rotation margin of error", HFILL } },
1220 { &hf_ppi_vector_err_off,
1221 { "Err-Off", "ppi_vector.err_off",
1222 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_meter_meters), 0x0,
1223 "Offset margin of error", HFILL } },
1225 /* V1 only */
1226 { &hf_ppi_vector_err_vel,
1227 { "Err-Vel", "ppi_vector.err_vel",
1228 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_meter_sec), 0x0,
1229 "Velocity margin of error", HFILL } },
1230 { &hf_ppi_vector_err_acc,
1231 { "Err-Accel", "ppi_vector.err_acc",
1232 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_meter_sec_squared), 0x0,
1233 "Acceleration margin of error", HFILL } },
1235 { &hf_ppi_vector_descstr,
1236 { "Description", "ppi_vector.descr",
1237 FT_STRING, BASE_NONE, NULL, 0x0,
1238 NULL, HFILL } } ,
1239 { &hf_ppi_vector_appspecific_num,
1240 { "Application Specific id", "ppi_vector.appid",
1241 FT_UINT32, BASE_HEX, NULL, 0x0,
1242 "Application-specific identifier", HFILL } },
1243 { &hf_ppi_vector_appspecific_data,
1244 { "Application specific data", "ppi_vector.appdata",
1245 FT_BYTES, BASE_NONE, NULL, 0x0,
1246 "Application-specific data", HFILL } },
1248 /* Boolean vector flags */
1249 { &hf_ppi_vector_vflags_defines_forward,
1250 { "Defines forward", "ppi_vector.vflags.forward",
1251 FT_BOOLEAN, 32, NULL, PPI_VECTOR_VFLAGS_DEFINES_FORWARD,
1252 "Current vector indicates forward frame of reference", HFILL } },
1254 /* V1 */
1255 { &hf_ppi_vector_vflags_rots_absolute,
1256 { "Absolute (E/N/U) rotations", "ppi_vector.vflags.abs_rots",
1257 FT_BOOLEAN, 32, NULL, PPI_VECTOR_VFLAGS_ROTS_ABSOLUTE,
1258 "Rotations are in East/North/Up coord. sys", HFILL } },
1259 { &hf_ppi_vector_vflags_offsets_from_gps,
1260 { "Offsets from prev GPS TAG", "ppi_vector.vflags.offsets_from_gps",
1261 FT_BOOLEAN, 32, NULL, PPI_VECTOR_VFLAGS_OFFSETS_FROM_GPS,
1262 "Offsets fied rel. to Curr_Gps", HFILL } },
1264 /* V2 */
1265 { &hf_ppi_vector_vflags_relative_to,
1266 { "RelativeTo", "ppi_vector.vflags.relative_to", FT_UINT32, BASE_HEX, VALS(relativeto_string), PPI_VECTOR_VFLAGS_RELATIVE_TO,
1267 "Reference frame vectors are RelativeTo:", HFILL } },
1269 /* Boolean vector chars */
1270 { &hf_ppi_vector_vchars_antenna,
1271 { "Antenna", "ppi_vector.chars.antenna",
1272 FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_ANTENNA,
1273 "Vector represents: Antenna", HFILL } },
1275 { &hf_ppi_vector_vchars_dir_of_travel,
1276 { "Dir of travel", "ppi_vector.chars.dir_of_travel",
1277 FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_DIR_OF_TRAVEL,
1278 "Vector represents: Direction of travel", HFILL } },
1280 { &hf_ppi_vector_vchars_front_of_veh,
1281 { "Front of vehicle", "ppi_vector.chars.front_of_veh",
1282 FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_FRONT_OF_VEH,
1283 "Vector represents: Front of vehicle", HFILL } },
1285 /* V2 only */
1286 { &hf_ppi_vector_vchars_angle_of_arrival,
1287 { "Angle of arrival", "ppi_vector.chars.angle_of_arr",
1288 FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_AOA,
1289 "Vector represents: Angle of Arrival", HFILL } },
1290 { &hf_ppi_vector_vchars_transmitter_pos,
1291 { "Transmitter Position", "ppi_vector.chars.transmitter_pos",
1292 FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_TRANSMITTER_POS,
1293 "Vector position represents computed transmitter location", HFILL } },
1295 { &hf_ppi_vector_vchars_gps_derived,
1296 { "GPS Derived", "ppi_vector.vflags.gps_derived",
1297 FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_GPS_DERIVED,
1298 "Vector derived from: gps", HFILL } },
1300 { &hf_ppi_vector_vchars_ins_derived,
1301 { "INS Derived", "ppi_vector.vflags.ins_derived",
1302 FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_INS_DERIVED,
1303 "Vector derived from: inertial nav system", HFILL } },
1305 { &hf_ppi_vector_vchars_compass_derived,
1306 { "Compass derived", "ppi_vector.vflags.compass_derived",
1307 FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_COMPASS_DERIVED,
1308 "Vector derived from: compass", HFILL } },
1310 { &hf_ppi_vector_vchars_accelerometer_derived,
1311 { "Accelerometer derived", "ppi_vector.vflags.accelerometer_derived",
1312 FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_ACCELEROMETER_DERIVED,
1313 "Vector derived from: accelerometer", HFILL } },
1315 { &hf_ppi_vector_vchars_human_derived,
1316 { "Human derived", "ppi_vector.vflags.human_derived",
1317 FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_HUMAN_DERIVED,
1318 "Vector derived from: human", HFILL } },
1320 { &hf_ppi_vector_unknown_data,
1321 { "Data for unknown version", "ppi_vector.unknown_data",
1322 FT_BYTES, BASE_NONE, NULL, 0x0,
1323 NULL, HFILL } },
1326 static int *ett[] = {
1327 &ett_ppi_vector,
1328 &ett_ppi_vector_present,
1329 &ett_ppi_vectorflags,
1330 &ett_ppi_vectorchars
1333 static ei_register_info ei[] = {
1334 { &ei_ppi_vector_present_bit, { "ppi_vector.present.unknown_bit", PI_PROTOCOL, PI_WARN, "Error: PPI-VECTOR: unknown bit set in present field.", EXPFILL }},
1335 { &ei_ppi_vector_length, { "ppi_vector.length.invalid", PI_MALFORMED, PI_ERROR, "Invalid length", EXPFILL }},
1338 expert_module_t* expert_ppi_vector;
1340 proto_ppi_vector = proto_register_protocol("PPI vector decoder", "PPI vector Decoder", "ppi_vector");
1341 proto_register_field_array(proto_ppi_vector, hf, array_length(hf));
1342 proto_register_subtree_array(ett, array_length(ett));
1343 expert_ppi_vector = expert_register_protocol(proto_ppi_vector);
1344 expert_register_field_array(expert_ppi_vector, ei, array_length(ei));
1345 register_dissector("ppi_vector", dissect_ppi_vector, proto_ppi_vector);
1350 * Editor modelines
1352 * Local Variables:
1353 * c-basic-offset: 4
1354 * tab-width: 8
1355 * indent-tabs-mode: nil
1356 * End:
1358 * ex: set shiftwidth=4 tabstop=8 expandtab:
1359 * :indentSize=4:tabSize=8:noTabs=true: