2 * Routines for PPI-GEOLOCATION-SENSOR dissection
3 * Copyright 2010, Harris Corp, jellch@harris.com
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * Copied from packet-ppi-antenna.c
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32 #include <epan/packet.h>
33 #include "packet-ppi-geolocation-common.h"
35 enum ppi_sensor_type
{
36 PPI_SENSOR_SENSORTYPE
= 0, /* Velocity, Acceleration, etc */
37 PPI_SENSOR_SCALEFACTOR
= 1, /* 10^scalefactor applied to all values */
38 PPI_SENSOR_VAL_X
= 2, /* X-dimension reading */
39 PPI_SENSOR_VAL_Y
= 3, /* Y-dimension reading */
40 PPI_SENSOR_VAL_Z
= 4, /* Z-dimension reading */
41 PPI_SENSOR_VAL_T
= 5, /* Total reading */
42 PPI_SENSOR_VAL_E
= 6, /* Error reading */
43 PPI_SENSOR_DESCSTR
= 28, /*32 bytes, fixed length, null terminated description of what the sensor is for */
44 PPI_SENSOR_APPID
= 29, /*4-byte identifier*/
45 PPI_SENSOR_APPDATA
= 30, /* 60-byte app-id specific data*/
46 PPI_SENSOR_EXT
= 31 /* Indicates n extended bitmap follows */
48 #define PPI_SENSOR_MAXTAGLEN 127 /* Increase as fields are added */
52 #define SENSOR_RESERVED0 0
53 /*The values of these sensors corresponds to the order of their derivatives. double geek win */
54 #define SENSOR_VELOCITY 1
55 #define SENSOR_ACCELERATION 2
57 #define SENSOR_ROTATION 100
58 #define SENSOR_MAGNETIC 101
59 #define SENSOR_TEMPERATURE 1000
60 #define SENSOR_BAROMETER 1001
61 #define SENSOR_HUMIDITY 1002
62 #define SENSOR_TDOA_CLOCK 2000
63 #define SENSOR_PHASE 2001
65 static const value_string sensor_type_str
[] = {
66 { SENSOR_RESERVED0
, "Reserved" },
67 { SENSOR_VELOCITY
, "Velocity"},
68 { SENSOR_ACCELERATION
, "Acceleration"},
69 { SENSOR_JERK
, "Jerk"},
70 { SENSOR_ROTATION
, "Rotation"},
71 { SENSOR_MAGNETIC
, "Magnetic"},
72 { SENSOR_TEMPERATURE
, "Temperature"},
73 { SENSOR_BAROMETER
, "Barometer"},
74 { SENSOR_HUMIDITY
, "Humidity"},
75 { SENSOR_TDOA_CLOCK
, "TDOA_Clock"},
76 { SENSOR_PHASE
, "Phase"},
80 static const value_string sensor_unit_str
[] = {
81 { SENSOR_RESERVED0
, "Reserved" },
82 { SENSOR_VELOCITY
, "Meters/sec"},
83 { SENSOR_ACCELERATION
, "Meters/sec/sec"},
84 { SENSOR_JERK
, "Meters/sec/sec/sec"},
85 { SENSOR_ROTATION
, "Degrees/sec"},
86 { SENSOR_MAGNETIC
, "Tesla"},
87 { SENSOR_TEMPERATURE
, "Degrees Celsius"},
88 { SENSOR_BAROMETER
, "Pascal"},
89 { SENSOR_HUMIDITY
, "Humidity"},
90 { SENSOR_TDOA_CLOCK
, "Seconds"},
91 { SENSOR_PHASE
, "Degrees"},
96 static int proto_ppi_sensor
= -1;
98 static int hf_ppi_sensor_version
= -1;
99 static int hf_ppi_sensor_pad
= -1;
100 static int hf_ppi_sensor_length
= -1;
101 static int hf_ppi_sensor_present
= -1;
102 static int hf_ppi_sensor_sensortype
= -1;
103 static int hf_ppi_sensor_scalefactor
= -1;
104 static int hf_ppi_sensor_val_x
= -1;
105 static int hf_ppi_sensor_val_y
= -1;
106 static int hf_ppi_sensor_val_z
= -1;
107 static int hf_ppi_sensor_val_t
= -1;
108 static int hf_ppi_sensor_val_e
= -1;
109 static int hf_ppi_sensor_descstr
= -1;
110 static int hf_ppi_sensor_appspecific_num
= -1; /* 4-byte tag no */
111 static int hf_ppi_sensor_appspecific_data
= -1; /* 60 byte arbitrary data */
114 /* "Present" flags */
115 /* These represent decoded-bits in the gui */
116 static int hf_ppi_sensor_present_sensortype
= -1;
117 static int hf_ppi_sensor_present_scalefactor
= -1;
118 static int hf_ppi_sensor_present_val_x
= -1;
119 static int hf_ppi_sensor_present_val_y
= -1;
120 static int hf_ppi_sensor_present_val_z
= -1;
121 static int hf_ppi_sensor_present_val_t
= -1;
122 static int hf_ppi_sensor_present_val_e
= -1;
123 static int hf_ppi_sensor_present_descstr
= -1;
124 static int hf_ppi_sensor_present_appspecific_num
= -1;
125 static int hf_ppi_sensor_present_appspecific_data
= -1;
126 static int hf_ppi_sensor_present_ext
= -1;
129 /* These represent arrow-dropdownthings in the gui */
130 static gint ett_ppi_sensor
= -1;
131 static gint ett_ppi_sensor_present
= -1;
133 /* used with ScaleFactor */
135 base_10_expt(int power
)
138 int provide_frac
= 0;
140 if (power
== 0) /* likely*/
143 /* if negative, negate when we return*/
161 dissect_ppi_sensor(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
) {
162 /* The fixed values up front */
165 guint length_remaining
;
167 proto_tree
*ppi_sensor_tree
= NULL
;
168 proto_tree
*present_tree
= NULL
;
169 proto_tree
*pt
, *my_pt
;
170 proto_item
*ti
= NULL
;
171 proto_item
*sensor_line
= NULL
;
172 /* sensor type in english */
173 const gchar
*type_str
= "Unknown sensor";
174 const gchar
*unit_str
= "Unknown unit";
178 guint32 present
, next_present
;
180 /* values actually read out, for displaying */
181 guint16 sensortype
=0;
182 gchar scalefactor
= 0;
183 gdouble c_val
=0; /*curr val */
184 guint32 val_t
=0; /*temp curr val*/
185 guint32 t_appspecific_num
; /* temporary conversions */
187 gdouble curr_native_val
; /* this will have scaling_factor applied. displayed in sensor line */
192 /* Clear out stuff in the info column */
193 col_clear(pinfo
->cinfo
,COL_INFO
);
195 /* pull out the first three fields of the BASE-GEOTAG-HEADER */
196 version
= tvb_get_guint8(tvb
, offset
);
197 length
= tvb_get_letohs(tvb
, offset
+2);
198 present
= tvb_get_letohl(tvb
, offset
+4);
200 /* Setup basic column info */
201 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "PPI Sensor info v%u, Length %u ",
204 /* Create the basic dissection tree*/
206 ti
= proto_tree_add_protocol_format(tree
, proto_ppi_sensor
,
207 tvb
, 0, length
, "PPI Sensor Header v%u, Length %u", version
, length
);
208 sensor_line
= ti
; /* we will almost definitely overwrite this in the field processing below */
210 /*Add in the fixed ppi-geotagging-header fields: ver, pad, len */
211 ppi_sensor_tree
= proto_item_add_subtree(ti
, ett_ppi_sensor
);
212 proto_tree_add_uint(ppi_sensor_tree
, hf_ppi_sensor_version
,
213 tvb
, offset
, 1, version
);
214 proto_tree_add_item(ppi_sensor_tree
, hf_ppi_sensor_pad
,
215 tvb
, offset
+ 1, 1, ENC_BIG_ENDIAN
);
216 ti
= proto_tree_add_uint(ppi_sensor_tree
, hf_ppi_sensor_length
,
217 tvb
, offset
+ 2, 2, length
);
218 /*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) ) {
224 proto_item_append_text(ti
, "invalid version (got %d, expected 1 or 2)", version
);
228 length_remaining
= length
;
229 /* minimum length check, should atleast be a fixed-size geotagging-base header*/
230 if (length_remaining
< PPI_GEOBASE_MIN_HEADER_LEN
) {
232 * Base-geotag-header (Radiotap lookalike) is shorter than the fixed-length portion
233 * plus one "present" bitset.
236 proto_item_append_text(ti
, " (invalid - minimum length is 8)");
240 /* perform max length sanity checking */
241 if (length
> PPI_SENSOR_MAXTAGLEN
) {
243 proto_item_append_text(ti
, "Invalid PPI-Sensor length (got %d, %d max\n)", length
, PPI_SENSOR_MAXTAGLEN
);
248 /* Subtree for the "present flags" bitfield. */
250 pt
= proto_tree_add_uint(ppi_sensor_tree
, hf_ppi_sensor_present
, tvb
, offset
+ 4, 4, present
);
251 present_tree
= proto_item_add_subtree(pt
, ett_ppi_sensor_present
); /* this represents the present bitmask field */
253 proto_tree_add_item(present_tree
, hf_ppi_sensor_present_sensortype
, tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
254 proto_tree_add_item(present_tree
, hf_ppi_sensor_present_scalefactor
, tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
255 proto_tree_add_item(present_tree
, hf_ppi_sensor_present_val_x
, tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
256 proto_tree_add_item(present_tree
, hf_ppi_sensor_present_val_y
, tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
257 proto_tree_add_item(present_tree
, hf_ppi_sensor_present_val_z
, tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
258 proto_tree_add_item(present_tree
, hf_ppi_sensor_present_val_t
, tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
259 proto_tree_add_item(present_tree
, hf_ppi_sensor_present_val_e
, tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
260 proto_tree_add_item(present_tree
, hf_ppi_sensor_present_descstr
, tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
261 proto_tree_add_item(present_tree
, hf_ppi_sensor_present_appspecific_num
, tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
262 proto_tree_add_item(present_tree
, hf_ppi_sensor_present_appspecific_data
, tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
263 proto_tree_add_item(present_tree
, hf_ppi_sensor_present_ext
, tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
265 offset
+= PPI_GEOBASE_MIN_HEADER_LEN
;
266 length_remaining
-= PPI_GEOBASE_MIN_HEADER_LEN
;
268 /* Now all of the fixed length, fixed location stuff is over. Loop over the bits */
269 for (; present
; present
= next_present
) {
270 /* clear the least significant bit that is set */
271 next_present
= present
& (present
- 1);
272 /* extract the least significant bit that is set */
273 bit
= BITNO_32(present
^ next_present
);
275 case PPI_SENSOR_SENSORTYPE
:
276 if (length_remaining
< 2)
278 sensortype
= tvb_get_letohs(tvb
, offset
);
279 type_str
= val_to_str_const (sensortype
, sensor_type_str
, "Unknown Sensor type");
280 unit_str
= val_to_str_const (sensortype
, sensor_unit_str
, "Unknown Unit");
283 my_pt
= proto_tree_add_uint(ppi_sensor_tree
, hf_ppi_sensor_sensortype
, tvb
, offset
, 2, sensortype
);
284 proto_item_append_text (my_pt
, " %s", type_str
);
285 proto_item_set_text(sensor_line
, "Sensor: %s", type_str
);
290 case PPI_SENSOR_SCALEFACTOR
:
291 if (length_remaining
< 1)
293 scalefactor
= (gchar
) tvb_get_guint8(tvb
, offset
);
296 proto_tree_add_int(ppi_sensor_tree
, hf_ppi_sensor_scalefactor
, tvb
, offset
, 1, scalefactor
);
301 case PPI_SENSOR_VAL_X
:
302 if (length_remaining
< 4)
304 val_t
= tvb_get_letohl(tvb
, offset
);
305 c_val
= ppi_fixed6_4_to_gdouble(val_t
);
307 my_pt
= proto_tree_add_double(ppi_sensor_tree
, hf_ppi_sensor_val_x
, tvb
, offset
, 4, c_val
);
308 proto_item_append_text (my_pt
, " %s", unit_str
);
309 curr_native_val
= c_val
* base_10_expt(scalefactor
); /* this will almost always be eqaul to the original val */
310 proto_item_set_text(sensor_line
, "Sensor: %s %f %s", type_str
, curr_native_val
, unit_str
);
315 case PPI_SENSOR_VAL_Y
:
316 if (length_remaining
< 4)
318 val_t
= tvb_get_letohl(tvb
, offset
);
319 c_val
= ppi_fixed6_4_to_gdouble(val_t
);
321 my_pt
= proto_tree_add_double(ppi_sensor_tree
, hf_ppi_sensor_val_y
, tvb
, offset
, 4, c_val
);
322 proto_item_append_text (my_pt
, " %s", unit_str
);
323 curr_native_val
= c_val
* base_10_expt(scalefactor
); /* this will almost always be eqaul to the original val */
324 proto_item_set_text(sensor_line
, "Sensor: %s %f %s", type_str
, curr_native_val
, unit_str
);
330 case PPI_SENSOR_VAL_Z
:
331 if (length_remaining
< 4)
333 val_t
= tvb_get_letohl(tvb
, offset
);
334 c_val
= ppi_fixed6_4_to_gdouble(val_t
);
336 my_pt
= proto_tree_add_double(ppi_sensor_tree
, hf_ppi_sensor_val_z
, tvb
, offset
, 4, c_val
);
337 proto_item_append_text (my_pt
, " %s", unit_str
);
338 curr_native_val
= c_val
* base_10_expt(scalefactor
); /* this will almost always be eqaul to the original val */
339 proto_item_set_text(sensor_line
, "Sensor: %s %f %s", type_str
, curr_native_val
, unit_str
);
344 case PPI_SENSOR_VAL_T
:
345 if (length_remaining
< 4)
347 val_t
= tvb_get_letohl(tvb
, offset
);
348 c_val
= ppi_fixed6_4_to_gdouble(val_t
);
350 my_pt
= proto_tree_add_double(ppi_sensor_tree
, hf_ppi_sensor_val_t
, tvb
, offset
, 4, c_val
);
351 proto_item_append_text (my_pt
, " %s", unit_str
);
352 curr_native_val
= c_val
* base_10_expt(scalefactor
); /* this will almost always be eqaul to the original val */
353 proto_item_set_text(sensor_line
, "Sensor: %s %f %s", type_str
, curr_native_val
, unit_str
);
358 case PPI_SENSOR_VAL_E
:
359 if (length_remaining
< 4)
361 val_t
= tvb_get_letohl(tvb
, offset
);
362 c_val
= ppi_fixed6_4_to_gdouble(val_t
);
364 my_pt
= proto_tree_add_double(ppi_sensor_tree
, hf_ppi_sensor_val_e
, tvb
, offset
, 4, c_val
);
365 proto_item_append_text (my_pt
, " %s", unit_str
);
371 case PPI_SENSOR_DESCSTR
:
372 if (length_remaining
< 32)
376 /* proto_tree_add_item(ppi_vector_tree, hf_ppi_vector_descstr, tvb, offset, 32, ENC_NA); */
377 curr_str
= tvb_format_stringzpad(tvb
, offset
, 32);
378 proto_tree_add_string(ppi_sensor_tree
, hf_ppi_sensor_descstr
, tvb
, offset
, 32, curr_str
);
379 proto_item_append_text(sensor_line
, " (%s)", curr_str
);
382 length_remaining
-=32;
384 case PPI_SENSOR_APPID
:
385 if (length_remaining
< 4)
387 t_appspecific_num
= tvb_get_letohl(tvb
, offset
); /* application specific parsers may switch on this later */
389 proto_tree_add_uint(ppi_sensor_tree
, hf_ppi_sensor_appspecific_num
, tvb
, offset
, 4, t_appspecific_num
);
394 case PPI_SENSOR_APPDATA
:
395 if (length_remaining
< 60)
398 proto_tree_add_item(ppi_sensor_tree
, hf_ppi_sensor_appspecific_data
, tvb
, offset
, 60, ENC_NA
);
401 length_remaining
-=60;
405 * This indicates a field whose size we do not
406 * know, so we cannot proceed.
408 proto_tree_add_text(ppi_sensor_tree
, tvb
, offset
, 0, "Error: PPI-SENSOR: unknown bit (%d) set in present field.\n", bit
);
418 proto_register_ppi_sensor(void) {
419 /* The following array initializes those header fields declared above to the values displayed */
420 static hf_register_info hf
[] = {
421 { &hf_ppi_sensor_version
,
422 { "Header revision", "ppi_sensor.version",
423 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
424 "Version of ppi_sensor header format", HFILL
} },
425 { &hf_ppi_sensor_pad
,
426 { "Header pad", "ppi_sensor.pad",
427 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
428 "Padding", HFILL
} },
429 { &hf_ppi_sensor_length
,
430 { "Header length", "ppi_sensor.length",
431 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
432 "Length of header including version, pad, length and data fields", HFILL
} },
433 { &hf_ppi_sensor_present
,
434 { "Present", "ppi_sensor.present",
435 FT_UINT32
, BASE_HEX
, NULL
, 0x0, "Bitmask indicating which fields are present", HFILL
} },
437 /* This first set is for the base_tag_header.it_present bitfield */
438 #define PPI_SENSOR_MASK_SENSORTYPE 0x00000001 /* 0 */
439 #define PPI_SENSOR_MASK_SCALEFACTOR 0x00000002 /* 1 */
440 #define PPI_SENSOR_MASK_VAL_X 0x00000004 /* 2 */
441 #define PPI_SENSOR_MASK_VAL_Y 0x00000008 /* 3 */
442 #define PPI_SENSOR_MASK_VAL_Z 0x00000010 /* 4 */
443 #define PPI_SENSOR_MASK_VAL_T 0x00000020 /* 5 */
444 #define PPI_SENSOR_MASK_VAL_E 0x00000040 /* 6 */
445 #define PPI_SENSOR_MASK_SERIALNUM 0x04000000 /* 26 */
446 #define PPI_SENSOR_MASK_MODELSTR 0x08000000 /* 27 */
447 #define PPI_SENSOR_MASK_DESCSTR 0x10000000 /* 28 */
448 #define PPI_SENSOR_MASK_APPID 0x20000000 /* 29 */
449 #define PPI_SENSOR_MASK_APPDATA 0x40000000 /* 30 */
450 #define PPI_SENSOR_MASK_EXT 0x80000000 /* 31 */
452 /* Boolean 'present' flags */
453 { &hf_ppi_sensor_present_sensortype
,
454 { "sensortype", "ppi_sensor.present.sensortype",
455 FT_BOOLEAN
, 32, NULL
, PPI_SENSOR_MASK_SENSORTYPE
,
456 "Specifies if the sensor type field is present", HFILL
} },
457 { &hf_ppi_sensor_present_scalefactor
,
458 { "scalefactor", "ppi_sensor.present.scalefactor",
459 FT_BOOLEAN
, 32, NULL
, PPI_SENSOR_MASK_SCALEFACTOR
,
460 "Specifies if the sensor scale factor field is present", HFILL
} },
462 { &hf_ppi_sensor_present_val_x
,
463 { "val_x", "ppi_sensor.present.val_x",
464 FT_BOOLEAN
, 32, NULL
, PPI_SENSOR_MASK_VAL_X
,
465 "Specifies if the sensor val_x field is present", HFILL
} },
466 { &hf_ppi_sensor_present_val_y
,
467 { "val_y", "ppi_sensor.present.val_y",
468 FT_BOOLEAN
, 32, NULL
, PPI_SENSOR_MASK_VAL_Y
,
469 "Specifies if the sensor val_y field is present", HFILL
} },
470 { &hf_ppi_sensor_present_val_z
,
471 { "val_z", "ppi_sensor.present.val_z",
472 FT_BOOLEAN
, 32, NULL
, PPI_SENSOR_MASK_VAL_Z
,
473 "Specifies if the BeamID field is present", HFILL
} },
475 { &hf_ppi_sensor_present_val_t
,
476 { "val_t", "ppi_sensor.present.val_t",
477 FT_BOOLEAN
, 32, NULL
, PPI_SENSOR_MASK_VAL_T
,
478 "Specifies if the val_t field is present", HFILL
} },
479 { &hf_ppi_sensor_present_val_e
,
480 { "val_e", "ppi_sensor.present.val_e",
481 FT_BOOLEAN
, 32, NULL
, PPI_SENSOR_MASK_VAL_E
,
482 "Specifies if the val_e field is present", HFILL
} },
484 { &hf_ppi_sensor_present_descstr
,
485 { "Description", "ppi_sensor.present.descr",
486 FT_BOOLEAN
, 32, NULL
, PPI_SENSOR_MASK_DESCSTR
,
487 "Specifies if the description string is present", HFILL
} },
488 { &hf_ppi_sensor_present_appspecific_num
,
489 { "appid", "ppi_sensor.present.appid",
490 FT_BOOLEAN
, 32, NULL
, PPI_SENSOR_MASK_APPID
,
491 "Specifies if the application specific field id is present", HFILL
} },
492 { &hf_ppi_sensor_present_appspecific_data
,
493 { "appdata", "ppi_sensor.present.appdata",
494 FT_BOOLEAN
, 32, NULL
, PPI_SENSOR_MASK_APPDATA
,
495 "Specifies if the application specific data field is present", HFILL
} },
496 { &hf_ppi_sensor_present_ext
,
497 { "ext", "ppi_sensor.present.ext",
498 FT_BOOLEAN
, 32, NULL
, PPI_SENSOR_MASK_EXT
,
499 "Specifies if there are any extensions to the header present", HFILL
} },
502 /* Now we get to the actual data fields */
503 { &hf_ppi_sensor_sensortype
,
504 { "SensorType", "ppi_sensor.sensortype",
505 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
506 "Type of sensor", HFILL
} },
507 { &hf_ppi_sensor_scalefactor
,
508 { "ScaleFactor", "ppi_sensor.scalefactor",
509 FT_INT8
, BASE_DEC
, NULL
, 0x0,
510 "Scaling factor", HFILL
} },
511 { &hf_ppi_sensor_val_x
,
512 { "Val_X", "ppi_sensor.val_x",
513 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
514 "Value in X-dimesion", HFILL
} },
515 { &hf_ppi_sensor_val_y
,
516 { "Val_Y", "ppi_sensor.val_y",
517 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
518 "Value in Y-dimension", HFILL
} },
519 { &hf_ppi_sensor_val_z
,
520 { "Val_Z", "ppi_sensor.val_z",
521 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
522 "Value in Z-dimension", HFILL
} },
523 { &hf_ppi_sensor_val_t
,
524 { "Val_T", "ppi_sensor.val_t",
525 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
526 "Value total (dimensionless)", HFILL
} },
527 { &hf_ppi_sensor_val_e
,
528 { "Val_E", "ppi_sensor.val_e",
529 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
530 "Margin of error", HFILL
} },
533 { &hf_ppi_sensor_descstr
,
534 { "Description", "ppi_sensor.descr",
535 FT_STRING
, BASE_NONE
, NULL
, 0x0,
537 { &hf_ppi_sensor_appspecific_num
,
538 { "Application Specific id", "ppi_sensor.appid",
539 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
540 "Application-specific identifier", HFILL
} },
541 { &hf_ppi_sensor_appspecific_data
,
542 { "Application specific data", "ppi_sensor.appdata",
543 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
544 "Application-specific data", HFILL
} },
546 static gint
*ett
[] = {
548 &ett_ppi_sensor_present
,
551 proto_ppi_sensor
= proto_register_protocol("PPI sensor decoder", "PPI sensor Decoder", "ppi_sensor");
552 proto_register_field_array(proto_ppi_sensor
, hf
, array_length(hf
));
553 proto_register_subtree_array(ett
, array_length(ett
));
554 register_dissector("ppi_sensor", dissect_ppi_sensor
, proto_ppi_sensor
);
564 * indent-tabs-mode: nil
567 * ex: set shiftwidth=4 tabstop=8 expandtab:
568 * :indentSize=4:tabSize=8:noTabs=true: