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