Coverage Report

Created: 2026-05-14 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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