2 * Routines for PPI-GEOLOCATION-SENSOR dissection
3 * Copyright 2010, Harris Corp, jellch@harris.com
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * Copied from packet-ppi-antenna.c
11 * SPDX-License-Identifier: GPL-2.0-or-later
16 #include <epan/packet.h>
17 #include <epan/expert.h>
18 #include "packet-ppi-geolocation-common.h"
20 enum ppi_sensor_type
{
21 PPI_SENSOR_SENSORTYPE
= 0, /* Velocity, Acceleration, etc */
22 PPI_SENSOR_SCALEFACTOR
= 1, /* 10^scalefactor applied to all values */
23 PPI_SENSOR_VAL_X
= 2, /* X-dimension reading */
24 PPI_SENSOR_VAL_Y
= 3, /* Y-dimension reading */
25 PPI_SENSOR_VAL_Z
= 4, /* Z-dimension reading */
26 PPI_SENSOR_VAL_T
= 5, /* Total reading */
27 PPI_SENSOR_VAL_E
= 6, /* Error reading */
28 PPI_SENSOR_DESCSTR
= 28, /*32 bytes, fixed length, null terminated description of what the sensor is for */
29 PPI_SENSOR_APPID
= 29, /*4-byte identifier*/
30 PPI_SENSOR_APPDATA
= 30, /* 60-byte app-id specific data*/
31 PPI_SENSOR_EXT
= 31 /* Indicates n extended bitmap follows */
33 #define PPI_SENSOR_MAXTAGLEN 127 /* Increase as fields are added */
37 #define SENSOR_RESERVED0 0
38 /*The values of these sensors corresponds to the order of their derivatives. double geek win */
39 #define SENSOR_VELOCITY 1
40 #define SENSOR_ACCELERATION 2
42 #define SENSOR_ROTATION 100
43 #define SENSOR_MAGNETIC 101
44 #define SENSOR_TEMPERATURE 1000
45 #define SENSOR_BAROMETER 1001
46 #define SENSOR_HUMIDITY 1002
47 #define SENSOR_TDOA_CLOCK 2000
48 #define SENSOR_PHASE 2001
50 static const value_string sensor_type_str
[] = {
51 { SENSOR_RESERVED0
, "Reserved" },
52 { SENSOR_VELOCITY
, "Velocity"},
53 { SENSOR_ACCELERATION
, "Acceleration"},
54 { SENSOR_JERK
, "Jerk"},
55 { SENSOR_ROTATION
, "Rotation"},
56 { SENSOR_MAGNETIC
, "Magnetic"},
57 { SENSOR_TEMPERATURE
, "Temperature"},
58 { SENSOR_BAROMETER
, "Barometer"},
59 { SENSOR_HUMIDITY
, "Humidity"},
60 { SENSOR_TDOA_CLOCK
, "TDOA_Clock"},
61 { SENSOR_PHASE
, "Phase"},
65 static const value_string sensor_unit_str
[] = {
66 { SENSOR_RESERVED0
, "Reserved" },
67 { SENSOR_VELOCITY
, "Meters/sec"},
68 { SENSOR_ACCELERATION
, "Meters/sec/sec"},
69 { SENSOR_JERK
, "Meters/sec/sec/sec"},
70 { SENSOR_ROTATION
, "Degrees/sec"},
71 { SENSOR_MAGNETIC
, "Tesla"},
72 { SENSOR_TEMPERATURE
, "Degrees Celsius"},
73 { SENSOR_BAROMETER
, "Pascal"},
74 { SENSOR_HUMIDITY
, "Humidity"},
75 { SENSOR_TDOA_CLOCK
, "Seconds"},
76 { SENSOR_PHASE
, "Degrees"},
80 void proto_register_ppi_sensor(void);
82 static int proto_ppi_sensor
;
84 static int hf_ppi_sensor_version
;
85 static int hf_ppi_sensor_pad
;
86 static int hf_ppi_sensor_length
;
87 static int hf_ppi_sensor_present
;
88 static int hf_ppi_sensor_sensortype
;
89 static int hf_ppi_sensor_scalefactor
;
90 static int hf_ppi_sensor_val_x
;
91 static int hf_ppi_sensor_val_y
;
92 static int hf_ppi_sensor_val_z
;
93 static int hf_ppi_sensor_val_t
;
94 static int hf_ppi_sensor_val_e
;
95 static int hf_ppi_sensor_descstr
;
96 static int hf_ppi_sensor_appspecific_num
; /* 4-byte tag no */
97 static int hf_ppi_sensor_appspecific_data
; /* 60 byte arbitrary data */
100 /* "Present" flags */
101 /* These represent decoded-bits in the gui */
102 static int hf_ppi_sensor_present_sensortype
;
103 static int hf_ppi_sensor_present_scalefactor
;
104 static int hf_ppi_sensor_present_val_x
;
105 static int hf_ppi_sensor_present_val_y
;
106 static int hf_ppi_sensor_present_val_z
;
107 static int hf_ppi_sensor_present_val_t
;
108 static int hf_ppi_sensor_present_val_e
;
109 static int hf_ppi_sensor_present_descstr
;
110 static int hf_ppi_sensor_present_appspecific_num
;
111 static int hf_ppi_sensor_present_appspecific_data
;
112 static int hf_ppi_sensor_present_ext
;
115 /* These represent arrow-dropdownthings in the gui */
116 static int ett_ppi_sensor
;
117 static int ett_ppi_sensor_present
;
119 static expert_field ei_ppi_sensor_present_bit
;
120 static expert_field ei_ppi_sensor_version
;
121 static expert_field ei_ppi_sensor_length
;
123 /* used with ScaleFactor */
125 base_10_expt(int power
)
128 int provide_frac
= 0;
130 if (power
== 0) /* likely*/
133 /* if negative, negate when we return*/
151 dissect_ppi_sensor(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
) {
152 /* The fixed values up front */
155 unsigned length_remaining
;
157 proto_tree
*ppi_sensor_tree
= NULL
;
158 proto_tree
*pt
, *my_pt
;
159 proto_item
*version_item
, *length_item
;
160 proto_tree
*sensor_line
;
161 /* sensor type in english */
162 const char *type_str
= "Unknown sensor";
163 const char *unit_str
= "Unknown unit";
165 static int * const ppi_sensor_present_flags
[] = {
166 &hf_ppi_sensor_present_sensortype
,
167 &hf_ppi_sensor_present_scalefactor
,
168 &hf_ppi_sensor_present_val_x
,
169 &hf_ppi_sensor_present_val_y
,
170 &hf_ppi_sensor_present_val_z
,
171 &hf_ppi_sensor_present_val_t
,
172 &hf_ppi_sensor_present_val_e
,
173 &hf_ppi_sensor_present_descstr
,
174 &hf_ppi_sensor_present_appspecific_num
,
175 &hf_ppi_sensor_present_appspecific_data
,
176 &hf_ppi_sensor_present_ext
,
182 uint32_t present
, next_present
;
184 /* values actually read out, for displaying */
185 uint16_t sensortype
=0;
186 char scalefactor
= 0;
187 double c_val
=0; /*curr val */
188 uint32_t val_t
=0; /*temp curr val*/
189 uint32_t t_appspecific_num
; /* temporary conversions */
191 double curr_native_val
; /* this will have scaling_factor applied. displayed in sensor line */
196 /* Clear out stuff in the info column */
197 col_clear(pinfo
->cinfo
,COL_INFO
);
199 /* pull out the first three fields of the BASE-GEOTAG-HEADER */
200 version
= tvb_get_uint8(tvb
, offset
);
201 length
= tvb_get_letohs(tvb
, offset
+2);
202 present
= tvb_get_letohl(tvb
, offset
+4);
204 /* Setup basic column info */
205 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "PPI Sensor info v%u, Length %u ",
208 /* Create the basic dissection tree*/
209 sensor_line
= proto_tree_add_protocol_format(tree
, proto_ppi_sensor
,
210 tvb
, 0, length
, "PPI Sensor Header v%u, Length %u", version
, length
);
211 /*Add in the fixed ppi-geotagging-header fields: ver, pad, len */
212 ppi_sensor_tree
= proto_item_add_subtree(sensor_line
, ett_ppi_sensor
);
213 version_item
= proto_tree_add_uint(ppi_sensor_tree
, hf_ppi_sensor_version
,
214 tvb
, offset
, 1, version
);
215 proto_tree_add_item(ppi_sensor_tree
, hf_ppi_sensor_pad
,
216 tvb
, offset
+ 1, 1, ENC_BIG_ENDIAN
);
217 length_item
= proto_tree_add_uint(ppi_sensor_tree
, hf_ppi_sensor_length
,
218 tvb
, offset
+ 2, 2, length
);
219 /*fixed ppi-geotagging-header fields finished, move onto the fields marked present*/
221 /* We support v1 and v2 of Sensor tags (identical) */
222 if (! (version
== 1 || version
== 2) ) {
223 expert_add_info_format(pinfo
, version_item
, &ei_ppi_sensor_version
, "Invalid version (got %d, expected 1 or 2)", version
);
226 length_remaining
= length
;
227 /* minimum length check, should atleast be a fixed-size geotagging-base header*/
228 if (length_remaining
< PPI_GEOBASE_MIN_HEADER_LEN
) {
230 * Base-geotag-header (Radiotap lookalike) is shorter than the fixed-length portion
231 * plus one "present" bitset.
233 expert_add_info_format(pinfo
, length_item
, &ei_ppi_sensor_length
, "Invalid PPI-Sensor length - minimum length is 8");
237 /* perform max length sanity checking */
238 if (length
> PPI_SENSOR_MAXTAGLEN
) {
239 expert_add_info_format(pinfo
, length_item
, &ei_ppi_sensor_length
, "Invalid PPI-Sensor length (got %d, %d max\n)", length
, PPI_SENSOR_MAXTAGLEN
);
243 /* Subtree for the "present flags" bitfield. */
244 pt
= proto_tree_add_bitmask(ppi_sensor_tree
, tvb
, offset
+ 4, hf_ppi_sensor_present
, ett_ppi_sensor_present
, ppi_sensor_present_flags
, ENC_LITTLE_ENDIAN
);
246 offset
+= PPI_GEOBASE_MIN_HEADER_LEN
;
247 length_remaining
-= PPI_GEOBASE_MIN_HEADER_LEN
;
249 /* Now all of the fixed length, fixed location stuff is over. Loop over the bits */
250 for (; present
; present
= next_present
) {
251 /* clear the least significant bit that is set */
252 next_present
= present
& (present
- 1);
253 /* extract the least significant bit that is set */
254 bit
= BITNO_32(present
^ next_present
);
256 case PPI_SENSOR_SENSORTYPE
:
257 if (length_remaining
< 2)
259 sensortype
= tvb_get_letohs(tvb
, offset
);
260 type_str
= val_to_str_const (sensortype
, sensor_type_str
, "Unknown Sensor type");
261 unit_str
= val_to_str_const (sensortype
, sensor_unit_str
, "Unknown Unit");
264 my_pt
= proto_tree_add_uint(ppi_sensor_tree
, hf_ppi_sensor_sensortype
, tvb
, offset
, 2, sensortype
);
265 proto_item_append_text (my_pt
, " %s", type_str
);
266 proto_item_set_text(sensor_line
, "Sensor: %s", type_str
);
271 case PPI_SENSOR_SCALEFACTOR
:
272 if (length_remaining
< 1)
274 scalefactor
= (char) tvb_get_uint8(tvb
, offset
);
275 proto_tree_add_int(ppi_sensor_tree
, hf_ppi_sensor_scalefactor
, tvb
, offset
, 1, scalefactor
);
279 case PPI_SENSOR_VAL_X
:
280 if (length_remaining
< 4)
282 val_t
= tvb_get_letohl(tvb
, offset
);
283 c_val
= ppi_fixed6_4_to_double(val_t
);
285 my_pt
= proto_tree_add_double(ppi_sensor_tree
, hf_ppi_sensor_val_x
, tvb
, offset
, 4, c_val
);
286 proto_item_append_text (my_pt
, " %s", unit_str
);
287 curr_native_val
= c_val
* base_10_expt(scalefactor
); /* this will almost always be equal to the original val */
288 proto_item_set_text(sensor_line
, "Sensor: %s %f %s", type_str
, curr_native_val
, unit_str
);
293 case PPI_SENSOR_VAL_Y
:
294 if (length_remaining
< 4)
296 val_t
= tvb_get_letohl(tvb
, offset
);
297 c_val
= ppi_fixed6_4_to_double(val_t
);
299 my_pt
= proto_tree_add_double(ppi_sensor_tree
, hf_ppi_sensor_val_y
, tvb
, offset
, 4, c_val
);
300 proto_item_append_text (my_pt
, " %s", unit_str
);
301 curr_native_val
= c_val
* base_10_expt(scalefactor
); /* this will almost always be equal to the original val */
302 proto_item_set_text(sensor_line
, "Sensor: %s %f %s", type_str
, curr_native_val
, unit_str
);
308 case PPI_SENSOR_VAL_Z
:
309 if (length_remaining
< 4)
311 val_t
= tvb_get_letohl(tvb
, offset
);
312 c_val
= ppi_fixed6_4_to_double(val_t
);
314 my_pt
= proto_tree_add_double(ppi_sensor_tree
, hf_ppi_sensor_val_z
, tvb
, offset
, 4, c_val
);
315 proto_item_append_text (my_pt
, " %s", unit_str
);
316 curr_native_val
= c_val
* base_10_expt(scalefactor
); /* this will almost always be equal to the original val */
317 proto_item_set_text(sensor_line
, "Sensor: %s %f %s", type_str
, curr_native_val
, unit_str
);
322 case PPI_SENSOR_VAL_T
:
323 if (length_remaining
< 4)
325 val_t
= tvb_get_letohl(tvb
, offset
);
326 c_val
= ppi_fixed6_4_to_double(val_t
);
328 my_pt
= proto_tree_add_double(ppi_sensor_tree
, hf_ppi_sensor_val_t
, tvb
, offset
, 4, c_val
);
329 proto_item_append_text (my_pt
, " %s", unit_str
);
330 curr_native_val
= c_val
* base_10_expt(scalefactor
); /* this will almost always be equal to the original val */
331 proto_item_set_text(sensor_line
, "Sensor: %s %f %s", type_str
, curr_native_val
, unit_str
);
336 case PPI_SENSOR_VAL_E
:
337 if (length_remaining
< 4)
339 val_t
= tvb_get_letohl(tvb
, offset
);
340 c_val
= ppi_fixed6_4_to_double(val_t
);
342 my_pt
= proto_tree_add_double(ppi_sensor_tree
, hf_ppi_sensor_val_e
, tvb
, offset
, 4, c_val
);
343 proto_item_append_text (my_pt
, " %s", unit_str
);
349 case PPI_SENSOR_DESCSTR
:
350 if (length_remaining
< 32)
354 /* proto_tree_add_item(ppi_vector_tree, hf_ppi_vector_descstr, tvb, offset, 32, ENC_NA); */
355 curr_str
= tvb_format_stringzpad(pinfo
->pool
, tvb
, offset
, 32);
356 proto_tree_add_string(ppi_sensor_tree
, hf_ppi_sensor_descstr
, tvb
, offset
, 32, curr_str
);
357 proto_item_append_text(sensor_line
, " (%s)", curr_str
);
360 length_remaining
-=32;
362 case PPI_SENSOR_APPID
:
363 if (length_remaining
< 4)
365 t_appspecific_num
= tvb_get_letohl(tvb
, offset
); /* application specific parsers may switch on this later */
366 proto_tree_add_uint(ppi_sensor_tree
, hf_ppi_sensor_appspecific_num
, tvb
, offset
, 4, t_appspecific_num
);
370 case PPI_SENSOR_APPDATA
:
371 if (length_remaining
< 60)
373 proto_tree_add_item(ppi_sensor_tree
, hf_ppi_sensor_appspecific_data
, tvb
, offset
, 60, ENC_NA
);
375 length_remaining
-=60;
379 * This indicates a field whose size we do not
380 * know, so we cannot proceed.
382 expert_add_info_format(pinfo
, pt
, &ei_ppi_sensor_present_bit
, "Error: PPI-SENSOR: unknown bit (%d) set in present field.", bit
);
388 return tvb_captured_length(tvb
);
392 proto_register_ppi_sensor(void) {
393 /* The following array initializes those header fields declared above to the values displayed */
394 static hf_register_info hf
[] = {
395 { &hf_ppi_sensor_version
,
396 { "Header revision", "ppi_sensor.version",
397 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
398 "Version of ppi_sensor header format", HFILL
} },
399 { &hf_ppi_sensor_pad
,
400 { "Header pad", "ppi_sensor.pad",
401 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
402 "Padding", HFILL
} },
403 { &hf_ppi_sensor_length
,
404 { "Header length", "ppi_sensor.length",
405 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
406 "Length of header including version, pad, length and data fields", HFILL
} },
407 { &hf_ppi_sensor_present
,
408 { "Present", "ppi_sensor.present",
409 FT_UINT32
, BASE_HEX
, NULL
, 0x0, "Bitmask indicating which fields are present", HFILL
} },
411 /* This first set is for the base_tag_header.it_present bitfield */
412 #define PPI_SENSOR_MASK_SENSORTYPE 0x00000001 /* 0 */
413 #define PPI_SENSOR_MASK_SCALEFACTOR 0x00000002 /* 1 */
414 #define PPI_SENSOR_MASK_VAL_X 0x00000004 /* 2 */
415 #define PPI_SENSOR_MASK_VAL_Y 0x00000008 /* 3 */
416 #define PPI_SENSOR_MASK_VAL_Z 0x00000010 /* 4 */
417 #define PPI_SENSOR_MASK_VAL_T 0x00000020 /* 5 */
418 #define PPI_SENSOR_MASK_VAL_E 0x00000040 /* 6 */
419 #define PPI_SENSOR_MASK_SERIALNUM 0x04000000 /* 26 */
420 #define PPI_SENSOR_MASK_MODELSTR 0x08000000 /* 27 */
421 #define PPI_SENSOR_MASK_DESCSTR 0x10000000 /* 28 */
422 #define PPI_SENSOR_MASK_APPID 0x20000000 /* 29 */
423 #define PPI_SENSOR_MASK_APPDATA 0x40000000 /* 30 */
424 #define PPI_SENSOR_MASK_EXT 0x80000000 /* 31 */
426 /* Boolean 'present' flags */
427 { &hf_ppi_sensor_present_sensortype
,
428 { "sensortype", "ppi_sensor.present.sensortype",
429 FT_BOOLEAN
, 32, NULL
, PPI_SENSOR_MASK_SENSORTYPE
,
430 "Specifies if the sensor type field is present", HFILL
} },
431 { &hf_ppi_sensor_present_scalefactor
,
432 { "scalefactor", "ppi_sensor.present.scalefactor",
433 FT_BOOLEAN
, 32, NULL
, PPI_SENSOR_MASK_SCALEFACTOR
,
434 "Specifies if the sensor scale factor field is present", HFILL
} },
436 { &hf_ppi_sensor_present_val_x
,
437 { "val_x", "ppi_sensor.present.val_x",
438 FT_BOOLEAN
, 32, NULL
, PPI_SENSOR_MASK_VAL_X
,
439 "Specifies if the sensor val_x field is present", HFILL
} },
440 { &hf_ppi_sensor_present_val_y
,
441 { "val_y", "ppi_sensor.present.val_y",
442 FT_BOOLEAN
, 32, NULL
, PPI_SENSOR_MASK_VAL_Y
,
443 "Specifies if the sensor val_y field is present", HFILL
} },
444 { &hf_ppi_sensor_present_val_z
,
445 { "val_z", "ppi_sensor.present.val_z",
446 FT_BOOLEAN
, 32, NULL
, PPI_SENSOR_MASK_VAL_Z
,
447 "Specifies if the BeamID field is present", HFILL
} },
449 { &hf_ppi_sensor_present_val_t
,
450 { "val_t", "ppi_sensor.present.val_t",
451 FT_BOOLEAN
, 32, NULL
, PPI_SENSOR_MASK_VAL_T
,
452 "Specifies if the val_t field is present", HFILL
} },
453 { &hf_ppi_sensor_present_val_e
,
454 { "val_e", "ppi_sensor.present.val_e",
455 FT_BOOLEAN
, 32, NULL
, PPI_SENSOR_MASK_VAL_E
,
456 "Specifies if the val_e field is present", HFILL
} },
458 { &hf_ppi_sensor_present_descstr
,
459 { "Description", "ppi_sensor.present.descr",
460 FT_BOOLEAN
, 32, NULL
, PPI_SENSOR_MASK_DESCSTR
,
461 "Specifies if the description string is present", HFILL
} },
462 { &hf_ppi_sensor_present_appspecific_num
,
463 { "appid", "ppi_sensor.present.appid",
464 FT_BOOLEAN
, 32, NULL
, PPI_SENSOR_MASK_APPID
,
465 "Specifies if the application specific field id is present", HFILL
} },
466 { &hf_ppi_sensor_present_appspecific_data
,
467 { "appdata", "ppi_sensor.present.appdata",
468 FT_BOOLEAN
, 32, NULL
, PPI_SENSOR_MASK_APPDATA
,
469 "Specifies if the application specific data field is present", HFILL
} },
470 { &hf_ppi_sensor_present_ext
,
471 { "ext", "ppi_sensor.present.ext",
472 FT_BOOLEAN
, 32, NULL
, PPI_SENSOR_MASK_EXT
,
473 "Specifies if there are any extensions to the header present", HFILL
} },
476 /* Now we get to the actual data fields */
477 { &hf_ppi_sensor_sensortype
,
478 { "SensorType", "ppi_sensor.sensortype",
479 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
480 "Type of sensor", HFILL
} },
481 { &hf_ppi_sensor_scalefactor
,
482 { "ScaleFactor", "ppi_sensor.scalefactor",
483 FT_INT8
, BASE_DEC
, NULL
, 0x0,
484 "Scaling factor", HFILL
} },
485 { &hf_ppi_sensor_val_x
,
486 { "Val_X", "ppi_sensor.val_x",
487 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
488 "Value in X-dimesion", HFILL
} },
489 { &hf_ppi_sensor_val_y
,
490 { "Val_Y", "ppi_sensor.val_y",
491 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
492 "Value in Y-dimension", HFILL
} },
493 { &hf_ppi_sensor_val_z
,
494 { "Val_Z", "ppi_sensor.val_z",
495 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
496 "Value in Z-dimension", HFILL
} },
497 { &hf_ppi_sensor_val_t
,
498 { "Val_T", "ppi_sensor.val_t",
499 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
500 "Value total (dimensionless)", HFILL
} },
501 { &hf_ppi_sensor_val_e
,
502 { "Val_E", "ppi_sensor.val_e",
503 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
504 "Margin of error", HFILL
} },
507 { &hf_ppi_sensor_descstr
,
508 { "Description", "ppi_sensor.descr",
509 FT_STRING
, BASE_NONE
, NULL
, 0x0,
511 { &hf_ppi_sensor_appspecific_num
,
512 { "Application Specific id", "ppi_sensor.appid",
513 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
514 "Application-specific identifier", HFILL
} },
515 { &hf_ppi_sensor_appspecific_data
,
516 { "Application specific data", "ppi_sensor.appdata",
517 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
518 "Application-specific data", HFILL
} },
520 static int *ett
[] = {
522 &ett_ppi_sensor_present
,
525 static ei_register_info ei
[] = {
526 { &ei_ppi_sensor_present_bit
, { "ppi_sensor.present.unknown_bit", PI_PROTOCOL
, PI_WARN
, "Error: PPI-ANTENNA: unknown bit set in present field.", EXPFILL
}},
527 { &ei_ppi_sensor_version
, { "ppi_sensor.version.unsupported", PI_PROTOCOL
, PI_WARN
, "Invalid version", EXPFILL
}},
528 { &ei_ppi_sensor_length
, { "ppi_sensor.length.invalid", PI_MALFORMED
, PI_ERROR
, "Invalid length", EXPFILL
}},
531 expert_module_t
* expert_ppi_sensor
;
533 proto_ppi_sensor
= proto_register_protocol("PPI sensor decoder", "PPI sensor Decoder", "ppi_sensor");
534 proto_register_field_array(proto_ppi_sensor
, hf
, array_length(hf
));
535 proto_register_subtree_array(ett
, array_length(ett
));
536 expert_ppi_sensor
= expert_register_protocol(proto_ppi_sensor
);
537 expert_register_field_array(expert_ppi_sensor
, ei
, array_length(ei
));
538 register_dissector("ppi_sensor", dissect_ppi_sensor
, proto_ppi_sensor
);
548 * indent-tabs-mode: nil
551 * ex: set shiftwidth=4 tabstop=8 expandtab:
552 * :indentSize=4:tabSize=8:noTabs=true: