Coverage Report

Created: 2026-11-12 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-usb-hid.c
Line
Count
Source
1
/* packet-usb-hid.c
2
 *
3
 * USB HID dissector
4
 * By Adam Nielsen <a.nielsen@shikadi.net> 2009
5
 *
6
 * SPDX-License-Identifier: GPL-2.0-or-later
7
 */
8
9
/* See specification at
10
 * https://www.usb.org/sites/default/files/hid1_11.pdf
11
 * https://www.usb.org/sites/default/files/hut1_22.pdf
12
 */
13
14
#include "config.h"
15
16
17
#include <epan/packet.h>
18
#include "wsutil/sign_ext.h"
19
#include "wsutil/pint.h"
20
#include "packet-usb.h"
21
#include "packet-usb-hid.h"
22
#include "packet-btsdp.h"
23
24
25
void proto_register_usb_hid(void);
26
void proto_reg_handoff_usb_hid(void);
27
28
/* Dissector handles */
29
static dissector_handle_t usb_hid_control_handle;
30
static dissector_handle_t usb_hid_interrupt_handle;
31
static dissector_handle_t usb_hid_descr_handle;
32
33
/* protocols and header fields */
34
static int proto_usb_hid;
35
static int hf_usb_hid_item_bSize;
36
static int hf_usb_hid_item_bType;
37
static int hf_usb_hid_mainitem_bTag;
38
static int hf_usb_hid_globalitem_bTag;
39
static int hf_usb_hid_localitem_bTag;
40
static int hf_usb_hid_longitem_bTag;
41
static int hf_usb_hid_item_bDataSize;
42
static int hf_usb_hid_item_bLongItemTag;
43
static int hf_usb_hid_item_unk_data;
44
45
static int hf_usb_hid_mainitem_bit0;
46
static int hf_usb_hid_mainitem_bit1;
47
static int hf_usb_hid_mainitem_bit2;
48
static int hf_usb_hid_mainitem_bit3;
49
static int hf_usb_hid_mainitem_bit4;
50
static int hf_usb_hid_mainitem_bit5;
51
static int hf_usb_hid_mainitem_bit6;
52
static int hf_usb_hid_mainitem_bit7;
53
static int hf_usb_hid_mainitem_bit7_input;
54
static int hf_usb_hid_mainitem_bit8;
55
static int hf_usb_hid_mainitem_colltype;
56
57
static int hf_usb_hid_globalitem_usage;
58
static int hf_usb_hid_globalitem_log_min;
59
static int hf_usb_hid_globalitem_log_max;
60
static int hf_usb_hid_globalitem_phy_min;
61
static int hf_usb_hid_globalitem_phy_max;
62
static int hf_usb_hid_globalitem_unit_exp;
63
static int hf_usb_hid_globalitem_unit_sys;
64
static int hf_usb_hid_globalitem_unit_len;
65
static int hf_usb_hid_globalitem_unit_mass;
66
static int hf_usb_hid_globalitem_unit_time;
67
static int hf_usb_hid_globalitem_unit_temp;
68
static int hf_usb_hid_globalitem_unit_current;
69
static int hf_usb_hid_globalitem_unit_brightness;
70
static int hf_usb_hid_globalitem_report_size;
71
static int hf_usb_hid_globalitem_report_id;
72
static int hf_usb_hid_globalitem_report_count;
73
static int hf_usb_hid_globalitem_push;
74
static int hf_usb_hid_globalitem_pop;
75
76
static int hf_usb_hid_localitem_usage;
77
static int hf_usb_hid_localitem_usage_min;
78
static int hf_usb_hid_localitem_usage_max;
79
static int hf_usb_hid_localitem_desig_index;
80
static int hf_usb_hid_localitem_desig_min;
81
static int hf_usb_hid_localitem_desig_max;
82
static int hf_usb_hid_localitem_string_index;
83
static int hf_usb_hid_localitem_string_min;
84
static int hf_usb_hid_localitem_string_max;
85
static int hf_usb_hid_localitem_delimiter;
86
87
static int ett_usb_hid_report;
88
static int ett_usb_hid_item_header;
89
static int ett_usb_hid_wValue;
90
static int ett_usb_hid_descriptor;
91
static int ett_usb_hid_data;
92
static int ett_usb_hid_unknown_data;
93
static int ett_usb_hid_array;
94
95
static int hf_usb_hid_request;
96
static int hf_usb_hid_value;
97
static int hf_usb_hid_index;
98
static int hf_usb_hid_length;
99
static int hf_usb_hid_report_type;
100
static int hf_usb_hid_report_id;
101
static int hf_usb_hid_duration;
102
static int hf_usb_hid_zero;
103
static int hf_usb_hid_protocol;
104
105
static int hf_usb_hid_bcdHID;
106
static int hf_usb_hid_bCountryCode;
107
static int hf_usb_hid_bNumDescriptors;
108
static int hf_usb_hid_bDescriptorIndex;
109
static int hf_usb_hid_bDescriptorType;
110
static int hf_usb_hid_wInterfaceNumber;
111
static int hf_usb_hid_wDescriptorLength;
112
113
static int hf_usbhid_boot_report_keyboard_modifier_right_gui;
114
static int hf_usbhid_boot_report_keyboard_modifier_right_alt;
115
static int hf_usbhid_boot_report_keyboard_modifier_right_shift;
116
static int hf_usbhid_boot_report_keyboard_modifier_right_ctrl;
117
static int hf_usbhid_boot_report_keyboard_modifier_left_gui;
118
static int hf_usbhid_boot_report_keyboard_modifier_left_alt;
119
static int hf_usbhid_boot_report_keyboard_modifier_left_shift;
120
static int hf_usbhid_boot_report_keyboard_modifier_left_ctrl;
121
static int hf_usbhid_boot_report_keyboard_reserved;
122
static int hf_usbhid_boot_report_keyboard_keycode_1;
123
static int hf_usbhid_boot_report_keyboard_keycode_2;
124
static int hf_usbhid_boot_report_keyboard_keycode_3;
125
static int hf_usbhid_boot_report_keyboard_keycode_4;
126
static int hf_usbhid_boot_report_keyboard_keycode_5;
127
static int hf_usbhid_boot_report_keyboard_keycode_6;
128
static int hf_usbhid_boot_report_keyboard_leds_constants;
129
static int hf_usbhid_boot_report_keyboard_leds_kana;
130
static int hf_usbhid_boot_report_keyboard_leds_compose;
131
static int hf_usbhid_boot_report_keyboard_leds_scroll_lock;
132
static int hf_usbhid_boot_report_keyboard_leds_caps_lock;
133
static int hf_usbhid_boot_report_keyboard_leds_num_lock;
134
static int hf_usbhid_boot_report_mouse_button_8;
135
static int hf_usbhid_boot_report_mouse_button_7;
136
static int hf_usbhid_boot_report_mouse_button_6;
137
static int hf_usbhid_boot_report_mouse_button_5;
138
static int hf_usbhid_boot_report_mouse_button_4;
139
static int hf_usbhid_boot_report_mouse_button_middle;
140
static int hf_usbhid_boot_report_mouse_button_right;
141
static int hf_usbhid_boot_report_mouse_button_left;
142
static int hf_usbhid_boot_report_mouse_x_displacement;
143
static int hf_usbhid_boot_report_mouse_y_displacement;
144
static int hf_usbhid_boot_report_mouse_horizontal_scroll_wheel;
145
static int hf_usbhid_boot_report_mouse_vertical_scroll_wheel;
146
static int hf_usbhid_data;
147
static int hf_usbhid_unknown_data;
148
static int hf_usbhid_vendor_data;
149
static int hf_usbhid_report_id;
150
static int hf_usbhid_padding;
151
static int hf_usbhid_axis_x;
152
static int hf_usbhid_axis_y;
153
static int hf_usbhid_axis_z;
154
static int hf_usbhid_axis_rx;
155
static int hf_usbhid_axis_ry;
156
static int hf_usbhid_axis_rz;
157
static int hf_usbhid_axis_slider;
158
static int hf_usbhid_axis_vx;
159
static int hf_usbhid_axis_vy;
160
static int hf_usbhid_axis_vz;
161
static int hf_usbhid_axis_vbrx;
162
static int hf_usbhid_axis_vbry;
163
static int hf_usbhid_axis_vbrz;
164
static int hf_usbhid_axis_vno;
165
static int hf_usbhid_button;
166
static int hf_usbhid_key;
167
static int hf_usbhid_array;
168
static int hf_usbhid_array_usage;
169
170
static const true_false_string tfs_mainitem_bit0 = {"Constant", "Data"};
171
static const true_false_string tfs_mainitem_bit1 = {"Variable", "Array"};
172
static const true_false_string tfs_mainitem_bit2 = {"Relative", "Absolute"};
173
static const true_false_string tfs_mainitem_bit3 = {"Wrap", "No Wrap"};
174
static const true_false_string tfs_mainitem_bit4 = {"Non Linear", "Linear"};
175
static const true_false_string tfs_mainitem_bit5 = {"No Preferred", "Preferred State"};
176
static const true_false_string tfs_mainitem_bit6 = {"Null state", "No Null position"};
177
static const true_false_string tfs_mainitem_bit7 = {"Volatile", "Non Volatile"};
178
static const true_false_string tfs_mainitem_bit8 = {"Buffered Bytes", "Bit Field"};
179
180
181
struct usb_hid_global_state {
182
    unsigned int usage_page;
183
};
184
185
static wmem_tree_t *report_descriptors;
186
187
188
/* local items */
189
0
#define HID_USAGE_MIN       (1 << 0)
190
#define HID_USAGE_MAX       (1 << 1)
191
192
/* global items */
193
0
#define HID_REPORT_ID       (1 << 2)
194
0
#define HID_REPORT_COUNT    (1 << 3)
195
0
#define HID_REPORT_SIZE     (1 << 4)
196
0
#define HID_LOGICAL_MIN     (1 << 5)
197
0
#define HID_LOGICAL_MAX     (1 << 6)
198
0
#define HID_USAGE_PAGE      (1 << 7)
199
200
/* main items */
201
#define HID_INPUT           (1 << 8)
202
#define HID_OUTPUT          (1 << 9)
203
#define HID_FEATURE         (1 << 10)
204
205
0
#define HID_EXTENDED_USAGE  (1 << 11)
206
207
/* masks */
208
209
0
#define HID_GLOBAL_MASK     (HID_REPORT_ID | \
210
0
                             HID_REPORT_COUNT | \
211
0
                             HID_REPORT_SIZE | \
212
0
                             HID_LOGICAL_MIN | \
213
0
                             HID_LOGICAL_MAX | \
214
0
                             HID_USAGE_PAGE)
215
216
0
#define HID_REQUIRED_MASK   (HID_REPORT_COUNT | \
217
0
                             HID_REPORT_SIZE | \
218
0
                             HID_LOGICAL_MIN | \
219
0
                             HID_LOGICAL_MAX)
220
221
222
#define HID_MAIN_CONSTANT       (1 << 0) /* data / constant                 */
223
0
#define HID_MAIN_TYPE           (1 << 1) /* array / variable                */
224
#define HID_MAIN_RELATIVE       (1 << 2) /* absolute / relative             */
225
#define HID_MAIN_WRAP           (1 << 3) /* no wrap / wrap                  */
226
#define HID_MAIN_NON_LINEAR     (1 << 4) /* linear / non linear             */
227
#define HID_MAIN_NO_PREFERRED   (1 << 5) /* preferred state / no preferred  */
228
#define HID_MAIN_NULL_STATE     (1 << 6) /* no null position / null state   */
229
#define HID_MAIN_BUFFERED_BYTES (1 << 8) /* bit field / buffered bytes      */
230
231
232
0
#define HID_MAIN_ARRAY          (0 << 1)
233
#define HID_MAIN_VARIABLE       (1 << 1)
234
235
236
#define HID_USAGE_UNSET         0
237
#define HID_USAGE_SINGLE        1
238
#define HID_USAGE_RANGE         2
239
240
241
0
#define USAGE_ID(usage)    (usage & 0x0000FFFF)
242
0
#define USAGE_PAGE(usage) ((usage & 0xFFFF0000) >> 16)
243
244
typedef struct _hid_field hid_field_t;
245
246
struct _hid_field {
247
    wmem_array_t   *usages;
248
249
    uint32_t        report_id;  /* optional */
250
    uint32_t        report_count;
251
    uint32_t        report_size;
252
    int32_t         logical_min;
253
    int32_t         logical_max;
254
    uint32_t        properties;
255
256
    hid_field_t *next;
257
};
258
259
260
typedef struct _report_descriptor report_descriptor_t;
261
262
struct _report_descriptor {
263
    uint16_t                bus_id;
264
    uint16_t                device_address;
265
    uint8_t                 interface;
266
    uint32_t                frame_num;
267
268
    int                     desc_length;
269
    uint8_t                *desc_body;
270
271
    bool                    uses_report_id;
272
    wmem_array_t           *fields_in;
273
    wmem_array_t           *fields_out;
274
    /* TODO: features */
275
276
    report_descriptor_t    *next;
277
};
278
279
0
#define USBHID_GENERIC_DESKTOP_CONTROLS_X           0x0030
280
0
#define USBHID_GENERIC_DESKTOP_CONTROLS_Y           0x0031
281
0
#define USBHID_GENERIC_DESKTOP_CONTROLS_Z           0x0032
282
0
#define USBHID_GENERIC_DESKTOP_CONTROLS_RX          0x0033
283
0
#define USBHID_GENERIC_DESKTOP_CONTROLS_RY          0x0034
284
0
#define USBHID_GENERIC_DESKTOP_CONTROLS_RZ          0x0035
285
0
#define USBHID_GENERIC_DESKTOP_CONTROLS_SLIDER      0x0036
286
287
0
#define USBHID_GENERIC_DESKTOP_CONTROLS_VX          0x0040
288
0
#define USBHID_GENERIC_DESKTOP_CONTROLS_VY          0x0041
289
0
#define USBHID_GENERIC_DESKTOP_CONTROLS_VZ          0x0042
290
0
#define USBHID_GENERIC_DESKTOP_CONTROLS_VBRX        0x0043
291
0
#define USBHID_GENERIC_DESKTOP_CONTROLS_VBRY        0x0044
292
0
#define USBHID_GENERIC_DESKTOP_CONTROLS_VBRZ        0x0045
293
0
#define USBHID_GENERIC_DESKTOP_CONTROLS_VNO         0x0046
294
295
/* HID class specific descriptor types */
296
0
#define USB_DT_HID        0x21
297
0
#define USB_DT_HID_REPORT 0x22
298
static const value_string hid_descriptor_type_vals[] = {
299
    {USB_DT_HID, "HID"},
300
    {USB_DT_HID_REPORT, "HID Report"},
301
    {0, NULL}
302
};
303
static value_string_ext hid_descriptor_type_vals_ext =
304
               VALUE_STRING_EXT_INIT(hid_descriptor_type_vals);
305
306
307
16
#define USBHID_SIZE_MASK  0x03
308
16
#define USBHID_TYPE_MASK  0x0C
309
64
#define USBHID_TAG_MASK   0xF0
310
311
static const value_string usb_hid_item_bSize_vals[] = {
312
    {0, "0 bytes"},
313
    {1, "1 byte"},
314
    {2, "2 bytes"},
315
    {3, "4 bytes"},
316
    {0, NULL}
317
};
318
319
0
#define USBHID_ITEMTYPE_MAIN    0
320
0
#define USBHID_ITEMTYPE_GLOBAL  1
321
0
#define USBHID_ITEMTYPE_LOCAL   2
322
#define USBHID_ITEMTYPE_LONG    3
323
static const value_string usb_hid_item_bType_vals[] = {
324
    {USBHID_ITEMTYPE_MAIN,   "Main"},
325
    {USBHID_ITEMTYPE_GLOBAL, "Global"},
326
    {USBHID_ITEMTYPE_LOCAL,  "Local"},
327
    {USBHID_ITEMTYPE_LONG,   "Long item"},
328
    {0, NULL}
329
};
330
331
0
#define USBHID_MAINITEM_TAG_INPUT           8
332
0
#define USBHID_MAINITEM_TAG_OUTPUT          9
333
0
#define USBHID_MAINITEM_TAG_FEATURE        11
334
0
#define USBHID_MAINITEM_TAG_COLLECTION     10
335
0
#define USBHID_MAINITEM_TAG_ENDCOLLECTION  12
336
static const value_string usb_hid_mainitem_bTag_vals[] = {
337
    {USBHID_MAINITEM_TAG_INPUT,         "Input"},
338
    {USBHID_MAINITEM_TAG_OUTPUT,        "Output"},
339
    {USBHID_MAINITEM_TAG_FEATURE,       "Feature"},
340
    {USBHID_MAINITEM_TAG_COLLECTION,    "Collection"},
341
    {USBHID_MAINITEM_TAG_ENDCOLLECTION, "End Collection"},
342
    {0, NULL}
343
};
344
0
#define USBHID_GLOBALITEM_TAG_USAGE_PAGE    0
345
0
#define USBHID_GLOBALITEM_TAG_LOG_MIN       1
346
0
#define USBHID_GLOBALITEM_TAG_LOG_MAX       2
347
0
#define USBHID_GLOBALITEM_TAG_PHY_MIN       3
348
0
#define USBHID_GLOBALITEM_TAG_PHY_MAX       4
349
0
#define USBHID_GLOBALITEM_TAG_UNIT_EXP      5
350
0
#define USBHID_GLOBALITEM_TAG_UNIT          6
351
0
#define USBHID_GLOBALITEM_TAG_REPORT_SIZE   7
352
0
#define USBHID_GLOBALITEM_TAG_REPORT_ID     8
353
0
#define USBHID_GLOBALITEM_TAG_REPORT_COUNT  9
354
0
#define USBHID_GLOBALITEM_TAG_PUSH         10
355
0
#define USBHID_GLOBALITEM_TAG_POP          11
356
static const value_string usb_hid_globalitem_bTag_vals[] = {
357
    {USBHID_GLOBALITEM_TAG_USAGE_PAGE,   "Usage Page"},
358
    {USBHID_GLOBALITEM_TAG_LOG_MIN,      "Logical Minimum"},
359
    {USBHID_GLOBALITEM_TAG_LOG_MAX,      "Logical Maximum"},
360
    {USBHID_GLOBALITEM_TAG_PHY_MIN,      "Physical Minimum"},
361
    {USBHID_GLOBALITEM_TAG_PHY_MAX,      "Physical Maximum"},
362
    {USBHID_GLOBALITEM_TAG_UNIT_EXP,     "Unit Exponent"},
363
    {USBHID_GLOBALITEM_TAG_UNIT,         "Unit"},
364
    {USBHID_GLOBALITEM_TAG_REPORT_SIZE,  "Report Size"},
365
    {USBHID_GLOBALITEM_TAG_REPORT_ID,    "Report ID"},
366
    {USBHID_GLOBALITEM_TAG_REPORT_COUNT, "Report Count"},
367
    {USBHID_GLOBALITEM_TAG_PUSH,         "Push"},
368
    {USBHID_GLOBALITEM_TAG_POP,          "Pop"},
369
    {12, "[Reserved]"},
370
    {13, "[Reserved]"},
371
    {14, "[Reserved]"},
372
    {15, "[Reserved]"},
373
    {0, NULL}
374
};
375
0
#define USBHID_LOCALITEM_TAG_USAGE          0
376
0
#define USBHID_LOCALITEM_TAG_USAGE_MIN      1
377
0
#define USBHID_LOCALITEM_TAG_USAGE_MAX      2
378
0
#define USBHID_LOCALITEM_TAG_DESIG_INDEX    3
379
0
#define USBHID_LOCALITEM_TAG_DESIG_MIN      4
380
0
#define USBHID_LOCALITEM_TAG_DESIG_MAX      5
381
/* No 6 in spec */
382
0
#define USBHID_LOCALITEM_TAG_STRING_INDEX   7
383
0
#define USBHID_LOCALITEM_TAG_STRING_MIN     8
384
0
#define USBHID_LOCALITEM_TAG_STRING_MAX     9
385
0
#define USBHID_LOCALITEM_TAG_DELIMITER     10 /* Also listed as reserved in spec! */
386
static const value_string usb_hid_localitem_bTag_vals[] = {
387
    {USBHID_LOCALITEM_TAG_USAGE,        "Usage"},
388
    {USBHID_LOCALITEM_TAG_USAGE_MIN,    "Usage Minimum"},
389
    {USBHID_LOCALITEM_TAG_USAGE_MAX,    "Usage Maximum"},
390
    {USBHID_LOCALITEM_TAG_DESIG_INDEX,  "Designator Index"},
391
    {USBHID_LOCALITEM_TAG_DESIG_MIN,    "Designator Minimum"},
392
    {USBHID_LOCALITEM_TAG_DESIG_MAX,    "Designator Maximum"},
393
    {USBHID_LOCALITEM_TAG_STRING_INDEX, "String Index"},
394
    {USBHID_LOCALITEM_TAG_STRING_MIN,   "String Minimum"},
395
    {USBHID_LOCALITEM_TAG_STRING_MAX,   "String Maximum"},
396
    {USBHID_LOCALITEM_TAG_DELIMITER,    "Delimiter"},
397
    {11, "[Reserved]"},
398
    {12, "[Reserved]"},
399
    {13, "[Reserved]"},
400
    {14, "[Reserved]"},
401
    {15, "[Reserved]"},
402
    {0, NULL}
403
};
404
static const value_string usb_hid_longitem_bTag_vals[] = {
405
    {15, "Long item"},
406
    {0, NULL}
407
};
408
409
static const range_string usb_hid_mainitem_colltype_vals[] = {
410
    {0x00, 0x00, "Physical"},
411
    {0x01, 0x01, "Application"},
412
    {0x02, 0x02, "Logical"},
413
    {0x03, 0x03, "Report"},
414
    {0x04, 0x04, "Named array"},
415
    {0x05, 0x05, "Usage switch"},
416
    {0x06, 0x06, "Usage modifier"},
417
    {0x07, 0x7F, "[Reserved]"},
418
    {0x80, 0xFF, "[Vendor-defined]"},
419
    {0, 0, NULL}
420
};
421
422
static const value_string usb_hid_globalitem_unit_exp_vals[] = {
423
    {0x0, "n^0"},
424
    {0x1, "n^1"},
425
    {0x2, "n^2"},
426
    {0x3, "n^3"},
427
    {0x4, "n^4"},
428
    {0x5, "n^5"},
429
    {0x6, "n^6"},
430
    {0x7, "n^7"},
431
    {0x8, "n^-8"},
432
    {0x9, "n^-7"},
433
    {0xA, "n^-6"},
434
    {0xB, "n^-5"},
435
    {0xC, "n^-4"},
436
    {0xD, "n^-3"},
437
    {0xE, "n^-2"},
438
    {0xF, "n^-1"},
439
    {0, NULL}
440
};
441
442
0
#define GENERIC_DESKTOP_CONTROLS_PAGE   0x01
443
0
#define SIMULATION_CONTROLS_PAGE        0x02
444
0
#define VR_CONTROLS_PAGE                0x03
445
0
#define SPORT_CONTROLS_PAGE             0x04
446
0
#define GAME_CONTROLS_PAGE              0x05
447
0
#define GENERIC_DEVICE_CONTROLS_PAGE    0x06
448
0
#define KEYBOARD_KEYPAD_PAGE            0x07
449
0
#define LED_PAGE                        0x08
450
0
#define BUTTON_PAGE                     0x09
451
0
#define ORDINAL_PAGE                    0x0A
452
0
#define TELEPHONY_PAGE                  0x0B
453
0
#define CONSUMER_PAGE                   0x0C
454
0
#define DIGITIZER_PAGE                  0x0D
455
0
#define HAPTICS_PAGE                    0x0E
456
0
#define PID_PAGE                        0x0F
457
0
#define UNICODE_PAGE                    0x10
458
0
#define SOC_PAGE                        0x11
459
0
#define EYE_AND_HEAD_TRACKER_PAGE       0x12
460
0
#define ALPHANUMERIC_DISPLAY_PAGE       0x14
461
0
#define SENSOR_PAGE                     0x20
462
0
#define MEDICAL_INSTRUMENTS_PAGE        0x40
463
0
#define BRAILLE_DISPLAY_PAGE            0x41
464
0
#define LIGHTING_AND_ILLUMINATION_PAGE  0x59
465
0
#define USB_MONITOR_PAGE                0x80
466
0
#define USB_ENUMERATED_VALUES_PAGE      0x81
467
0
#define VESA_VIRTUAL_CONTROLS_PAGE      0x82
468
0
#define POWER_DEVICE_PAGE               0x84
469
0
#define BATTERY_SYSTEM_PAGE             0x85
470
0
#define BARCODE_SCANNER_PAGE            0x8C
471
0
#define WEIGHING_PAGE                   0x8D
472
0
#define MSR_PAGE                        0x8E
473
#define RESERVED_POS_PAGE               0x8F
474
0
#define CAMERA_CONTROL_PAGE             0x90
475
0
#define ARCADE_PAGE                     0x91
476
#define GAMING_DEVICE_PAGE              0x92
477
0
#define FIDO_ALLIANCE_PAGE              0xF1D0
478
0
#define VENDOR_PAGE_HBYTE               0xFF00
479
static const value_string usb_hid_item_usage_page_vals[] = {
480
    {0x00, "Undefined"},
481
    {GENERIC_DESKTOP_CONTROLS_PAGE,     "Generic Desktop Controls"},
482
    {SIMULATION_CONTROLS_PAGE,          "Simulation Controls"},
483
    {VR_CONTROLS_PAGE,                  "VR Controls"},
484
    {SPORT_CONTROLS_PAGE,               "Sport Controls"},
485
    {GAME_CONTROLS_PAGE,                "Game Controls"},
486
    {GENERIC_DEVICE_CONTROLS_PAGE,      "Generic Device Controls"},
487
    {KEYBOARD_KEYPAD_PAGE,              "Keyboard/Keypad"},
488
    {LED_PAGE,                          "LED"},
489
    {BUTTON_PAGE,                       "Button"},
490
    {ORDINAL_PAGE,                      "Ordinal"},
491
    {TELEPHONY_PAGE,                    "Telephony"},
492
    {CONSUMER_PAGE,                     "Consumer"},
493
    {DIGITIZER_PAGE,                    "Digitizer"},
494
    {HAPTICS_PAGE,                      "Haptics"},
495
    {PID_PAGE,                          "Physical Interface Device (PID)"},
496
    {UNICODE_PAGE,                      "Unicode"},
497
    {SOC_PAGE,                          "System-on-Chip"},
498
    {EYE_AND_HEAD_TRACKER_PAGE,         "Eye and Head Tracker"},
499
    {ALPHANUMERIC_DISPLAY_PAGE,         "Alphanumeric Display"},
500
    {SENSOR_PAGE,                       "Sensor"},
501
    {MEDICAL_INSTRUMENTS_PAGE,          "Medical Instruments"},
502
    {BRAILLE_DISPLAY_PAGE,              "Braille Display"},
503
    {LIGHTING_AND_ILLUMINATION_PAGE,    "Lighting and Illumination"},
504
    {USB_MONITOR_PAGE,                  "USB Monitor"},
505
    {USB_ENUMERATED_VALUES_PAGE,        "USB Enumerated Values"},
506
    {VESA_VIRTUAL_CONTROLS_PAGE,        "VESA Virtual Controls"},
507
    {POWER_DEVICE_PAGE,                 "Power Device"},
508
    {BATTERY_SYSTEM_PAGE,               "Battery Device"},
509
    {BARCODE_SCANNER_PAGE,              "Barcode Scanner"},
510
    {WEIGHING_PAGE,                     "Weighing"},
511
    {MSR_PAGE,                          "Magnetic Stripe Reading (MSR) Devices"},
512
    {RESERVED_POS_PAGE,                 "[Reserved Point of Sale page]"},
513
    {CAMERA_CONTROL_PAGE,               "Camera Control Page"},
514
    {ARCADE_PAGE,                       "Arcade"},
515
    {GAMING_DEVICE_PAGE,                "Gaming Device"},
516
    {FIDO_ALLIANCE_PAGE ,               "FIDO Alliance"},
517
    {0, NULL}
518
};
519
520
static const value_string usb_hid_generic_desktop_controls_usage_page_vals[] = {
521
    {0x00, "Undefined"},
522
    {0x01, "Pointer"},
523
    {0x02, "Mouse"},
524
    {0x04, "Joystick"},
525
    {0x05, "Game Pad"},
526
    {0x06, "Keyboard"},
527
    {0x07, "Keypad"},
528
    {0x08, "Multi-axis Controller"},
529
    {0x09, "Tablet PC System Controls"},
530
    {0x0A, "Water Cooling Device"},
531
    {0x0B, "Computer Chassis Device"},
532
    {0x0C, "Wireless Radio Controls"},
533
    {0x0D, "Portable Device Control"},
534
    {0x0E, "System Multi-Axis Controller"},
535
    {0x0F, "Spatial Controller"},
536
    {0x10, "Assistive Control"},
537
    {0x11, "Device Dock"},
538
    {0x12, "Dockable Device"},
539
    {0x13, "Call State Management Control"},
540
    {0x30, "X"},
541
    {0x31, "Y"},
542
    {0x32, "Z"},
543
    {0x33, "Rx"},
544
    {0x34, "Ry"},
545
    {0x35, "Rz"},
546
    {0x36, "Slider"},
547
    {0x37, "Dial"},
548
    {0x38, "Wheel"},
549
    {0x39, "Hat switch"},
550
    {0x3A, "Counted Buffer"},
551
    {0x3B, "Byte Count"},
552
    {0x3C, "Motion Wakeup"},
553
    {0x3D, "Start"},
554
    {0x3E, "Select"},
555
    {0x40, "Vx"},
556
    {0x41, "Vy"},
557
    {0x42, "Vz"},
558
    {0x43, "Vbrx"},
559
    {0x44, "Vbry"},
560
    {0x45, "Vbrz"},
561
    {0x46, "Vno"},
562
    {0x47, "Feature Notification"},
563
    {0x48, "Resolution Multiplier"},
564
    {0x49, "Qx"},
565
    {0x4A, "Qy"},
566
    {0x4B, "Qz"},
567
    {0x4C, "Qw"},
568
    {0x80, "System Control"},
569
    {0x81, "System Power Down"},
570
    {0x82, "System Sleep"},
571
    {0x83, "System Wake Up"},
572
    {0x84, "System Context Menu"},
573
    {0x85, "System Main Menu"},
574
    {0x86, "System App Menu"},
575
    {0x87, "System Menu Help"},
576
    {0x88, "System Menu Exit"},
577
    {0x89, "System Menu Select"},
578
    {0x8A, "System Menu Right"},
579
    {0x8B, "System Menu Left"},
580
    {0x8C, "System Menu Up"},
581
    {0x8D, "System Menu Down"},
582
    {0x8E, "System Cold Restart"},
583
    {0x8F, "System Warm Restart"},
584
    {0x90, "D-pad Up"},
585
    {0x91, "D-pad Down"},
586
    {0x92, "D-pad Right"},
587
    {0x93, "D-pad Left"},
588
    {0x94, "Index Trigger"},
589
    {0x95, "Palm Trigger"},
590
    {0x96, "Thumbstick"},
591
    {0x97, "System Function Shift"},
592
    {0x98, "System Function Shift Lock"},
593
    {0x99, "System Function Shift Lock Indicator"},
594
    {0x9A, "System Dismiss Notification"},
595
    {0x9B, "System Do Not Disturb"},
596
    {0xA0, "System Dock"},
597
    {0xA1, "System Undock"},
598
    {0xA2, "System Setup"},
599
    {0xA3, "System Break"},
600
    {0xA4, "System Debugger Break"},
601
    {0xA5, "Application Break"},
602
    {0xA6, "Application Debugger Break"},
603
    {0xA7, "System Speaker Mute"},
604
    {0xA8, "System Hibernate"},
605
    {0xA9, "System Microphone Mute"},
606
    {0xB0, "System Display Invert"},
607
    {0xB1, "System Display Internal"},
608
    {0xB2, "System Display External"},
609
    {0xB3, "System Display Both"},
610
    {0xB4, "System Display Dual"},
611
    {0xB5, "System Display Toggle Int/Ext"},
612
    {0xB6, "System Display Swap Primary/Secondary"},
613
    {0xB7, "System Display LCD Autoscale"},
614
    {0xC0, "Sensor Zone"},
615
    {0xC1, "RPM"},
616
    {0xC2, "Coolant Level"},
617
    {0xC3, "Coolant Critical Level"},
618
    {0xC4, "Coolant Pump"},
619
    {0xC5, "Chassis Enclosure"},
620
    {0xC6, "Wireless Radio Button"},
621
    {0xC7, "Wireless Radio LED"},
622
    {0xC8, "Wireless Radio Slider Switch"},
623
    {0xC9, "System Display Rotation Lock Button"},
624
    {0xCA, "System Display Rotation Lock Slider Switch"},
625
    {0xCB, "Control Enable"},
626
    {0xD0, "Dockable Device Unique ID"},
627
    {0xD1, "Dockable Device Vendor ID"},
628
    {0xD2, "Dockable Device Primary Usage Page"},
629
    {0xD3, "Dockable Device Primary Usage ID"},
630
    {0xD4, "Dockable Device Docking State"},
631
    {0xD5, "Dockable Device Display Occlusion"},
632
    {0xD6, "Dockable Device Object Type"},
633
    {0xE0, "Call Active LED"},
634
    {0xE1, "Call Mute Toggle"},
635
    {0xE2, "Call Mute LED"},
636
    {0, NULL}
637
};
638
static const value_string usb_hid_simulation_control_usage_page_vals[] = {
639
    {0x00, "Undefined"},
640
    {0x01, "Flight Simulation Device"},
641
    {0x02, "Automobile Simulation Device"},
642
    {0x03, "Tank Simulation Device"},
643
    {0x04, "Spaceship Simulation Device"},
644
    {0x05, "Submarine Simulation Device"},
645
    {0x06, "Sailing Simulation Device"},
646
    {0x07, "Motorcycle Simulation Device"},
647
    {0x08, "Sports Simulation Device"},
648
    {0x09, "Airplane Simulation Device"},
649
    {0x0A, "Helicopter Simulation Device"},
650
    {0x0B, "Magic Carpet Simulation Device"},
651
    {0x0C, "Bicycle Simulation Device"},
652
    {0x20, "Flight Control Stick"},
653
    {0x21, "Flight Stick"},
654
    {0x22, "Cyclic Control"},
655
    {0x23, "Cyclic Trim"},
656
    {0x24, "Flight Yoke"},
657
    {0x25, "Track Control"},
658
    {0xB0, "Aileron"},
659
    {0xB1, "Aileron Trim"},
660
    {0xB2, "Anti-Torque Control"},
661
    {0xB3, "Autopilot Enable"},
662
    {0xB4, "Chaff Release"},
663
    {0xB5, "Collective Control"},
664
    {0xB6, "Dive Brake"},
665
    {0xB7, "Electronic Countermeasures"},
666
    {0xB8, "Elevator"},
667
    {0xB9, "Elevator Trim"},
668
    {0xBA, "Rudder"},
669
    {0xBB, "Throttle"},
670
    {0xBC, "Flight Communications"},
671
    {0xBD, "Flare Release"},
672
    {0xBE, "Landing Gear"},
673
    {0xBF, "Toe Brake"},
674
    {0xC0, "Trigger"},
675
    {0xC1, "Weapons Arm"},
676
    {0xC2, "Weapons Select"},
677
    {0xC3, "Wing Flaps"},
678
    {0xC4, "Accelerator"},
679
    {0xC5, "Brake"},
680
    {0xC6, "Clutch"},
681
    {0xC7, "Shifter"},
682
    {0xC8, "Steering"},
683
    {0xC9, "Turret Direction"},
684
    {0xCA, "Barrel Elevation"},
685
    {0xCB, "Dive Plane"},
686
    {0xCC, "Ballast"},
687
    {0xCD, "Bicycle Crank"},
688
    {0xCE, "Handle Bars"},
689
    {0xCF, "Front Brake"},
690
    {0xD0, "Rear Brake"},
691
    {0, NULL}
692
};
693
static const value_string usb_hid_vr_controls_usage_page_vals[] = {
694
    {0x00, "Undefined"},
695
    {0x01, "Belt"},
696
    {0x02, "Body Suit"},
697
    {0x03, "Flexor"},
698
    {0x04, "Glove"},
699
    {0x05, "Head Tracker"},
700
    {0x06, "Head Mounted Display"},
701
    {0x07, "Hand Tracker"},
702
    {0x08, "Oculometer"},
703
    {0x09, "Vest"},
704
    {0x0A, "Animatronic Device"},
705
    {0x20, "Stereo Enable"},
706
    {0x21, "Display Enable"},
707
    {0, NULL}
708
};
709
static const value_string usb_hid_sport_controls_usage_page_vals[] = {
710
    {0x00, "Undefined"},
711
    {0x01, "Baseball Bat"},
712
    {0x02, "Golf Club"},
713
    {0x03, "Rowing Machine"},
714
    {0x04, "Treadmill"},
715
    {0x30, "Oar"},
716
    {0x31, "Slope"},
717
    {0x32, "Rate"},
718
    {0x33, "Stick Speed"},
719
    {0x34, "Stick Face Angle"},
720
    {0x35, "Stick Heel/Toe"},
721
    {0x36, "Stick Follow Through"},
722
    {0x37, "Stick Tempo"},
723
    {0x38, "Stick Type"},
724
    {0x39, "Stick Height"},
725
    {0x50, "Putter"},
726
    {0x51, "1 Iron"},
727
    {0x52, "2 Iron"},
728
    {0x53, "3 Iron"},
729
    {0x54, "4 Iron"},
730
    {0x55, "5 Iron"},
731
    {0x56, "6 Iron"},
732
    {0x57, "7 Iron"},
733
    {0x58, "8 Iron"},
734
    {0x59, "9 Iron"},
735
    {0x5A, "10 Iron"},
736
    {0x5B, "11 Iron"},
737
    {0x5C, "Sand Wedge"},
738
    {0x5D, "Loft Wedge"},
739
    {0x5E, "Power Wedge"},
740
    {0x5F, "1 Wood"},
741
    {0x60, "3 Wood"},
742
    {0x61, "5 Wood"},
743
    {0x62, "7 Wood"},
744
    {0x63, "9 Wood"},
745
    {0, NULL}
746
};
747
static const value_string usb_hid_game_controls_usage_page_vals[] = {
748
    {0x00, "Undefined"},
749
    {0x01, "3D Game Controller"},
750
    {0x02, "Pinball Device"},
751
    {0x03, "Gun Device"},
752
    {0x20, "Point of View"},
753
    {0x21, "Turn Right/Left"},
754
    {0x22, "Pitch Forward/Backward"},
755
    {0x23, "Roll Right/Left"},
756
    {0x24, "Move Right/Left"},
757
    {0x25, "Move Forward/Backward"},
758
    {0x26, "Move Up/Down"},
759
    {0x27, "Lean Right/Left"},
760
    {0x28, "Lean Forward/Backward"},
761
    {0x29, "Height of POV"},
762
    {0x2A, "Flipper"},
763
    {0x2B, "Secondary Flipper"},
764
    {0x2C, "Bump"},
765
    {0x2D, "New Game"},
766
    {0x2E, "Shoot Ball"},
767
    {0x2F, "Player"},
768
    {0x30, "Gun Bolt"},
769
    {0x31, "Gun Clip"},
770
    {0x32, "Gun Selector"},
771
    {0x33, "Gun Single Shot"},
772
    {0x34, "Gun Burst"},
773
    {0x35, "Gun Automatic"},
774
    {0x36, "Gun Safety"},
775
    {0x37, "Gamepad Fire/Jump"},
776
    {0x39, "Gamepad Trigger"},
777
    {0x3A, "Form-fitting Gamepad"},
778
    {0, NULL}
779
};
780
static const value_string usb_hid_generic_device_controls_usage_page_vals[] = {
781
    {0x00, "Undefined"},
782
    {0x01, "Background/Nonuser Controls"},
783
    {0x20, "Battery Strength"},
784
    {0x21, "Wireless Channel"},
785
    {0x22, "Wireless ID"},
786
    {0x23, "Discover Wireless Control"},
787
    {0x24, "Security Code Character Entered"},
788
    {0x25, "Security Code Character Erased"},
789
    {0x26, "Security Code Cleared"},
790
    {0x27, "Sequence ID"},
791
    {0x28, "Sequence ID Reset"},
792
    {0x29, "RF Signal Strength"},
793
    {0x2A, "Software Version"},
794
    {0x2B, "Protocol Version"},
795
    {0x2C, "Hardware Version"},
796
    {0x2D, "Major"},
797
    {0x2E, "Minor"},
798
    {0x2F, "Revision"},
799
    {0x30, "Handedness"},
800
    {0x31, "Either Hand"},
801
    {0x32, "Left Hand"},
802
    {0x33, "Right Hand"},
803
    {0x34, "Both Hands"},
804
    {0x40, "Grip Pose Offset"},
805
    {0x41, "Pointer Pose Offset"},
806
    {0, NULL}
807
};
808
static const value_string usb_hid_keyboard_keypad_usage_page_vals[] = {
809
    {0x00, "Reserved (no event indicated)"},
810
    {0x01, "Keyboard ErrorRollOver"},
811
    {0x02, "Keyboard POSTFail"},
812
    {0x03, "Keyboard ErrorUndefined"},
813
    {0x04, "Keyboard a and A"},
814
    {0x05, "Keyboard b and B"},
815
    {0x06, "Keyboard c and C"},
816
    {0x07, "Keyboard d and D"},
817
    {0x08, "Keyboard e and E"},
818
    {0x09, "Keyboard f and F"},
819
    {0x0A, "Keyboard g and G"},
820
    {0x0B, "Keyboard h and H"},
821
    {0x0C, "Keyboard i and I"},
822
    {0x0D, "Keyboard j and J"},
823
    {0x0E, "Keyboard k and K"},
824
    {0x0F, "Keyboard l and L"},
825
    {0x10, "Keyboard m and M"},
826
    {0x11, "Keyboard n and N"},
827
    {0x12, "Keyboard o and O"},
828
    {0x13, "Keyboard p and P"},
829
    {0x14, "Keyboard q and Q"},
830
    {0x15, "Keyboard r and R"},
831
    {0x16, "Keyboard s and S"},
832
    {0x17, "Keyboard t and T"},
833
    {0x18, "Keyboard u and U"},
834
    {0x19, "Keyboard v and V"},
835
    {0x1A, "Keyboard w and W"},
836
    {0x1B, "Keyboard x and X"},
837
    {0x1C, "Keyboard y and Y"},
838
    {0x1D, "Keyboard z and Z"},
839
    {0x1E, "Keyboard 1 and !"},
840
    {0x1F, "Keyboard 2 and @"},
841
    {0x20, "Keyboard 3 and #"},
842
    {0x21, "Keyboard 4 and $"},
843
    {0x22, "Keyboard 5 and %"},
844
    {0x23, "Keyboard 6 and ^"},
845
    {0x24, "Keyboard 7 and &"},
846
    {0x25, "Keyboard 8 and *"},
847
    {0x26, "Keyboard 9 and ("},
848
    {0x27, "Keyboard 0 and )"},
849
    {0x28, "Keyboard Return (ENTER)"},
850
    {0x29, "Keyboard ESCAPE"},
851
    {0x2A, "Keyboard DELETE (Backspace)"},
852
    {0x2B, "Keyboard Tab"},
853
    {0x2C, "Keyboard Spacebar"},
854
    {0x2D, "Keyboard - and (underscore)"},
855
    {0x2E, "Keyboard = and +"},
856
    {0x2F, "Keyboard [ and {"},
857
    {0x30, "Keyboard ] and }"},
858
    {0x31, "Keyboard \\ and |"},
859
    {0x32, "Keyboard Non-US # and ~"},
860
    {0x33, "Keyboard ; and :"},
861
    {0x34, "Keyboard ' and \""},
862
    {0x35, "Keyboard Grave Accent and Tilde"},
863
    {0x36, "Keyboard , and <"},
864
    {0x37, "Keyboard . and >"},
865
    {0x38, "Keyboard / and ?"},
866
    {0x39, "Keyboard Caps Lock"},
867
    {0x3A, "Keyboard F1"},
868
    {0x3B, "Keyboard F2"},
869
    {0x3C, "Keyboard F3"},
870
    {0x3D, "Keyboard F4"},
871
    {0x3E, "Keyboard F5"},
872
    {0x3F, "Keyboard F6"},
873
    {0x40, "Keyboard F7"},
874
    {0x41, "Keyboard F8"},
875
    {0x42, "Keyboard F9"},
876
    {0x43, "Keyboard F10"},
877
    {0x44, "Keyboard F11"},
878
    {0x45, "Keyboard F12"},
879
    {0x46, "Keyboard PrintScreen"},
880
    {0x47, "Keyboard Scroll Lock"},
881
    {0x48, "Keyboard Pause"},
882
    {0x49, "Keyboard Insert"},
883
    {0x4A, "Keyboard Home"},
884
    {0x4B, "Keyboard PageUp"},
885
    {0x4C, "Keyboard Delete Forward"},
886
    {0x4D, "Keyboard End"},
887
    {0x4E, "Keyboard PageDown"},
888
    {0x4F, "Keyboard RightArrow"},
889
    {0x50, "Keyboard LeftArrow"},
890
    {0x51, "Keyboard DownArrow"},
891
    {0x52, "Keyboard UpArrow"},
892
    {0x53, "Keypad Num Lock and Clear"},
893
    {0x54, "Keypad /"},
894
    {0x55, "Keypad *"},
895
    {0x56, "Keypad -"},
896
    {0x57, "Keypad +"},
897
    {0x58, "Keypad ENTER"},
898
    {0x59, "Keypad 1 and End"},
899
    {0x5A, "Keypad 2 and Down Arrow"},
900
    {0x5B, "Keypad 3 and PageDn"},
901
    {0x5C, "Keypad 4 and Left Arrow"},
902
    {0x5D, "Keypad 5"},
903
    {0x5E, "Keypad 6 and Right Arrow"},
904
    {0x5F, "Keypad 7 and Home"},
905
    {0x60, "Keypad 8 and Up Arrow"},
906
    {0x61, "Keypad 9 and PageUp"},
907
    {0x62, "Keypad 0 and Insert"},
908
    {0x63, "Keypad . and Delete"},
909
    {0x64, "Keyboard Non-US \\ and |"},
910
    {0x65, "Keyboard Application"},
911
    {0x66, "Keyboard Power"},
912
    {0x67, "Keypad ="},
913
    {0x68, "Keyboard F13"},
914
    {0x69, "Keyboard F14"},
915
    {0x6A, "Keyboard F15"},
916
    {0x6B, "Keyboard F16"},
917
    {0x6C, "Keyboard F17"},
918
    {0x6D, "Keyboard F18"},
919
    {0x6E, "Keyboard F19"},
920
    {0x6F, "Keyboard F20"},
921
    {0x70, "Keyboard F21"},
922
    {0x71, "Keyboard F22"},
923
    {0x72, "Keyboard F23"},
924
    {0x73, "Keyboard F24"},
925
    {0x74, "Keyboard Execute"},
926
    {0x75, "Keyboard Help"},
927
    {0x76, "Keyboard Menu"},
928
    {0x77, "Keyboard Select"},
929
    {0x78, "Keyboard Stop"},
930
    {0x79, "Keyboard Again"},
931
    {0x7A, "Keyboard Undo"},
932
    {0x7B, "Keyboard Cut"},
933
    {0x7C, "Keyboard Copy"},
934
    {0x7D, "Keyboard Paste"},
935
    {0x7E, "Keyboard Find"},
936
    {0x7F, "Keyboard Mute"},
937
    {0x80, "Keyboard Volume Up"},
938
    {0x81, "Keyboard Volume Down"},
939
    {0x82, "Keyboard Locking Caps Lock"},
940
    {0x83, "Keyboard Locking Num Lock"},
941
    {0x84, "Keyboard Locking Scroll Lock"},
942
    {0x85, "Keypad Comma"},
943
    {0x86, "Keypad Equal Sign"},
944
    {0x87, "Keyboard International1"},
945
    {0x88, "Keyboard International2"},
946
    {0x89, "Keyboard International3"},
947
    {0x8A, "Keyboard International4"},
948
    {0x8B, "Keyboard International5"},
949
    {0x8C, "Keyboard International6"},
950
    {0x8D, "Keyboard International7"},
951
    {0x8E, "Keyboard International8"},
952
    {0x8F, "Keyboard International9"},
953
    {0x90, "Keyboard LANG1"},
954
    {0x91, "Keyboard LANG2"},
955
    {0x92, "Keyboard LANG3"},
956
    {0x93, "Keyboard LANG4"},
957
    {0x94, "Keyboard LANG5"},
958
    {0x95, "Keyboard LANG6"},
959
    {0x96, "Keyboard LANG7"},
960
    {0x97, "Keyboard LANG8"},
961
    {0x98, "Keyboard LANG9"},
962
    {0x99, "Keyboard Alternate Erase"},
963
    {0x9A, "Keyboard SysReq/Attention"},
964
    {0x9B, "Keyboard Cancel"},
965
    {0x9C, "Keyboard Clear"},
966
    {0x9D, "Keyboard Prior"},
967
    {0x9E, "Keyboard Return"},
968
    {0x9F, "Keyboard Separator"},
969
    {0xA0, "Keyboard Out"},
970
    {0xA1, "Keyboard Oper"},
971
    {0xA2, "Keyboard Clear/Again"},
972
    {0xA3, "Keyboard CrSel/Props"},
973
    {0xA4, "Keyboard ExSel"},
974
    {0xB0, "Keypad 00"},
975
    {0xB1, "Keypad 000"},
976
    {0xB2, "Thousands Separator"},
977
    {0xB3, "Decimal Separator"},
978
    {0xB4, "Currency Unit"},
979
    {0xB5, "Currency Sub-unit"},
980
    {0xB6, "Keypad ("},
981
    {0xB7, "Keypad )"},
982
    {0xB8, "Keypad {"},
983
    {0xB9, "Keypad }"},
984
    {0xBA, "Keypad Tab"},
985
    {0xBB, "Keypad Backspace"},
986
    {0xBC, "Keypad A"},
987
    {0xBD, "Keypad B"},
988
    {0xBE, "Keypad C"},
989
    {0xBF, "Keypad D"},
990
    {0xC0, "Keypad E"},
991
    {0xC1, "Keypad F"},
992
    {0xC2, "Keypad XOR"},
993
    {0xC3, "Keypad ^"},
994
    {0xC4, "Keypad %"},
995
    {0xC5, "Keypad <"},
996
    {0xC6, "Keypad >"},
997
    {0xC7, "Keypad &"},
998
    {0xC8, "Keypad &&"},
999
    {0xC9, "Keypad |"},
1000
    {0xCA, "Keypad ||"},
1001
    {0xCB, "Keypad :"},
1002
    {0xCC, "Keypad #"},
1003
    {0xCD, "Keypad Space"},
1004
    {0xCE, "Keypad @"},
1005
    {0xCF, "Keypad !"},
1006
    {0xD0, "Keypad Memory Store"},
1007
    {0xD1, "Keypad Memory Recall"},
1008
    {0xD2, "Keypad Memory Clear"},
1009
    {0xD3, "Keypad Memory Add"},
1010
    {0xD4, "Keypad Memory Subtract"},
1011
    {0xD5, "Keypad Memory Multiply"},
1012
    {0xD6, "Keypad Memory Divide"},
1013
    {0xD7, "Keypad +/-"},
1014
    {0xD8, "Keypad Clear"},
1015
    {0xD9, "Keypad Clear Entry"},
1016
    {0xDA, "Keypad Binary"},
1017
    {0xDB, "Keypad Octal"},
1018
    {0xDC, "Keypad Decimal"},
1019
    {0xDD, "Keypad Hexadecimal"},
1020
    {0xE0, "Keyboard LeftControl"},
1021
    {0xE1, "Keyboard LeftShift"},
1022
    {0xE2, "Keyboard LeftAlt"},
1023
    {0xE3, "Keyboard Left GUI"},
1024
    {0xE4, "Keyboard RightControl"},
1025
    {0xE5, "Keyboard RightShift"},
1026
    {0xE6, "Keyboard RightAlt"},
1027
    {0xE7, "Keyboard Right GUI"},
1028
    {0, NULL}
1029
};
1030
static const value_string usb_hid_led_usage_page_vals[] = {
1031
    {0x00, "Undefined"},
1032
    {0x01, "Num Lock"},
1033
    {0x02, "Caps Lock"},
1034
    {0x03, "Scroll Lock"},
1035
    {0x04, "Compose"},
1036
    {0x05, "Kana"},
1037
    {0x06, "Power"},
1038
    {0x07, "Shift"},
1039
    {0x08, "Do Not Disturb"},
1040
    {0x09, "Mute"},
1041
    {0x0A, "Tone Enable"},
1042
    {0x0B, "High Cut Filter"},
1043
    {0x0C, "Low Cut Filter"},
1044
    {0x0D, "Equalizer Enable"},
1045
    {0x0E, "Sound Field On"},
1046
    {0x0F, "Surround On"},
1047
    {0x10, "Repeat"},
1048
    {0x11, "Stereo"},
1049
    {0x12, "Sampling Rate Detect"},
1050
    {0x13, "Spinning"},
1051
    {0x14, "CAV"},
1052
    {0x15, "CLV"},
1053
    {0x16, "Recording Format Detect"},
1054
    {0x17, "Off-Hook"},
1055
    {0x18, "Ring"},
1056
    {0x19, "Message Waiting"},
1057
    {0x1A, "Data Mode"},
1058
    {0x1B, "Battery Operation"},
1059
    {0x1C, "Battery OK"},
1060
    {0x1D, "Battery Low"},
1061
    {0x1E, "Speaker"},
1062
    {0x1F, "Head Set"},
1063
    {0x20, "Hold"},
1064
    {0x21, "Microphone"},
1065
    {0x22, "Coverage"},
1066
    {0x23, "Night Mode"},
1067
    {0x24, "Send Calls"},
1068
    {0x25, "Call Pickup"},
1069
    {0x26, "Conference"},
1070
    {0x27, "Stand-by"},
1071
    {0x28, "Camera On"},
1072
    {0x29, "Camera Off"},
1073
    {0x2A, "On-Line"},
1074
    {0x2B, "Off-Line"},
1075
    {0x2C, "Busy"},
1076
    {0x2D, "Ready"},
1077
    {0x2E, "Paper-Out"},
1078
    {0x2F, "Paper-Jam"},
1079
    {0x30, "Remote"},
1080
    {0x31, "Forward"},
1081
    {0x32, "Reverse"},
1082
    {0x33, "Stop"},
1083
    {0x34, "Rewind"},
1084
    {0x35, "Fast Forward"},
1085
    {0x36, "Play"},
1086
    {0x37, "Pause"},
1087
    {0x38, "Record"},
1088
    {0x39, "Error"},
1089
    {0x3A, "Usage Selected Indicator"},
1090
    {0x3B, "Usage In Use Indicator"},
1091
    {0x3C, "Usage Multi Mode Indicator"},
1092
    {0x3D, "Indicator On"},
1093
    {0x3E, "Indicator Flash"},
1094
    {0x3F, "Indicator Slow Blink"},
1095
    {0x40, "Indicator Fast Blink"},
1096
    {0x41, "Indicator Off"},
1097
    {0x42, "Flash On Time"},
1098
    {0x43, "Slow Blink On Time"},
1099
    {0x44, "Slow Blink Off Time"},
1100
    {0x45, "Fast Blink On Time"},
1101
    {0x46, "Fast Blink Off Time"},
1102
    {0x47, "Usage Indicator Color"},
1103
    {0x48, "Indicator Red"},
1104
    {0x49, "Indicator Green"},
1105
    {0x4A, "Indicator Amber"},
1106
    {0x4B, "Generic Indicator"},
1107
    {0x4C, "System Suspend"},
1108
    {0x4D, "External Power Connected"},
1109
    {0x4E, "Indicator Blue"},
1110
    {0x4F, "Indicator Orange"},
1111
    {0x50, "Good Status"},
1112
    {0x51, "Warning Status"},
1113
    {0x52, "RGB LED"},
1114
    {0x53, "Red LED Channel"},
1115
    {0x54, "Blue LED Channel"},
1116
    {0x55, "Green LED Channel"},
1117
    {0x56, "LED Intensity"},
1118
    {0x57, "System Microphone Mute"},
1119
    {0x60, "Player Indicator"},
1120
    {0x61, "Player 1"},
1121
    {0x62, "Player 2"},
1122
    {0x63, "Player 3"},
1123
    {0x64, "Player 4"},
1124
    {0x65, "Player 5"},
1125
    {0x66, "Player 6"},
1126
    {0x67, "Player 7"},
1127
    {0x68, "Player 8"},
1128
    {0, NULL}
1129
};
1130
static const value_string usb_hid_button_usage_page_vals[] = {
1131
    {0x00, "No button pressed"},
1132
    {0x01, "Button 1 (primary/trigger)"},
1133
    {0x02, "Button 2 (secondary)"},
1134
    {0x03, "Button 3 (tertiary)"},
1135
    /* Other Buttons parsed as "Button %u" in get_usage_page_item_string */
1136
    {0, NULL}
1137
};
1138
static const value_string usb_hid_ordinal_usage_page_vals[] = {
1139
    {0x00, "Reserved"},
1140
    /* Instances parsed as "Instance %u" in get_usage_page_item_string */
1141
    {0, NULL}
1142
};
1143
static const value_string usb_hid_telephony_device_usage_page_vals[] = {
1144
    {0x000, "Undefined"},
1145
    {0x001, "Phone"},
1146
    {0x002, "Answering Machine"},
1147
    {0x003, "Message Controls"},
1148
    {0x004, "Handset"},
1149
    {0x005, "Headset"},
1150
    {0x006, "Telephony Key Pad"},
1151
    {0x007, "Programmable Button"},
1152
    {0x020, "Hook Switch"},
1153
    {0x021, "Flash"},
1154
    {0x022, "Feature"},
1155
    {0x023, "Hold"},
1156
    {0x024, "Redial"},
1157
    {0x025, "Transfer"},
1158
    {0x026, "Drop"},
1159
    {0x027, "Park"},
1160
    {0x028, "Forward Calls"},
1161
    {0x029, "Alternate Function"},
1162
    {0x02A, "Line"},
1163
    {0x02B, "Speaker Phone"},
1164
    {0x02C, "Conference"},
1165
    {0x02D, "Ring Enable"},
1166
    {0x02E, "Ring Select"},
1167
    {0x02F, "Phone Mute"},
1168
    {0x030, "Caller ID"},
1169
    {0x031, "Send"},
1170
    {0x050, "Speed Dial"},
1171
    {0x051, "Store Number"},
1172
    {0x052, "Recall Number"},
1173
    {0x053, "Phone Directory"},
1174
    {0x070, "Voice Mail"},
1175
    {0x071, "Screen Calls"},
1176
    {0x072, "Do Not Disturb"},
1177
    {0x073, "Message"},
1178
    {0x074, "Answer On/Off"},
1179
    {0x090, "Inside Dial Tone"},
1180
    {0x091, "Outside Dial Tone"},
1181
    {0x092, "Inside Ring Tone"},
1182
    {0x093, "Outside Ring Tone"},
1183
    {0x094, "Priority Ring Tone"},
1184
    {0x095, "Inside Ringback"},
1185
    {0x096, "Priority Ringback"},
1186
    {0x097, "Line Busy Tone"},
1187
    {0x098, "Reorder Tone"},
1188
    {0x099, "Call Waiting Tone"},
1189
    {0x09A, "Confirmation Tone 1"},
1190
    {0x09B, "Confirmation Tone 2"},
1191
    {0x09C, "Tones Off"},
1192
    {0x09D, "Outside Ringback"},
1193
    {0x09E, "Ringer"},
1194
    {0x0B0, "Phone Key 0"},
1195
    {0x0B1, "Phone Key 1"},
1196
    {0x0B2, "Phone Key 2"},
1197
    {0x0B3, "Phone Key 3"},
1198
    {0x0B4, "Phone Key 4"},
1199
    {0x0B5, "Phone Key 5"},
1200
    {0x0B6, "Phone Key 6"},
1201
    {0x0B7, "Phone Key 7"},
1202
    {0x0B8, "Phone Key 8"},
1203
    {0x0B9, "Phone Key 9"},
1204
    {0x0BA, "Phone Key Star"},
1205
    {0x0BB, "Phone Key Pound"},
1206
    {0x0BC, "Phone Key A"},
1207
    {0x0BD, "Phone Key B"},
1208
    {0x0BE, "Phone Key C"},
1209
    {0x0BF, "Phone Key D"},
1210
    {0x0C0, "Phone Call History Key"},
1211
    {0x0C1, "Phone Caller ID Key"},
1212
    {0x0C2, "Phone Settings Key"},
1213
    {0x0F0, "Host Control"},
1214
    {0x0F1, "Host Available"},
1215
    {0x0F2, "Host Call Active"},
1216
    {0x0F3, "Activate Handset Audio"},
1217
    {0x0F4, "Ring Type"},
1218
    {0x0F5, "Re-dialable Phone Number"},
1219
    {0x0F8, "Stop Ring Tone"},
1220
    {0x0F9, "PSTN Ring Tone"},
1221
    {0x0FA, "Host Ring Tone"},
1222
    {0x0FB, "Alert Sound Error"},
1223
    {0x0FC, "Alert Sound Confirm"},
1224
    {0x0FD, "Alert Sound Notification"},
1225
    {0x0FE, "Silent Ring"},
1226
    {0x108, "Email Message Waiting"},
1227
    {0x109, "Voicemail Message Waiting"},
1228
    {0x10A, "Host Hold"},
1229
    {0x110, "Incoming Call History Count"},
1230
    {0x111, "Outgoing Call History Count"},
1231
    {0x112, "Incoming Call History"},
1232
    {0x113, "Outgoing Call History"},
1233
    {0x114, "Phone Locale"},
1234
    {0x140, "Phone Time Second"},
1235
    {0x141, "Phone Time Minute"},
1236
    {0x142, "Phone Time Hour"},
1237
    {0x143, "Phone Date Day"},
1238
    {0x144, "Phone Date Month"},
1239
    {0x145, "Phone Date Year"},
1240
    {0x146, "Handset Nickname"},
1241
    {0x147, "Address Book ID"},
1242
    {0x14A, "Call Duration"},
1243
    {0x14B, "Dual Mode Phone"},
1244
    {0, NULL}
1245
};
1246
static const value_string usb_hid_consumer_usage_page_vals[] = {
1247
    {0x000, "Undefined"},
1248
    {0x001, "Consumer Control"},
1249
    {0x002, "Numeric Key Pad"},
1250
    {0x003, "Programmable Buttons"},
1251
    {0x004, "Microphone"},
1252
    {0x005, "Headphone"},
1253
    {0x006, "Graphic Equalizer"},
1254
    {0x020, "+10"},
1255
    {0x021, "+100"},
1256
    {0x022, "AM/PM"},
1257
    {0x030, "Power"},
1258
    {0x031, "Reset"},
1259
    {0x032, "Sleep"},
1260
    {0x033, "Sleep After"},
1261
    {0x034, "Sleep Mode"},
1262
    {0x035, "Illumination"},
1263
    {0x036, "Function Buttons"},
1264
    {0x040, "Menu"},
1265
    {0x041, "Menu Pick"},
1266
    {0x042, "Menu Up"},
1267
    {0x043, "Menu Down"},
1268
    {0x044, "Menu Left"},
1269
    {0x045, "Menu Right"},
1270
    {0x046, "Menu Escape"},
1271
    {0x047, "Menu Value Increase"},
1272
    {0x048, "Menu Value Decrease"},
1273
    {0x060, "Data On Screen"},
1274
    {0x061, "Closed Caption"},
1275
    {0x062, "Closed Caption Select"},
1276
    {0x063, "VCR/TV"},
1277
    {0x064, "Broadcast Mode"},
1278
    {0x065, "Snapshot"},
1279
    {0x066, "Still"},
1280
    {0x067, "Picture-in-Picture Toggle"},
1281
    {0x068, "Picture-in-Picture Swap"},
1282
    {0x069, "Red Menu Button"},
1283
    {0x06A, "Green Menu Button"},
1284
    {0x06B, "Blue Menu Button"},
1285
    {0x06C, "Yellow Menu Button"},
1286
    {0x06D, "Aspect"},
1287
    {0x06E, "3D Mode Select"},
1288
    {0x06F, "Display Brightness Increment"},
1289
    {0x070, "Display Brightness Decrement"},
1290
    {0x071, "Display Brightness"},
1291
    {0x072, "Display Backlight Toggle"},
1292
    {0x073, "Display Set Brightness to Minimum"},
1293
    {0x074, "Display Set Brightness to Maximum"},
1294
    {0x075, "Display Set Auto Brightness"},
1295
    {0x076, "Camera Access Enabled"},
1296
    {0x077, "Camera Access Disabled"},
1297
    {0x078, "Camera Access Toggle"},
1298
    {0x079, "Keyboard Brightness Increment"},
1299
    {0x07A, "Keyboard Brightness Decrement"},
1300
    {0x07B, "Keyboard Backlight Set Level"},
1301
    {0x07C, "Keyboard Backlight OOC"},
1302
    {0x07D, "Keyboard Backlight Set Minimum"},
1303
    {0x07E, "Keyboard Backlight Set Maximum"},
1304
    {0x07F, "Keyboard Backlight Auto"},
1305
    {0x080, "Selection"},
1306
    {0x081, "Assign Selection"},
1307
    {0x082, "Mode Step"},
1308
    {0x083, "Recall Last"},
1309
    {0x084, "Enter Channel"},
1310
    {0x085, "Order Movie"},
1311
    {0x086, "Channel"},
1312
    {0x087, "Media Selection"},
1313
    {0x088, "Media Select Computer"},
1314
    {0x089, "Media Select TV"},
1315
    {0x08A, "Media Select WWW"},
1316
    {0x08B, "Media Select DVD"},
1317
    {0x08C, "Media Select Telephone"},
1318
    {0x08D, "Media Select Program Guide"},
1319
    {0x08E, "Media Select Video Phone"},
1320
    {0x08F, "Media Select Games"},
1321
    {0x090, "Media Select Messages"},
1322
    {0x091, "Media Select CD"},
1323
    {0x092, "Media Select VCR"},
1324
    {0x093, "Media Select Tuner"},
1325
    {0x094, "Quit"},
1326
    {0x095, "Help"},
1327
    {0x096, "Media Select Tape"},
1328
    {0x097, "Media Select Cable"},
1329
    {0x098, "Media Select Satellite"},
1330
    {0x099, "Media Select Security"},
1331
    {0x09A, "Media Select Home"},
1332
    {0x09B, "Media Select Call"},
1333
    {0x09C, "Channel Increment"},
1334
    {0x09D, "Channel Decrement"},
1335
    {0x09E, "Media Select SAP"},
1336
    {0x0A0, "VCR Plus"},
1337
    {0x0A1, "Once"},
1338
    {0x0A2, "Daily"},
1339
    {0x0A3, "Weekly"},
1340
    {0x0A4, "Monthly"},
1341
    {0x0B0, "Play"},
1342
    {0x0B1, "Pause"},
1343
    {0x0B2, "Record"},
1344
    {0x0B3, "Fast Forward"},
1345
    {0x0B4, "Rewind"},
1346
    {0x0B5, "Scan Next Track"},
1347
    {0x0B6, "Scan Previous Track"},
1348
    {0x0B7, "Stop"},
1349
    {0x0B8, "Eject"},
1350
    {0x0B9, "Random Play"},
1351
    {0x0BA, "Select Disc"},
1352
    {0x0BB, "Enter Disc"},
1353
    {0x0BC, "Repeat"},
1354
    {0x0BD, "Tracking"},
1355
    {0x0BE, "Track Normal"},
1356
    {0x0BF, "Slow Tracking"},
1357
    {0x0C0, "Frame Forward"},
1358
    {0x0C1, "Frame Back"},
1359
    {0x0C2, "Mark"},
1360
    {0x0C3, "Clear Mark"},
1361
    {0x0C4, "Repeat From Mark"},
1362
    {0x0C5, "Return To Mark"},
1363
    {0x0C6, "Search Mark Forward"},
1364
    {0x0C7, "Search Mark Backwards"},
1365
    {0x0C8, "Counter Reset"},
1366
    {0x0C9, "Show Counter"},
1367
    {0x0CA, "Tracking Increment"},
1368
    {0x0CB, "Tracking Decrement"},
1369
    {0x0CC, "Stop/Eject"},
1370
    {0x0CD, "Play/Pause"},
1371
    {0x0CE, "Play/Skip"},
1372
    {0x0CF, "Voice Command"},
1373
    {0x0D0, "Invoke Capture Interface"},
1374
    {0x0D1, "Start or Stop Game Recording"},
1375
    {0x0D2, "Historical Game Capture"},
1376
    {0x0D3, "Capture Game Screenshot"},
1377
    {0x0D4, "Show or Hide Recording Indicator"},
1378
    {0x0D5, "Start or Stop Microphone Capture"},
1379
    {0x0D6, "Start or Stop Camera Capture"},
1380
    {0x0D7, "Start or Stop Game Broadcast"},
1381
    {0x0D8, "Start or Stop Voice Dictation Session"},
1382
    {0x0D9, "Invoke/Dismiss Emoji Picker"},
1383
    {0x0E0, "Volume"},
1384
    {0x0E1, "Balance"},
1385
    {0x0E2, "Mute"},
1386
    {0x0E3, "Bass"},
1387
    {0x0E4, "Treble"},
1388
    {0x0E5, "Bass Boost"},
1389
    {0x0E6, "Surround Mode"},
1390
    {0x0E7, "Loudness"},
1391
    {0x0E8, "MPX"},
1392
    {0x0E9, "Volume Increment"},
1393
    {0x0EA, "Volume Decrement"},
1394
    {0x0F0, "Speed Select"},
1395
    {0x0F1, "Playback Speed"},
1396
    {0x0F2, "Standard Play"},
1397
    {0x0F3, "Long Play"},
1398
    {0x0F4, "Extended Play"},
1399
    {0x0F5, "Slow"},
1400
    {0x100, "Fan Enable"},
1401
    {0x101, "Fan Speed"},
1402
    {0x102, "Light Enable"},
1403
    {0x103, "Light Illumination Level"},
1404
    {0x104, "Climate Control Enable"},
1405
    {0x105, "Room Temperature"},
1406
    {0x106, "Security Enable"},
1407
    {0x107, "Fire Alarm"},
1408
    {0x108, "Police Alarm"},
1409
    {0x109, "Proximity"},
1410
    {0x10A, "Motion"},
1411
    {0x10B, "Duress Alarm"},
1412
    {0x10C, "Holdup Alarm"},
1413
    {0x10D, "Medical Alarm"},
1414
    {0x150, "Balance Right"},
1415
    {0x151, "Balance Left"},
1416
    {0x152, "Bass Increment"},
1417
    {0x153, "Bass Decrement"},
1418
    {0x154, "Treble Increment"},
1419
    {0x155, "Treble Decrement"},
1420
    {0x160, "Speaker System"},
1421
    {0x161, "Channel Left"},
1422
    {0x162, "Channel Right"},
1423
    {0x163, "Channel Center"},
1424
    {0x164, "Channel Front"},
1425
    {0x165, "Channel Center Front"},
1426
    {0x166, "Channel Side"},
1427
    {0x167, "Channel Surround"},
1428
    {0x168, "Channel Low Frequency Enhancement"},
1429
    {0x169, "Channel Top"},
1430
    {0x16A, "Channel Unknown"},
1431
    {0x170, "Sub-channel"},
1432
    {0x171, "Sub-channel Increment"},
1433
    {0x172, "Sub-channel Decrement"},
1434
    {0x173, "Alternate Audio Increment"},
1435
    {0x174, "Alternate Audio Decrement"},
1436
    {0x180, "Application Launch Buttons"},
1437
    {0x181, "AL Launch Button Configuration Tool"},
1438
    {0x182, "AL Programmable Button Configuration"},
1439
    {0x183, "AL Consumer Control Configuration"},
1440
    {0x184, "AL Word Processor"},
1441
    {0x185, "AL Text Editor"},
1442
    {0x186, "AL Spreadsheet"},
1443
    {0x187, "AL Graphics Editor"},
1444
    {0x188, "AL Presentation App"},
1445
    {0x189, "AL Database App"},
1446
    {0x18A, "AL Email Reader"},
1447
    {0x18B, "AL Newsreader"},
1448
    {0x18C, "AL Voicemail"},
1449
    {0x18D, "AL Contacts/Address Book"},
1450
    {0x18E, "AL Calendar/Schedule"},
1451
    {0x18F, "AL Task/Project Manager"},
1452
    {0x190, "AL Log/Journal/Timecard"},
1453
    {0x191, "AL Checkbook/Finance"},
1454
    {0x192, "AL Calculator"},
1455
    {0x193, "AL A/V Capture/Playback"},
1456
    {0x194, "AL Local Machine Browser"},
1457
    {0x195, "AL LAN/WAN Browser"},
1458
    {0x196, "AL Internet Browser"},
1459
    {0x197, "AL Remote Networking/ISP Connect"},
1460
    {0x198, "AL Network Conference"},
1461
    {0x199, "AL Network Chat"},
1462
    {0x19A, "AL Telephony/Dialer"},
1463
    {0x19B, "AL Logon"},
1464
    {0x19C, "AL Logoff"},
1465
    {0x19D, "AL Logon/Logoff"},
1466
    {0x19E, "AL Terminal Lock/Screensaver"},
1467
    {0x19F, "AL Control Panel"},
1468
    {0x1A0, "AL Command Line Processor/Run"},
1469
    {0x1A1, "AL Process/Task Manager"},
1470
    {0x1A2, "AL Select Task/Application"},
1471
    {0x1A3, "AL Next Task/Application"},
1472
    {0x1A4, "AL Previous Task/Application"},
1473
    {0x1A5, "AL Preemptive Halt Task/Application"},
1474
    {0x1A6, "AL Integrated Help Center"},
1475
    {0x1A7, "AL Documents"},
1476
    {0x1A8, "AL Thesaurus"},
1477
    {0x1A9, "AL Dictionary"},
1478
    {0x1AA, "AL Desktop"},
1479
    {0x1AB, "AL Spell Check"},
1480
    {0x1AC, "AL Grammar Check"},
1481
    {0x1AD, "AL Wireless Status"},
1482
    {0x1AE, "AL Keyboard Layout"},
1483
    {0x1AF, "AL Virus Protection"},
1484
    {0x1B0, "AL Encryption"},
1485
    {0x1B1, "AL Screen Saver"},
1486
    {0x1B2, "AL Alarms"},
1487
    {0x1B3, "AL Clock"},
1488
    {0x1B4, "AL File Browser"},
1489
    {0x1B5, "AL Power Status"},
1490
    {0x1B6, "AL Image Browser"},
1491
    {0x1B7, "AL Audio Browser"},
1492
    {0x1B8, "AL Movie Browser"},
1493
    {0x1B9, "AL Digital Rights Manager"},
1494
    {0x1BA, "AL Digital Wallet"},
1495
    {0x1BC, "AL Instant Messaging"},
1496
    {0x1BD, "AL OEM Features/ Tips/Tutorial Browser"},
1497
    {0x1BE, "AL OEM Help"},
1498
    {0x1BF, "AL Online Community"},
1499
    {0x1C0, "AL Entertainment Content Browser"},
1500
    {0x1C1, "AL Online Shopping Browser"},
1501
    {0x1C2, "AL SmartCard Information/Help"},
1502
    {0x1C3, "AL Market Monitor/Finance Browser"},
1503
    {0x1C4, "AL Customized Corporate News Browser"},
1504
    {0x1C5, "AL Online Activity Browser"},
1505
    {0x1C6, "AL Research/Search Browser"},
1506
    {0x1C7, "AL Audio Player"},
1507
    {0x1C8, "AL Message Status"},
1508
    {0x1C9, "AL Contact Sync"},
1509
    {0x1CA, "AL Navigation"},
1510
    {0x1CB, "AL Context-aware Desktop Assistant"},
1511
    {0x200, "Generic GUI Application Controls"},
1512
    {0x201, "AC New"},
1513
    {0x202, "AC Open"},
1514
    {0x203, "AC Close"},
1515
    {0x204, "AC Exit"},
1516
    {0x205, "AC Maximize"},
1517
    {0x206, "AC Minimize"},
1518
    {0x207, "AC Save"},
1519
    {0x208, "AC Print"},
1520
    {0x209, "AC Properties"},
1521
    {0x21A, "AC Undo"},
1522
    {0x21B, "AC Copy"},
1523
    {0x21C, "AC Cut"},
1524
    {0x21D, "AC Paste"},
1525
    {0x21E, "AC Select All"},
1526
    {0x21F, "AC Find"},
1527
    {0x220, "AC Find and Replace"},
1528
    {0x221, "AC Search"},
1529
    {0x222, "AC Go To"},
1530
    {0x223, "AC Home"},
1531
    {0x224, "AC Back"},
1532
    {0x225, "AC Forward"},
1533
    {0x226, "AC Stop"},
1534
    {0x227, "AC Refresh"},
1535
    {0x228, "AC Previous Link"},
1536
    {0x229, "AC Next Link"},
1537
    {0x22A, "AC Bookmarks"},
1538
    {0x22B, "AC History"},
1539
    {0x22C, "AC Subscriptions"},
1540
    {0x22D, "AC Zoom In"},
1541
    {0x22E, "AC Zoom Out"},
1542
    {0x22F, "AC Zoom"},
1543
    {0x230, "AC Full Screen View"},
1544
    {0x231, "AC Normal View"},
1545
    {0x232, "AC View Toggle"},
1546
    {0x233, "AC Scroll Up"},
1547
    {0x234, "AC Scroll Down"},
1548
    {0x235, "AC Scroll"},
1549
    {0x236, "AC Pan Left"},
1550
    {0x237, "AC Pan Right"},
1551
    {0x238, "AC Pan"},
1552
    {0x239, "AC New Window"},
1553
    {0x23A, "AC Tile Horizontally"},
1554
    {0x23B, "AC Tile Vertically"},
1555
    {0x23C, "AC Format"},
1556
    {0x23D, "AC Edit"},
1557
    {0x23E, "AC Bold"},
1558
    {0x23F, "AC Italics"},
1559
    {0x240, "AC Underline"},
1560
    {0x241, "AC Strikethrough"},
1561
    {0x242, "AC Subscript"},
1562
    {0x243, "AC Superscript"},
1563
    {0x244, "AC All Caps"},
1564
    {0x245, "AC Rotate"},
1565
    {0x246, "AC Resize"},
1566
    {0x247, "AC Flip Horizontal"},
1567
    {0x248, "AC Flip Vertical"},
1568
    {0x249, "AC Mirror Horizontal"},
1569
    {0x24A, "AC Mirror Vertical"},
1570
    {0x24B, "AC Font Select"},
1571
    {0x24C, "AC Font Color"},
1572
    {0x24D, "AC Font Size"},
1573
    {0x24E, "AC Justify Left"},
1574
    {0x24F, "AC Justify Center H"},
1575
    {0x250, "AC Justify Right"},
1576
    {0x251, "AC Justify Block H"},
1577
    {0x252, "AC Justify Top"},
1578
    {0x253, "AC Justify Center V"},
1579
    {0x254, "AC Justify Bottom"},
1580
    {0x255, "AC Justify Block V"},
1581
    {0x256, "AC Indent Decrease"},
1582
    {0x257, "AC Indent Increase"},
1583
    {0x258, "AC Numbered List"},
1584
    {0x259, "AC Restart Numbering"},
1585
    {0x25A, "AC Bulleted List"},
1586
    {0x25B, "AC Promote"},
1587
    {0x25C, "AC Demote"},
1588
    {0x25D, "AC Yes"},
1589
    {0x25E, "AC No"},
1590
    {0x25F, "AC Cancel"},
1591
    {0x260, "AC Catalog"},
1592
    {0x261, "AC Buy/Checkout"},
1593
    {0x262, "AC Add to Cart"},
1594
    {0x263, "AC Expand"},
1595
    {0x264, "AC Expand All"},
1596
    {0x265, "AC Collapse"},
1597
    {0x266, "AC Collapse All"},
1598
    {0x267, "AC Print Preview"},
1599
    {0x268, "AC Paste Special"},
1600
    {0x269, "AC Insert Mode"},
1601
    {0x26A, "AC Delete"},
1602
    {0x26B, "AC Lock"},
1603
    {0x26C, "AC Unlock"},
1604
    {0x26D, "AC Protect"},
1605
    {0x26E, "AC Unprotect"},
1606
    {0x26F, "AC Attach Comment"},
1607
    {0x270, "AC Delete Comment"},
1608
    {0x271, "AC View Comment"},
1609
    {0x272, "AC Select Word"},
1610
    {0x273, "AC Select Sentence"},
1611
    {0x274, "AC Select Paragraph"},
1612
    {0x275, "AC Select Column"},
1613
    {0x276, "AC Select Row"},
1614
    {0x277, "AC Select Table"},
1615
    {0x278, "AC Select Object"},
1616
    {0x279, "AC Redo/Repeat"},
1617
    {0x27A, "AC Sort"},
1618
    {0x27B, "AC Sort Ascending"},
1619
    {0x27C, "AC Sort Descending"},
1620
    {0x27D, "AC Filter"},
1621
    {0x27E, "AC Set Clock"},
1622
    {0x27F, "AC View Clock"},
1623
    {0x280, "AC Select Time Zone"},
1624
    {0x281, "AC Edit Time Zones"},
1625
    {0x282, "AC Set Alarm"},
1626
    {0x283, "AC Clear Alarm"},
1627
    {0x284, "AC Snooze Alarm"},
1628
    {0x285, "AC Reset Alarm"},
1629
    {0x286, "AC Synchronize"},
1630
    {0x287, "AC Send/Receive"},
1631
    {0x288, "AC Send To"},
1632
    {0x289, "AC Reply"},
1633
    {0x28A, "AC Reply All"},
1634
    {0x28B, "AC Forward Msg"},
1635
    {0x28C, "AC Send"},
1636
    {0x28D, "AC Attach File"},
1637
    {0x28E, "AC Upload"},
1638
    {0x28F, "AC Download (Save Target As)"},
1639
    {0x290, "AC Set Borders"},
1640
    {0x291, "AC Insert Row"},
1641
    {0x292, "AC Insert Column"},
1642
    {0x293, "AC Insert File"},
1643
    {0x294, "AC Insert Picture"},
1644
    {0x295, "AC Insert Object"},
1645
    {0x296, "AC Insert Symbol"},
1646
    {0x297, "AC Save and Close"},
1647
    {0x298, "AC Rename"},
1648
    {0x299, "AC Merge"},
1649
    {0x29A, "AC Split"},
1650
    {0x29B, "AC Distribute Horizontally"},
1651
    {0x29C, "AC Distribute Vertically"},
1652
    {0x29D, "AC Next Keyboard Layout Select"},
1653
    {0x29E, "AC Navigation Guidance"},
1654
    {0x29F, "AC Desktop Show All Windows"},
1655
    {0x2A0, "AC Soft Key Left"},
1656
    {0x2A1, "AC Soft Key Right"},
1657
    {0x2A2, "AC Desktop Show All Applications"},
1658
    {0x2B0, "AC Idle Keep Alive"},
1659
    {0x2C0, "Extended Keyboard Attributes Collection"},
1660
    {0x2C1, "Keyboard Form Factor"},
1661
    {0x2C2, "Keyboard Key Type"},
1662
    {0x2C3, "Keyboard Physical Layout"},
1663
    {0x2C4, "Vendor-Specific Keyboard Physical Layout"},
1664
    {0x2C5, "Keyboard IETF Language Tag Index"},
1665
    {0x2C6, "Implemented Keyboard Input Assist Controls"},
1666
    {0x2C7, "Keyboard Input Assist Previous"},
1667
    {0x2C8, "Keyboard Input Assist Next"},
1668
    {0x2C9, "Keyboard Input Assist Previous Group"},
1669
    {0x2CA, "Keyboard Input Assist Next Group"},
1670
    {0x2CB, "Keyboard Input Assist Accept"},
1671
    {0x2CC, "Keyboard Input Assist Cancel"},
1672
    {0x2D0, "Privacy Screen Toggle"},
1673
    {0x2D1, "Privacy Screen Level Decrement"},
1674
    {0x2D2, "Privacy Screen Level Increment"},
1675
    {0x2D3, "Privacy Screen Level Minimum"},
1676
    {0x2D4, "Privacy Screen Level Maximum"},
1677
    {0x500, "Contact Edited"},
1678
    {0x501, "Contact Added"},
1679
    {0x502, "Contact Record Active"},
1680
    {0x503, "Contact Index"},
1681
    {0x504, "Contact Nickname"},
1682
    {0x505, "Contact First Name"},
1683
    {0x506, "Contact Last Name"},
1684
    {0x507, "Contact Full Name"},
1685
    {0x508, "Contact Phone Number Personal"},
1686
    {0x509, "Contact Phone Number Business"},
1687
    {0x50A, "Contact Phone Number Mobile"},
1688
    {0x50B, "Contact Phone Number Pager"},
1689
    {0x50C, "Contact Phone Number Fax"},
1690
    {0x50D, "Contact Phone Number Other"},
1691
    {0x50E, "Contact Email Personal"},
1692
    {0x50F, "Contact Email Business"},
1693
    {0x510, "Contact Email Other"},
1694
    {0x511, "Contact Email Main"},
1695
    {0x512, "Contact Speed Dial Number"},
1696
    {0x513, "Contact Status Flag"},
1697
    {0x514, "Contact Misc."},
1698
    {0, NULL}
1699
};
1700
static const value_string usb_hid_digitizers_usage_page_vals[] = {
1701
    {0x00, "Undefined"},
1702
    {0x01, "Digitizer"},
1703
    {0x02, "Pen"},
1704
    {0x03, "Light Pen"},
1705
    {0x04, "Touch Screen"},
1706
    {0x05, "Touch Pad"},
1707
    {0x06, "Whiteboard"},
1708
    {0x07, "Coordinate Measuring Machine"},
1709
    {0x08, "3D Digitizer"},
1710
    {0x09, "Stereo Plotter"},
1711
    {0x0A, "Articulated Arm"},
1712
    {0x0B, "Armature"},
1713
    {0x0C, "Multiple Point Digitizer"},
1714
    {0x0D, "Free Space Wand"},
1715
    {0x0E, "Device Configuration"},
1716
    {0x0F, "Capacitive Heat Map Digitizer"},
1717
    {0x20, "Stylus"},
1718
    {0x21, "Puck"},
1719
    {0x22, "Finger"},
1720
    {0x23, "Device settings"},
1721
    {0x24, "Character Gesture"},
1722
    {0x30, "Tip Pressure"},
1723
    {0x31, "Barrel Pressure"},
1724
    {0x32, "In Range"},
1725
    {0x33, "Touch"},
1726
    {0x34, "Untouch"},
1727
    {0x35, "Tap"},
1728
    {0x36, "Quality"},
1729
    {0x37, "Data Valid"},
1730
    {0x38, "Transducer Index"},
1731
    {0x39, "Tablet Function Keys"},
1732
    {0x3A, "Program Change Keys"},
1733
    {0x3B, "Battery Strength"},
1734
    {0x3C, "Invert"},
1735
    {0x3D, "X Tilt"},
1736
    {0x3E, "Y Tilt"},
1737
    {0x3F, "Azimuth"},
1738
    {0x40, "Altitude"},
1739
    {0x41, "Twist"},
1740
    {0x42, "Tip Switch"},
1741
    {0x43, "Secondary Tip Switch"},
1742
    {0x44, "Barrel Switch"},
1743
    {0x45, "Eraser"},
1744
    {0x46, "Tablet Pick"},
1745
    {0x47, "Touch Valid"},
1746
    {0x48, "Width"},
1747
    {0x49, "Height"},
1748
    {0x51, "Contact Identifier"},
1749
    {0x52, "Device Mode"},
1750
    {0x53, "Device Identifier"},
1751
    {0x54, "Contact Count"},
1752
    {0x55, "Contact Count Maximum"},
1753
    {0x56, "Scan Time"},
1754
    {0x57, "Surface Switch"},
1755
    {0x58, "Button Switch"},
1756
    {0x59, "Pad Type"},
1757
    {0x5A, "Secondary Barrel Switch"},
1758
    {0x5B, "Transducer Serial Number"},
1759
    {0x5C, "Preferred Color"},
1760
    {0x5D, "Preferred Color is Locked"},
1761
    {0x5E, "Preferred Line Width"},
1762
    {0x5F, "Preferred Line Width is Locked"},
1763
    {0x60, "Latency Mode"},
1764
    {0x61, "Gesture Character Quality"},
1765
    {0x62, "Character Gesture Data Length"},
1766
    {0x63, "Character Gesture Data"},
1767
    {0x64, "Gesture Character Encoding"},
1768
    {0x65, "UTF8 Character Gesture Encoding"},
1769
    {0x66, "UTF16 Little Endian Character Gesture Encoding"},
1770
    {0x67, "UTF16 Big Endian Character Gesture Encoding"},
1771
    {0x68, "UTF32 Little Endian Character Gesture Encoding"},
1772
    {0x69, "UTF32 Big Endian Character Gesture Encoding"},
1773
    {0x6A, "Capacitive Heat Map Protocol Vendor ID"},
1774
    {0x6B, "Capacitive Heat Map Protocol Version"},
1775
    {0x6C, "Capacitive Heat Map Frame Data"},
1776
    {0x6D, "Gesture Character Enable"},
1777
    {0x6E, "Transducer Serial Number Part 2"},
1778
    {0x6F, "No Preferred Color"},
1779
    {0x70, "Preferred Line Style"},
1780
    {0x71, "Preferred Line Style is Locked"},
1781
    {0x72, "Ink"},
1782
    {0x73, "Pencil"},
1783
    {0x74, "Highlighter"},
1784
    {0x75, "Chisel Marker"},
1785
    {0x76, "Brush"},
1786
    {0x77, "No Preference"},
1787
    {0x80, "Digitizer Diagnostic"},
1788
    {0x81, "Digitizer Error"},
1789
    {0x82, "Err Normal Status"},
1790
    {0x83, "Err Transducers Exceeded"},
1791
    {0x84, "Err Full Trans Features Unavailable"},
1792
    {0x85, "Err Charge Low"},
1793
    {0x90, "Transducer Software Info"},
1794
    {0x91, "Transducer Vendor Id"},
1795
    {0x92, "Transducer Product Id"},
1796
    {0x93, "Device Supported Protocols"},
1797
    {0x94, "Transducer Supported Protocols"},
1798
    {0x95, "No Protocol"},
1799
    {0x96, "Wacom AES Protocol"},
1800
    {0x97, "USI Protocol"},
1801
    {0x98, "Microsoft Pen Protocol"},
1802
    {0xA0, "Supported Report Rates"},
1803
    {0xA1, "Report Rate"},
1804
    {0xA2, "Transducer Connected"},
1805
    {0xA3, "Switch Disabled"},
1806
    {0xA4, "Switch Unimplemented"},
1807
    {0xA5, "Transducer Switches"},
1808
    {0xA6, "Transducer Index Selector"},
1809
    {0xB0, "Button Press Threshold"},
1810
    {0, NULL}
1811
};
1812
static const value_string usb_hid_haptic_usage_page_vals[] = {
1813
    {0x0000, "Undefined"},
1814
    {0x0001, "Simple Haptic Controller"},
1815
    {0x0010, "Waveform List"},
1816
    {0x0011, "Duration List"},
1817
    {0x0020, "Auto Trigger"},
1818
    {0x0021, "Manual Trigger"},
1819
    {0x0022, "Auto Trigger Associated Control"},
1820
    {0x0023, "Intensity"},
1821
    {0x0024, "Repeat Count"},
1822
    {0x0025, "Retrigger Period"},
1823
    {0x0026, "Waveform Vendor Page"},
1824
    {0x0027, "Waveform Vendor ID"},
1825
    {0x0028, "Waveform Cutoff Time"},
1826
    {0x1001, "Waveform None"},
1827
    {0x1002, "Waveform Stop"},
1828
    {0x1003, "Waveform Click"},
1829
    {0x1004, "Waveform Buzz Continuous"},
1830
    {0x1005, "Waveform Rumble Continuous"},
1831
    {0x1006, "Waveform Press"},
1832
    {0x1007, "Waveform Release"},
1833
    {0x1008, "Waveform Hover"},
1834
    {0x1009, "Waveform Success"},
1835
    {0x100A, "Waveform Error"},
1836
    {0x100B, "Waveform Ink Continuous"},
1837
    {0x100C, "Waveform Pencil Continuous"},
1838
    {0x100D, "Waveform Marker Continuous"},
1839
    {0x100E, "Waveform Chisel Marker Continuous"},
1840
    {0x100F, "Waveform Brush Continuous"},
1841
    {0x1010, "Waveform Eraser Continuous"},
1842
    {0x1011, "Waveform Sparkle Continuous"},
1843
    {0, NULL}
1844
};
1845
static const value_string usb_hid_physical_input_device_usage_page_vals[] = {
1846
    {0x00, "Undefined"},
1847
    {0x01, "Physical Interface Device"},
1848
    {0x20, "Normal"},
1849
    {0x21, "Set Effect Report"},
1850
    {0x22, "Effect Block Index"},
1851
    {0x23, "Parameter Block Offset"},
1852
    {0x24, "ROM Flag"},
1853
    {0x25, "Effect Type"},
1854
    {0x26, "ET Constant Force"},
1855
    {0x27, "ET Ramp"},
1856
    {0x28, "ET Custom Force Data"},
1857
    {0x30, "ET Square"},
1858
    {0x31, "ET Sine"},
1859
    {0x32, "ET Triangle"},
1860
    {0x33, "ET Sawtooth Up"},
1861
    {0x34, "ET Sawtooth Down"},
1862
    {0x40, "ET Spring"},
1863
    {0x41, "ET Damper"},
1864
    {0x42, "ET Inertia"},
1865
    {0x43, "ET Friction"},
1866
    {0x50, "Duration"},
1867
    {0x51, "Sample Period"},
1868
    {0x52, "Gain"},
1869
    {0x53, "Trigger Button"},
1870
    {0x54, "Trigger Repeat Interval"},
1871
    {0x55, "Axes Enable"},
1872
    {0x56, "Direction Enable"},
1873
    {0x57, "Direction"},
1874
    {0x58, "Type Specific Block Offset"},
1875
    {0x59, "Block Type"},
1876
    {0x5A, "Set Envelope Report"},
1877
    {0x5B, "Attack Level"},
1878
    {0x5C, "Attack Time"},
1879
    {0x5D, "Fade Level"},
1880
    {0x5E, "Fade Time"},
1881
    {0x5F, "Set Condition Report"},
1882
    {0x60, "CP Offset"},
1883
    {0x61, "Positive Coefficient"},
1884
    {0x62, "Negative Coefficient"},
1885
    {0x63, "Positive Saturation"},
1886
    {0x64, "Negative Saturation"},
1887
    {0x65, "Dead Band"},
1888
    {0x66, "Download Force Sample"},
1889
    {0x67, "Isoch Custom Force Enable"},
1890
    {0x68, "Custom Force Data Report"},
1891
    {0x69, "Custom Force Data"},
1892
    {0x6A, "Custom Force Vendor Defined Data"},
1893
    {0x6B, "Set Custom Force Report"},
1894
    {0x6C, "Custom Force Data Offset"},
1895
    {0x6D, "Sample Count"},
1896
    {0x6E, "Set Periodic Report"},
1897
    {0x6F, "Offset"},
1898
    {0x70, "Magnitude"},
1899
    {0x71, "Phase"},
1900
    {0x72, "Period"},
1901
    {0x73, "Set Constant Force Report"},
1902
    {0x74, "Set Ramp Force Report"},
1903
    {0x75, "Ramp Start"},
1904
    {0x76, "Ramp End"},
1905
    {0x77, "Effect Operation Report"},
1906
    {0x78, "Effect Operation"},
1907
    {0x79, "Op Effect Start"},
1908
    {0x7A, "Op Effect Start Solo"},
1909
    {0x7B, "Op Effect Stop"},
1910
    {0x7C, "Loop Count"},
1911
    {0x7D, "Device Gain Report"},
1912
    {0x7E, "Device Gain"},
1913
    {0x7F, "PID Pool Report"},
1914
    {0x80, "RAM Pool Size"},
1915
    {0x81, "ROM Pool Size"},
1916
    {0x82, "ROM Effect Block Count"},
1917
    {0x83, "Simultaneous Effects Max"},
1918
    {0x84, "Pool Alignment"},
1919
    {0x85, "PID Pool Move Report"},
1920
    {0x86, "Move Source"},
1921
    {0x87, "Move Destination"},
1922
    {0x88, "Move Length"},
1923
    {0x89, "PID Block Load Report"},
1924
    {0x8B, "Block Load Status"},
1925
    {0x8C, "Block Load Success"},
1926
    {0x8D, "Block Load Full"},
1927
    {0x8E, "Block Load Error"},
1928
    {0x8F, "Block Handle"},
1929
    {0x90, "PID Block Free Report"},
1930
    {0x91, "Type Specific Block Handle"},
1931
    {0x92, "PID State Report"},
1932
    {0x94, "Effect Playing"},
1933
    {0x95, "PID Device Control Report"},
1934
    {0x96, "PID Device Control"},
1935
    {0x97, "DC Enable Actuators"},
1936
    {0x98, "DC Disable Actuators"},
1937
    {0x99, "DC Stop All Effects"},
1938
    {0x9A, "DC Device Reset"},
1939
    {0x9B, "DC Device Pause"},
1940
    {0x9C, "DC Device Continue"},
1941
    {0x9F, "Device Paused"},
1942
    {0xA0, "Actuators Enabled"},
1943
    {0xA4, "Safety Switch"},
1944
    {0xA5, "Actuator Override Switch"},
1945
    {0xA6, "Actuator Power"},
1946
    {0xA7, "Start Delay"},
1947
    {0xA8, "Parameter Block Size"},
1948
    {0xA9, "Device Managed Pool"},
1949
    {0xAA, "Shared Parameter Blocks"},
1950
    {0xAB, "Create New Effect Report"},
1951
    {0xAC, "RAM Pool Available"},
1952
    {0, NULL}
1953
};
1954
static const value_string usb_hid_soc_usage_page_vals[] = {
1955
    {0x00, "Undefined"},
1956
    {0x01, "SocControl"},
1957
    {0x02, "FirmwareTransfer"},
1958
    {0x03, "FirmwareFileId"},
1959
    {0x04, "FileOffsetInBytes"},
1960
    {0x05, "FileTransferSizeMaxInBytes"},
1961
    {0x06, "FilePayload"},
1962
    {0x07, "FilePayloadSizeInBytes"},
1963
    {0x08, "FilePayloadContainsLastBytes"},
1964
    {0x09, "FileTransferStop"},
1965
    {0x0A, "FileTransferTillEnd"},
1966
    {0, NULL}
1967
};
1968
static const value_string usb_hid_eye_and_head_tracker_usage_page_vals[] = {
1969
    {0x0000, "Undefined"},
1970
    {0x0001, "Eye Tracker"},
1971
    {0x0002, "Head Tracker"},
1972
    {0x0010, "Tracking Data"},
1973
    {0x0011, "Capabilities"},
1974
    {0x0012, "Configuration"},
1975
    {0x0013, "Status"},
1976
    {0x0014, "Control"},
1977
    {0x0020, "Sensor Timestamp"},
1978
    {0x0021, "Position X"},
1979
    {0x0022, "Position Y"},
1980
    {0x0023, "Position Z"},
1981
    {0x0024, "Gaze Point"},
1982
    {0x0025, "Left Eye Position"},
1983
    {0x0026, "Right Eye Position"},
1984
    {0x0027, "Head Position"},
1985
    {0x0028, "Head Direction Point"},
1986
    {0x0029, "Rotation about X axis"},
1987
    {0x002A, "Rotation about Y axis"},
1988
    {0x002B, "Rotation about Z axis"},
1989
    {0x0100, "Tracker Quality"},
1990
    {0x0101, "Minimum Tracking Distance"},
1991
    {0x0102, "Optimum Tracking Distance"},
1992
    {0x0103, "Maximum Tracking Distance"},
1993
    {0x0104, "Maximum Screen Plane Width"},
1994
    {0x0105, "Maximum Screen Plane Height"},
1995
    {0x0200, "Display Manufacturer ID"},
1996
    {0x0201, "Display Product ID"},
1997
    {0x0202, "Display Serial Number"},
1998
    {0x0203, "Display Manufacturer Date"},
1999
    {0x0204, "Calibrated Screen Width"},
2000
    {0x0205, "Calibrated Screen Height"},
2001
    {0x0300, "Sampling Frequency"},
2002
    {0x0301, "Configuration Status"},
2003
    {0x0400, "Device Mode Request"},
2004
    {0, NULL}
2005
};
2006
static const value_string usb_hid_alphanumeric_display_usage_page_vals[] = {
2007
    {0x00, "Undefined"},
2008
    {0x01, "Alphanumeric Display"},
2009
    {0x02, "Auxiliary Display"},
2010
    {0x20, "Display Attributes Report"},
2011
    {0x21, "ASCII Character Set"},
2012
    {0x22, "Data Read Back"},
2013
    {0x23, "Font Read Back"},
2014
    {0x24, "Display Control Report"},
2015
    {0x25, "Clear Display"},
2016
    {0x26, "Display Enable"},
2017
    {0x27, "Screen Saver Delay"},
2018
    {0x28, "Screen Saver Enable"},
2019
    {0x29, "Vertical Scroll"},
2020
    {0x2A, "Horizontal Scroll"},
2021
    {0x2B, "Character Report"},
2022
    {0x2C, "Display Data"},
2023
    {0x2D, "Display Status"},
2024
    {0x2E, "Stat Not Ready"},
2025
    {0x2F, "Stat Ready"},
2026
    {0x30, "Err Not a loadable character"},
2027
    {0x31, "Err Font data cannot be read"},
2028
    {0x32, "Cursor Position Report"},
2029
    {0x33, "Row"},
2030
    {0x34, "Column"},
2031
    {0x35, "Rows"},
2032
    {0x36, "Columns"},
2033
    {0x37, "Cursor Pixel Positioning"},
2034
    {0x38, "Cursor Mode"},
2035
    {0x39, "Cursor Enable"},
2036
    {0x3A, "Cursor Blink"},
2037
    {0x3B, "Font Report"},
2038
    {0x3C, "Font Data"},
2039
    {0x3D, "Character Width"},
2040
    {0x3E, "Character Height"},
2041
    {0x3F, "Character Spacing Horizontal"},
2042
    {0x40, "Character Spacing Vertical"},
2043
    {0x41, "Unicode Character Set"},
2044
    {0x42, "Font 7-Segment"},
2045
    {0x43, "7-Segment Direct Map"},
2046
    {0x44, "Font 14-Segment"},
2047
    {0x45, "14-Segment Direct Map"},
2048
    {0x46, "Display Brightness"},
2049
    {0x47, "Display Contrast"},
2050
    {0x48, "Character Attribute"},
2051
    {0x49, "Attribute Readback"},
2052
    {0x4A, "Attribute Data"},
2053
    {0x4B, "Char Attr Enhance"},
2054
    {0x4C, "Char Attr Underline"},
2055
    {0x4D, "Char Attr Blink"},
2056
    {0x80, "Bitmap Size X"},
2057
    {0x81, "Bitmap Size Y"},
2058
    {0x82, "Max Blit Size"},
2059
    {0x83, "Bit Depth Format"},
2060
    {0x84, "Display Orientation"},
2061
    {0x85, "Palette Report"},
2062
    {0x86, "Palette Data Size"},
2063
    {0x87, "Palette Data Offset"},
2064
    {0x88, "Palette Data"},
2065
    {0x8A, "Blit Report"},
2066
    {0x8B, "Blit Rectangle X1"},
2067
    {0x8C, "Blit Rectangle Y1"},
2068
    {0x8D, "Blit Rectangle X2"},
2069
    {0x8E, "Blit Rectangle Y2"},
2070
    {0x8F, "Blit Data"},
2071
    {0x90, "Soft Button"},
2072
    {0x91, "Soft Button ID"},
2073
    {0x92, "Soft Button Side"},
2074
    {0x93, "Soft Button Offset 1"},
2075
    {0x94, "Soft Button Offset 2"},
2076
    {0x95, "Soft Button Report"},
2077
    {0xC2, "Soft Keys"},
2078
    {0xCC, "Display Data Extensions"},
2079
    {0xCF, "Character Mapping"},
2080
    {0xDD, "Unicode Equivalent"},
2081
    {0xDF, "Character Page Mapping"},
2082
    {0xFF, "Request Report"},
2083
    {0, NULL}
2084
};
2085
static const value_string usb_hid_sensor_usage_page_vals[] = {
2086
    {0x0000, "Undefined"},
2087
    {0x0001, "Sensor"},
2088
    {0x0010, "Biometric"},
2089
    {0x0011, "Biometric: Human Presence"},
2090
    {0x0012, "Biometric: Human Proximity"},
2091
    {0x0013, "Biometric: Human Touch"},
2092
    {0x0014, "Biometric: Blood Pressure"},
2093
    {0x0015, "Biometric: Body Temperature"},
2094
    {0x0016, "Biometric: Heart Rate"},
2095
    {0x0017, "Biometric: Heart Rate Variability"},
2096
    {0x0018, "Biometric: Peripheral Oxygen Saturation"},
2097
    {0x0019, "Biometric: Respiratory Rate"},
2098
    {0x0020, "Electrical"},
2099
    {0x0021, "Electrical: Capacitance"},
2100
    {0x0022, "Electrical: Current"},
2101
    {0x0023, "Electrical: Power"},
2102
    {0x0024, "Electrical: Inductance"},
2103
    {0x0025, "Electrical: Resistance"},
2104
    {0x0026, "Electrical: Voltage"},
2105
    {0x0027, "Electrical: Potentiometer"},
2106
    {0x0028, "Electrical: Frequency"},
2107
    {0x0029, "Electrical: Period"},
2108
    {0x0030, "Environmental"},
2109
    {0x0031, "Environmental: Atmospheric Pressure"},
2110
    {0x0032, "Environmental: Humidity"},
2111
    {0x0033, "Environmental: Temperature"},
2112
    {0x0034, "Environmental: Wind Direction"},
2113
    {0x0035, "Environmental: Wind Speed"},
2114
    {0x0036, "Environmental: Air Quality"},
2115
    {0x0037, "Environmental: Heat Index"},
2116
    {0x0038, "Environmental: Surface Temperature"},
2117
    {0x0039, "Environmental: Volatile Organic Compounds"},
2118
    {0x003A, "Environmental: Object Presence"},
2119
    {0x003B, "Environmental: Object Proximity"},
2120
    {0x0040, "Light"},
2121
    {0x0041, "Light: Ambient Light"},
2122
    {0x0042, "Light: Consumer Infrared"},
2123
    {0x0043, "Light: Infrared Light"},
2124
    {0x0044, "Light: Visible Light"},
2125
    {0x0045, "Light: Ultraviolet Light"},
2126
    {0x0050, "Location"},
2127
    {0x0051, "Location: Broadcast"},
2128
    {0x0052, "Location: Dead Reckoning"},
2129
    {0x0053, "Location: GPS (Global Positioning System)"},
2130
    {0x0054, "Location: Lookup"},
2131
    {0x0055, "Location: Other"},
2132
    {0x0056, "Location: Static"},
2133
    {0x0057, "Location: Triangulation"},
2134
    {0x0060, "Mechanical"},
2135
    {0x0061, "Mechanical: Boolean Switch"},
2136
    {0x0062, "Mechanical: Boolean Switch Array"},
2137
    {0x0063, "Mechanical: Multivalue Switch"},
2138
    {0x0064, "Mechanical: Force"},
2139
    {0x0065, "Mechanical: Pressure"},
2140
    {0x0066, "Mechanical: Strain"},
2141
    {0x0067, "Mechanical: Weight"},
2142
    {0x0068, "Mechanical: Haptic Vibrator"},
2143
    {0x0069, "Mechanical: Hall Effect Switch"},
2144
    {0x0070, "Motion"},
2145
    {0x0071, "Motion: Accelerometer 1D"},
2146
    {0x0072, "Motion: Accelerometer 2D"},
2147
    {0x0073, "Motion: Accelerometer 3D"},
2148
    {0x0074, "Motion: Gyrometer 1D"},
2149
    {0x0075, "Motion: Gyrometer 2D"},
2150
    {0x0076, "Motion: Gyrometer 3D"},
2151
    {0x0077, "Motion: Motion Detector"},
2152
    {0x0078, "Motion: Speedometer"},
2153
    {0x0079, "Motion: Accelerometer"},
2154
    {0x007A, "Motion: Gyrometer"},
2155
    {0x007B, "Motion: Gravity Vector"},
2156
    {0x007C, "Motion: Linear Accelerometer"},
2157
    {0x0080, "Orientation"},
2158
    {0x0081, "Orientation: Compass 1D"},
2159
    {0x0082, "Orientation: Compass 2D"},
2160
    {0x0083, "Orientation: Compass 3D"},
2161
    {0x0084, "Orientation: Inclinometer 1D"},
2162
    {0x0085, "Orientation: Inclinometer 2D"},
2163
    {0x0086, "Orientation: Inclinometer 3D"},
2164
    {0x0087, "Orientation: Distance 1D"},
2165
    {0x0088, "Orientation: Distance 2D"},
2166
    {0x0089, "Orientation: Distance 3D"},
2167
    {0x008A, "Orientation: Device Orientation"},
2168
    {0x008B, "Orientation: Compass"},
2169
    {0x008C, "Orientation: Inclinometer"},
2170
    {0x008D, "Orientation: Distance"},
2171
    {0x008E, "Orientation: Relative Orientation"},
2172
    {0x008F, "Orientation: Simple Orientation"},
2173
    {0x0090, "Scanner"},
2174
    {0x0091, "Scanner: Barcode"},
2175
    {0x0092, "Scanner: RFID"},
2176
    {0x0093, "Scanner: NFC"},
2177
    {0x00A0, "Time"},
2178
    {0x00A1, "Time: Alarm Timer"},
2179
    {0x00A2, "Time: Real Time Clock"},
2180
    {0x00B0, "Personal Activity"},
2181
    {0x00B1, "Personal Activity: Activity Detection"},
2182
    {0x00B2, "Personal Activity: Device Position"},
2183
    {0x00B3, "Personal Activity: Floor Tracker"},
2184
    {0x00B4, "Personal Activity: Pedometer"},
2185
    {0x00B5, "Personal Activity: Step Detection"},
2186
    {0x00C0, "Orientation Extended"},
2187
    {0x00C1, "Orientation Extended: Geomagnetic Orientation"},
2188
    {0x00C2, "Orientation Extended: Magnetometer"},
2189
    {0x00D0, "Gesture"},
2190
    {0x00D1, "Gesture: Chassis Flip Gesture"},
2191
    {0x00D2, "Gesture: Hinge Fold Gesture"},
2192
    {0x00E0, "Other"},
2193
    {0x00E1, "Other: Custom"},
2194
    {0x00E2, "Other: Generic"},
2195
    {0x00E3, "Other: Generic Enumerator"},
2196
    {0x00E4, "Other: Hinge Angle"},
2197
    {0x0200, "Event"},
2198
    {0x0201, "Event: Sensor State"},
2199
    {0x0202, "Event: Sensor Event"},
2200
    {0x0300, "Property"},
2201
    {0x0301, "Property: Friendly Name"},
2202
    {0x0302, "Property: Persistent Unique ID"},
2203
    {0x0303, "Property: Sensor Status"},
2204
    {0x0304, "Property: Minimum Report Interval"},
2205
    {0x0305, "Property: Sensor Manufacturer"},
2206
    {0x0306, "Property: Sensor Model"},
2207
    {0x0307, "Property: Sensor Serial Number"},
2208
    {0x0308, "Property: Sensor Description"},
2209
    {0x0309, "Property: Sensor Connection Type"},
2210
    {0x030A, "Property: Sensor Device Path"},
2211
    {0x030B, "Property: Hardware Revision"},
2212
    {0x030C, "Property: Firmware Version"},
2213
    {0x030D, "Property: Release Date"},
2214
    {0x030E, "Property: Report Interval"},
2215
    {0x030F, "Property: Change Sensitivity Absolute"},
2216
    {0x0310, "Property: Change Sensitivity Percent of Range"},
2217
    {0x0311, "Property: Change Sensitivity Percent Relative"},
2218
    {0x0312, "Property: Accuracy"},
2219
    {0x0313, "Property: Resolution"},
2220
    {0x0314, "Property: Maximum"},
2221
    {0x0315, "Property: Minimum"},
2222
    {0x0316, "Property: Reporting State"},
2223
    {0x0317, "Property: Sampling Rate"},
2224
    {0x0318, "Property: Response Curve"},
2225
    {0x0319, "Property: Power State"},
2226
    {0x031A, "Property: Maximum FIFO Events"},
2227
    {0x031B, "Property: Report Latency"},
2228
    {0x031C, "Property: Flush FIFO Events"},
2229
    {0x031D, "Property: Maximum Power Consumption"},
2230
    {0x031E, "Property: Is Primary"},
2231
    {0x031F, "Property: Human Presence Detection Type"},
2232
    {0x0400, "Data Field: Location"},
2233
    {0x0401, "Reserved (Data Field: Location)"},
2234
    {0x0402, "Data Field: Altitude Antenna Sea Level"},
2235
    {0x0403, "Data Field: Differential Reference Station ID"},
2236
    {0x0404, "Data Field: Altitude Ellipsoid Error"},
2237
    {0x0405, "Data Field: Altitude Ellipsoid"},
2238
    {0x0406, "Data Field: Altitude Sea Level Error"},
2239
    {0x0407, "Data Field: Altitude Sea Level"},
2240
    {0x0408, "Data Field: Differential GPS Data Age"},
2241
    {0x0409, "Data Field: Error Radius"},
2242
    {0x040A, "Data Field: Fix Quality"},
2243
    {0x040B, "Data Field: Fix Type"},
2244
    {0x040C, "Data Field: Geoidal Separation"},
2245
    {0x040D, "Data Field: GPS Operation Mode"},
2246
    {0x040E, "Data Field: GPS Selection Mode"},
2247
    {0x040F, "Data Field: GPS Status"},
2248
    {0x0410, "Data Field: Position Dilution of Precision"},
2249
    {0x0411, "Data Field: Horizontal Dilution of Precision"},
2250
    {0x0412, "Data Field: Vertical Dilution of Precision"},
2251
    {0x0413, "Data Field: Latitude"},
2252
    {0x0414, "Data Field: Longitude"},
2253
    {0x0415, "Data Field: True Heading"},
2254
    {0x0416, "Data Field: Magnetic Heading"},
2255
    {0x0417, "Data Field: Magnetic Variation"},
2256
    {0x0418, "Data Field: Speed"},
2257
    {0x0419, "Data Field: Satellites in View"},
2258
    {0x041A, "Data Field: Satellites in View Azimuth"},
2259
    {0x041B, "Data Field: Satellites in View Elevation"},
2260
    {0x041C, "Data Field: Satellites in View IDs"},
2261
    {0x041D, "Data Field: Satellites in View PRNs"},
2262
    {0x041E, "Data Field: Satellites in View S/N Ratios"},
2263
    {0x041F, "Data Field: Satellites Used Count"},
2264
    {0x0420, "Data Field: Satellites Used PRNs"},
2265
    {0x0421, "Data Field: NMEA Sentence"},
2266
    {0x0422, "Data Field: Address Line 1"},
2267
    {0x0423, "Data Field: Address Line 2"},
2268
    {0x0424, "Data Field: City"},
2269
    {0x0425, "Data Field: State or Province"},
2270
    {0x0426, "Data Field: Country or Region"},
2271
    {0x0427, "Data Field: Postal Code"},
2272
    {0x042A, "Property: Location"},
2273
    {0x042B, "Property: Location Desired Accuracy"},
2274
    {0x0430, "Data Field: Environmental"},
2275
    {0x0431, "Data Field: Atmospheric Pressure"},
2276
    {0x0432, "Reserved (Data Field: Environmental)"},
2277
    {0x0433, "Data Field: Relative Humidity"},
2278
    {0x0434, "Data Field: Temperature"},
2279
    {0x0435, "Data Field: Wind Direction"},
2280
    {0x0436, "Data Field: Wind Speed"},
2281
    {0x0437, "Data Field: Air Quality Index"},
2282
    {0x0438, "Data Field: Equivalent CO2"},
2283
    {0x0439, "Data Field: Volatile Organic Compound Concentration"},
2284
    {0x043A, "Data Field: Object Presence"},
2285
    {0x043B, "Data Field: Object Proximity Range"},
2286
    {0x043C, "Data Field: Object Proximity Out of Range"},
2287
    {0x0440, "Property: Environmental"},
2288
    {0x0441, "Property: Reference Pressure"},
2289
    {0x0450, "Data Field: Motion"},
2290
    {0x0451, "Data Field: Motion State"},
2291
    {0x0452, "Data Field: Acceleration"},
2292
    {0x0453, "Data Field: Acceleration Axis X"},
2293
    {0x0454, "Data Field: Acceleration Axis Y"},
2294
    {0x0455, "Data Field: Acceleration Axis Z"},
2295
    {0x0456, "Data Field: Angular Velocity"},
2296
    {0x0457, "Data Field: Angular Velocity about X Axis"},
2297
    {0x0458, "Data Field: Angular Velocity about Y Axis"},
2298
    {0x0459, "Data Field: Angular Velocity about Z Axis"},
2299
    {0x045A, "Data Field: Angular Position"},
2300
    {0x045B, "Data Field: Angular Position about X Axis"},
2301
    {0x045C, "Data Field: Angular Position about Y Axis"},
2302
    {0x045D, "Data Field: Angular Position about Z Axis"},
2303
    {0x045E, "Data Field: Motion Speed"},
2304
    {0x045F, "Data Field: Motion Intensity"},
2305
    {0x0470, "Data Field: Orientation"},
2306
    {0x0471, "Data Field: Heading"},
2307
    {0x0472, "Data Field: Heading X Axis"},
2308
    {0x0473, "Data Field: Heading Y Axis"},
2309
    {0x0474, "Data Field: Heading Z Axis"},
2310
    {0x0475, "Data Field: Heading Compensated Magnetic North"},
2311
    {0x0476, "Data Field: Heading Compensated True North"},
2312
    {0x0477, "Data Field: Heading Magnetic North"},
2313
    {0x0478, "Data Field: Heading True North"},
2314
    {0x0479, "Data Field: Distance"},
2315
    {0x047A, "Data Field: Distance X Axis"},
2316
    {0x047B, "Data Field: Distance Y Axis"},
2317
    {0x047C, "Data Field: Distance Z Axis"},
2318
    {0x047D, "Data Field: Distance Out-of-Range"},
2319
    {0x047E, "Data Field: Tilt"},
2320
    {0x047F, "Data Field: Tilt X Axis"},
2321
    {0x0480, "Data Field: Tilt Y Axis"},
2322
    {0x0481, "Data Field: Tilt Z Axis"},
2323
    {0x0482, "Data Field: Rotation Matrix"},
2324
    {0x0483, "Data Field: Quaternion"},
2325
    {0x0484, "Data Field: Magnetic Flux"},
2326
    {0x0485, "Data Field: Magnetic Flux X Axis"},
2327
    {0x0486, "Data Field: Magnetic Flux Y Axis"},
2328
    {0x0487, "Data Field: Magnetic Flux Z Axis"},
2329
    {0x0488, "Data Field: Magnetometer Accuracy"},
2330
    {0x0489, "Data Field: Simple Orientation Direction"},
2331
    {0x0490, "Data Field: Mechanical"},
2332
    {0x0491, "Data Field: Boolean Switch State"},
2333
    {0x0492, "Data Field: Boolean Switch Array States"},
2334
    {0x0493, "Data Field: Multivalue Switch Value"},
2335
    {0x0494, "Data Field: Force"},
2336
    {0x0495, "Data Field: Absolute Pressure"},
2337
    {0x0496, "Data Field: Gauge Pressure"},
2338
    {0x0497, "Data Field: Strain"},
2339
    {0x0498, "Data Field: Weight"},
2340
    {0x04A0, "Property: Mechanical"},
2341
    {0x04A1, "Property: Vibration State"},
2342
    {0x04A2, "Property: Forward Vibration Speed"},
2343
    {0x04A3, "Property: Backward Vibration Speed"},
2344
    {0x04B0, "Data Field: Biometric"},
2345
    {0x04B1, "Data Field: Human Presence"},
2346
    {0x04B2, "Data Field: Human Proximity Range"},
2347
    {0x04B3, "Data Field: Human Proximity Out of Range"},
2348
    {0x04B4, "Data Field: Human Touch State"},
2349
    {0x04B5, "Data Field: Blood Pressure"},
2350
    {0x04B6, "Data Field: Blood Pressure Diastolic"},
2351
    {0x04B7, "Data Field: Blood Pressure Systolic"},
2352
    {0x04B8, "Data Field: Heart Rate"},
2353
    {0x04B9, "Data Field: Resting Heart Rate"},
2354
    {0x04BA, "Data Field: Heartbeat Interval"},
2355
    {0x04BB, "Data Field: Respiratory Rate"},
2356
    {0x04BC, "Data Field: SpO2"},
2357
    {0x04BD, "Data Field: Human Attention Detected"},
2358
    {0x04BE, "Data Field: Human Head Azimuth"},
2359
    {0x04BF, "Data Field: Human Head Altitude"},
2360
    {0x04C0, "Data Field: Human Head Roll"},
2361
    {0x04C1, "Data Field: Human Head Pitch"},
2362
    {0x04C2, "Data Field: Human Head Yaw"},
2363
    {0x04C3, "Data Field: Human Correlation Id"},
2364
    {0x04D0, "Data Field: Light"},
2365
    {0x04D1, "Data Field: Illuminance"},
2366
    {0x04D2, "Data Field: Color Temperature"},
2367
    {0x04D3, "Data Field: Chromaticity"},
2368
    {0x04D4, "Data Field: Chromaticity X"},
2369
    {0x04D5, "Data Field: Chromaticity Y"},
2370
    {0x04D6, "Data Field: Consumer IR Sentence Receive"},
2371
    {0x04D7, "Data Field: Infrared Light"},
2372
    {0x04D8, "Data Field: Red Light"},
2373
    {0x04D9, "Data Field: Green Light"},
2374
    {0x04DA, "Data Field: Blue Light"},
2375
    {0x04DB, "Data Field: Ultraviolet A Light"},
2376
    {0x04DC, "Data Field: Ultraviolet B Light"},
2377
    {0x04DD, "Data Field: Ultraviolet Index"},
2378
    {0x04DE, "Data Field: Near Infrared Light"},
2379
    {0x04DF, "Property: Light"},
2380
    {0x04E0, "Property: Consumer IR Sentence Send"},
2381
    {0x04E2, "Property: Auto Brightness Preferred"},
2382
    {0x04E3, "Property: Auto Color Preferred"},
2383
    {0x04F0, "Data Field: Scanner"},
2384
    {0x04F1, "Data Field: RFID Tag 40 Bit"},
2385
    {0x04F2, "Data Field: NFC Sentence Receive"},
2386
    {0x04F8, "Property: Scanner"},
2387
    {0x04F9, "Property: NFC Sentence Send"},
2388
    {0x0500, "Data Field: Electrical"},
2389
    {0x0501, "Data Field: Capacitance"},
2390
    {0x0502, "Data Field: Current"},
2391
    {0x0503, "Data Field: Electrical Power"},
2392
    {0x0504, "Data Field: Inductance"},
2393
    {0x0505, "Data Field: Resistance"},
2394
    {0x0506, "Data Field: Voltage"},
2395
    {0x0507, "Data Field: Frequency"},
2396
    {0x0508, "Data Field: Period"},
2397
    {0x0509, "Data Field: Percent of Range"},
2398
    {0x0520, "Data Field: Time"},
2399
    {0x0521, "Data Field: Year"},
2400
    {0x0522, "Data Field: Month"},
2401
    {0x0523, "Data Field: Day"},
2402
    {0x0524, "Data Field: Day of Week"},
2403
    {0x0525, "Data Field: Hour"},
2404
    {0x0526, "Data Field: Minute"},
2405
    {0x0527, "Data Field: Second"},
2406
    {0x0528, "Data Field: Millisecond"},
2407
    {0x0529, "Data Field: Timestamp"},
2408
    {0x052A, "Data Field: Julian Day of Year"},
2409
    {0x052B, "Data Field: Time Since System Boot"},
2410
    {0x0530, "Property: Time"},
2411
    {0x0531, "Property: Time Zone Offset from UTC"},
2412
    {0x0532, "Property: Time Zone Name"},
2413
    {0x0533, "Property: Daylight Savings Time Observed"},
2414
    {0x0534, "Property: Time Trim Adjustment"},
2415
    {0x0535, "Property: Arm Alarm"},
2416
    {0x0540, "Data Field: Custom"},
2417
    {0x0541, "Data Field: Custom Usage"},
2418
    {0x0542, "Data Field: Custom Boolean Array"},
2419
    {0x0543, "Data Field: Custom Value"},
2420
    {0x0544, "Data Field: Custom Value 1"},
2421
    {0x0545, "Data Field: Custom Value 2"},
2422
    {0x0546, "Data Field: Custom Value 3"},
2423
    {0x0547, "Data Field: Custom Value 4"},
2424
    {0x0548, "Data Field: Custom Value 5"},
2425
    {0x0549, "Data Field: Custom Value 6"},
2426
    {0x054A, "Data Field: Custom Value 7"},
2427
    {0x054B, "Data Field: Custom Value 8"},
2428
    {0x054C, "Data Field: Custom Value 9"},
2429
    {0x054D, "Data Field: Custom Value 10"},
2430
    {0x054E, "Data Field: Custom Value 11"},
2431
    {0x054F, "Data Field: Custom Value 12"},
2432
    {0x0550, "Data Field: Custom Value 13"},
2433
    {0x0551, "Data Field: Custom Value 14"},
2434
    {0x0552, "Data Field: Custom Value 15"},
2435
    {0x0553, "Data Field: Custom Value 16"},
2436
    {0x0554, "Data Field: Custom Value 17"},
2437
    {0x0555, "Data Field: Custom Value 18"},
2438
    {0x0556, "Data Field: Custom Value 19"},
2439
    {0x0557, "Data Field: Custom Value 20"},
2440
    {0x0558, "Data Field: Custom Value 21"},
2441
    {0x0559, "Data Field: Custom Value 22"},
2442
    {0x055A, "Data Field: Custom Value 23"},
2443
    {0x055B, "Data Field: Custom Value 24"},
2444
    {0x055C, "Data Field: Custom Value 25"},
2445
    {0x055D, "Data Field: Custom Value 26"},
2446
    {0x055E, "Data Field: Custom Value 27"},
2447
    {0x055F, "Data Field: Custom Value 28"},
2448
    {0x0560, "Data Field: Generic"},
2449
    {0x0561, "Data Field: Generic GUID or PROPERTYKEY"},
2450
    {0x0562, "Data Field: Generic Category GUID"},
2451
    {0x0563, "Data Field: Generic Type GUID"},
2452
    {0x0564, "Data Field: Generic Event PROPERTYKEY"},
2453
    {0x0565, "Data Field: Generic Property PROPERTYKEY"},
2454
    {0x0566, "Data Field: Generic Data Field PROPERTYKEY"},
2455
    {0x0567, "Data Field: Generic Event"},
2456
    {0x0568, "Data Field: Generic Property"},
2457
    {0x0569, "Data Field: Generic Data Field"},
2458
    {0x056A, "Data Field: Enumerator Table Row Index"},
2459
    {0x056B, "Data Field: Enumerator Table Row Count"},
2460
    {0x056C, "Data Field: Generic GUID or PROPERTYKEY kind"},
2461
    {0x056D, "Data Field: Generic GUID"},
2462
    {0x056E, "Data Field: Generic PROPERTYKEY"},
2463
    {0x056F, "Data Field: Generic Top Level Collection ID"},
2464
    {0x0570, "Data Field: Generic Report ID"},
2465
    {0x0571, "Data Field: Generic Report Item Position Index"},
2466
    {0x0572, "Data Field: Generic Firmware VARTYPE"},
2467
    {0x0573, "Data Field: Generic Unit of Measure"},
2468
    {0x0574, "Data Field: Generic Unit Exponent"},
2469
    {0x0575, "Data Field: Generic Report Size"},
2470
    {0x0576, "Data Field: Generic Report Count"},
2471
    {0x0580, "Property: Generic"},
2472
    {0x0581, "Property: Enumerator Table Row Index"},
2473
    {0x0582, "Property: Enumerator Table Row Count"},
2474
    {0x0590, "Data Field: Personal Activity"},
2475
    {0x0591, "Data Field: Activity Type"},
2476
    {0x0592, "Data Field: Activity State"},
2477
    {0x0593, "Data Field: Device Position"},
2478
    {0x0594, "Data Field: Step Count"},
2479
    {0x0595, "Data Field: Step Count Reset"},
2480
    {0x0596, "Data Field: Step Duration"},
2481
    {0x0597, "Data Field: Step Type"},
2482
    {0x05A0, "Property: Minimum Activity Detection Interval"},
2483
    {0x05A1, "Property: Supported Activity Types"},
2484
    {0x05A2, "Property: Subscribed Activity Types"},
2485
    {0x05A3, "Property: Supported Step Types"},
2486
    {0x05A4, "Property: Subscribed Step Types"},
2487
    {0x05A5, "Property: Floor Height"},
2488
    {0x05B0, "Data Field: Custom Type ID"},
2489
    {0x05C0, "Property: Custom"},
2490
    {0x05C1, "Property: Custom Value 1"},
2491
    {0x05C2, "Property: Custom Value 2"},
2492
    {0x05C3, "Property: Custom Value 3"},
2493
    {0x05C4, "Property: Custom Value 4"},
2494
    {0x05C5, "Property: Custom Value 5"},
2495
    {0x05C6, "Property: Custom Value 6"},
2496
    {0x05C7, "Property: Custom Value 7"},
2497
    {0x05C8, "Property: Custom Value 8"},
2498
    {0x05C9, "Property: Custom Value 9"},
2499
    {0x05CA, "Property: Custom Value 10"},
2500
    {0x05CB, "Property: Custom Value 11"},
2501
    {0x05CC, "Property: Custom Value 12"},
2502
    {0x05CD, "Property: Custom Value 13"},
2503
    {0x05CE, "Property: Custom Value 14"},
2504
    {0x05CF, "Property: Custom Value 15"},
2505
    {0x05D0, "Property: Custom Value 16"},
2506
    {0x05E0, "Data Field: Hinge"},
2507
    {0x05E1, "Data Field: Hinge Angle"},
2508
    {0x05F0, "Data Field: Gesture Sensor"},
2509
    {0x05F1, "Data Field: Gesture State"},
2510
    {0x05F2, "Data Field: Hinge Fold Initial Angle"},
2511
    {0x05F3, "Data Field: Hinge Fold Final Angle"},
2512
    {0x05F4, "Data Field: Hinge Fold Contributing Panel"},
2513
    {0x05F5, "Data Field: Hinge Fold Type"},
2514
    {0x0800, "Sensor State: Undefined"},
2515
    {0x0801, "Sensor State: Ready"},
2516
    {0x0802, "Sensor State: Not Available"},
2517
    {0x0803, "Sensor State: No Data"},
2518
    {0x0804, "Sensor State: Initializing"},
2519
    {0x0805, "Sensor State: Access Denied"},
2520
    {0x0806, "Sensor State: Error"},
2521
    {0x0810, "Sensor Event: Unknown"},
2522
    {0x0811, "Sensor Event: State Changed"},
2523
    {0x0812, "Sensor Event: Property Changed"},
2524
    {0x0813, "Sensor Event: Data Updated"},
2525
    {0x0814, "Sensor Event: Poll Response"},
2526
    {0x0815, "Sensor Event: Change Sensitivity"},
2527
    {0x0816, "Sensor Event: Range Maximum Reached"},
2528
    {0x0817, "Sensor Event: Range Minimum Reached"},
2529
    {0x0818, "Sensor Event: High Threshold Cross Upward"},
2530
    {0x0819, "Sensor Event: High Threshold Cross Downward"},
2531
    {0x081A, "Sensor Event: Low Threshold Cross Upward"},
2532
    {0x081B, "Sensor Event: Low Threshold Cross Downward"},
2533
    {0x081C, "Sensor Event: Zero Threshold Cross Upward"},
2534
    {0x081D, "Sensor Event: Zero Threshold Cross Downward"},
2535
    {0x081E, "Sensor Event: Period Exceeded"},
2536
    {0x081F, "Sensor Event: Frequency Exceeded"},
2537
    {0x0820, "Sensor Event: Complex Trigger"},
2538
    {0x0830, "Connection Type: PC Integrated"},
2539
    {0x0831, "Connection Type: PC Attached"},
2540
    {0x0832, "Connection Type: PC External"},
2541
    {0x0840, "Reporting State: Report No Events"},
2542
    {0x0841, "Reporting State: Report All Events"},
2543
    {0x0842, "Reporting State: Report Threshold Events"},
2544
    {0x0843, "Reporting State: Wake On No Events"},
2545
    {0x0844, "Reporting State: Wake On All Events"},
2546
    {0x0845, "Reporting State: Wake On Threshold Events"},
2547
    {0x0846, "Reporting State: Anytime"},
2548
    {0x0850, "Power State: Undefined"},
2549
    {0x0851, "Power State: D0 Full Power"},
2550
    {0x0852, "Power State: D1 Low Power"},
2551
    {0x0853, "Power State: D2 Standby Power with Wakeup"},
2552
    {0x0854, "Power State: D3 Sleep with Wakeup"},
2553
    {0x0855, "Power State: D4 Power Off"},
2554
    {0x0860, "Accuracy: Default"},
2555
    {0x0861, "Accuracy: High"},
2556
    {0x0862, "Accuracy: Medium"},
2557
    {0x0863, "Accuracy: Low"},
2558
    {0x0870, "Fix Quality: No Fix"},
2559
    {0x0871, "Fix Quality: GPS"},
2560
    {0x0872, "Fix Quality: DGPS"},
2561
    {0x0880, "Fix Type: No Fix"},
2562
    {0x0881, "Fix Type: GPS SPS Mode, Fix Valid"},
2563
    {0x0882, "Fix Type: DGPS SPS Mode, Fix Valid"},
2564
    {0x0883, "Fix Type: GPS PPS Mode, Fix Valid"},
2565
    {0x0884, "Fix Type: Real Time Kinematic"},
2566
    {0x0885, "Fix Type: Float RTK"},
2567
    {0x0886, "Fix Type: Estimated (dead reckoned)"},
2568
    {0x0887, "Fix Type: Manual Input Mode"},
2569
    {0x0888, "Fix Type: Simulator Mode"},
2570
    {0x0890, "GPS Operation Mode: Manual"},
2571
    {0x0891, "GPS Operation Mode: Automatic"},
2572
    {0x08A0, "GPS Selection Mode: Autonomous"},
2573
    {0x08A1, "GPS Selection Mode: DGPS"},
2574
    {0x08A2, "GPS Selection Mode: Estimated (dead reckoned)"},
2575
    {0x08A3, "GPS Selection Mode: Manual Input"},
2576
    {0x08A4, "GPS Selection Mode: Simulator"},
2577
    {0x08A5, "GPS Selection Mode: Data Not Valid"},
2578
    {0x08B0, "GPS Status Data: Valid"},
2579
    {0x08B1, "GPS Status Data: Not Valid"},
2580
    {0x08C0, "Day of Week: Sunday"},
2581
    {0x08C1, "Day of Week: Monday"},
2582
    {0x08C2, "Day of Week: Tuesday"},
2583
    {0x08C3, "Day of Week: Wednesday"},
2584
    {0x08C4, "Day of Week: Thursday"},
2585
    {0x08C5, "Day of Week: Friday"},
2586
    {0x08C6, "Day of Week: Saturday"},
2587
    {0x08D0, "Kind: Category"},
2588
    {0x08D1, "Kind: Type"},
2589
    {0x08D2, "Kind: Event"},
2590
    {0x08D3, "Kind: Property"},
2591
    {0x08D4, "Kind: Data Field"},
2592
    {0x08E0, "Magnetometer Accuracy: Low"},
2593
    {0x08E1, "Magnetometer Accuracy: Medium"},
2594
    {0x08E2, "Magnetometer Accuracy: High"},
2595
    {0x08F0, "Simple Orientation Direction: Not Rotated"},
2596
    {0x08F1, "Simple Orientation Direction: Rotated 90 Degrees CCW"},
2597
    {0x08F2, "Simple Orientation Direction: Rotated 180 Degrees CCW"},
2598
    {0x08F3, "Simple Orientation Direction: Rotated 270 Degrees CCW"},
2599
    {0x08F4, "Simple Orientation Direction: Face Up"},
2600
    {0x08F5, "Simple Orientation Direction: Face Down"},
2601
    {0x0900, "VT_NULL: Empty"},
2602
    {0x0901, "VT_BOOL: Boolean"},
2603
    {0x0902, "VT_UI1: Byte"},
2604
    {0x0903, "VT_I1: Character"},
2605
    {0x0904, "VT_UI2: Unsigned Short"},
2606
    {0x0905, "VT_I2: Short"},
2607
    {0x0906, "VT_UI4: Unsigned Long"},
2608
    {0x0907, "VT_I4: Long"},
2609
    {0x0908, "VT_UI8: Unsigned Long Long"},
2610
    {0x0909, "VT_I8: Long Long"},
2611
    {0x090A, "VT_R4: Float"},
2612
    {0x090B, "VT_R8: Double"},
2613
    {0x090C, "VT_WSTR: Wide String"},
2614
    {0x090D, "VT_STR: Narrow String"},
2615
    {0x090E, "VT_CLSID: Guid"},
2616
    {0x090F, "VT_VECTOR|VT_UI1: Opaque Structure"},
2617
    {0x0910, "VT_F16E0: HID 16-bit Float with Unit Exponent 0"},
2618
    {0x0911, "VT_F16E1: HID 16-bit Float with Unit Exponent 1"},
2619
    {0x0912, "VT_F16E2: HID 16-bit Float with Unit Exponent 2"},
2620
    {0x0913, "VT_F16E3: HID 16-bit Float with Unit Exponent 3"},
2621
    {0x0914, "VT_F16E4: HID 16-bit Float with Unit Exponent 4"},
2622
    {0x0915, "VT_F16E5: HID 16-bit Float with Unit Exponent 5"},
2623
    {0x0916, "VT_F16E6: HID 16-bit Float with Unit Exponent 6"},
2624
    {0x0917, "VT_F16E7: HID 16-bit Float with Unit Exponent 7"},
2625
    {0x0918, "VT_F16E8: HID 16-bit Float with Unit Exponent 8"},
2626
    {0x0919, "VT_F16E9: HID 16-bit Float with Unit Exponent 9"},
2627
    {0x091A, "VT_F16EA: HID 16-bit Float with Unit Exponent A"},
2628
    {0x091B, "VT_F16EB: HID 16-bit Float with Unit Exponent B"},
2629
    {0x091C, "VT_F16EC: HID 16-bit Float with Unit Exponent C"},
2630
    {0x091D, "VT_F16ED: HID 16-bit Float with Unit Exponent D"},
2631
    {0x091E, "VT_F16EE: HID 16-bit Float with Unit Exponent E"},
2632
    {0x091F, "VT_F16EF: HID 16-bit Float with Unit Exponent F"},
2633
    {0x0920, "VT_F32E0: HID 32-bit Float with Unit Exponent 0"},
2634
    {0x0921, "VT_F32E1: HID 32-bit Float with Unit Exponent 1"},
2635
    {0x0922, "VT_F32E2: HID 32-bit Float with Unit Exponent 2"},
2636
    {0x0923, "VT_F32E3: HID 32-bit Float with Unit Exponent 3"},
2637
    {0x0924, "VT_F32E4: HID 32-bit Float with Unit Exponent 4"},
2638
    {0x0925, "VT_F32E5: HID 32-bit Float with Unit Exponent 5"},
2639
    {0x0926, "VT_F32E6: HID 32-bit Float with Unit Exponent 6"},
2640
    {0x0927, "VT_F32E7: HID 32-bit Float with Unit Exponent 7"},
2641
    {0x0928, "VT_F32E8: HID 32-bit Float with Unit Exponent 8"},
2642
    {0x0929, "VT_F32E9: HID 32-bit Float with Unit Exponent 9"},
2643
    {0x092A, "VT_F32EA: HID 32-bit Float with Unit Exponent A"},
2644
    {0x092B, "VT_F32EB: HID 32-bit Float with Unit Exponent B"},
2645
    {0x092C, "VT_F32EC: HID 32-bit Float with Unit Exponent C"},
2646
    {0x092D, "VT_F32ED: HID 32-bit Float with Unit Exponent D"},
2647
    {0x092E, "VT_F32EE: HID 32-bit Float with Unit Exponent E"},
2648
    {0x092F, "VT_F32EF: HID 32-bit Float with Unit Exponent F"},
2649
    {0x0930, "Activity Type: Unknown"},
2650
    {0x0931, "Activity Type: Stationary"},
2651
    {0x0932, "Activity Type: Fidgeting"},
2652
    {0x0933, "Activity Type: Walking"},
2653
    {0x0934, "Activity Type: Running"},
2654
    {0x0935, "Activity Type: In Vehicle"},
2655
    {0x0936, "Activity Type: Biking"},
2656
    {0x0937, "Activity Type: Idle"},
2657
    {0x0940, "Unit: Not Specified"},
2658
    {0x0941, "Unit: Lux"},
2659
    {0x0942, "Unit: Degrees Kelvin"},
2660
    {0x0943, "Unit: Degrees Celsius"},
2661
    {0x0944, "Unit: Pascal"},
2662
    {0x0945, "Unit: Newton"},
2663
    {0x0946, "Unit: Meters/Second"},
2664
    {0x0947, "Unit: Kilogram"},
2665
    {0x0948, "Unit: Meter"},
2666
    {0x0949, "Unit: Meters/Second/Second"},
2667
    {0x094A, "Unit: Farad"},
2668
    {0x094B, "Unit: Ampere"},
2669
    {0x094C, "Unit: Watt"},
2670
    {0x094D, "Unit: Henry"},
2671
    {0x094E, "Unit: Ohm"},
2672
    {0x094F, "Unit: Volt"},
2673
    {0x0950, "Unit: Hertz"},
2674
    {0x0951, "Unit: Bar"},
2675
    {0x0952, "Unit: Degrees Anti-clockwise"},
2676
    {0x0953, "Unit: Degrees Clockwise"},
2677
    {0x0954, "Unit: Degrees"},
2678
    {0x0955, "Unit: Degrees/Second"},
2679
    {0x0956, "Unit: Degrees/Second/Second"},
2680
    {0x0957, "Unit: Knot"},
2681
    {0x0958, "Unit: Percent"},
2682
    {0x0959, "Unit: Second"},
2683
    {0x095A, "Unit: Millisecond"},
2684
    {0x095B, "Unit: G"},
2685
    {0x095C, "Unit: Bytes"},
2686
    {0x095D, "Unit: Milligauss"},
2687
    {0x095E, "Unit: Bits"},
2688
    {0x0960, "Activity State: No State Change"},
2689
    {0x0961, "Activity State: Start Activity"},
2690
    {0x0962, "Activity State: End Activity"},
2691
    {0x0970, "Exponent 0: 1"},
2692
    {0x0971, "Exponent 1: 10"},
2693
    {0x0972, "Exponent 2: 100"},
2694
    {0x0973, "Exponent 3: 1 000"},
2695
    {0x0974, "Exponent 4: 10 000"},
2696
    {0x0975, "Exponent 5: 100 000"},
2697
    {0x0976, "Exponent 6: 1 000 000"},
2698
    {0x0977, "Exponent 7: 10 000 000"},
2699
    {0x0978, "Exponent 8: 0.00 000 001"},
2700
    {0x0979, "Exponent 9: 0.0 000 001"},
2701
    {0x097A, "Exponent A: 0.000 001"},
2702
    {0x097B, "Exponent B: 0.00 001"},
2703
    {0x097C, "Exponent C: 0.0 001"},
2704
    {0x097D, "Exponent D: 0.001"},
2705
    {0x097E, "Exponent E: 0.01"},
2706
    {0x097F, "Exponent F: 0.1"},
2707
    {0x0980, "Device Position: Unknown"},
2708
    {0x0981, "Device Position: Unchanged"},
2709
    {0x0982, "Device Position: On Desk"},
2710
    {0x0983, "Device Position: In Hand"},
2711
    {0x0984, "Device Position: Moving in Bag"},
2712
    {0x0985, "Device Position: Stationary in Bag"},
2713
    {0x0990, "Step Type: Unknown"},
2714
    {0x0991, "Step Type: Running"},
2715
    {0x0992, "Step Type: Walking"},
2716
    {0x09A0, "Gesture State: Unknown"},
2717
    {0x09A1, "Gesture State: Started"},
2718
    {0x09A2, "Gesture State: Completed"},
2719
    {0x09A3, "Gesture State: Cancelled"},
2720
    {0x09B0, "Hinge Fold Contributing Panel: Unknown"},
2721
    {0x09B1, "Hinge Fold Contributing Panel: Panel 1"},
2722
    {0x09B2, "Hinge Fold Contributing Panel: Panel 2"},
2723
    {0x09B3, "Hinge Fold Contributing Panel: Both"},
2724
    {0x09B4, "Hinge Fold Type: Unknown"},
2725
    {0x09B5, "Hinge Fold Type: Increasing"},
2726
    {0x09B6, "Hinge Fold Type: Decreasing"},
2727
    {0x09C0, "Human Presence Detection: Vendor-Defined Non-Biometric"},
2728
    {0x09C1, "Human Presence Detection: Vendor-Defined Biometric"},
2729
    {0x09C2, "Human Presence Detection: Facial Biometric"},
2730
    {0x09C3, "Human Presence Detection: Audio Biometric"},
2731
    {0x1000, "Modifier: Change Sensitivity Absolute"},
2732
    {0x2000, "Modifier: Maximum"},
2733
    {0x3000, "Modifier: Minimum"},
2734
    {0x4000, "Modifier: Accuracy"},
2735
    {0x5000, "Modifier: Resolution"},
2736
    {0x6000, "Modifier: Threshold High"},
2737
    {0x7000, "Modifier: Threshold Low"},
2738
    {0x8000, "Modifier: Calibration Offset"},
2739
    {0x9000, "Modifier: Calibration Multiplier"},
2740
    {0xA000, "Modifier: Report Interval"},
2741
    {0xB000, "Modifier: Frequency Max"},
2742
    {0xC000, "Modifier: Period Max"},
2743
    {0xD000, "Modifier: Change Sensitivity Percent of Range"},
2744
    {0xE000, "Modifier: Change Sensitivity Percent Relative"},
2745
    {0xF000, "Modifier: Vendor Reserved"},
2746
    {0, NULL}
2747
};
2748
static const range_string usb_hid_sensor_usage_page_ranges[] = {
2749
    {0x001A, 0x001F, "Reserved (Biometric)"},
2750
    {0x002A, 0x002F, "Reserved (Electrical)"},
2751
    {0x003C, 0x003F, "Reserved (Environmental)"},
2752
    {0x0046, 0x004F, "Reserved (Light)"},
2753
    {0x0058, 0x005F, "Reserved (Location)"},
2754
    {0x006A, 0x006F, "Reserved (Mechanical)"},
2755
    {0x007D, 0x007F, "Reserved (Motion)"},
2756
    {0x0094, 0x009F, "Reserved (Scanner)"},
2757
    {0x00A3, 0x00AF, "Reserved (Time)"},
2758
    {0x00B5, 0x00BF, "Reserved (Personal Activity)"},
2759
    {0x00C3, 0x00CF, "Reserved (Orientation Extended)"},
2760
    {0x00D3, 0x00DF, "Reserved (Gesture)"},
2761
    {0x00E5, 0x00EF, "Reserved (Other)"},
2762
    {0x00F0, 0x00FF, "Reserved for Vendors/OEMs"},
2763
    {0x031F, 0x03FF, "Reserved (Property)"},
2764
    {0x0428, 0x0429, "Reserved (Data Field: Location)"},
2765
    {0x042C, 0x042F, "Reserved (Property: Location)"},
2766
    {0x043D, 0x043F, "Reserved (Data Field: Environmental)"},
2767
    {0x0442, 0x044F, "Reserved (Property: Environmental)"},
2768
    {0x0460, 0x046F, "Reserved (Data Field: Motion)"},
2769
    {0x048A, 0x048F, "Reserved (Data Field: Orientation)"},
2770
    {0x0499, 0x049F, "Reserved (Data Field: Mechanical)"},
2771
    {0x04A4, 0x04AF, "Reserved (Property: Mechanical)"},
2772
    {0x04BD, 0x04CF, "Reserved (Data Field: Biometric)"},
2773
    {0x04E4, 0x04EF, "Reserved (Property: Light)"},
2774
    {0x04F3, 0x04F7, "Reserved (Data Field: Scanner)"},
2775
    {0x04FA, 0x04FF, "Reserved (Property: Scanner)"},
2776
    {0x050A, 0x051F, "Reserved (Data Field: Electrical)"},
2777
    {0x052C, 0x052F, "Reserved (Data Field: Time)"},
2778
    {0x0536, 0x053F, "Reserved (Property: Time)"},
2779
    {0x0577, 0x057F, "Reserved (Data Field: Generic)"},
2780
    {0x0583, 0x058F, "Reserved (Property: Generic)"},
2781
    {0x0598, 0x059F, "Reserved (Data Field: Personal Activity)"},
2782
    {0x05A6, 0x05AF, "Reserved (Property: Personal Activity)"},
2783
    {0x05B1, 0x05BF, "Reserved (Data Field: Custom)"},
2784
    {0x05C0, 0x07FF, "Reserved for future use as Sensor Types, Data Fields and Properties"},
2785
    {0x0800, 0x09FF, "Reserved for use as Selection Values"},
2786
    {0x1100, 0x17FF, "Reserved for use as Change Sensitivity Absolute modifier range"},
2787
    {0x2100, 0x27FF, "Reserved for use as Maximum modifier range"},
2788
    {0x3100, 0x37FF, "Reserved for use as Minimum modifier range"},
2789
    {0x4100, 0x47FF, "Reserved for use as Accuracy modifier range"},
2790
    {0x5100, 0x57FF, "Reserved for use as Resolution modifier range"},
2791
    {0x6100, 0x67FF, "Reserved for use as Threshold High modifier range"},
2792
    {0x7100, 0x77FF, "Reserved for use as Threshold Low modifier range"},
2793
    {0x8100, 0x87FF, "Reserved for use as Calibration Offset modifier range"},
2794
    {0x9100, 0x97FF, "Reserved for use as Calibration Multiplier modifier range"},
2795
    {0xA100, 0xA7FF, "Reserved for use as Report Interval modifier range"},
2796
    {0xB100, 0xB7FF, "Reserved for use as Frequency Max modifier range"},
2797
    {0xC100, 0xC7FF, "Reserved for use as Period Max modifier range"},
2798
    {0xD100, 0xD7FF, "Reserved for use as Change Sensitivity Percent modifier range"},
2799
    {0xE100, 0xE7FF, "Reserved for use as Change Sensitivity Percent modifier range"},
2800
    {0xF100, 0xF7FF, "Reserved for use as Vendor Reserved modifier range"},
2801
    /* More generic (and overlapping) ranges in case a better match isn't found above */
2802
    {0x1000, 0xEFFF, "Reserved for use as \"Data Fields with Modifiers\""},
2803
    {0xF000, 0xFFFF, "Reserved for Vendors/OEMs"},
2804
    {0, 0, NULL}
2805
};
2806
static const value_string usb_hid_medical_instrument_usage_page_vals[] = {
2807
    {0x00, "Undefined"},
2808
    {0x01, "Medical Ultrasound"},
2809
    {0x20, "VCR/Acquisition"},
2810
    {0x21, "Freeze/Thaw"},
2811
    {0x22, "Clip Store"},
2812
    {0x23, "Update"},
2813
    {0x24, "Next"},
2814
    {0x25, "Save"},
2815
    {0x26, "Print"},
2816
    {0x27, "Microphone Enable"},
2817
    {0x40, "Cine"},
2818
    {0x41, "Transmit Power"},
2819
    {0x42, "Volume"},
2820
    {0x43, "Focus"},
2821
    {0x44, "Depth"},
2822
    {0x60, "Soft Step - Primary"},
2823
    {0x61, "Soft Step - Secondary"},
2824
    {0x70, "Depth Gain Compensation"},
2825
    {0x80, "Zoom Select"},
2826
    {0x81, "Zoom Adjust"},
2827
    {0x82, "Spectral Doppler Mode Select"},
2828
    {0x83, "Spectral Doppler Adjust"},
2829
    {0x84, "Color Doppler Mode Select"},
2830
    {0x85, "Color Doppler Adjust"},
2831
    {0x86, "Motion Mode Select"},
2832
    {0x87, "Motion Mode Adjust"},
2833
    {0x88, "2-D Mode Select"},
2834
    {0x89, "2-D Mode Adjust"},
2835
    {0xA0, "Soft Control Select"},
2836
    {0xA1, "Soft Control Adjust"},
2837
    {0, NULL}
2838
};
2839
static const value_string usb_hid_braille_display_usage_page_vals[] = {
2840
    {0x000, "Undefined"},
2841
    {0x001, "Braille Display"},
2842
    {0x002, "Braille Row"},
2843
    {0x003, "8 Dot Braille Cell"},
2844
    {0x004, "6 Dot Braille Cell"},
2845
    {0x005, "Number of Braille Cells"},
2846
    {0x006, "Screen Reader Control"},
2847
    {0x007, "Screen Reader Identifier"},
2848
    {0x0FA, "Router Set 1"},
2849
    {0x0FB, "Router Set 2"},
2850
    {0x0FC, "Router Set 3"},
2851
    {0x100, "Router Key"},
2852
    {0x101, "Row Router Key"},
2853
    {0x200, "Braille Buttons"},
2854
    {0x201, "Braille Keyboard Dot 1"},
2855
    {0x202, "Braille Keyboard Dot 2"},
2856
    {0x203, "Braille Keyboard Dot 3"},
2857
    {0x204, "Braille Keyboard Dot 4"},
2858
    {0x205, "Braille Keyboard Dot 5"},
2859
    {0x206, "Braille Keyboard Dot 6"},
2860
    {0x207, "Braille Keyboard Dot 7"},
2861
    {0x208, "Braille Keyboard Dot 8"},
2862
    {0x209, "Braille Keyboard Space"},
2863
    {0x20A, "Braille Keyboard Left Space"},
2864
    {0x20B, "Braille Keyboard Right Space"},
2865
    {0x20C, "Braille Face Controls"},
2866
    {0x20D, "Braille Left Controls"},
2867
    {0x20E, "Braille Right Controls"},
2868
    {0x20F, "Braille Top Controls"},
2869
    {0x210, "Braille Joystick Center"},
2870
    {0x211, "Braille Joystick Up"},
2871
    {0x212, "Braille Joystick Down"},
2872
    {0x213, "Braille Joystick Left"},
2873
    {0x214, "Braille Joystick Right"},
2874
    {0x215, "Braille D-Pad Center"},
2875
    {0x216, "Braille D-Pad Up"},
2876
    {0x217, "Braille D-Pad Down"},
2877
    {0x218, "Braille D-Pad Left"},
2878
    {0x219, "Braille D-Pad Right"},
2879
    {0x21A, "Braille Pan Left"},
2880
    {0x21B, "Braille Pan Right"},
2881
    {0x21C, "Braille Rocker Up"},
2882
    {0x21D, "Braille Rocker Down"},
2883
    {0x21E, "Braille Rocker Press"},
2884
    {0, NULL}
2885
};
2886
static const value_string usb_hid_lighting_and_illumination_usage_page_vals[] = {
2887
    {0x00, "Undefined"},
2888
    {0x01, "LampArray"},
2889
    {0x02, "LampArrayAttributesReport"},
2890
    {0x03, "LampCount"},
2891
    {0x04, "BoundingBoxWidthInMicrometers"},
2892
    {0x05, "BoundingBoxHeightInMicrometers"},
2893
    {0x06, "BoundingBoxDepthInMicrometers"},
2894
    {0x07, "LampArrayKind"},
2895
    {0x08, "MinUpdateIntervalInMicroseconds"},
2896
    {0x20, "LampAttributesRequestReport"},
2897
    {0x21, "LampId"},
2898
    {0x22, "LampAttributesResponseReport"},
2899
    {0x23, "PositionXInMicrometers"},
2900
    {0x24, "PositionYInMicrometers"},
2901
    {0x25, "PositionZInMicrometers"},
2902
    {0x26, "LampPurposes"},
2903
    {0x27, "UpdateLatencyInMicroseconds"},
2904
    {0x28, "RedLevelCount"},
2905
    {0x29, "GreenLevelCount"},
2906
    {0x2A, "BlueLevelCount"},
2907
    {0x2B, "IntensityLevelCount"},
2908
    {0x2C, "IsProgrammable"},
2909
    {0x2D, "InputBinding"},
2910
    {0x50, "LampMultiUpdateReport"},
2911
    {0x51, "RedUpdateChannel"},
2912
    {0x52, "GreenUpdateChannel"},
2913
    {0x53, "BlueUpdateChannel"},
2914
    {0x54, "IntensityUpdateChannel"},
2915
    {0x55, "LampUpdateFlags"},
2916
    {0x60, "LampRangeUpdateReport"},
2917
    {0x61, "LampIdStart"},
2918
    {0x62, "LampIdEnd"},
2919
    {0x70, "LampArrayControlReport"},
2920
    {0x71, "AutonomousMode"},
2921
    {0, NULL}
2922
};
2923
static const value_string usb_hid_monitor_usage_page_vals[] = {
2924
    {0x00, "Reserved"},
2925
    {0x01, "Monitor Control"},
2926
    {0x02, "EDID Information"},
2927
    {0x03, "VDIF Information"},
2928
    {0x04, "VESA Version"},
2929
    {0, NULL}
2930
};
2931
static const value_string usb_hid_vesa_virtual_control_usage_page_vals[] = {
2932
    /* Contiguous Controls */
2933
    {0x10, "Brightness"},
2934
    {0x12, "Contrast"},
2935
    {0x16, "Red Video Gain"},
2936
    {0x18, "Green Video Gain"},
2937
    {0x1A, "Blue Video Gain"},
2938
    {0x1C, "Focus"},
2939
    {0x20, "Horizontal Position"},
2940
    {0x22, "Horizontal Size"},
2941
    {0x24, "Horizontal Pincushion"},
2942
    {0x26, "Horizontal Pincushion Balance"},
2943
    {0x28, "Horizontal Misconvergence"},
2944
    {0x2A, "Horizontal Linearity"},
2945
    {0x2C, "Horizontal Linearity Balance"},
2946
    {0x30, "Vertical Position"},
2947
    {0x32, "Vertical Size"},
2948
    {0x34, "Vertical Pincushion"},
2949
    {0x36, "Vertical Pincushion Balance"},
2950
    {0x38, "Vertical Misconvergence"},
2951
    {0x3A, "Vertical Linearity"},
2952
    {0x3C, "Vertical Linearity Balance"},
2953
    {0x40, "Parallelogram Distortion (Key Balance)"},
2954
    {0x42, "Trapezoidal Distortion (Key)"},
2955
    {0x44, "Tilt (Rotation)"},
2956
    {0x46, "Top Corner Distortion Control"},
2957
    {0x48, "Top Corner Distortion Balance"},
2958
    {0x4A, "Bottom Corner Distortion Control"},
2959
    {0x4C, "Bottom Corner Distortion Balance"},
2960
    {0x56, "Horizontal Moire"},
2961
    {0x58, "Vertical Moire"},
2962
    {0x6C, "Red Video Black Level"},
2963
    {0x6E, "Green Video Black Level"},
2964
    {0x70, "Blue Video Black Level"},
2965
    /* Non-contiguous Controls (Read/Write) */
2966
    {0x5E, "Input Level Select"},
2967
    {0x60, "Input Source Select"},
2968
    {0xCA, "On Screen Display"},
2969
    {0xD4, "StereoMode"},
2970
    /* Non-contiguous Controls (Read-only) */
2971
    {0xA2, "Auto Size Center"},
2972
    {0xA4, "Polarity Horizontal Synchronization"},
2973
    {0xA6, "Polarity Vertical Synchronization"},
2974
    {0xA8, "Synchronization Type"},
2975
    {0xAA, "Screen Orientation"},
2976
    {0xAC, "Horizontal Frequency"},
2977
    {0xAE, "Vertical Frequency"},
2978
    /* Non-contiguous Controls (Write-only) */
2979
    {0x01, "Degauss"},
2980
    {0xB0, "Settings"},
2981
    {0, NULL}
2982
};
2983
static const value_string usb_hid_power_device_usage_page_vals[] = {
2984
    {0x00, "Undefined"},
2985
    {0x01, "iName"},
2986
    {0x02, "PresentStatus"},
2987
    {0x03, "ChangedStatus"},
2988
    {0x04, "UPS"},
2989
    {0x05, "PowerSupply"},
2990
    {0x10, "BatterySystem"},
2991
    {0x11, "BatterySystemID"},
2992
    {0x12, "Battery"},
2993
    {0x13, "BatteryID"},
2994
    {0x14, "Charger"},
2995
    {0x15, "ChargerID"},
2996
    {0x16, "PowerConverter"},
2997
    {0x17, "PowerConverterID"},
2998
    {0x18, "OutletSystem"},
2999
    {0x19, "OutletSystemID"},
3000
    {0x1A, "Input"},
3001
    {0x1B, "InputID"},
3002
    {0x1C, "Output"},
3003
    {0x1D, "OutputID"},
3004
    {0x1E, "Flow"},
3005
    {0x1F, "FlowID"},
3006
    {0x20, "Outlet"},
3007
    {0x21, "OutletID"},
3008
    {0x22, "Gang"},
3009
    {0x23, "GangID"},
3010
    {0x24, "PowerSummary"},
3011
    {0x25, "PowerSummaryID"},
3012
    {0x30, "Voltage"},
3013
    {0x31, "Current"},
3014
    {0x32, "Frequency"},
3015
    {0x33, "ApparentPower"},
3016
    {0x34, "ActivePower"},
3017
    {0x35, "PercentLoad"},
3018
    {0x36, "Temperature"},
3019
    {0x37, "Humidity"},
3020
    {0x38, "BadCount"},
3021
    {0x40, "ConfigVoltage"},
3022
    {0x41, "ConfigCurrent"},
3023
    {0x42, "ConfigFrequency"},
3024
    {0x43, "ConfigApparentPower"},
3025
    {0x44, "ConfigActivePower"},
3026
    {0x45, "ConfigPercentLoad"},
3027
    {0x46, "ConfigTemperature"},
3028
    {0x47, "ConfigHumidity"},
3029
    {0x50, "SwitchOnControl"},
3030
    {0x51, "SwitchOffControl"},
3031
    {0x52, "ToggleControl"},
3032
    {0x53, "LowVoltageTransfer"},
3033
    {0x54, "HighVoltageTransfer"},
3034
    {0x55, "DelayBeforeReboot"},
3035
    {0x56, "DelayBeforeStartup"},
3036
    {0x57, "DelayBeforeShutdown"},
3037
    {0x58, "Test"},
3038
    {0x59, "ModuleReset"},
3039
    {0x5A, "AudibleAlarmControl"},
3040
    {0x60, "Present"},
3041
    {0x61, "Good"},
3042
    {0x62, "InternalFailure"},
3043
    {0x63, "VoltageOutOfRange"},
3044
    {0x64, "FrequencyOutOfRange"},
3045
    {0x65, "Overload"},
3046
    {0x66, "OverCharged"},
3047
    {0x67, "OverTemperature"},
3048
    {0x68, "ShutdownRequested"},
3049
    {0x69, "ShutdownImminent"},
3050
    {0x6B, "SwitchOn/Off"},
3051
    {0x6C, "Switchable"},
3052
    {0x6D, "Used"},
3053
    {0x6E, "Boost"},
3054
    {0x6F, "Buck"},
3055
    {0x70, "Initialized"},
3056
    {0x71, "Tested"},
3057
    {0x72, "AwaitingPower"},
3058
    {0x73, "CommunicationLost"},
3059
    {0xFD, "iManufacturer"},
3060
    {0xFE, "iProduct"},
3061
    {0xFF, "iSerialNumber"},
3062
    {0, NULL}
3063
};
3064
static const value_string usb_hid_battery_system_usage_page_vals[] = {
3065
    {0x00, "Undefined"},
3066
    {0x01, "SMBBatteryMode"},
3067
    {0x02, "SMBBatteryStatus"},
3068
    {0x03, "SMBAlarmWarning"},
3069
    {0x04, "SMBChargerMode"},
3070
    {0x05, "SMBChargerStatus"},
3071
    {0x06, "SMBChargerSpecInfo"},
3072
    {0x07, "SMBSelectorState"},
3073
    {0x08, "SMBSelectorPresets"},
3074
    {0x09, "SMBSelectorInfo"},
3075
    {0x10, "OptionalMfgFunction1"},
3076
    {0x11, "OptionalMfgFunction2"},
3077
    {0x12, "OptionalMfgFunction3"},
3078
    {0x13, "OptionalMfgFunction4"},
3079
    {0x14, "OptionalMfgFunction5"},
3080
    {0x15, "ConnectionToSMBus"},
3081
    {0x16, "OutputConnection"},
3082
    {0x17, "ChargerConnection"},
3083
    {0x18, "BatteryInsertion"},
3084
    {0x19, "Usenext"},
3085
    {0x1A, "OKToUse"},
3086
    {0x1B, "BatterySupported"},
3087
    {0x1C, "SelectorRevision"},
3088
    {0x1D, "ChargingIndicator"},
3089
    {0x28, "ManufacturerAccess"},
3090
    {0x29, "RemainingCapacityLimit"},
3091
    {0x2A, "RemainingTimeLimit"},
3092
    {0x2B, "AtRate"},
3093
    {0x2C, "CapacityMode"},
3094
    {0x2D, "BroadcastToCharger"},
3095
    {0x2E, "PrimaryBattery"},
3096
    {0x2F, "ChargeController"},
3097
    {0x40, "TerminateCharge"},
3098
    {0x41, "TerminateDischarge"},
3099
    {0x42, "BelowRemainingCapacityLimit"},
3100
    {0x43, "RemainingTimeLimitExpired"},
3101
    {0x44, "Charging"},
3102
    {0x45, "Discharging"},
3103
    {0x46, "FullyCharged"},
3104
    {0x47, "FullyDischarged"},
3105
    {0x48, "ConditioningFlag"},
3106
    {0x49, "AtRateOK"},
3107
    {0x4A, "SMBErrorCode"},
3108
    {0x4B, "NeedReplacement"},
3109
    {0x60, "AtRateTimeToFull"},
3110
    {0x61, "AtRateTimeToEmpty"},
3111
    {0x62, "AverageCurrent"},
3112
    {0x63, "MaxError"},
3113
    {0x64, "RelativeStateOfCharge"},
3114
    {0x65, "AbsoluteStateOfCharge"},
3115
    {0x66, "RemainingCapacity"},
3116
    {0x67, "FullChargeCapacity"},
3117
    {0x68, "RunTimeToEmpty"},
3118
    {0x69, "AverageTimeToEmpty"},
3119
    {0x6A, "AverageTimeToFull"},
3120
    {0x6B, "CycleCount"},
3121
    {0x80, "BattPackModelLevel"},
3122
    {0x81, "InternalChargeController"},
3123
    {0x82, "PrimaryBatterySupport"},
3124
    {0x83, "DesignCapacity"},
3125
    {0x84, "SpecificationInfo"},
3126
    {0x85, "ManufacturerDate"},
3127
    {0x86, "SerialNumber"},
3128
    {0x87, "iManufacturerName"},
3129
    {0x88, "iDeviceName"},
3130
    {0x89, "iDeviceChemistry"},
3131
    {0x8A, "ManufacturerData"},
3132
    {0x8B, "Rechargeable"},
3133
    {0x8C, "WarningCapacityLimit"},
3134
    {0x8D, "CapacityGranularity1"},
3135
    {0x8E, "CapacityGranularity2"},
3136
    {0x8F, "iOEMInformation"},
3137
    {0xC0, "InhibitCharge"},
3138
    {0xC1, "EnablePolling"},
3139
    {0xC2, "ResetToZero"},
3140
    {0xD0, "ACPresent"},
3141
    {0xD1, "BatteryPresent"},
3142
    {0xD2, "PowerFail"},
3143
    {0xD3, "AlarmInhibited"},
3144
    {0xD4, "ThermistorUnderRange"},
3145
    {0xD5, "ThermistorHot"},
3146
    {0xD6, "ThermistorCold"},
3147
    {0xD7, "ThermistorOverRange"},
3148
    {0xD8, "VoltageOutOfRange"},
3149
    {0xD9, "CurrentOutOfRange"},
3150
    {0xDA, "CurrentNotRegulated"},
3151
    {0xDB, "VoltageNotRegulated"},
3152
    {0xDC, "MasterMode"},
3153
    {0xF0, "ChargerSelectorSupport"},
3154
    {0xF1, "ChargerSpec"},
3155
    {0xF2, "Level2"},
3156
    {0xF3, "Level3"},
3157
    {0, NULL}
3158
};
3159
static const value_string usb_hid_barcode_scanner_usage_page_vals[] = {
3160
    {0x000, "Undefined"},
3161
    {0x001, "Bar Code Badge Reader"},
3162
    {0x002, "Bar Code Scanner"},
3163
    {0x003, "Dumb Bar Code Scanner"},
3164
    {0x004, "Cordless Scanner Base"},
3165
    {0x005, "Bar Code Scanner Cradle"},
3166
    {0x010, "Attribute Report"},
3167
    {0x011, "Settings Report"},
3168
    {0x012, "Scanned Data Report"},
3169
    {0x013, "Raw Scanned Data Report"},
3170
    {0x014, "Trigger Report"},
3171
    {0x015, "Status Report"},
3172
    {0x016, "UPC/EAN Control Report"},
3173
    {0x017, "EAN 2/3 Label Control Report"},
3174
    {0x018, "Code 39 Control Report"},
3175
    {0x019, "Interleaved 2 of 5 Control Report"},
3176
    {0x01A, "Standard 2 of 5 Control Report"},
3177
    {0x01B, "MSI Plessey Control Report"},
3178
    {0x01C, "Codabar Control Report"},
3179
    {0x01D, "Code 128 Control Report"},
3180
    {0x01E, "Misc 1D Control Report"},
3181
    {0x01F, "2D Control Report"},
3182
    {0x030, "Aiming/Pointer Mode"},
3183
    {0x031, "Bar Code Present Sensor"},
3184
    {0x032, "Class 1A Laser"},
3185
    {0x033, "Class 2 Laser"},
3186
    {0x034, "Heater Present"},
3187
    {0x035, "Contact Scanner"},
3188
    {0x036, "Electronic Article Surveillance Notification"},
3189
    {0x037, "Constant Electronic Article Surveillance"},
3190
    {0x038, "Error Indication"},
3191
    {0x039, "Fixed Beeper"},
3192
    {0x03A, "Good Decode Indication"},
3193
    {0x03B, "Hands Free Scanning"},
3194
    {0x03C, "Intrinsically Safe"},
3195
    {0x03D, "Klasse Eins Laser"},
3196
    {0x03E, "Long Range Scanner"},
3197
    {0x03F, "Mirror Speed Control"},
3198
    {0x040, "Not On File Indication"},
3199
    {0x041, "Programmable Beeper"},
3200
    {0x042, "Triggerless"},
3201
    {0x043, "Wand"},
3202
    {0x044, "Water Resistant"},
3203
    {0x045, "Multi-Range Scanner"},
3204
    {0x046, "Proximity Sensor"},
3205
    {0x04D, "Fragment Decoding"},
3206
    {0x04E, "Scanner Read Confidence"},
3207
    {0x04F, "Data Prefix"},
3208
    {0x050, "Prefix AIMI"},
3209
    {0x051, "Prefix None"},
3210
    {0x052, "Prefix Proprietary"},
3211
    {0x055, "Active Time"},
3212
    {0x056, "Aiming Laser Pattern"},
3213
    {0x057, "Bar Code Present"},
3214
    {0x058, "Beeper State"},
3215
    {0x059, "Laser On Time"},
3216
    {0x05A, "Laser State"},
3217
    {0x05B, "Lockout Time"},
3218
    {0x05C, "Motor State"},
3219
    {0x05D, "Motor Timeout"},
3220
    {0x05E, "Power On Reset Scanner"},
3221
    {0x05F, "Prevent Read of Barcodes"},
3222
    {0x060, "Initiate Barcode Read"},
3223
    {0x061, "Trigger State"},
3224
    {0x062, "Trigger Mode"},
3225
    {0x063, "Trigger Mode Blinking Laser On"},
3226
    {0x064, "Trigger Mode Continuous Laser On"},
3227
    {0x065, "Trigger Mode Laser on while Pulled"},
3228
    {0x066, "Trigger Mode Laser stays on after Trigger release"},
3229
    {0x06D, "Commit Parameters to NVM"},
3230
    {0x06E, "Parameter Scanning"},
3231
    {0x06F, "Parameters Changed"},
3232
    {0x070, "Set parameter default values"},
3233
    {0x075, "Scanner In Cradle"},
3234
    {0x076, "Scanner In Range"},
3235
    {0x07A, "Aim Duration"},
3236
    {0x07B, "Good Read Lamp Duration"},
3237
    {0x07C, "Good Read Lamp Intensity"},
3238
    {0x07D, "Good Read LED"},
3239
    {0x07E, "Good Read Tone Frequency"},
3240
    {0x07F, "Good Read Tone Length"},
3241
    {0x080, "Good Read Tone Volume"},
3242
    {0x082, "No Read Message"},
3243
    {0x083, "Not on File Volume"},
3244
    {0x084, "Powerup Beep"},
3245
    {0x085, "Sound Error Beep"},
3246
    {0x086, "Sound Good Read Beep"},
3247
    {0x087, "Sound Not On File Beep"},
3248
    {0x088, "Good Read When to Write"},
3249
    {0x089, "GRWTI After Decode"},
3250
    {0x08A, "GRWTI Beep/Lamp after transmit"},
3251
    {0x08B, "GRWTI No Beep/Lamp use at all"},
3252
    {0x091, "Bookland EAN"},
3253
    {0x092, "Convert EAN 8 to 13 Type"},
3254
    {0x093, "Convert UPC A to EAN-13"},
3255
    {0x094, "Convert UPC-E to A"},
3256
    {0x095, "EAN-13"},
3257
    {0x096, "EAN-8"},
3258
    {0x097, "EAN-99 128_Mandatory"},
3259
    {0x098, "EAN-99 P5/128_Optional"},
3260
    {0x099, "Enable EAN Two Label"},
3261
    {0x09A, "UPC/EAN"},
3262
    {0x09B, "UPC/EAN Coupon Code"},
3263
    {0x09C, "UPC/EAN Periodicals"},
3264
    {0x09D, "UPC-A"},
3265
    {0x09E, "UPC-A with 128 Mandatory"},
3266
    {0x09F, "UPC-A with 128 Optional"},
3267
    {0x0A0, "UPC-A with P5 Optional"},
3268
    {0x0A1, "UPC-E"},
3269
    {0x0A2, "UPC-E1"},
3270
    {0x0A9, "Periodical"},
3271
    {0x0AA, "Periodical Auto-Discriminate + 2"},
3272
    {0x0AB, "Periodical Only Decode with + 2"},
3273
    {0x0AC, "Periodical Ignore + 2"},
3274
    {0x0AD, "Periodical Auto-Discriminate + 5"},
3275
    {0x0AE, "Periodical Only Decode with + 5"},
3276
    {0x0AF, "Periodical Ignore + 5"},
3277
    {0x0B0, "Check"},
3278
    {0x0B1, "Check Disable Price"},
3279
    {0x0B2, "Check Enable 4 digit Price"},
3280
    {0x0B3, "Check Enable 5 digit Price"},
3281
    {0x0B4, "Check Enable European 4 digit Price"},
3282
    {0x0B5, "Check Enable European 5 digit Price"},
3283
    {0x0B7, "EAN Two Label"},
3284
    {0x0B8, "EAN Three Label"},
3285
    {0x0B9, "EAN 8 Flag Digit 1"},
3286
    {0x0BA, "EAN 8 Flag Digit 2"},
3287
    {0x0BB, "EAN 8 Flag Digit 3"},
3288
    {0x0BC, "EAN 13 Flag Digit 1"},
3289
    {0x0BD, "EAN 13 Flag Digit 2"},
3290
    {0x0BE, "EAN 13 Flag Digit 3"},
3291
    {0x0BF, "Add EAN 2/3 Label Definition"},
3292
    {0x0C0, "Clear all EAN 2/3 Label Definitions"},
3293
    {0x0C3, "Codabar"},
3294
    {0x0C4, "Code 128"},
3295
    {0x0C7, "Code 39"},
3296
    {0x0C8, "Code 93 "},
3297
    {0x0C9, "Full ASCII Conversion"},
3298
    {0x0CA, "Interleaved 2 of 5"},
3299
    {0x0CB, "Italian Pharmacy Code"},
3300
    {0x0CC, "MSI/Plessey"},
3301
    {0x0CD, "Standard 2 of 5 IATA"},
3302
    {0x0CE, "Standard 2 of 5"},
3303
    {0x0D3, "Transmit Start/Stop"},
3304
    {0x0D4, "Tri-Optic"},
3305
    {0x0D5, "UCC/EAN-128"},
3306
    {0x0D6, "Check Digit"},
3307
    {0x0D7, "Check Digit Disable"},
3308
    {0x0D8, "Check Digit Enable Interleaved 2 of 5 OPCC"},
3309
    {0x0D9, "Check Digit Enable Interleaved 2 of 5 USS"},
3310
    {0x0DA, "Check Digit Enable Standard 2 of 5 OPCC"},
3311
    {0x0DB, "Check Digit Enable Standard 2 of 5 USS"},
3312
    {0x0DC, "Check Digit Enable One MSI Plessey"},
3313
    {0x0DD, "Check Digit Enable Two MSI Plessey"},
3314
    {0x0DE, "Check Digit Codabar Enable"},
3315
    {0x0DF, "Check Digit Code 39 Enable"},
3316
    {0x0F0, "Transmit Check Digit"},
3317
    {0x0F1, "Disable Check Digit Transmit"},
3318
    {0x0F2, "Enable Check Digit Transmit"},
3319
    {0x0FB, "Symbology Identifier 1"},
3320
    {0x0FC, "Symbology Identifier 2"},
3321
    {0x0FD, "Symbology Identifier 3"},
3322
    {0x0FE, "Decoded Data"},
3323
    {0x0FF, "Decode Data Continued"},
3324
    {0x100, "Bar Space Data"},
3325
    {0x101, "Scanner Data Accuracy"},
3326
    {0x102, "Raw Data Polarity"},
3327
    {0x103, "Polarity Inverted Bar Code"},
3328
    {0x104, "Polarity Normal Bar Code"},
3329
    {0x106, "Minimum Length to Decode"},
3330
    {0x107, "Maximum Length to Decode"},
3331
    {0x108, "First Discrete Length to Decode"},
3332
    {0x109, "Second Discrete Length to Decode"},
3333
    {0x10A, "Data Length Method"},
3334
    {0x10B, "DL Method Read any"},
3335
    {0x10C, "DL Method Check in Range"},
3336
    {0x10D, "DL Method Check for Discrete"},
3337
    {0x110, "Aztec Code"},
3338
    {0x111, "BC412"},
3339
    {0x112, "Channel Code"},
3340
    {0x113, "Code 16"},
3341
    {0x114, "Code 32"},
3342
    {0x115, "Code 49"},
3343
    {0x116, "Code One"},
3344
    {0x117, "Colorcode"},
3345
    {0x118, "Data Matrix"},
3346
    {0x119, "MaxiCode"},
3347
    {0x11A, "MicroPDF"},
3348
    {0x11B, "PDF-417"},
3349
    {0x11C, "PosiCode"},
3350
    {0x11D, "QR Code"},
3351
    {0x11E, "SuperCode"},
3352
    {0x11F, "UltraCode"},
3353
    {0x120, "USD-5 (Slug Code)"},
3354
    {0x121, "VeriCode"},
3355
    {0, NULL}
3356
};
3357
static const value_string usb_hid_weighing_devices_usage_page_vals[] = {
3358
    {0x00, "Undefined"},
3359
    {0x01, "Weighing Device"},
3360
    {0x20, "Scale Device"},
3361
    {0x21, "Scale Class I Metric"},
3362
    {0x22, "Scale Class I Metric"},
3363
    {0x23, "Scale Class II Metric"},
3364
    {0x24, "Scale Class III Metric"},
3365
    {0x25, "Scale Class IIIL Metric"},
3366
    {0x26, "Scale Class IV Metric"},
3367
    {0x27, "Scale Class III English"},
3368
    {0x28, "Scale Class IIIL English"},
3369
    {0x29, "Scale Class IV English"},
3370
    {0x2A, "Scale Class Generic"},
3371
    {0x30, "Scale Attribute Report"},
3372
    {0x31, "Scale Control Report"},
3373
    {0x32, "Scale Data Report"},
3374
    {0x33, "Scale Status Report"},
3375
    {0x34, "Scale Weight Limit Report"},
3376
    {0x35, "Scale Statistics Report"},
3377
    {0x40, "Data Weight"},
3378
    {0x41, "Data Scaling"},
3379
    {0x50, "Weight Unit"},
3380
    {0x51, "Weight Unit Milligram"},
3381
    {0x52, "Weight Unit Gram"},
3382
    {0x53, "Weight Unit Kilogram"},
3383
    {0x54, "Weight Unit Carats"},
3384
    {0x55, "Weight Unit Taels"},
3385
    {0x56, "Weight Unit Grains"},
3386
    {0x57, "Weight Unit Pennyweights"},
3387
    {0x58, "Weight Unit Metric Ton"},
3388
    {0x59, "Weight Unit Avoir Ton"},
3389
    {0x5A, "Weight Unit Troy Ounce"},
3390
    {0x5B, "Weight Unit Ounce"},
3391
    {0x5C, "Weight Unit Pound"},
3392
    {0x60, "Calibration Count"},
3393
    {0x61, "Re-Zero Count"},
3394
    {0x70, "Scale Status"},
3395
    {0x71, "Scale Status Fault"},
3396
    {0x72, "Scale Status Stable at Center of Zero"},
3397
    {0x73, "Scale Status In Motion"},
3398
    {0x74, "Scale Status Weight Stable"},
3399
    {0x75, "Scale Status Under Zero"},
3400
    {0x76, "Scale Status Over Weight Limit"},
3401
    {0x77, "Scale Status Requires Calibration"},
3402
    {0x78, "Scale Status Requires Re- zeroing"},
3403
    {0x80, "Zero Scale"},
3404
    {0x81, "Enforced Zero Return"},
3405
    {0, NULL}
3406
};
3407
static const value_string usb_hid_magnetic_stripe_reader_usage_page_vals[] = {
3408
    {0x00, "Undefined"},
3409
    {0x01, "MSR Device Read-Only"},
3410
    {0x11, "Track 1 Length"},
3411
    {0x12, "Track 2 Length"},
3412
    {0x13, "Track 3 Length"},
3413
    {0x14, "Track JIS Length"},
3414
    {0x20, "Track Data"},
3415
    {0x21, "Track 1 Data"},
3416
    {0x22, "Track 2 Data"},
3417
    {0x23, "Track 3 Data"},
3418
    {0x24, "Track JIS Data"},
3419
    {0, NULL}
3420
};
3421
static const value_string usb_hid_camera_control_usage_page_vals[] = {
3422
    {0x00, "Undefined"},
3423
    {0x20, "Camera Auto-focus"},
3424
    {0x21, "Camera Shutter"},
3425
    {0, NULL}
3426
};
3427
static const value_string usb_hid_arcade_usage_page_vals[] = {
3428
    {0x00, "Undefined"},
3429
    {0x01, "General Purpose IO Card"},
3430
    {0x02, "Coin Door"},
3431
    {0x03, "Watchdog Timer"},
3432
    {0x30, "General Purpose Analog Input State"},
3433
    {0x31, "General Purpose Digital Input State"},
3434
    {0x32, "General Purpose Optical Input State"},
3435
    {0x33, "General Purpose Digital Output State"},
3436
    {0x34, "Number of Coin Doors"},
3437
    {0x35, "Coin Drawer Drop Count"},
3438
    {0x36, "Coin Drawer Start"},
3439
    {0x37, "Coin Drawer Service"},
3440
    {0x38, "Coin Drawer Tilt"},
3441
    {0x39, "Coin Door Test"},
3442
    {0x3F, "[Undefined]"},
3443
    {0x40, "Coin Door Lockout"},
3444
    {0x41, "Watchdog Timeout"},
3445
    {0x42, "Watchdog Action"},
3446
    {0x43, "Watchdog Reboot"},
3447
    {0x44, "Watchdog Restart"},
3448
    {0x45, "Alarm Input"},
3449
    {0x46, "Coin Door Counter"},
3450
    {0x47, "I/O Direction Mapping"},
3451
    {0x48, "Set I/O Direction"},
3452
    {0x49, "Extended Optical Input State"},
3453
    {0x4A, "Pin Pad Input State"},
3454
    {0x4B, "Pin Pad Status"},
3455
    {0x4C, "Pin Pad Output"},
3456
    {0x4D, "Pin Pad Command"},
3457
    {0, NULL}
3458
};
3459
static const value_string usb_hid_fido_alliance_usage_page_vals[] = {
3460
    {0x00, "Undefined"},
3461
    {0x01, "U2F Authenticator Device"},
3462
    {0x20, "Input Report Data"},
3463
    {0x21, "Output Report Data"},
3464
    {0, NULL}
3465
};
3466
3467
static const value_string keycode_vals[] = {
3468
    {0x00, "<ACTION KEY UP>"},
3469
    {0x01, "ErrorRollOver"},
3470
    {0x02, "POSTFail"},
3471
    {0x03, "ErrorUndefined"},
3472
3473
    {0x04, "a"},
3474
    {0x05, "b"},
3475
    {0x06, "c"},
3476
    {0x07, "d"},
3477
    {0x08, "e"},
3478
    {0x09, "f"},
3479
    {0x0A, "g"},
3480
    {0x0B, "h"},
3481
    {0x0C, "i"},
3482
    {0x0D, "j"},
3483
    {0x0E, "k"},
3484
    {0x0F, "l"},
3485
    {0x10, "m"},
3486
    {0x11, "n"},
3487
    {0x12, "o"},
3488
    {0x13, "p"},
3489
    {0x14, "q"},
3490
    {0x15, "r"},
3491
    {0x16, "s"},
3492
    {0x17, "t"},
3493
    {0x18, "u"},
3494
    {0x19, "v"},
3495
    {0x1A, "w"},
3496
    {0x1B, "x"},
3497
    {0x1C, "y"},
3498
    {0x1D, "z"},
3499
3500
    {0x1E, "1"},
3501
    {0x1F, "2"},
3502
    {0x20, "3"},
3503
    {0x21, "4"},
3504
    {0x22, "5"},
3505
    {0x23, "6"},
3506
    {0x24, "7"},
3507
    {0x25, "8"},
3508
    {0x26, "9"},
3509
    {0x27, "0"},
3510
3511
    {0x28, "ENTER"},
3512
    {0x29, "Escape"},
3513
    {0x2A, "Backspace"},
3514
    {0x2B, "Tab"},
3515
    {0x2C, "Spacebar"},
3516
3517
    {0x2D, "-"},
3518
    {0x2E, "="},
3519
    {0x2F, "["},
3520
    {0x30, "]"},
3521
    {0x31, "\\"},
3522
    {0x32, "NonUS #/~"},
3523
    {0x33, ";"},
3524
    {0x34, "'"},
3525
    {0x35, "`"},
3526
    {0x36, ","},
3527
    {0x37, "."},
3528
    {0x38, "/"},
3529
    {0x39, "CapsLock"},
3530
    {0x3A, "F1"},
3531
    {0x3B, "F2"},
3532
    {0x3C, "F3"},
3533
    {0x3D, "F4"},
3534
    {0x3E, "F5"},
3535
    {0x3F, "F6"},
3536
    {0x40, "F7"},
3537
    {0x41, "F8"},
3538
    {0x42, "F9"},
3539
    {0x43, "F10"},
3540
    {0x44, "F11"},
3541
    {0x45, "F12"},
3542
    {0x46, "PrintScreen"},
3543
    {0x47, "ScrollLock"},
3544
    {0x48, "Pause"},
3545
    {0x49, "Insert"},
3546
    {0x4A, "Home"},
3547
    {0x4B, "PageUp"},
3548
    {0x4C, "DeleteForward"},
3549
    {0x4D, "End"},
3550
    {0x4E, "PageDown"},
3551
    {0x4F, "RightArrow"},
3552
    {0x50, "LeftArrow"},
3553
    {0x51, "DownArrow"},
3554
    {0x52, "UpArrow"},
3555
    {0x53, "NumLock"},
3556
3557
    /* Keypad */
3558
    {0x54, "Keypad /"},
3559
    {0x55, "Keypad *"},
3560
    {0x56, "Keypad -"},
3561
    {0x57, "Keypad +"},
3562
    {0x58, "Keypad ENTER"},
3563
    {0x59, "Keypad 1"},
3564
    {0x5A, "Keypad 2"},
3565
    {0x5B, "Keypad 3"},
3566
    {0x5C, "Keypad 4"},
3567
    {0x5D, "Keypad 5"},
3568
    {0x5E, "Keypad 6"},
3569
    {0x5F, "Keypad 7"},
3570
    {0x60, "Keypad 8"},
3571
    {0x61, "Keypad 9"},
3572
    {0x62, "Keypad 0"},
3573
    {0x63, "Keypad ."},
3574
3575
    /* non PC AT */
3576
    {0x64, "NonUS \\/|"},
3577
    {0x65, "Application"},
3578
    {0x66, "Power"},
3579
    {0x67, "Keypad ="},
3580
    {0x68, "F13"},
3581
    {0x69, "F14"},
3582
    {0x6A, "F15"},
3583
    {0x6B, "F16"},
3584
    {0x6C, "F17"},
3585
    {0x6D, "F18"},
3586
    {0x6E, "F19"},
3587
    {0x6F, "F20"},
3588
3589
    {0x70, "F21"},
3590
    {0x71, "F22"},
3591
    {0x72, "F23"},
3592
    {0x73, "F24"},
3593
    {0x74, "Execute"},
3594
    {0x75, "Help"},
3595
    {0x76, "Menu"},
3596
    {0x77, "Select"},
3597
    {0x78, "Stop"},
3598
    {0x79, "Again"},
3599
    {0x7A, "Undo"},
3600
    {0x7B, "Cut"},
3601
    {0x7C, "Copy"},
3602
    {0x7D, "Paste"},
3603
    {0x7E, "Find"},
3604
    {0x7F, "Mute"},
3605
3606
    {0x80, "VolumeUp"},
3607
    {0x81, "VolumeDown"},
3608
    {0x82, "Locking CapsLock"},
3609
    {0x83, "Locking NumLock"},
3610
    {0x84, "Locking ScrollLock"},
3611
    {0x85, "Keypad Comma"},
3612
    {0x86, "Keypad EqualSign"},
3613
    {0x87, "International1"},
3614
    {0x88, "International2"},
3615
    {0x89, "International3"},
3616
    {0x8A, "International4"},
3617
    {0x8B, "International5"},
3618
    {0x8C, "International6"},
3619
    {0x8D, "International7"},
3620
    {0x8E, "International8"},
3621
    {0x8F, "International9"},
3622
3623
    {0x90, "LANG1"},
3624
    {0x91, "LANG2"},
3625
    {0x92, "LANG3"},
3626
    {0x93, "LANG4"},
3627
    {0x94, "LANG5"},
3628
    {0x95, "LANG6"},
3629
    {0x96, "LANG7"},
3630
    {0x97, "LANG8"},
3631
    {0x98, "LANG9"},
3632
    {0x99, "AlternateErase"},
3633
    {0x9A, "SysReq/Attention"},
3634
    {0x9B, "Cancel"},
3635
    {0x9C, "Clear"},
3636
    {0x9D, "Prior"},
3637
    {0x9E, "Return"},
3638
    {0x9F, "Separator"},
3639
3640
    {0xA0, "Out"},
3641
    {0xA1, "Oper"},
3642
    {0xA2, "Clear/Again"},
3643
    {0xA3, "CrSel/Props"},
3644
    {0xA4, "ExSel"},
3645
    /* 0xA5..0xAF - reserved */
3646
    {0xB0, "Keypad 00"},
3647
    {0xB1, "Keypad 000"},
3648
    {0xB2, "ThousandsSeparator"},
3649
    {0xB3, "DecimalSeparator"},
3650
    {0xB4, "CurrencyUnit"},
3651
    {0xB5, "CurrencySubunit"},
3652
    {0xB6, "Keypad ("},
3653
    {0xB7, "Keypad )"},
3654
    {0xB8, "Keypad {"},
3655
    {0xB9, "Keypad }"},
3656
    {0xBA, "Keypad Tab"},
3657
    {0xBB, "Keypad Backspace"},
3658
    {0xBC, "Keypad A"},
3659
    {0xBD, "Keypad B"},
3660
    {0xBE, "Keypad C"},
3661
    {0xBF, "Keypad D"},
3662
3663
    {0xC0, "Keypad E"},
3664
    {0xC1, "Keypad F"},
3665
    {0xC2, "Keypad XOR"},
3666
    {0xC3, "Keypad ^"},
3667
    {0xC4, "Keypad %"},
3668
    {0xC5, "Keypad <"},
3669
    {0xC6, "Keypad >"},
3670
    {0xC7, "Keypad &"},
3671
    {0xC8, "Keypad &&"},
3672
    {0xC9, "Keypad |"},
3673
    {0xCA, "Keypad ||"},
3674
    {0xCB, "Keypad :"},
3675
    {0xCC, "Keypad #"},
3676
    {0xCD, "Keypad Space"},
3677
    {0xCE, "Keypad @"},
3678
    {0xCF, "Keypad !"},
3679
3680
    {0xD0, "Keypad Memory Store"},
3681
    {0xD1, "Keypad Memory Recall"},
3682
    {0xD2, "Keypad Memory Clear"},
3683
    {0xD3, "Keypad Memory Add"},
3684
    {0xD4, "Keypad Memory Subtract"},
3685
    {0xD5, "Keypad Memory Multiply"},
3686
    {0xD6, "Keypad Memory Divide"},
3687
    {0xD7, "Keypad +/-"},
3688
    {0xD8, "Keypad Clear"},
3689
    {0xD9, "Keypad Clear Entry"},
3690
    {0xDA, "Keypad Binary"},
3691
    {0xDB, "Keypad Octal"},
3692
    {0xDC, "Keypad Decimal"},
3693
    {0xDD, "Keypad Hexadecimal"},
3694
    /* 0xDE..0xDF - reserved,  */
3695
    {0xE0, "LeftControl"},
3696
    {0xE1, "LeftShift"},
3697
    {0xE2, "LeftAlt"},
3698
    {0xE3, "LeftGUI"},
3699
    {0xE4, "RightControl"},
3700
    {0xE5, "RightShift"},
3701
    {0xE6, "RightAlt"},
3702
    {0xE7, "RightGUI"},
3703
3704
    {0, NULL}
3705
};
3706
static value_string_ext keycode_vals_ext = VALUE_STRING_EXT_INIT(keycode_vals);
3707
3708
static uint32_t
3709
hid_unpack_value(uint8_t *data, unsigned int idx, unsigned int size)
3710
0
{
3711
0
    uint32_t value = 0;
3712
3713
0
    for(unsigned int i = 1; i <= size; i++)
3714
0
        value |= data[idx + i] << (8 * (i - 1));
3715
3716
0
    return value;
3717
0
}
3718
3719
static bool
3720
hid_unpack_signed(uint8_t *data, unsigned int idx, unsigned int size, int32_t *value)
3721
0
{
3722
0
    if (size == 1)
3723
0
        *value = (int8_t) hid_unpack_value(data, idx, size);
3724
0
    else if (size == 2)
3725
0
        *value = (int16_t) hid_unpack_value(data, idx, size);
3726
0
    else if (size == 4)
3727
0
        *value = (int32_t) hid_unpack_value(data, idx, size);
3728
0
    else
3729
0
        return true;
3730
3731
0
    return false;
3732
0
}
3733
3734
0
#define MAX_REPORT_DESCRIPTOR_COUNT 100000 // Arbitrary
3735
static bool
3736
parse_report_descriptor(report_descriptor_t *rdesc)
3737
0
{
3738
0
    hid_field_t field;
3739
0
    uint8_t *data = rdesc->desc_body;
3740
0
    unsigned int tag, type, size;
3741
0
    uint8_t prefix;
3742
0
    uint32_t defined = 0, usage_page = 0, usage = 0, usage_min = 0, usage_max = 0;
3743
0
    wmem_allocator_t *scope = wmem_file_scope();
3744
0
    bool first_item = true;
3745
3746
0
    memset(&field, 0, sizeof(field));
3747
0
    field.usages = wmem_array_new(scope, sizeof(uint32_t));
3748
0
    rdesc->fields_in = wmem_array_new(scope, sizeof(hid_field_t));
3749
0
    rdesc->fields_out = wmem_array_new(scope, sizeof(hid_field_t));
3750
3751
0
    int i = 0;
3752
0
    while (i < rdesc->desc_length)
3753
0
    {
3754
0
        prefix = data[i];
3755
0
        tag = (prefix & 0b11110000) >> 4;
3756
0
        type = (prefix & 0b00001100) >> 2;
3757
0
        size = prefix & 0b00000011;
3758
3759
0
        if (size == 3)  /* HID spec: 6.2.2.2 - Short Items */
3760
0
            size = 4;
3761
3762
0
        switch (type)
3763
0
        {
3764
0
            case USBHID_ITEMTYPE_MAIN:
3765
0
                switch (tag)
3766
0
                {
3767
0
                    case USBHID_MAINITEM_TAG_INPUT:
3768
0
                        field.properties = hid_unpack_value(data, i, size);
3769
3770
0
                        if ((defined & HID_REQUIRED_MASK) != HID_REQUIRED_MASK)
3771
0
                            goto err;
3772
3773
                        /* new field */
3774
0
                        wmem_array_append_one(rdesc->fields_in, field);
3775
3776
0
                        field.usages = wmem_array_new(scope, sizeof(uint32_t));
3777
0
                        first_item = false;
3778
3779
                        /* only keep the global items */
3780
0
                        defined &= HID_GLOBAL_MASK;
3781
0
                        break;
3782
3783
0
                    case USBHID_MAINITEM_TAG_OUTPUT:
3784
0
                        field.properties = hid_unpack_value(data, i, size);
3785
3786
0
                        if ((defined & HID_REQUIRED_MASK) != HID_REQUIRED_MASK)
3787
0
                            goto err;
3788
3789
                        /* new field */
3790
0
                        wmem_array_append_one(rdesc->fields_out, field);
3791
3792
0
                        field.usages = wmem_array_new(scope, sizeof(uint32_t));
3793
0
                        first_item = false;
3794
3795
0
                        defined &= HID_GLOBAL_MASK;
3796
0
                        break;
3797
3798
0
                    case USBHID_MAINITEM_TAG_FEATURE:
3799
                        /*
3800
                        field.properties = hid_unpack_value(data, i, size);
3801
                        TODO
3802
                        */
3803
0
                        break;
3804
3805
0
                    case USBHID_MAINITEM_TAG_COLLECTION:
3806
                        /* clear usages */
3807
0
                        wmem_free(scope, field.usages);
3808
0
                        field.usages = wmem_array_new(scope, sizeof(uint32_t));
3809
0
                        break;
3810
3811
0
                    default:
3812
0
                        break;
3813
0
                }
3814
0
                break;
3815
3816
0
            case USBHID_ITEMTYPE_GLOBAL:
3817
0
                switch (tag)
3818
0
                {
3819
0
                    case USBHID_GLOBALITEM_TAG_USAGE_PAGE:
3820
0
                        usage_page = hid_unpack_value(data, i, size);
3821
0
                        if (usage_page > UINT16_MAX)
3822
0
                            goto err;
3823
0
                        defined |= HID_USAGE_PAGE;
3824
0
                        break;
3825
3826
0
                    case USBHID_GLOBALITEM_TAG_LOG_MIN:
3827
0
                        if (hid_unpack_signed(data, i, size, &field.logical_min))
3828
0
                            goto err;
3829
0
                        defined |= HID_LOGICAL_MIN;
3830
0
                        break;
3831
3832
0
                    case USBHID_GLOBALITEM_TAG_LOG_MAX:
3833
0
                        if (hid_unpack_signed(data, i, size, &field.logical_max))
3834
0
                            goto err;
3835
0
                        defined |= HID_LOGICAL_MAX;
3836
0
                        break;
3837
3838
0
                    case USBHID_GLOBALITEM_TAG_REPORT_SIZE:
3839
0
                        field.report_size = hid_unpack_value(data, i, size);
3840
0
                        defined |= HID_REPORT_SIZE;
3841
0
                        break;
3842
3843
0
                    case USBHID_GLOBALITEM_TAG_REPORT_ID:
3844
0
                        if (!first_item && !rdesc->uses_report_id)
3845
0
                            goto err;
3846
3847
0
                        rdesc->uses_report_id = true;
3848
3849
0
                        field.report_id = hid_unpack_value(data, i, size);
3850
0
                        defined |= HID_REPORT_ID;
3851
0
                        break;
3852
3853
0
                    case USBHID_GLOBALITEM_TAG_REPORT_COUNT:
3854
0
                        field.report_count = hid_unpack_value(data, i, size);
3855
0
                        defined |= HID_REPORT_COUNT;
3856
0
                        break;
3857
3858
0
                    case USBHID_GLOBALITEM_TAG_PUSH:
3859
0
                    case USBHID_GLOBALITEM_TAG_POP:
3860
                        /* TODO */
3861
0
                        goto err;
3862
3863
0
                    default:
3864
0
                        break;
3865
0
                }
3866
0
                break;
3867
3868
0
            case USBHID_ITEMTYPE_LOCAL:
3869
0
                switch (tag)
3870
0
                {
3871
0
                    case USBHID_LOCALITEM_TAG_USAGE:
3872
0
                        usage = hid_unpack_value(data, i, size);
3873
3874
                        /* Extended usage (size 4) combines both usage page and id */
3875
0
                        if (size != 4) {
3876
0
                            if (!(defined & HID_USAGE_PAGE))
3877
0
                                goto err;
3878
0
                            usage |= usage_page << 16;
3879
0
                        }
3880
3881
0
                        if (wmem_array_get_count(field.usages) + 1 > MAX_REPORT_DESCRIPTOR_COUNT) {
3882
0
                            goto err;
3883
0
                        }
3884
0
                        wmem_array_append_one(field.usages, usage);
3885
0
                        break;
3886
3887
0
                    case USBHID_LOCALITEM_TAG_USAGE_MIN:
3888
0
                        usage_min = hid_unpack_value(data, i, size);
3889
0
                        if (size == 4) {
3890
                            /* Usage max must be extended as well */
3891
0
                            defined |= HID_EXTENDED_USAGE;
3892
0
                        } else {
3893
0
                            if (!(defined & HID_USAGE_PAGE))
3894
0
                                goto err;
3895
0
                            usage_min |= usage_page << 16;
3896
0
                        }
3897
0
                        defined |= HID_USAGE_MIN;
3898
0
                        break;
3899
3900
0
                    case USBHID_LOCALITEM_TAG_USAGE_MAX:
3901
0
                        if (!(defined & HID_USAGE_MIN))
3902
0
                            goto err;
3903
3904
0
                        usage_max = hid_unpack_value(data, i, size);
3905
0
                        if (defined & HID_EXTENDED_USAGE) {
3906
                            /* Fail if max is not extended usage (HID spec 6.2.2.8) */
3907
0
                            if (size != 4)
3908
0
                                goto err;
3909
0
                        } else if (size == 4) {
3910
                            /* Fail because min wasn't extended, but max is */
3911
0
                            goto err;
3912
0
                        } else {
3913
0
                            if (!(defined & HID_USAGE_PAGE))
3914
0
                                goto err;
3915
0
                            usage_max |= usage_page << 16;
3916
0
                        }
3917
3918
                        /* Usage min and max must be on the same page */
3919
0
                        if (USAGE_PAGE(usage_min) != USAGE_PAGE(usage_max))  {
3920
0
                            goto err;
3921
0
                        }
3922
3923
0
                        if (usage_min > usage_max) {
3924
0
                            goto err;
3925
0
                        }
3926
3927
0
                        if (wmem_array_get_count(field.usages) + usage_max - usage_min >= MAX_REPORT_DESCRIPTOR_COUNT) {
3928
0
                            goto err;
3929
0
                        }
3930
3931
                        /* min and max are inclusive */
3932
0
                        wmem_array_grow(field.usages, usage_max - usage_min + 1);
3933
                        /* Ensure j doesn't overflow even if usage_max is UINT32_MAX */
3934
0
                        for (uint64_t j = usage_min; j <= usage_max; j++) {
3935
                            /* The array holds uint32_t */
3936
0
                            uint32_t range_usage = (uint32_t)j;
3937
0
                            wmem_array_append_one(field.usages, range_usage);
3938
0
                        }
3939
3940
0
                        defined &= ~(HID_USAGE_MIN | HID_EXTENDED_USAGE);
3941
0
                        break;
3942
3943
0
                    default: /* TODO */
3944
0
                        goto err;
3945
0
                }
3946
0
                break;
3947
3948
0
            default: /* reserved */
3949
0
                goto err;
3950
0
        }
3951
3952
0
        i += size + 1;
3953
0
    }
3954
3955
0
    return true;
3956
3957
0
err:
3958
0
    for (unsigned int j = 0; j < wmem_array_get_count(rdesc->fields_in); j++)
3959
0
        wmem_free(scope, ((hid_field_t*) wmem_array_index(rdesc->fields_in, j))->usages);
3960
3961
0
    for (unsigned int j = 0; j < wmem_array_get_count(rdesc->fields_out); j++)
3962
0
        wmem_free(scope, ((hid_field_t*) wmem_array_index(rdesc->fields_out, j))->usages);
3963
3964
0
    wmem_free(scope, rdesc->fields_in);
3965
0
    wmem_free(scope, rdesc->fields_out);
3966
0
    return false;
3967
0
}
3968
3969
3970
static bool
3971
is_correct_interface(urb_info_t *urb, report_descriptor_t *report)
3972
0
{
3973
0
    return (urb->bus_id == report->bus_id) &&
3974
0
           (urb->device_address == report->device_address) &&
3975
0
           (urb->conv->interfaceNum == report->interface);
3976
0
}
3977
3978
/* Returns the report descriptor */
3979
static report_descriptor_t _U_ *
3980
get_report_descriptor(packet_info *pinfo _U_, urb_info_t *urb)
3981
0
{
3982
0
    uint32_t bus_id = urb->bus_id;
3983
0
    uint32_t device_address = urb->device_address;
3984
0
    uint32_t interface = urb->conv->interfaceNum;
3985
0
    wmem_tree_key_t key[] = {
3986
0
        {1, &bus_id},
3987
0
        {1, &device_address},
3988
0
        {1, &interface},
3989
0
        {1, &pinfo->num},
3990
0
        {0, NULL}
3991
0
    };
3992
3993
0
    report_descriptor_t *data = NULL;
3994
0
    data = (report_descriptor_t*) wmem_tree_lookup32_array_le(report_descriptors, key);
3995
0
    if (data && is_correct_interface(urb, data))
3996
0
        return data;
3997
3998
0
    return NULL;
3999
0
}
4000
4001
/* Inserts the report descriptor */
4002
static void
4003
insert_report_descriptor(packet_info *pinfo, report_descriptor_t *data)
4004
0
{
4005
0
    uint32_t bus_id = data->bus_id;
4006
0
    uint32_t device_address = data->device_address;
4007
0
    uint32_t interface = data->interface;
4008
0
    wmem_tree_key_t key[] = {
4009
0
        {1, &bus_id},
4010
0
        {1, &device_address},
4011
0
        {1, &interface},
4012
0
        {1, &pinfo->num},
4013
0
        {0, NULL}
4014
0
    };
4015
4016
0
    wmem_tree_insert32_array(report_descriptors, key, data);
4017
0
}
4018
4019
/* Returns usage page string */
4020
static const char*
4021
get_usage_page_string(uint32_t usage_page)
4022
0
{
4023
0
    const char *str;
4024
4025
0
    str = try_val_to_str(usage_page, usb_hid_item_usage_page_vals);
4026
0
    if (!str) {
4027
0
        if ((usage_page & VENDOR_PAGE_HBYTE) == VENDOR_PAGE_HBYTE)
4028
0
            str = "Vendor";
4029
0
        else
4030
0
            str = "Reserved";
4031
0
    }
4032
4033
0
    return str;
4034
0
}
4035
4036
/* Returns usage page item string */
4037
static char*
4038
get_usage_page_item_string(wmem_allocator_t *pool, uint32_t usage_page, uint32_t id)
4039
0
{
4040
0
    const char *str = NULL;
4041
0
    const char *fmt_str = NULL;
4042
4043
0
    switch (usage_page)
4044
0
    {
4045
0
    case GENERIC_DESKTOP_CONTROLS_PAGE:
4046
0
        str = try_val_to_str(id, usb_hid_generic_desktop_controls_usage_page_vals);
4047
0
        break;
4048
0
    case SIMULATION_CONTROLS_PAGE:
4049
0
        str = try_val_to_str(id, usb_hid_simulation_control_usage_page_vals);
4050
0
        break;
4051
0
    case VR_CONTROLS_PAGE:
4052
0
        str = try_val_to_str(id, usb_hid_vr_controls_usage_page_vals);
4053
0
        break;
4054
0
    case SPORT_CONTROLS_PAGE:
4055
0
        str = try_val_to_str(id, usb_hid_sport_controls_usage_page_vals);
4056
0
        break;
4057
0
    case GAME_CONTROLS_PAGE:
4058
0
        str = try_val_to_str(id, usb_hid_game_controls_usage_page_vals);
4059
0
        break;
4060
0
    case GENERIC_DEVICE_CONTROLS_PAGE:
4061
0
        str = try_val_to_str(id, usb_hid_generic_device_controls_usage_page_vals);
4062
0
        break;
4063
0
    case KEYBOARD_KEYPAD_PAGE:
4064
0
        str = try_val_to_str(id, usb_hid_keyboard_keypad_usage_page_vals);
4065
0
        break;
4066
0
    case LED_PAGE:
4067
0
        str = try_val_to_str(id, usb_hid_led_usage_page_vals);
4068
0
        break;
4069
0
    case BUTTON_PAGE:
4070
0
        str = try_val_to_str(id, usb_hid_button_usage_page_vals);
4071
0
        if (!str)
4072
0
            fmt_str = "Button %u";
4073
0
        break;
4074
0
    case ORDINAL_PAGE:
4075
0
        str = try_val_to_str(id, usb_hid_ordinal_usage_page_vals);
4076
0
        break;
4077
0
    case TELEPHONY_PAGE:
4078
0
        str = try_val_to_str(id, usb_hid_telephony_device_usage_page_vals);
4079
0
        break;
4080
0
    case CONSUMER_PAGE:
4081
0
        str = try_val_to_str(id, usb_hid_consumer_usage_page_vals);
4082
0
        if (!str)
4083
0
            fmt_str = "Instance %u";
4084
0
        break;
4085
0
    case DIGITIZER_PAGE:
4086
0
        str = try_val_to_str(id, usb_hid_digitizers_usage_page_vals);
4087
0
        break;
4088
0
    case HAPTICS_PAGE:
4089
0
        str = try_val_to_str(id, usb_hid_haptic_usage_page_vals);
4090
0
        if (id >= 0x2001 && id <= 0x2FFF)
4091
0
            str = "Vendor Waveforms";
4092
0
        break;
4093
0
    case PID_PAGE:
4094
0
        str = try_val_to_str(id, usb_hid_physical_input_device_usage_page_vals);
4095
0
        break;
4096
0
    case UNICODE_PAGE:
4097
0
        fmt_str = "Character U+%04X";
4098
0
        break;
4099
0
    case SOC_PAGE:
4100
0
        str = try_val_to_str(id, usb_hid_soc_usage_page_vals);
4101
0
        break;
4102
0
    case EYE_AND_HEAD_TRACKER_PAGE:
4103
0
        str = try_val_to_str(id, usb_hid_eye_and_head_tracker_usage_page_vals);
4104
0
        break;
4105
0
    case ALPHANUMERIC_DISPLAY_PAGE:
4106
0
        str = try_val_to_str(id, usb_hid_alphanumeric_display_usage_page_vals);
4107
0
        break;
4108
0
    case SENSOR_PAGE:
4109
0
        str = try_val_to_str(id, usb_hid_sensor_usage_page_vals);
4110
0
        if (!str)
4111
0
            str = try_rval_to_str(id, usb_hid_sensor_usage_page_ranges);
4112
0
        break;
4113
0
    case MEDICAL_INSTRUMENTS_PAGE:
4114
0
        str = try_val_to_str(id, usb_hid_medical_instrument_usage_page_vals);
4115
0
        break;
4116
0
    case BRAILLE_DISPLAY_PAGE:
4117
0
        str = try_val_to_str(id, usb_hid_braille_display_usage_page_vals);
4118
0
        break;
4119
0
    case LIGHTING_AND_ILLUMINATION_PAGE:
4120
0
        str = try_val_to_str(id, usb_hid_lighting_and_illumination_usage_page_vals);
4121
0
        break;
4122
0
    case USB_MONITOR_PAGE:
4123
0
        str = try_val_to_str(id, usb_hid_monitor_usage_page_vals);
4124
0
        break;
4125
0
    case USB_ENUMERATED_VALUES_PAGE:
4126
0
        fmt_str = "ENUM_%u";
4127
0
        break;
4128
0
    case VESA_VIRTUAL_CONTROLS_PAGE:
4129
0
        str = try_val_to_str(id, usb_hid_vesa_virtual_control_usage_page_vals);
4130
0
        break;
4131
0
    case POWER_DEVICE_PAGE:
4132
0
        str = try_val_to_str(id, usb_hid_power_device_usage_page_vals);
4133
0
        break;
4134
0
    case BATTERY_SYSTEM_PAGE:
4135
0
        str = try_val_to_str(id, usb_hid_battery_system_usage_page_vals);
4136
0
        break;
4137
0
    case BARCODE_SCANNER_PAGE:
4138
0
        str = try_val_to_str(id, usb_hid_barcode_scanner_usage_page_vals);
4139
0
        break;
4140
0
    case WEIGHING_PAGE:
4141
0
        str = try_val_to_str(id, usb_hid_weighing_devices_usage_page_vals);
4142
0
        break;
4143
0
    case MSR_PAGE:
4144
0
        str = try_val_to_str(id, usb_hid_magnetic_stripe_reader_usage_page_vals);
4145
0
        break;
4146
0
    case CAMERA_CONTROL_PAGE:
4147
0
        str = try_val_to_str(id, usb_hid_camera_control_usage_page_vals);
4148
0
        break;
4149
0
    case ARCADE_PAGE:
4150
0
        str = try_val_to_str(id, usb_hid_arcade_usage_page_vals);
4151
0
        break;
4152
0
    case FIDO_ALLIANCE_PAGE:
4153
0
        str = try_val_to_str(id, usb_hid_fido_alliance_usage_page_vals);
4154
0
        break;
4155
0
    default:
4156
0
        if ((usage_page & VENDOR_PAGE_HBYTE) == VENDOR_PAGE_HBYTE)
4157
0
            str = "Vendor";
4158
0
        break;
4159
0
    }
4160
4161
0
    if (fmt_str) {
4162
0
        return wmem_strdup_printf(pool, fmt_str, id);
4163
0
    }
4164
0
    if (!str) {
4165
0
        str = "Reserved";
4166
0
    }
4167
0
    return wmem_strdup_printf(pool, "%s", str);
4168
0
}
4169
4170
/* Dissector for the data in a HID main report. */
4171
static int
4172
dissect_usb_hid_report_mainitem_data(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, unsigned int bSize, unsigned int bTag)
4173
0
{
4174
0
    proto_item *ti = proto_tree_get_parent(tree);
4175
0
    uint32_t val = 0;
4176
4177
0
    switch (bTag) {
4178
0
        case USBHID_MAINITEM_TAG_INPUT:
4179
0
        case USBHID_MAINITEM_TAG_OUTPUT:
4180
0
        case USBHID_MAINITEM_TAG_FEATURE:
4181
0
            proto_tree_add_item(tree, hf_usb_hid_mainitem_bit0, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
4182
0
            proto_tree_add_item(tree, hf_usb_hid_mainitem_bit1, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
4183
0
            proto_tree_add_item(tree, hf_usb_hid_mainitem_bit2, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
4184
0
            proto_tree_add_item(tree, hf_usb_hid_mainitem_bit3, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
4185
0
            proto_tree_add_item(tree, hf_usb_hid_mainitem_bit4, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
4186
0
            proto_tree_add_item(tree, hf_usb_hid_mainitem_bit5, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
4187
0
            proto_tree_add_item(tree, hf_usb_hid_mainitem_bit6, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
4188
0
            if (bTag == USBHID_MAINITEM_TAG_INPUT)
4189
0
                proto_tree_add_item(tree, hf_usb_hid_mainitem_bit7_input, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
4190
0
            else
4191
0
                proto_tree_add_item(tree, hf_usb_hid_mainitem_bit7, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
4192
0
            if (bSize > 1)
4193
0
                proto_tree_add_item(tree, hf_usb_hid_mainitem_bit8, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
4194
0
            else
4195
0
                proto_tree_add_boolean_format_value(tree, hf_usb_hid_mainitem_bit8, tvb, offset, 0, false, "Buffered bytes (default, no second byte present)");
4196
4197
0
            val = tvb_get_uint8(tvb, offset);
4198
0
            if (val & (1 << 0))
4199
0
                proto_item_append_text(ti, " (Const,");
4200
0
            else
4201
0
                proto_item_append_text(ti, " (Data,");
4202
0
            if (val & (1 << 1))
4203
0
                proto_item_append_text(ti, "Var,");
4204
0
            else
4205
0
                proto_item_append_text(ti, "Array,");
4206
0
            if (val & (1 << 2))
4207
0
                proto_item_append_text(ti, "Rel");
4208
0
            else
4209
0
                proto_item_append_text(ti, "Abs");
4210
0
            if (val & (1 << 3))
4211
0
                proto_item_append_text(ti, ",Wrap");
4212
0
            if (val & (1 << 4))
4213
0
                proto_item_append_text(ti, ",NonLinear");
4214
0
            if (val & (1 << 5))
4215
0
                proto_item_append_text(ti, ",NoPref");
4216
0
            if (val & (1 << 6))
4217
0
                proto_item_append_text(ti, ",Null");
4218
0
            if ((bTag == USBHID_MAINITEM_TAG_OUTPUT || bTag == USBHID_MAINITEM_TAG_FEATURE) && val & (1 << 7))
4219
0
                proto_item_append_text(ti, ",Volatile");
4220
0
            if (val & (1 << 8))
4221
0
                proto_item_append_text(ti, ",BuffBytes");
4222
0
            proto_item_append_text(ti, ")");
4223
0
            break;
4224
0
        case USBHID_MAINITEM_TAG_COLLECTION:
4225
0
            proto_tree_add_item_ret_uint(tree, hf_usb_hid_mainitem_colltype, tvb, offset, 1, ENC_LITTLE_ENDIAN, &val);
4226
0
            proto_item_append_text(ti, " (%s)", rval_to_str_const(val, usb_hid_mainitem_colltype_vals, "Unknown"));
4227
0
            break;
4228
0
        case USBHID_MAINITEM_TAG_ENDCOLLECTION:
4229
            /* No item data */
4230
0
            break;
4231
0
        default:
4232
0
            proto_tree_add_item(tree, hf_usb_hid_item_unk_data, tvb, offset, bSize, ENC_NA);
4233
0
            proto_item_append_text(ti, " (Unknown)");
4234
0
            break;
4235
0
    }
4236
0
    offset += bSize;
4237
0
    return offset;
4238
0
}
4239
4240
/* Dissector for the data in a HID main report. */
4241
static int
4242
dissect_usb_hid_report_globalitem_data(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, unsigned int bSize, unsigned int bTag, struct usb_hid_global_state *global)
4243
0
{
4244
0
    const char *str = NULL;
4245
0
    proto_item *ti = proto_tree_get_parent(tree);
4246
0
    uint32_t val = 0;
4247
0
    int32_t val_sig = 0;
4248
4249
0
    switch (bTag) {
4250
0
        case USBHID_GLOBALITEM_TAG_USAGE_PAGE:
4251
0
            switch (bSize) {
4252
0
                case 1: global->usage_page = tvb_get_uint8(tvb, offset); break;
4253
0
                case 2: global->usage_page = tvb_get_letohs(tvb, offset); break;
4254
0
                case 3: global->usage_page = tvb_get_letoh24(tvb, offset); break;
4255
0
                case 4: global->usage_page = tvb_get_letohl(tvb, offset); break;
4256
0
                default: global->usage_page = 0; break;
4257
0
            }
4258
0
            str = get_usage_page_string(global->usage_page);
4259
0
            proto_tree_add_uint_format_value(tree, hf_usb_hid_globalitem_usage, tvb, offset, bSize, global->usage_page, "%s (0x%04x)", str, global->usage_page);
4260
0
            proto_item_append_text(ti, " (%s)", str);
4261
0
            break;
4262
0
        case USBHID_GLOBALITEM_TAG_LOG_MIN:
4263
0
            proto_tree_add_item_ret_int(tree, hf_usb_hid_globalitem_log_min, tvb, offset, bSize, ENC_LITTLE_ENDIAN, &val_sig);
4264
0
            proto_item_append_text(ti, " (%d)", val_sig);
4265
0
            break;
4266
0
        case USBHID_GLOBALITEM_TAG_LOG_MAX:
4267
0
            proto_tree_add_item_ret_int(tree, hf_usb_hid_globalitem_log_max, tvb, offset, bSize, ENC_LITTLE_ENDIAN, &val_sig);
4268
0
            proto_item_append_text(ti, " (%d)", val_sig);
4269
0
            break;
4270
0
        case USBHID_GLOBALITEM_TAG_PHY_MIN:
4271
0
            proto_tree_add_item_ret_int(tree, hf_usb_hid_globalitem_phy_min, tvb, offset, bSize, ENC_LITTLE_ENDIAN, &val_sig);
4272
0
            proto_item_append_text(ti, " (%d)", val_sig);
4273
0
            break;
4274
0
        case USBHID_GLOBALITEM_TAG_PHY_MAX:
4275
0
            proto_tree_add_item_ret_int(tree, hf_usb_hid_globalitem_phy_max, tvb, offset, bSize, ENC_LITTLE_ENDIAN, &val_sig);
4276
0
            proto_item_append_text(ti, " (%d)", val_sig);
4277
0
            break;
4278
0
        case USBHID_GLOBALITEM_TAG_UNIT_EXP:
4279
0
            proto_tree_add_item_ret_uint(tree, hf_usb_hid_globalitem_unit_exp, tvb, offset, bSize, ENC_LITTLE_ENDIAN, &val);
4280
0
            if (val >= 7)
4281
0
                proto_item_append_text(ti, " (%u)", val);
4282
0
            else
4283
0
                proto_item_append_text(ti, " (%d)", -(16 - (int) val));
4284
0
            break;
4285
0
        case USBHID_GLOBALITEM_TAG_UNIT:
4286
0
            proto_tree_add_item(tree, hf_usb_hid_globalitem_unit_sys, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
4287
0
            proto_tree_add_item(tree, hf_usb_hid_globalitem_unit_len, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
4288
0
            proto_tree_add_item(tree, hf_usb_hid_globalitem_unit_mass, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
4289
0
            proto_tree_add_item(tree, hf_usb_hid_globalitem_unit_time, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
4290
0
            proto_tree_add_item(tree, hf_usb_hid_globalitem_unit_temp, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
4291
0
            proto_tree_add_item(tree, hf_usb_hid_globalitem_unit_current, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
4292
0
            proto_tree_add_item(tree, hf_usb_hid_globalitem_unit_brightness, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
4293
0
            proto_item_append_text(ti, " (0x%02x)", tvb_get_uint8(tvb, offset));
4294
0
            break;
4295
0
        case USBHID_GLOBALITEM_TAG_REPORT_SIZE:
4296
0
            proto_tree_add_item_ret_uint(tree, hf_usb_hid_globalitem_report_size, tvb, offset, bSize, ENC_LITTLE_ENDIAN, &val);
4297
0
            proto_item_append_text(ti, " (%u)", val);
4298
0
            break;
4299
0
        case USBHID_GLOBALITEM_TAG_REPORT_ID:
4300
0
            proto_tree_add_item_ret_uint(tree, hf_usb_hid_globalitem_report_id, tvb, offset, bSize, ENC_LITTLE_ENDIAN, &val);
4301
0
            proto_item_append_text(ti, " (0x%02x)", val);
4302
0
            break;
4303
0
        case USBHID_GLOBALITEM_TAG_REPORT_COUNT:
4304
0
            proto_tree_add_item_ret_uint(tree, hf_usb_hid_globalitem_report_count, tvb, offset, bSize, ENC_LITTLE_ENDIAN, &val);
4305
0
            proto_item_append_text(ti, " (%u)", val);
4306
0
            break;
4307
0
        case USBHID_GLOBALITEM_TAG_PUSH:
4308
            // Push and Pop have no data, but the HID spec 6.2.2.7 doesn't prohibit it.
4309
0
            if(bSize > 0) {
4310
0
                proto_tree_add_item_ret_uint(tree, hf_usb_hid_globalitem_push, tvb, offset, bSize, ENC_LITTLE_ENDIAN, &val);
4311
0
                proto_item_append_text(ti, " (%u)", val);
4312
0
            }
4313
0
            break;
4314
0
        case USBHID_GLOBALITEM_TAG_POP:
4315
            // Push and Pop have no data, but the HID spec 6.2.2.7 doesn't prohibit it.
4316
0
            if(bSize > 0) {
4317
0
                proto_tree_add_item_ret_uint(tree, hf_usb_hid_globalitem_pop, tvb, offset, bSize, ENC_LITTLE_ENDIAN, &val);
4318
0
                proto_item_append_text(ti, " (%u)", val);
4319
0
            }
4320
0
            break;
4321
0
        default:
4322
0
            proto_tree_add_item(tree, hf_usb_hid_item_unk_data, tvb, offset, bSize, ENC_NA);
4323
0
            proto_item_append_text(ti, " (Unknown)");
4324
0
            break;
4325
0
    }
4326
0
    offset += bSize;
4327
0
    return offset;
4328
0
}
4329
4330
/* Dissector for the data in a HID main report. */
4331
static int
4332
dissect_usb_hid_report_localitem_data(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, unsigned int bSize, unsigned int bTag, struct usb_hid_global_state *global)
4333
0
{
4334
0
    uint32_t id = 0xffff;
4335
0
    proto_item *ti = proto_tree_get_parent(tree);
4336
0
    char *str = NULL;
4337
0
    uint32_t val = 0;
4338
4339
0
    switch (bTag) {
4340
0
        case USBHID_LOCALITEM_TAG_USAGE:
4341
0
            if (bSize > 2) {
4342
                /* Full page ID */
4343
0
                proto_tree_add_item(tree, hf_usb_hid_localitem_usage, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
4344
0
            } else {
4345
                /* Only lower few bits given, need to combine with last global ID */
4346
0
                if (bSize == 1)
4347
0
                    id = tvb_get_uint8(tvb, offset);
4348
0
                else if (bSize == 2)
4349
0
                    id = tvb_get_letohs(tvb, offset);
4350
0
                str = get_usage_page_item_string(pinfo->pool, global->usage_page, id);
4351
0
                proto_tree_add_uint_format_value(tree, hf_usb_hid_localitem_usage, tvb, offset, bSize, id, "%s (0x%04x)", str, id);
4352
0
                proto_item_append_text(ti, " (%s)", str);
4353
0
            }
4354
0
            break;
4355
0
        case USBHID_LOCALITEM_TAG_USAGE_MIN:
4356
0
            proto_tree_add_item_ret_uint(tree, hf_usb_hid_localitem_usage_min, tvb, offset, bSize, ENC_LITTLE_ENDIAN, &val);
4357
0
            proto_item_append_text(ti, " (0x%04x)", val);
4358
0
            break;
4359
0
        case USBHID_LOCALITEM_TAG_USAGE_MAX:
4360
0
            proto_tree_add_item_ret_uint(tree, hf_usb_hid_localitem_usage_max, tvb, offset, bSize, ENC_LITTLE_ENDIAN, &val);
4361
0
            proto_item_append_text(ti, " (0x%04x)", val);
4362
0
            break;
4363
0
        case USBHID_LOCALITEM_TAG_DESIG_INDEX:
4364
0
            proto_tree_add_item_ret_uint(tree, hf_usb_hid_localitem_desig_index, tvb, offset, bSize, ENC_LITTLE_ENDIAN, &val);
4365
0
            proto_item_append_text(ti, " (0x%02x)", val);
4366
0
            break;
4367
0
        case USBHID_LOCALITEM_TAG_DESIG_MIN:
4368
0
            proto_tree_add_item_ret_uint(tree, hf_usb_hid_localitem_desig_min, tvb, offset, bSize, ENC_LITTLE_ENDIAN, &val);
4369
0
            proto_item_append_text(ti, " (0x%02x)", val);
4370
0
            break;
4371
0
        case USBHID_LOCALITEM_TAG_DESIG_MAX:
4372
0
            proto_tree_add_item_ret_uint(tree, hf_usb_hid_localitem_desig_max, tvb, offset, bSize, ENC_LITTLE_ENDIAN, &val);
4373
0
            proto_item_append_text(ti, " (0x%02x)", val);
4374
0
            break;
4375
0
        case USBHID_LOCALITEM_TAG_STRING_INDEX:
4376
0
            proto_tree_add_item_ret_uint(tree, hf_usb_hid_localitem_string_index, tvb, offset, bSize, ENC_LITTLE_ENDIAN, &val);
4377
0
            proto_item_append_text(ti, " (0x%02x)", val);
4378
0
            break;
4379
0
        case USBHID_LOCALITEM_TAG_STRING_MIN:
4380
0
            proto_tree_add_item_ret_uint(tree, hf_usb_hid_localitem_string_min, tvb, offset, bSize, ENC_LITTLE_ENDIAN, &val);
4381
0
            proto_item_append_text(ti, " (0x%02x)", val);
4382
0
            break;
4383
0
        case USBHID_LOCALITEM_TAG_STRING_MAX:
4384
0
            proto_tree_add_item_ret_uint(tree, hf_usb_hid_localitem_string_max, tvb, offset, bSize, ENC_LITTLE_ENDIAN, &val);
4385
0
            proto_item_append_text(ti, " (0x%02x)", val);
4386
0
            break;
4387
0
        case USBHID_LOCALITEM_TAG_DELIMITER:
4388
0
            proto_tree_add_item_ret_uint(tree, hf_usb_hid_localitem_delimiter, tvb, offset, bSize, ENC_LITTLE_ENDIAN, &val);
4389
0
            proto_item_append_text(ti, " (0x%02x)", val);
4390
0
            break;
4391
0
        default:
4392
0
            proto_tree_add_item(tree, hf_usb_hid_item_unk_data, tvb, offset, bSize, ENC_NA);
4393
0
            proto_item_append_text(ti, " (Unknown)");
4394
0
            break;
4395
0
    }
4396
0
    offset += bSize;
4397
4398
0
    return offset;
4399
0
}
4400
4401
/* Dissector for individual HID report items.  Recursive. */
4402
static int
4403
// NOLINTNEXTLINE(misc-no-recursion)
4404
dissect_usb_hid_report_item(packet_info *pinfo _U_, proto_tree *parent_tree, tvbuff_t *tvb, int offset, urb_info_t *urb, const struct usb_hid_global_state *global)
4405
0
{
4406
0
    proto_item *subitem;
4407
0
    proto_tree *tree, *subtree;
4408
0
    int old_offset;
4409
0
    unsigned int tmp;
4410
0
    unsigned int bSize, bType, bTag;
4411
0
    const value_string *usb_hid_cur_bTag_vals;
4412
0
    int hf_usb_hid_curitem_bTag;
4413
0
    struct usb_hid_global_state cur_global;
4414
0
    memcpy(&cur_global, global, sizeof(struct usb_hid_global_state));
4415
4416
0
    while (tvb_reported_length_remaining(tvb, offset) > 0)
4417
0
    {
4418
0
        old_offset=offset;
4419
4420
0
        tmp = tvb_get_uint8(tvb, offset);
4421
0
        bSize = tmp & USBHID_SIZE_MASK;
4422
0
        if (bSize == 3) bSize++; /* 3 == four bytes */
4423
0
        bType = (tmp & USBHID_TYPE_MASK) >> 2;
4424
0
        bTag = (tmp & USBHID_TAG_MASK) >> 4;
4425
4426
0
        switch (bType) {
4427
0
            case USBHID_ITEMTYPE_MAIN:
4428
0
                hf_usb_hid_curitem_bTag = hf_usb_hid_mainitem_bTag;
4429
0
                usb_hid_cur_bTag_vals = usb_hid_mainitem_bTag_vals;
4430
0
                break;
4431
0
            case USBHID_ITEMTYPE_GLOBAL:
4432
0
                hf_usb_hid_curitem_bTag = hf_usb_hid_globalitem_bTag;
4433
0
                usb_hid_cur_bTag_vals = usb_hid_globalitem_bTag_vals;
4434
0
                break;
4435
0
            case USBHID_ITEMTYPE_LOCAL:
4436
0
                hf_usb_hid_curitem_bTag = hf_usb_hid_localitem_bTag;
4437
0
                usb_hid_cur_bTag_vals = usb_hid_localitem_bTag_vals;
4438
0
                break;
4439
0
            default: /* Only USBHID_ITEMTYPE_LONG, but keep compiler happy */
4440
0
                hf_usb_hid_curitem_bTag = hf_usb_hid_longitem_bTag;
4441
0
                usb_hid_cur_bTag_vals = usb_hid_longitem_bTag_vals;
4442
0
                break;
4443
0
        }
4444
4445
0
        subtree = proto_tree_add_subtree_format(parent_tree, tvb, offset, bSize + 1, ett_usb_hid_item_header, &subitem, "%s", val_to_str(pinfo->pool, bTag, usb_hid_cur_bTag_vals, "Unknown/%u tag"));
4446
4447
0
        tree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_usb_hid_item_header, NULL, "Header");
4448
0
        proto_tree_add_item(tree, hf_usb_hid_item_bSize, tvb, offset,   1, ENC_LITTLE_ENDIAN);
4449
0
        proto_tree_add_item(tree, hf_usb_hid_item_bType, tvb, offset,   1, ENC_LITTLE_ENDIAN);
4450
0
        proto_tree_add_item(tree, hf_usb_hid_curitem_bTag, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4451
0
        offset++;
4452
0
        if ((bType == 3) && (bTag == 16)) {
4453
            /* Long item */
4454
0
            proto_tree_add_item_ret_uint(subtree, hf_usb_hid_item_bDataSize, tvb, offset, 1, ENC_LITTLE_ENDIAN, &bSize);
4455
0
            offset++;
4456
0
            proto_tree_add_item(subtree, hf_usb_hid_item_bLongItemTag, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4457
0
            offset++;
4458
0
            proto_tree_add_item(subtree, hf_usb_hid_item_unk_data, tvb, offset, bSize, ENC_NA);
4459
0
            offset += bSize;
4460
0
        } else {
4461
            /* Short item */
4462
0
            switch (bType) {
4463
0
                case USBHID_ITEMTYPE_MAIN:
4464
0
                    offset = dissect_usb_hid_report_mainitem_data(pinfo, subtree, tvb, offset, bSize, bTag);
4465
0
                    break;
4466
0
                case USBHID_ITEMTYPE_GLOBAL:
4467
0
                    offset = dissect_usb_hid_report_globalitem_data(pinfo, subtree, tvb, offset, bSize, bTag, &cur_global);
4468
0
                    break;
4469
0
                case USBHID_ITEMTYPE_LOCAL:
4470
0
                    offset = dissect_usb_hid_report_localitem_data(pinfo, subtree, tvb, offset, bSize, bTag, &cur_global);
4471
0
                    break;
4472
0
                default: /* Only USBHID_ITEMTYPE_LONG, but keep compiler happy */
4473
0
                    proto_tree_add_item(subtree, hf_usb_hid_item_unk_data, tvb, offset, bSize, ENC_NA);
4474
0
                    offset += bSize;
4475
0
                    break;
4476
0
            }
4477
0
        }
4478
4479
0
        if (bType == USBHID_ITEMTYPE_MAIN) {
4480
0
            if (bTag == USBHID_MAINITEM_TAG_COLLECTION) {
4481
                /* Begin collection, nest following elements under us */
4482
0
                increment_dissection_depth(pinfo);
4483
0
                offset = dissect_usb_hid_report_item(pinfo, subtree, tvb, offset, urb, &cur_global);
4484
0
                decrement_dissection_depth(pinfo);
4485
0
                proto_item_set_len(subitem, offset-old_offset);
4486
0
            } else if (bTag == USBHID_MAINITEM_TAG_ENDCOLLECTION) {
4487
                /* End collection, break out to parent tree item */
4488
0
                break;
4489
0
            }
4490
0
        }
4491
0
    }
4492
0
    return offset;
4493
0
}
4494
4495
/* Dissector for HID "GET DESCRIPTOR" subtype. */
4496
int
4497
dissect_usb_hid_get_report_descriptor(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, int offset, urb_info_t *urb)
4498
0
{
4499
0
    proto_item *item;
4500
0
    proto_tree *tree;
4501
0
    int old_offset=offset;
4502
0
    struct usb_hid_global_state initial_global;
4503
4504
0
    memset(&initial_global, 0, sizeof(struct usb_hid_global_state));
4505
4506
0
    item = proto_tree_add_protocol_format(parent_tree, proto_usb_hid, tvb, offset,
4507
0
                                          -1, "HID Report");
4508
0
    tree = proto_item_add_subtree(item, ett_usb_hid_report);
4509
0
    offset = dissect_usb_hid_report_item(pinfo, tree, tvb, offset, urb, &initial_global);
4510
4511
    /* only insert report descriptor the first time we parse it */
4512
0
    if (!PINFO_FD_VISITED(pinfo) && urb && urb->conv) {
4513
0
        wmem_allocator_t *scope = wmem_file_scope();
4514
0
        report_descriptor_t *data = wmem_new0(scope, report_descriptor_t);
4515
4516
0
        data->bus_id = urb->bus_id;
4517
0
        data->device_address = urb->device_address;
4518
0
        data->interface = urb->conv->interfaceNum;
4519
0
        data->frame_num = pinfo->num;
4520
0
        data->desc_length = offset - old_offset;
4521
0
        data->desc_body = (uint8_t*) tvb_memdup(scope, tvb, old_offset, data->desc_length);
4522
4523
0
        if (parse_report_descriptor(data)) {
4524
0
            insert_report_descriptor(pinfo, data);
4525
0
        } else {
4526
0
            wmem_free(scope, data->desc_body);
4527
0
            wmem_free(scope, data);
4528
0
        }
4529
0
    }
4530
4531
0
    proto_item_set_len(item, offset-old_offset);
4532
4533
0
    return offset;
4534
0
}
4535
4536
static int dissect_usb_hid_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data);
4537
4538
/* Dissector for HID GET_REPORT request. See USBHID 1.11, Chapter 7.2.1 Get_Report Request */
4539
static int
4540
dissect_usb_hid_get_report(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, bool is_request, urb_info_t *urb)
4541
0
{
4542
0
    proto_item *item;
4543
0
    proto_tree *subtree;
4544
4545
0
    if (!is_request) {
4546
0
        offset += dissect_usb_hid_data(tvb_new_subset_remaining(tvb, offset), pinfo, tree, urb);
4547
4548
0
        return offset;
4549
0
    }
4550
4551
0
    item = proto_tree_add_item(tree, hf_usb_hid_value, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4552
0
    subtree = proto_item_add_subtree(item, ett_usb_hid_wValue);
4553
4554
    /* Report Type in the high byte, Report ID in the low byte */
4555
0
    proto_tree_add_item(subtree, hf_usb_hid_report_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4556
0
    offset++;
4557
0
    proto_tree_add_item(subtree, hf_usb_hid_report_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4558
0
    offset++;
4559
4560
0
    proto_tree_add_item(tree, hf_usb_hid_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4561
0
    offset += 2;
4562
4563
0
    proto_tree_add_item(tree, hf_usb_hid_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4564
0
    offset += 2;
4565
4566
0
    return offset;
4567
0
}
4568
4569
/* Dissector for HID SET_REPORT request. See USBHID 1.11, Chapter 7.2.2 Set_Report Request */
4570
static int
4571
dissect_usb_hid_set_report(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, bool is_request, urb_info_t *urb)
4572
0
{
4573
0
    proto_item *item;
4574
0
    proto_tree *subtree;
4575
4576
0
    if (!is_request)
4577
0
        return offset;
4578
4579
0
    item = proto_tree_add_item(tree, hf_usb_hid_value, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4580
0
    subtree = proto_item_add_subtree(item, ett_usb_hid_wValue);
4581
4582
0
    proto_tree_add_item(subtree, hf_usb_hid_report_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4583
0
    offset++;
4584
0
    proto_tree_add_item(subtree, hf_usb_hid_report_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4585
0
    offset++;
4586
4587
0
    proto_tree_add_item(tree, hf_usb_hid_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4588
0
    offset += 2;
4589
4590
0
    proto_tree_add_item(tree, hf_usb_hid_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4591
0
    offset += 2;
4592
4593
0
    offset += dissect_usb_hid_data(tvb_new_subset_remaining(tvb, offset), pinfo,
4594
0
        proto_tree_get_parent_tree(tree), urb);
4595
4596
0
    return offset;
4597
0
}
4598
4599
4600
/* Dissector for HID GET_IDLE request. See USBHID 1.11, Chapter 7.2.3 Get_Idle Request */
4601
static int
4602
dissect_usb_hid_get_idle(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, bool is_request, urb_info_t *urb _U_)
4603
0
{
4604
0
    proto_item *item;
4605
0
    proto_tree *subtree;
4606
4607
0
    if (!is_request) {
4608
0
        proto_tree_add_item(tree, hf_usb_hid_duration, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4609
0
        offset++;
4610
4611
0
        return offset;
4612
0
    }
4613
4614
0
    item = proto_tree_add_item(tree, hf_usb_hid_value, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4615
0
    subtree = proto_item_add_subtree(item, ett_usb_hid_wValue);
4616
4617
0
    proto_tree_add_item(subtree, hf_usb_hid_report_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4618
0
    offset++;
4619
0
    proto_tree_add_item(subtree, hf_usb_hid_zero, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4620
0
    offset++;
4621
4622
0
    proto_tree_add_item(tree, hf_usb_hid_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4623
0
    offset += 2;
4624
4625
0
    proto_tree_add_item(tree, hf_usb_hid_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4626
0
    offset += 2;
4627
4628
0
    return offset;
4629
0
}
4630
4631
/* Dissector for HID SET_IDLE request. See USBHID 1.11, Chapter 7.2.4 Set_Idle Request */
4632
static int
4633
dissect_usb_hid_set_idle(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, bool is_request, urb_info_t *urb _U_)
4634
0
{
4635
0
    proto_item *item;
4636
0
    proto_tree *subtree;
4637
4638
0
    if (!is_request)
4639
0
        return offset;
4640
4641
0
    item = proto_tree_add_item(tree, hf_usb_hid_value, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4642
0
    subtree = proto_item_add_subtree(item, ett_usb_hid_wValue);
4643
4644
    /* Duration in the high byte, Report ID in the low byte */
4645
0
    proto_tree_add_item(subtree, hf_usb_hid_report_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4646
0
    offset++;
4647
0
    proto_tree_add_item(subtree, hf_usb_hid_duration, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4648
0
    offset++;
4649
4650
0
    proto_tree_add_item(tree, hf_usb_hid_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4651
0
    offset += 2;
4652
4653
0
    proto_tree_add_item(tree, hf_usb_hid_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4654
0
    offset += 2;
4655
4656
0
    return offset;
4657
0
}
4658
4659
/* Dissector for HID GET_PROTOCOL request. See USBHID 1.11, Chapter 7.2.5 Get_Protocol Request */
4660
static int
4661
dissect_usb_hid_get_protocol(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, bool is_request, urb_info_t *urb _U_)
4662
0
{
4663
0
    if (!is_request) {
4664
0
        proto_tree_add_item(tree, hf_usb_hid_protocol, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4665
0
        offset++;
4666
4667
0
        return offset;
4668
0
    }
4669
4670
0
    proto_tree_add_item(tree, hf_usb_hid_value, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4671
0
    offset += 2;
4672
4673
0
    proto_tree_add_item(tree, hf_usb_hid_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4674
0
    offset += 2;
4675
4676
0
    proto_tree_add_item(tree, hf_usb_hid_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4677
0
    offset += 2;
4678
4679
0
    return offset;
4680
0
}
4681
4682
/* Dissector for HID SET_PROTOCOL request. See USBHID 1.11, Chapter 7.2.6 Set_Protocol Request */
4683
static int
4684
dissect_usb_hid_set_protocol(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, bool is_request, urb_info_t *urb _U_)
4685
0
{
4686
0
    proto_item *item;
4687
0
    proto_tree *subtree;
4688
4689
0
    if (!is_request)
4690
0
        return offset;
4691
4692
0
    item = proto_tree_add_item(tree, hf_usb_hid_value, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4693
0
    subtree = proto_item_add_subtree(item, ett_usb_hid_wValue);
4694
4695
0
    proto_tree_add_item(subtree, hf_usb_hid_protocol, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4696
0
    offset += 2;
4697
4698
0
    proto_tree_add_item(tree, hf_usb_hid_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4699
0
    offset += 2;
4700
4701
0
    proto_tree_add_item(tree, hf_usb_hid_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
4702
0
    offset += 2;
4703
4704
0
    return offset;
4705
0
}
4706
4707
4708
typedef int (*usb_setup_dissector)(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, bool is_request, urb_info_t *urb);
4709
4710
typedef struct _usb_setup_dissector_table_t {
4711
    uint8_t request;
4712
    usb_setup_dissector dissector;
4713
} usb_setup_dissector_table_t;
4714
4715
/* USBHID 1.11, Chapter 7.1 Standard Requests */
4716
#define USB_STD_SETUP_GET_DESCRIPTOR  0x06
4717
4718
4719
/* USBHID 1.11, Chapter 7.2 Class-Specific Requests */
4720
#define USB_HID_SETUP_GET_REPORT      0x01
4721
#define USB_HID_SETUP_GET_IDLE        0x02
4722
#define USB_HID_SETUP_GET_PROTOCOL    0x03
4723
/* 0x04..0x08: Reserved */
4724
#define USB_HID_SETUP_SET_REPORT      0x09
4725
#define USB_HID_SETUP_SET_IDLE        0x0A
4726
#define USB_HID_SETUP_SET_PROTOCOL    0x0B
4727
4728
static const usb_setup_dissector_table_t setup_dissectors[] = {
4729
    { USB_HID_SETUP_GET_REPORT,   dissect_usb_hid_get_report },
4730
    { USB_HID_SETUP_GET_IDLE,     dissect_usb_hid_get_idle },
4731
    { USB_HID_SETUP_GET_PROTOCOL, dissect_usb_hid_get_protocol },
4732
    { USB_HID_SETUP_SET_REPORT,   dissect_usb_hid_set_report },
4733
    { USB_HID_SETUP_SET_IDLE,     dissect_usb_hid_set_idle },
4734
    { USB_HID_SETUP_SET_PROTOCOL, dissect_usb_hid_set_protocol },
4735
    { 0, NULL }
4736
};
4737
4738
static const value_string setup_request_names_vals[] = {
4739
    { USB_STD_SETUP_GET_DESCRIPTOR, "GET_DESCRIPTOR" },
4740
    { USB_HID_SETUP_GET_REPORT,     "GET_REPORT" },
4741
    { USB_HID_SETUP_GET_IDLE,       "GET_IDLE" },
4742
    { USB_HID_SETUP_GET_PROTOCOL,   "GET_PROTOCOL" },
4743
    { USB_HID_SETUP_SET_REPORT,     "SET_REPORT" },
4744
    { USB_HID_SETUP_SET_IDLE,       "SET_IDLE" },
4745
    { USB_HID_SETUP_SET_PROTOCOL,   "SET_PROTOCOL" },
4746
    { 0, NULL }
4747
};
4748
4749
static const value_string usb_hid_report_type_vals[] = {
4750
    { 1, "Input" },
4751
    { 2, "Output" },
4752
    { 3, "Feature" },
4753
    { 0, NULL }
4754
};
4755
4756
static const value_string setup_protocol_vals[] = {
4757
    { 0, "Boot Protocol" },
4758
    { 1, "Report Protocol" },
4759
    { 0, NULL }
4760
};
4761
4762
static int
4763
dissect_usb_hid_boot_keyboard_input_report(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
4764
0
{
4765
0
    int       offset = 0;
4766
0
    bool      shortcut_helper = false;
4767
0
    unsigned  modifier;
4768
0
    unsigned  keycode;
4769
4770
0
    proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_modifier_right_gui, tvb, offset, 1, ENC_BIG_ENDIAN);
4771
0
    proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_modifier_right_alt, tvb, offset, 1, ENC_BIG_ENDIAN);
4772
0
    proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_modifier_right_shift, tvb, offset, 1, ENC_BIG_ENDIAN);
4773
0
    proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_modifier_right_ctrl, tvb, offset, 1, ENC_BIG_ENDIAN);
4774
0
    proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_modifier_left_gui, tvb, offset, 1, ENC_BIG_ENDIAN);
4775
0
    proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_modifier_left_alt, tvb, offset, 1, ENC_BIG_ENDIAN);
4776
0
    proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_modifier_left_shift, tvb, offset, 1, ENC_BIG_ENDIAN);
4777
0
    proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_modifier_left_ctrl, tvb, offset, 1, ENC_BIG_ENDIAN);
4778
0
    modifier = tvb_get_uint8(tvb, offset);
4779
4780
0
    col_append_str(pinfo->cinfo, COL_INFO, " - ");
4781
0
    if (modifier & 0x80) {
4782
0
        col_append_str(pinfo->cinfo, COL_INFO, "RIGHT GUI");
4783
0
        shortcut_helper = true;
4784
0
    }
4785
0
    if (modifier & 0x40) {
4786
0
        if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
4787
0
        col_append_str(pinfo->cinfo, COL_INFO, "RIGHT ALT");
4788
0
        shortcut_helper = true;
4789
0
    }
4790
0
    if (modifier & 0x20) {
4791
0
        if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
4792
0
        col_append_str(pinfo->cinfo, COL_INFO, "RIGHT SHIFT");
4793
0
        shortcut_helper = true;
4794
0
    }
4795
0
    if (modifier & 0x10) {
4796
0
        if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
4797
0
        col_append_str(pinfo->cinfo, COL_INFO, "RIGHT CTRL");
4798
0
        shortcut_helper = true;
4799
0
    }
4800
0
    if (modifier & 0x08) {
4801
0
        if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
4802
0
        col_append_str(pinfo->cinfo, COL_INFO, "LEFT GUI");
4803
0
        shortcut_helper = true;
4804
0
    }
4805
0
    if (modifier & 0x04) {
4806
0
        if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
4807
0
        col_append_str(pinfo->cinfo, COL_INFO, "LEFT ALT");
4808
0
        shortcut_helper = true;
4809
0
    }
4810
0
    if (modifier & 0x02) {
4811
0
        if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
4812
0
        col_append_str(pinfo->cinfo, COL_INFO, "LEFT SHIFT");
4813
0
        shortcut_helper = true;
4814
0
    }
4815
0
    if (modifier & 0x01) {
4816
0
        if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
4817
0
        col_append_str(pinfo->cinfo, COL_INFO, "LEFT CTRL");
4818
0
        shortcut_helper = true;
4819
0
    }
4820
0
    offset += 1;
4821
4822
0
    proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
4823
0
    offset += 1;
4824
4825
0
    proto_tree_add_item_ret_uint(tree, hf_usbhid_boot_report_keyboard_keycode_1, tvb, offset, 1, ENC_BIG_ENDIAN, &keycode);
4826
0
    offset += 1;
4827
4828
0
    if (keycode) {
4829
0
        if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
4830
0
        col_append_str(pinfo->cinfo, COL_INFO, val_to_str_ext_const(keycode, &keycode_vals_ext, "Unknown"));
4831
0
        shortcut_helper = true;
4832
0
    }
4833
4834
0
    proto_tree_add_item_ret_uint(tree, hf_usbhid_boot_report_keyboard_keycode_2, tvb, offset, 1, ENC_BIG_ENDIAN, &keycode);
4835
0
    offset += 1;
4836
4837
0
    if (keycode) {
4838
0
        if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
4839
0
        col_append_str(pinfo->cinfo, COL_INFO, val_to_str_ext_const(keycode, &keycode_vals_ext, "Unknown"));
4840
0
        shortcut_helper = true;
4841
0
    }
4842
4843
0
    proto_tree_add_item_ret_uint(tree, hf_usbhid_boot_report_keyboard_keycode_3, tvb, offset, 1, ENC_BIG_ENDIAN, &keycode);
4844
0
    offset += 1;
4845
4846
0
    if (keycode) {
4847
0
        if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
4848
0
        col_append_str(pinfo->cinfo, COL_INFO, val_to_str_ext_const(keycode, &keycode_vals_ext, "Unknown"));
4849
0
        shortcut_helper = true;
4850
0
    }
4851
4852
0
    proto_tree_add_item_ret_uint(tree, hf_usbhid_boot_report_keyboard_keycode_4, tvb, offset, 1, ENC_BIG_ENDIAN, &keycode);
4853
0
    offset += 1;
4854
4855
0
    if (keycode) {
4856
0
        if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
4857
0
        col_append_str(pinfo->cinfo, COL_INFO, val_to_str_ext_const(keycode, &keycode_vals_ext, "Unknown"));
4858
0
        shortcut_helper = true;
4859
0
    }
4860
4861
0
    proto_tree_add_item_ret_uint(tree, hf_usbhid_boot_report_keyboard_keycode_5, tvb, offset, 1, ENC_BIG_ENDIAN, &keycode);
4862
0
    offset += 1;
4863
4864
0
    if (keycode) {
4865
0
        if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
4866
0
        col_append_str(pinfo->cinfo, COL_INFO, val_to_str_ext_const(keycode, &keycode_vals_ext, "Unknown"));
4867
0
        shortcut_helper = true;
4868
0
    }
4869
4870
0
    proto_tree_add_item_ret_uint(tree, hf_usbhid_boot_report_keyboard_keycode_6, tvb, offset, 1, ENC_BIG_ENDIAN, &keycode);
4871
0
    offset += 1;
4872
4873
0
    if (keycode) {
4874
0
        if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
4875
0
        col_append_str(pinfo->cinfo, COL_INFO, val_to_str_ext_const(keycode, &keycode_vals_ext, "Unknown"));
4876
0
        shortcut_helper = true;
4877
0
    }
4878
4879
0
    if (shortcut_helper == false) {
4880
0
        col_append_str(pinfo->cinfo, COL_INFO, "<action key up>");
4881
0
    }
4882
4883
0
    return offset;
4884
0
}
4885
4886
static int
4887
dissect_usb_hid_boot_keyboard_output_report(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
4888
0
{
4889
0
    int       offset = 0;
4890
0
    bool      shortcut_helper = false;
4891
0
    unsigned  leds;
4892
4893
0
    proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_leds_constants, tvb, offset, 1, ENC_BIG_ENDIAN);
4894
0
    proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_leds_kana, tvb, offset, 1, ENC_BIG_ENDIAN);
4895
0
    proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_leds_compose, tvb, offset, 1, ENC_BIG_ENDIAN);
4896
0
    proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_leds_scroll_lock, tvb, offset, 1, ENC_BIG_ENDIAN);
4897
0
    proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_leds_caps_lock, tvb, offset, 1, ENC_BIG_ENDIAN);
4898
0
    proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_leds_num_lock, tvb, offset, 1, ENC_BIG_ENDIAN);
4899
0
    leds = tvb_get_uint8(tvb, offset);
4900
4901
0
    col_append_str(pinfo->cinfo, COL_INFO, " - LEDs: ");
4902
0
    if (leds & 0x01) {
4903
0
        col_append_str(pinfo->cinfo, COL_INFO, "NumLock");
4904
0
        shortcut_helper = true;
4905
0
    }
4906
0
    if (leds & 0x02) {
4907
0
        if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, ", ");
4908
0
        col_append_str(pinfo->cinfo, COL_INFO, "CapsLock");
4909
0
        shortcut_helper = true;
4910
0
    }
4911
0
    if (leds & 0x04) {
4912
0
        if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, ", ");
4913
0
        col_append_str(pinfo->cinfo, COL_INFO, "ScrollLock");
4914
0
        shortcut_helper = true;
4915
0
    }
4916
0
    if (leds & 0x08) {
4917
0
        if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, ", ");
4918
0
        col_append_str(pinfo->cinfo, COL_INFO, "Compose");
4919
0
        shortcut_helper = true;
4920
0
    }
4921
0
    if (leds & 0x10) {
4922
0
        if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, ", ");
4923
0
        col_append_str(pinfo->cinfo, COL_INFO, "Kana");
4924
0
        shortcut_helper = true;
4925
0
    }
4926
0
    if (leds & 0x20) {
4927
0
        if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, ", ");
4928
0
        col_append_str(pinfo->cinfo, COL_INFO, "Constant1");
4929
0
        shortcut_helper = true;
4930
0
    }
4931
0
    if (leds & 0x40) {
4932
0
        if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, ", ");
4933
0
        col_append_str(pinfo->cinfo, COL_INFO, "Constant2");
4934
0
        shortcut_helper = true;
4935
0
    }
4936
0
    if (leds & 0x80) {
4937
0
        if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, ", ");
4938
0
        col_append_str(pinfo->cinfo, COL_INFO, "Constant3");
4939
        /*shortcut_helper = true;*/
4940
0
    }
4941
0
    if (!leds) {
4942
0
        col_append_str(pinfo->cinfo, COL_INFO, "none");
4943
0
    }
4944
4945
0
    offset += 1;
4946
4947
0
    return offset;
4948
0
}
4949
4950
static int
4951
dissect_usb_hid_boot_mouse_input_report(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
4952
0
{
4953
0
    int       offset = 0;
4954
0
    bool      shortcut_helper = false;
4955
0
    unsigned  buttons;
4956
4957
0
    proto_tree_add_item(tree, hf_usbhid_boot_report_mouse_button_8, tvb, offset, 1, ENC_BIG_ENDIAN);
4958
0
    proto_tree_add_item(tree, hf_usbhid_boot_report_mouse_button_7, tvb, offset, 1, ENC_BIG_ENDIAN);
4959
0
    proto_tree_add_item(tree, hf_usbhid_boot_report_mouse_button_6, tvb, offset, 1, ENC_BIG_ENDIAN);
4960
0
    proto_tree_add_item(tree, hf_usbhid_boot_report_mouse_button_5, tvb, offset, 1, ENC_BIG_ENDIAN);
4961
0
    proto_tree_add_item(tree, hf_usbhid_boot_report_mouse_button_4, tvb, offset, 1, ENC_BIG_ENDIAN);
4962
0
    proto_tree_add_item(tree, hf_usbhid_boot_report_mouse_button_middle, tvb, offset, 1, ENC_BIG_ENDIAN);
4963
0
    proto_tree_add_item(tree, hf_usbhid_boot_report_mouse_button_right, tvb, offset, 1, ENC_BIG_ENDIAN);
4964
0
    proto_tree_add_item(tree, hf_usbhid_boot_report_mouse_button_left, tvb, offset, 1, ENC_BIG_ENDIAN);
4965
0
    buttons = tvb_get_uint8(tvb, offset);
4966
0
    offset += 1;
4967
4968
0
    if (buttons) col_append_str(pinfo->cinfo, COL_INFO, " - ");
4969
0
    if (buttons & 0x01) {
4970
0
        col_append_str(pinfo->cinfo, COL_INFO, "Button LEFT");
4971
0
        shortcut_helper = true;
4972
0
    }
4973
0
    if (buttons & 0x02) {
4974
0
        if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
4975
0
        col_append_str(pinfo->cinfo, COL_INFO, "Button RIGHT");
4976
0
        shortcut_helper = true;
4977
0
    }
4978
0
    if (buttons & 0x04) {
4979
0
        if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
4980
0
        col_append_str(pinfo->cinfo, COL_INFO, "Button MIDDLE");
4981
0
    }
4982
0
    if (buttons & 0x08) {
4983
0
        if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
4984
0
        col_append_str(pinfo->cinfo, COL_INFO, "Button 4");
4985
0
        shortcut_helper = true;
4986
0
    }
4987
0
    if (buttons & 0x10) {
4988
0
        if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
4989
0
        col_append_str(pinfo->cinfo, COL_INFO, "Button 5");
4990
0
        shortcut_helper = true;
4991
0
    }
4992
0
    if (buttons & 0x20) {
4993
0
        if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
4994
0
        col_append_str(pinfo->cinfo, COL_INFO, "Button 6");
4995
0
        shortcut_helper = true;
4996
0
    }
4997
0
    if (buttons & 0x40) {
4998
0
        if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
4999
0
        col_append_str(pinfo->cinfo, COL_INFO, "Button 7");
5000
0
        shortcut_helper = true;
5001
0
    }
5002
0
    if (buttons & 0x80) {
5003
0
        if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
5004
0
        col_append_str(pinfo->cinfo, COL_INFO, "Button 8");
5005
        /* Not necessary, this is the last case where it is used
5006
         * shortcut_helper = true;
5007
         */
5008
0
    }
5009
5010
0
    proto_tree_add_item(tree, hf_usbhid_boot_report_mouse_x_displacement, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5011
0
    offset += 1;
5012
5013
0
    proto_tree_add_item(tree, hf_usbhid_boot_report_mouse_y_displacement, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5014
0
    offset += 1;
5015
5016
    /* not really in HID Specification */
5017
0
    if (tvb_reported_length_remaining(tvb, offset)) {
5018
0
        proto_tree_add_item(tree, hf_usbhid_boot_report_mouse_horizontal_scroll_wheel, tvb, offset, 1, ENC_BIG_ENDIAN);
5019
0
        offset += 1;
5020
0
    }
5021
5022
    /* not really in HID Specification */
5023
0
    if (tvb_reported_length_remaining(tvb, offset)) {
5024
0
        proto_tree_add_item(tree, hf_usbhid_boot_report_mouse_vertical_scroll_wheel, tvb, offset, 1, ENC_BIG_ENDIAN);
5025
0
        offset += 1;
5026
0
    }
5027
5028
0
    if (tvb_reported_length_remaining(tvb, offset)) {
5029
0
        proto_tree_add_item(tree, hf_usbhid_data, tvb, offset, -1, ENC_NA);
5030
0
        offset += tvb_captured_length_remaining(tvb, offset);
5031
0
    }
5032
5033
0
    return offset;
5034
0
}
5035
5036
5037
/* dissect a "standard" control message that's sent to an interface */
5038
static int
5039
dissect_usb_hid_control_std_intf(tvbuff_t *tvb, packet_info *pinfo,
5040
        proto_tree *tree, urb_info_t *urb)
5041
0
{
5042
0
    int               offset = 0;
5043
0
    usb_trans_info_t *usb_trans_info;
5044
0
    uint8_t           req;
5045
5046
0
    usb_trans_info = urb->usb_trans_info;
5047
5048
    /* XXX - can we do some plausibility checks here? */
5049
5050
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "USBHID");
5051
5052
    /* we can't use urb->is_request since urb
5053
       was replaced with the interface conversation */
5054
0
    if (usb_trans_info->request_in == pinfo->num) {
5055
        /* the tvb that we see here is the setup packet
5056
           without the request type byte */
5057
5058
0
        req = tvb_get_uint8(tvb, offset);
5059
0
        if (req != USB_SETUP_GET_DESCRIPTOR)
5060
0
            return offset;
5061
0
        proto_tree_add_item(tree, hf_usb_hid_request, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5062
0
        col_clear(pinfo->cinfo, COL_INFO);
5063
0
        col_append_str(pinfo->cinfo, COL_INFO, "GET DESCRIPTOR Request");
5064
0
        offset += 1;
5065
5066
0
        proto_tree_add_item(tree, hf_usb_hid_bDescriptorIndex, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5067
0
        usb_trans_info->u.get_descriptor.usb_index = tvb_get_uint8(tvb, offset);
5068
0
        offset += 1;
5069
5070
0
        proto_tree_add_item(tree, hf_usb_hid_bDescriptorType, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5071
0
        usb_trans_info->u.get_descriptor.type = tvb_get_uint8(tvb, offset);
5072
0
        col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
5073
0
                val_to_str_ext(pinfo->pool, usb_trans_info->u.get_descriptor.type,
5074
0
                    &hid_descriptor_type_vals_ext, "Unknown type %u"));
5075
0
        offset += 1;
5076
5077
0
        proto_tree_add_item(tree, hf_usb_hid_wInterfaceNumber, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5078
0
        offset += 2;
5079
5080
0
        proto_tree_add_item(tree, hf_usb_hid_wDescriptorLength, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5081
0
        offset += 2;
5082
0
    }
5083
0
    else {
5084
0
        col_clear(pinfo->cinfo, COL_INFO);
5085
0
        col_append_str(pinfo->cinfo, COL_INFO, "GET DESCRIPTOR Response");
5086
0
        col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
5087
0
                val_to_str_ext(pinfo->pool, usb_trans_info->u.get_descriptor.type,
5088
0
                    &hid_descriptor_type_vals_ext, "Unknown type %u"));
5089
0
        if (usb_trans_info->u.get_descriptor.type == USB_DT_HID_REPORT)
5090
0
            offset = dissect_usb_hid_get_report_descriptor(pinfo, tree, tvb, offset, urb);
5091
0
    }
5092
5093
0
    return offset;
5094
0
}
5095
5096
/* dissect a class-specific control message that's sent to an interface */
5097
static int
5098
dissect_usb_hid_control_class_intf(tvbuff_t *tvb, packet_info *pinfo,
5099
        proto_tree *tree, urb_info_t *urb)
5100
0
{
5101
0
    usb_trans_info_t *usb_trans_info;
5102
0
    bool is_request;
5103
0
    unsigned offset = 0;
5104
0
    usb_setup_dissector dissector = NULL;
5105
0
    const usb_setup_dissector_table_t *tmp;
5106
5107
0
    usb_trans_info = urb->usb_trans_info;
5108
5109
0
    is_request = (pinfo->srcport==NO_ENDPOINT);
5110
5111
    /* Check valid values for bmRequestType. See Chapter 7.2 in USBHID 1.11 */
5112
0
    for (tmp = setup_dissectors; tmp->dissector; tmp++) {
5113
0
        if (tmp->request == usb_trans_info->setup.request) {
5114
0
            dissector = tmp->dissector;
5115
0
            break;
5116
0
        }
5117
0
    }
5118
    /* No, we could not find any class specific dissector for this request
5119
     * return 0 and let USB try any of the standard requests.
5120
     */
5121
0
    if (!dissector)
5122
0
        return 0;
5123
5124
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "USBHID");
5125
5126
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
5127
0
                 val_to_str(pinfo->pool, usb_trans_info->setup.request, setup_request_names_vals, "Unknown type %x"),
5128
0
                 is_request ? "Request" : "Response");
5129
5130
0
    if (is_request) {
5131
0
        proto_tree_add_item(tree, hf_usb_hid_request, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5132
0
        offset += 1;
5133
0
    }
5134
5135
0
    offset = dissector(pinfo, tree, tvb, offset, is_request, urb);
5136
5137
0
    return offset;
5138
0
}
5139
5140
/* unpack a HID logical report field */
5141
static int hid_unpack_logical(tvbuff_t *tvb, int bit_offset, uint32_t size, int32_t min, int32_t *val)
5142
0
{
5143
0
    if (size > 32)
5144
0
        return -1;
5145
5146
0
    *val = tvb_get_bits32(tvb, bit_offset, size, ENC_LITTLE_ENDIAN);
5147
5148
0
    if (min < 0)
5149
0
        *val = ws_sign_ext32(*val, size);
5150
5151
0
    return 0;
5152
0
}
5153
5154
static int
5155
dissect_usb_hid_int_dynamic_value_variable(tvbuff_t *tvb, proto_tree *tree, hid_field_t *field,
5156
        int bit_offset, int hf)
5157
0
{
5158
0
    int32_t val = 0;
5159
5160
0
    if (hid_unpack_logical(tvb, bit_offset, field->report_size, field->logical_min, &val))
5161
0
        return -1;
5162
5163
0
    proto_tree_add_int_bits_format_value(tree, hf, tvb, bit_offset, field->report_size, val, ENC_LITTLE_ENDIAN, "%d", val);
5164
0
    return 0;
5165
0
}
5166
5167
/* dissect the Generic Desktop Controls (0x0001) usage page */
5168
static int
5169
dissect_usb_hid_generic_desktop_controls_page(tvbuff_t *tvb, packet_info _U_ *pinfo,
5170
        proto_tree *tree, hid_field_t *field, unsigned usage, int bit_offset)
5171
0
{
5172
0
    int ret = 0;
5173
5174
0
    DISSECTOR_ASSERT(USAGE_PAGE(usage) == GENERIC_DESKTOP_CONTROLS_PAGE);
5175
0
    usage = USAGE_ID(usage);
5176
0
    switch (usage)
5177
0
    {
5178
0
        case USBHID_GENERIC_DESKTOP_CONTROLS_X:
5179
0
            ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_x);
5180
0
            break;
5181
5182
0
        case USBHID_GENERIC_DESKTOP_CONTROLS_Y:
5183
0
            ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_y);
5184
0
            break;
5185
5186
0
        case USBHID_GENERIC_DESKTOP_CONTROLS_Z:
5187
0
            ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_z);
5188
0
            break;
5189
5190
0
        case USBHID_GENERIC_DESKTOP_CONTROLS_RX:
5191
0
            ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_rx);
5192
0
            break;
5193
5194
0
        case USBHID_GENERIC_DESKTOP_CONTROLS_RY:
5195
0
            ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_ry);
5196
0
            break;
5197
5198
0
        case USBHID_GENERIC_DESKTOP_CONTROLS_RZ:
5199
0
            ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_rz);
5200
0
            break;
5201
5202
0
        case USBHID_GENERIC_DESKTOP_CONTROLS_SLIDER:
5203
0
            ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_slider);
5204
0
            break;
5205
5206
0
        case USBHID_GENERIC_DESKTOP_CONTROLS_VX:
5207
0
            ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_vx);
5208
0
            break;
5209
5210
0
        case USBHID_GENERIC_DESKTOP_CONTROLS_VY:
5211
0
            ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_vy);
5212
0
            break;
5213
5214
0
        case USBHID_GENERIC_DESKTOP_CONTROLS_VZ:
5215
0
            ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_vz);
5216
0
            break;
5217
5218
0
        case USBHID_GENERIC_DESKTOP_CONTROLS_VBRX:
5219
0
            ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_vbrx);
5220
0
            break;
5221
5222
0
        case USBHID_GENERIC_DESKTOP_CONTROLS_VBRY:
5223
0
            ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_vbry);
5224
0
            break;
5225
5226
0
        case USBHID_GENERIC_DESKTOP_CONTROLS_VBRZ:
5227
0
            ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_vbrz);
5228
0
            break;
5229
5230
0
        case USBHID_GENERIC_DESKTOP_CONTROLS_VNO:
5231
0
            ret = dissect_usb_hid_int_dynamic_value_variable(tvb, tree, field, bit_offset, hf_usbhid_axis_vno);
5232
0
            break;
5233
5234
0
        default:
5235
0
            ret = -1;
5236
0
            break;
5237
0
    }
5238
5239
0
    return ret;
5240
0
}
5241
5242
/* dissect the Keyboard/Keypad (0x0007) usage page */
5243
static int
5244
dissect_usb_hid_keyboard_page(tvbuff_t *tvb, packet_info _U_ *pinfo,
5245
        proto_tree *tree, hid_field_t *field, uint32_t usage, int bit_offset)
5246
0
{
5247
0
    int32_t val = 0;
5248
5249
    /* the data is a boolean state for the usage (eg. KEY_SHIFT = 1, KEY_CONTROL = 0) */
5250
0
    if (hid_unpack_logical(tvb, bit_offset, field->report_size, field->logical_min, &val))
5251
0
        return -1;
5252
5253
0
    DISSECTOR_ASSERT(USAGE_PAGE(usage) == KEYBOARD_KEYPAD_PAGE);
5254
0
    usage = USAGE_ID(usage);
5255
5256
0
    proto_tree_add_boolean_bits_format_value(tree, hf_usbhid_key, tvb, bit_offset, field->report_size, val, ENC_LITTLE_ENDIAN,
5257
0
        "%s (0x%02x): %s", val_to_str_ext_const(usage, &keycode_vals_ext, "Unknown"), usage, val ? "DOWN" : "UP");
5258
0
    return 0;
5259
0
}
5260
5261
/* dissect the Button (0x0009) usage page */
5262
static int
5263
dissect_usb_hid_button_page(tvbuff_t *tvb, packet_info _U_ *pinfo,
5264
        proto_tree *tree, hid_field_t *field, uint32_t usage, int bit_offset)
5265
0
{
5266
0
    int32_t val = 0;
5267
0
    proto_item *ti;
5268
5269
0
    DISSECTOR_ASSERT(USAGE_PAGE(usage) == BUTTON_PAGE);
5270
0
    usage = USAGE_ID(usage);
5271
5272
0
    if (hid_unpack_logical(tvb, bit_offset, field->report_size, field->logical_min, &val))
5273
0
        return -1;
5274
5275
0
    ti = proto_tree_add_boolean_bits_format_value(tree, hf_usbhid_button, tvb, bit_offset, field->report_size, val, ENC_LITTLE_ENDIAN, "%u", usage);
5276
5277
0
    if (usage == 0)
5278
0
        proto_item_append_text(ti, " (No button pressed)");
5279
0
    else if (usage == 1)
5280
0
        proto_item_append_text(ti, " (primary/trigger)");
5281
0
    else if (usage == 2)
5282
0
        proto_item_append_text(ti, " (secondary)");
5283
0
    else if (usage == 3)
5284
0
        proto_item_append_text(ti, " (tertiary)");
5285
5286
0
    proto_item_append_text(ti, ": %s", val ? "DOWN" : "UP");
5287
0
    return 0;
5288
0
}
5289
5290
static void
5291
dissect_hid_variable(tvbuff_t* tvb, packet_info _U_* pinfo, proto_tree* tree, hid_field_t* field,
5292
                     uint32_t usage, int bit_offset)
5293
0
{
5294
0
    int ret = 0;
5295
5296
    /* vendor data (0xff00 - 0xffff) */
5297
0
    if ((USAGE_PAGE(usage) & 0xff00) == 0xff00) {
5298
        /* TODO: should this field be e.g FT_UINT64 ? */
5299
0
        proto_tree_add_bits_item(tree, hf_usbhid_vendor_data, tvb, bit_offset, field->report_size, ENC_LITTLE_ENDIAN);
5300
0
        return;
5301
0
    }
5302
5303
0
    switch (USAGE_PAGE(usage))
5304
0
    {
5305
0
    case GENERIC_DESKTOP_CONTROLS_PAGE:
5306
0
        ret = dissect_usb_hid_generic_desktop_controls_page(tvb, pinfo, tree, field, usage, bit_offset);
5307
0
        break;
5308
5309
0
    case KEYBOARD_KEYPAD_PAGE:
5310
0
        ret = dissect_usb_hid_keyboard_page(tvb, pinfo, tree, field, usage, bit_offset);
5311
0
        break;
5312
5313
0
    case BUTTON_PAGE:
5314
0
        ret = dissect_usb_hid_button_page(tvb, pinfo, tree, field, usage, bit_offset);
5315
0
        break;
5316
5317
0
    default:
5318
0
        ret = -1;
5319
0
        break;
5320
0
    }
5321
5322
0
    if (ret) {
5323
0
        uint32_t val = 0;
5324
0
        proto_item *ti =
5325
0
            proto_tree_add_uint_bits_format_value(tree, hf_usb_hid_localitem_usage, tvb, bit_offset, field->report_size,
5326
0
                                                  usage, ENC_LITTLE_ENDIAN, "%s", get_usage_page_item_string(pinfo->pool, USAGE_PAGE(usage), USAGE_ID(usage)));
5327
0
        if (0 == hid_unpack_logical(tvb, bit_offset, field->report_size, field->logical_min, (int32_t*)&val))
5328
0
            proto_item_append_text(ti, ": %d", val);
5329
0
    }
5330
0
}
5331
5332
static bool hid_get_usage_from_array(hid_field_t *field, int32_t idx, uint32_t *out)
5333
0
{
5334
0
    if ((idx >= field->logical_min) && (idx <= field->logical_max)) {
5335
0
        idx -= field->logical_min;
5336
0
        if ((uint32_t)idx < wmem_array_get_count(field->usages)) {
5337
0
            *out = (*((uint32_t*) wmem_array_index(field->usages, idx)));
5338
0
            return true;
5339
0
        }
5340
0
    }
5341
0
    return false;
5342
0
}
5343
5344
static int
5345
dissect_hid_field(tvbuff_t *tvb, packet_info _U_ *pinfo, proto_tree *tree, hid_field_t *field, int bit_offset)
5346
0
{
5347
0
    int start_offset = bit_offset;
5348
5349
0
    if ((field->properties & HID_MAIN_TYPE) == HID_MAIN_ARRAY) {
5350
0
        proto_item *array_ti;
5351
0
        proto_tree *array_tree;
5352
5353
0
        array_ti = proto_tree_add_bits_item(tree, hf_usbhid_array, tvb, bit_offset,
5354
0
            field->report_size * field->report_count, ENC_LITTLE_ENDIAN);
5355
0
        array_tree = proto_item_add_subtree(array_ti, ett_usb_hid_array);
5356
5357
0
        for(unsigned int j = 0; j < field->report_count; j++) {
5358
0
            uint32_t val = 0;
5359
0
            bool in_range;
5360
0
            if (hid_unpack_logical(tvb, bit_offset, field->report_size, field->logical_min, (int32_t*)&val)) {
5361
0
                in_range = false;
5362
0
            } else {
5363
0
                in_range = hid_get_usage_from_array(field, val, &val);
5364
0
            }
5365
0
            if (in_range) {
5366
0
                proto_tree_add_boolean_bits_format_value(array_tree, hf_usbhid_array_usage, tvb, bit_offset, field->report_size,
5367
0
                    val, ENC_LITTLE_ENDIAN, "%s (0x%04x, 0x%04x)", get_usage_page_item_string(pinfo->pool, USAGE_PAGE(val), USAGE_ID(val)),
5368
0
                    USAGE_PAGE(val), USAGE_ID(val));
5369
0
            } else {
5370
0
                proto_tree_add_boolean_bits_format_value(array_tree, hf_usbhid_array_usage, tvb, bit_offset, field->report_size,
5371
0
                    val, ENC_LITTLE_ENDIAN, "No controls asserted");
5372
0
            }
5373
0
            bit_offset += field->report_size;
5374
0
        }
5375
0
    } else {
5376
0
        unsigned int i;
5377
0
        unsigned int count = wmem_array_get_count(field->usages);
5378
0
        if (count > field->report_count) {
5379
0
            count = field->report_count;
5380
0
        }
5381
0
        for(i = 0; i < count; i++) {
5382
0
            uint32_t usage = *((uint32_t*) wmem_array_index(field->usages, i));
5383
0
            dissect_hid_variable(tvb, pinfo, tree, field, usage, bit_offset);
5384
0
            bit_offset += field->report_size;
5385
0
        }
5386
0
        if (field->report_count > count) {
5387
0
            int remaining_bits = (field->report_count - count) * field->report_size;
5388
0
            proto_tree_add_bits_item(tree, hf_usbhid_padding, tvb, bit_offset, remaining_bits, ENC_LITTLE_ENDIAN);
5389
0
            bit_offset += remaining_bits;
5390
0
        }
5391
0
    }
5392
5393
0
    return bit_offset - start_offset;
5394
0
}
5395
5396
/* Dissect USB HID data/reports */
5397
static int
5398
dissect_usb_hid_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5399
0
{
5400
0
    unsigned offset = 0, hid_bit_offset;
5401
0
    proto_item *hid_ti;
5402
0
    proto_tree *hid_tree;
5403
0
    wmem_array_t *fields;
5404
0
    urb_info_t *usb_data = (urb_info_t*) data;
5405
0
    report_descriptor_t *rdesc;
5406
0
    unsigned remaining = tvb_reported_length_remaining(tvb, offset);
5407
5408
0
    if (!usb_data) {
5409
0
        return 0;
5410
0
    }
5411
0
    rdesc = get_report_descriptor(pinfo, usb_data);
5412
5413
0
    if (remaining) {
5414
0
        hid_ti = proto_tree_add_item(tree, hf_usbhid_data, tvb, offset, -1, ENC_NA);
5415
0
        hid_tree = proto_item_add_subtree(hid_ti, ett_usb_hid_data);
5416
0
        hid_bit_offset = offset * 8;
5417
0
        uint8_t report_id = tvb_get_bits8(tvb, hid_bit_offset, 8);
5418
5419
0
        if (rdesc) {
5420
0
            if (pinfo->fd) {
5421
0
                mark_frame_as_depended_upon(pinfo->fd, rdesc->frame_num);
5422
0
            }
5423
0
            if (rdesc->uses_report_id) {
5424
0
                proto_tree_add_item(hid_tree, hf_usbhid_report_id, tvb, hid_bit_offset / 8, 1, ENC_NA);
5425
0
                hid_bit_offset += 8;
5426
0
            }
5427
5428
0
            if (usb_data->direction == P2P_DIR_RECV)
5429
0
                fields = rdesc->fields_in;
5430
0
            else
5431
0
                fields = rdesc->fields_out;
5432
5433
0
            for(unsigned int i = 0; i < wmem_array_get_count(fields); i++) {
5434
0
                hid_field_t *field = (hid_field_t*) wmem_array_index(fields, i);
5435
0
                unsigned int data_size = field->report_size * field->report_count;
5436
5437
                /* skip items with invalid report IDs */
5438
0
                if (rdesc->uses_report_id && field->report_id != report_id)
5439
0
                    continue;
5440
5441
                /* skip items with a report size of 0 (no data and won't
5442
                 * advance offset) */
5443
0
                if (field->report_size == 0) {
5444
0
                    continue;
5445
0
                }
5446
5447
                /* if the item has no usages, it is padding - HID spec 6.2.2.9 */
5448
0
                if (wmem_array_get_count(field->usages) == 0) {
5449
0
                    proto_tree_add_bits_item(hid_tree, hf_usbhid_padding, tvb, hid_bit_offset, data_size, ENC_LITTLE_ENDIAN);
5450
0
                    hid_bit_offset += data_size;
5451
0
                    continue;
5452
0
                }
5453
5454
0
                hid_bit_offset += dissect_hid_field(tvb, pinfo, hid_tree, field, hid_bit_offset);
5455
0
            }
5456
5457
0
            offset = (hid_bit_offset + 7) / 8;
5458
0
            proto_item_set_len(hid_ti, offset);
5459
0
        }
5460
0
    }
5461
5462
0
    return offset;
5463
0
}
5464
5465
/* Dissector for HID class-specific control request as defined in
5466
 * USBHID 1.11, Chapter 7.2.
5467
 * returns the number of bytes consumed */
5468
static int
5469
dissect_usb_hid_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5470
0
{
5471
0
    urb_info_t *urb;
5472
0
    usb_trans_info_t *usb_trans_info;
5473
0
    uint8_t type, recip;
5474
5475
0
    urb = (urb_info_t *)data;
5476
0
    if (!urb)
5477
0
        return 0;
5478
0
    usb_trans_info = urb->usb_trans_info;
5479
0
    if (!usb_trans_info)
5480
0
        return 0;
5481
5482
0
    type = USB_TYPE(usb_trans_info->setup.requesttype);
5483
0
    recip = USB_RECIPIENT(usb_trans_info->setup.requesttype);
5484
5485
0
    if (recip == RQT_SETUP_RECIPIENT_INTERFACE) {
5486
0
        if (type == RQT_SETUP_TYPE_STANDARD)
5487
0
            return dissect_usb_hid_control_std_intf(tvb, pinfo, tree, urb);
5488
0
        else if (type == RQT_SETUP_TYPE_CLASS)
5489
0
            return dissect_usb_hid_control_class_intf(tvb, pinfo, tree, urb);
5490
0
    }
5491
5492
0
    return dissect_usb_hid_data(tvb, pinfo, tree, data);
5493
0
}
5494
5495
/* dissect a descriptor that is specific to the HID class */
5496
static int
5497
dissect_usb_hid_class_descriptors(tvbuff_t *tvb, packet_info *pinfo _U_,
5498
        proto_tree *tree, void *data _U_)
5499
0
{
5500
0
    uint8_t     type;
5501
0
    int         offset = 0;
5502
0
    proto_item *ti;
5503
0
    proto_tree *desc_tree;
5504
0
    uint8_t     num_desc;
5505
0
    unsigned    i;
5506
5507
0
    type = tvb_get_uint8(tvb, 1);
5508
5509
    /* for now, we only handle the HID descriptor here */
5510
0
    if (type != USB_DT_HID)
5511
0
        return 0;
5512
5513
0
    desc_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_usb_hid_descriptor, &ti, "HID DESCRIPTOR");
5514
5515
0
    dissect_usb_descriptor_header(desc_tree, tvb, offset, &hid_descriptor_type_vals_ext);
5516
0
    offset += 2;
5517
0
    proto_tree_add_item(desc_tree, hf_usb_hid_bcdHID, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5518
0
    offset += 2;
5519
0
    proto_tree_add_item(desc_tree, hf_usb_hid_bCountryCode, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5520
0
    offset++;
5521
0
    num_desc = tvb_get_uint8(tvb, offset);
5522
0
    proto_tree_add_item(desc_tree, hf_usb_hid_bNumDescriptors, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5523
0
    offset++;
5524
0
    for (i=0;i<num_desc;i++) {
5525
0
        proto_tree_add_item(desc_tree, hf_usb_hid_bDescriptorType, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5526
0
        offset++;
5527
0
        proto_tree_add_item(desc_tree, hf_usb_hid_wDescriptorLength, tvb, offset, 2, ENC_LITTLE_ENDIAN);
5528
0
        offset += 2;
5529
0
    }
5530
5531
0
    proto_item_set_len(ti, offset);
5532
0
    return offset;
5533
0
}
5534
5535
/* USBHID 1.11, Chapter 7.2.4 */
5536
static void
5537
hid_duration_fmt(char *buf, uint8_t value)
5538
0
{
5539
0
    if (value == 0) {
5540
0
        snprintf(buf, ITEM_LABEL_LENGTH, "indefinite");
5541
0
    } else {
5542
0
        unsigned int ms = value * 4;
5543
0
        snprintf(buf, ITEM_LABEL_LENGTH, "%u ms", ms);
5544
0
    }
5545
0
}
5546
5547
5548
void
5549
proto_register_usb_hid(void)
5550
16
{
5551
16
    static hf_register_info hf[] = {
5552
16
        { &hf_usb_hid_item_bSize,
5553
16
            { "bSize", "usbhid.item.bSize", FT_UINT8, BASE_DEC,
5554
16
                VALS(usb_hid_item_bSize_vals), USBHID_SIZE_MASK, NULL, HFILL }},
5555
5556
16
        { &hf_usb_hid_item_bType,
5557
16
            { "bType", "usbhid.item.bType", FT_UINT8, BASE_DEC,
5558
16
                VALS(usb_hid_item_bType_vals), USBHID_TYPE_MASK, NULL, HFILL }},
5559
5560
16
        { &hf_usb_hid_mainitem_bTag,
5561
16
            { "bTag", "usbhid.item.bTag", FT_UINT8, BASE_HEX,
5562
16
                VALS(usb_hid_mainitem_bTag_vals), USBHID_TAG_MASK, NULL, HFILL }},
5563
5564
16
        { &hf_usb_hid_globalitem_bTag,
5565
16
            { "bTag", "usbhid.item.bTag", FT_UINT8, BASE_HEX,
5566
16
                VALS(usb_hid_globalitem_bTag_vals), USBHID_TAG_MASK, NULL, HFILL }},
5567
5568
16
        { &hf_usb_hid_localitem_bTag,
5569
16
            { "bTag", "usbhid.item.bTag", FT_UINT8, BASE_HEX,
5570
16
                VALS(usb_hid_localitem_bTag_vals), USBHID_TAG_MASK, NULL, HFILL }},
5571
5572
16
        { &hf_usb_hid_longitem_bTag,
5573
16
            { "bTag", "usbhid.item.bTag", FT_UINT8, BASE_HEX,
5574
16
                VALS(usb_hid_longitem_bTag_vals), USBHID_TAG_MASK, NULL, HFILL }},
5575
5576
16
        { &hf_usb_hid_item_bDataSize,
5577
16
            { "bDataSize", "usbhid.item.bDataSize", FT_UINT8, BASE_DEC,
5578
16
                NULL, 0, NULL, HFILL }},
5579
5580
16
        { &hf_usb_hid_item_bLongItemTag,
5581
16
            { "bTag", "usbhid.item.bLongItemTag", FT_UINT8, BASE_HEX,
5582
16
                NULL, 0, NULL, HFILL }},
5583
5584
        /* Main-report item data */
5585
5586
16
        { &hf_usb_hid_mainitem_bit0,
5587
16
            { "Data/constant", "usbhid.item.main.readonly", FT_BOOLEAN, 9,
5588
16
                TFS(&tfs_mainitem_bit0), 1<<0, NULL, HFILL }},
5589
5590
16
        { &hf_usb_hid_mainitem_bit1,
5591
16
            { "Data type", "usbhid.item.main.variable", FT_BOOLEAN, 9,
5592
16
                TFS(&tfs_mainitem_bit1), 1<<1, NULL, HFILL }},
5593
5594
16
        { &hf_usb_hid_mainitem_bit2,
5595
16
            { "Coordinates", "usbhid.item.main.relative", FT_BOOLEAN, 9,
5596
16
                TFS(&tfs_mainitem_bit2), 1<<2, NULL, HFILL }},
5597
5598
16
        { &hf_usb_hid_mainitem_bit3,
5599
16
            { "Min/max wraparound", "usbhid.item.main.wrap", FT_BOOLEAN, 9,
5600
16
                TFS(&tfs_mainitem_bit3), 1<<3, NULL, HFILL }},
5601
5602
16
        { &hf_usb_hid_mainitem_bit4,
5603
16
            { "Physical relationship to data", "usbhid.item.main.nonlinear", FT_BOOLEAN, 9,
5604
16
                TFS(&tfs_mainitem_bit4), 1<<4, NULL, HFILL }},
5605
5606
16
        { &hf_usb_hid_mainitem_bit5,
5607
16
            { "Preferred state", "usbhid.item.main.no_preferred_state", FT_BOOLEAN, 9,
5608
16
                TFS(&tfs_mainitem_bit5), 1<<5, NULL, HFILL }},
5609
5610
16
        { &hf_usb_hid_mainitem_bit6,
5611
16
            { "Has null position", "usbhid.item.main.nullstate", FT_BOOLEAN, 9,
5612
16
                TFS(&tfs_mainitem_bit6), 1<<6, NULL, HFILL }},
5613
5614
16
        { &hf_usb_hid_mainitem_bit7,
5615
16
            { "(Non)-volatile", "usbhid.item.main.volatile", FT_BOOLEAN, 9,
5616
16
                TFS(&tfs_mainitem_bit7), 1<<7, NULL, HFILL }},
5617
5618
16
        { &hf_usb_hid_mainitem_bit7_input,
5619
16
            { "[Reserved]", "usbhid.item.main.reserved", FT_BOOLEAN, 9,
5620
16
                NULL, 1<<7, NULL, HFILL }},
5621
5622
16
        { &hf_usb_hid_mainitem_bit8,
5623
16
            { "Bits or bytes", "usbhid.item.main.buffered_bytes", FT_BOOLEAN, 9,
5624
16
                TFS(&tfs_mainitem_bit8), 1<<8, NULL, HFILL }},
5625
5626
16
        { &hf_usb_hid_mainitem_colltype,
5627
16
            { "Collection type", "usbhid.item.main.colltype", FT_UINT8, BASE_RANGE_STRING|BASE_HEX,
5628
16
                RVALS(usb_hid_mainitem_colltype_vals), 0, NULL, HFILL }},
5629
5630
        /* Global-report item data */
5631
5632
16
        { &hf_usb_hid_globalitem_usage,
5633
16
            { "Usage page", "usbhid.item.global.usage", FT_UINT16, BASE_RANGE_STRING|BASE_HEX,
5634
16
                NULL, 0, NULL, HFILL }},
5635
5636
16
        { &hf_usb_hid_globalitem_log_min,
5637
16
            { "Logical minimum", "usbhid.item.global.log_min", FT_INT32, BASE_DEC,
5638
16
                NULL, 0, NULL, HFILL }},
5639
5640
16
        { &hf_usb_hid_globalitem_log_max,
5641
16
            { "Logical maximum", "usbhid.item.global.log_max", FT_INT32, BASE_DEC,
5642
16
                NULL, 0, NULL, HFILL }},
5643
5644
16
        { &hf_usb_hid_globalitem_phy_min,
5645
16
            { "Physical minimum", "usbhid.item.global.phy_min", FT_INT32, BASE_DEC,
5646
16
                NULL, 0, NULL, HFILL }},
5647
5648
16
        { &hf_usb_hid_globalitem_phy_max,
5649
16
            { "Physical maximum", "usbhid.item.global.phy_max", FT_INT32, BASE_DEC,
5650
16
                NULL, 0, NULL, HFILL }},
5651
5652
16
        { &hf_usb_hid_globalitem_unit_exp,
5653
16
            { "Unit exponent", "usbhid.item.global.unit_exp", FT_UINT8, BASE_DEC,
5654
16
                NULL, 0, NULL, HFILL }},
5655
5656
16
        { &hf_usb_hid_globalitem_unit_sys,
5657
16
            { "System", "usbhid.item.global.unit.system", FT_UINT32, BASE_HEX,
5658
16
                VALS(usb_hid_globalitem_unit_exp_vals), 0x0000000F, NULL, HFILL }},
5659
5660
16
        { &hf_usb_hid_globalitem_unit_len,
5661
16
            { "Length", "usbhid.item.global.unit.length", FT_UINT32, BASE_HEX,
5662
16
                VALS(usb_hid_globalitem_unit_exp_vals), 0x000000F0, NULL, HFILL }},
5663
5664
16
        { &hf_usb_hid_globalitem_unit_mass,
5665
16
            { "Mass", "usbhid.item.global.unit.mass", FT_UINT32, BASE_HEX,
5666
16
                VALS(usb_hid_globalitem_unit_exp_vals), 0x00000F00, NULL, HFILL }},
5667
5668
16
        { &hf_usb_hid_globalitem_unit_time,
5669
16
            { "Time", "usbhid.item.global.unit.time", FT_UINT32, BASE_HEX,
5670
16
                VALS(usb_hid_globalitem_unit_exp_vals), 0x0000F000, NULL, HFILL }},
5671
5672
16
        { &hf_usb_hid_globalitem_unit_temp,
5673
16
            { "Temperature", "usbhid.item.global.unit.temperature", FT_UINT32, BASE_HEX,
5674
16
                VALS(usb_hid_globalitem_unit_exp_vals), 0x000F0000, NULL, HFILL }},
5675
5676
16
        { &hf_usb_hid_globalitem_unit_current,
5677
16
            { "Current", "usbhid.item.global.unit.current", FT_UINT32, BASE_HEX,
5678
16
                VALS(usb_hid_globalitem_unit_exp_vals), 0x00F00000, NULL, HFILL }},
5679
5680
16
        { &hf_usb_hid_globalitem_unit_brightness,
5681
16
            { "Luminous intensity", "usbhid.item.global.unit.brightness", FT_UINT32, BASE_HEX,
5682
16
                VALS(usb_hid_globalitem_unit_exp_vals), 0x0F000000, NULL, HFILL }},
5683
5684
16
        { &hf_usb_hid_globalitem_report_size,
5685
16
            { "Report size", "usbhid.item.global.report_size", FT_UINT8, BASE_DEC,
5686
16
                NULL, 0, NULL, HFILL }},
5687
5688
16
        { &hf_usb_hid_globalitem_report_id,
5689
16
            { "Report ID", "usbhid.item.global.report_id", FT_UINT8, BASE_HEX,
5690
16
                NULL, 0, NULL, HFILL }},
5691
5692
16
        { &hf_usb_hid_globalitem_report_count,
5693
16
            { "Report count", "usbhid.item.global.report_count", FT_UINT8, BASE_DEC,
5694
16
                NULL, 0, NULL, HFILL }},
5695
5696
16
        { &hf_usb_hid_globalitem_push,
5697
16
            { "Push", "usbhid.item.global.push", FT_UINT8, BASE_HEX,
5698
16
                NULL, 0, NULL, HFILL }},
5699
5700
16
        { &hf_usb_hid_globalitem_pop,
5701
16
            { "Pop", "usbhid.item.global.pop", FT_UINT8, BASE_HEX,
5702
16
                NULL, 0, NULL, HFILL }},
5703
5704
        /* Local-report item data */
5705
5706
16
        { &hf_usb_hid_localitem_usage,
5707
16
            { "Usage", "usbhid.item.local.usage", FT_UINT16, BASE_HEX,
5708
16
                NULL, 0, NULL, HFILL }},
5709
5710
16
        { &hf_usb_hid_localitem_usage_min,
5711
16
            { "Usage minimum", "usbhid.item.local.usage_min", FT_UINT16, BASE_HEX,
5712
16
                NULL, 0, NULL, HFILL }},
5713
5714
16
        { &hf_usb_hid_localitem_usage_max,
5715
16
            { "Usage maximum", "usbhid.item.local.usage_max", FT_UINT16, BASE_HEX,
5716
16
                NULL, 0, NULL, HFILL }},
5717
5718
16
        { &hf_usb_hid_localitem_desig_index,
5719
16
            { "Designator index", "usbhid.item.local.desig_index", FT_UINT8, BASE_HEX,
5720
16
                NULL, 0, NULL, HFILL }},
5721
5722
16
        { &hf_usb_hid_localitem_desig_min,
5723
16
            { "Designator minimum", "usbhid.item.local.desig_min", FT_UINT8, BASE_HEX,
5724
16
                NULL, 0, NULL, HFILL }},
5725
5726
16
        { &hf_usb_hid_localitem_desig_max,
5727
16
            { "Designator maximum", "usbhid.item.local.desig_max", FT_UINT8, BASE_HEX,
5728
16
                NULL, 0, NULL, HFILL }},
5729
5730
16
        { &hf_usb_hid_localitem_string_index,
5731
16
            { "String index", "usbhid.item.local.string_index", FT_UINT8, BASE_HEX,
5732
16
                NULL, 0, NULL, HFILL }},
5733
5734
16
        { &hf_usb_hid_localitem_string_min,
5735
16
            { "String minimum", "usbhid.item.local.string_min", FT_UINT8, BASE_HEX,
5736
16
                NULL, 0, NULL, HFILL }},
5737
5738
16
        { &hf_usb_hid_localitem_string_max,
5739
16
            { "String maximum", "usbhid.item.local.string_max", FT_UINT8, BASE_HEX,
5740
16
                NULL, 0, NULL, HFILL }},
5741
5742
16
        { &hf_usb_hid_localitem_delimiter,
5743
16
            { "Delimiter", "usbhid.item.local.delimiter", FT_UINT8, BASE_HEX,
5744
16
                NULL, 0, NULL, HFILL }},
5745
5746
5747
16
        { &hf_usb_hid_item_unk_data,
5748
16
            { "Item data", "usbhid.item.data", FT_BYTES, BASE_NONE,
5749
16
                NULL, 0, NULL, HFILL }},
5750
5751
        /* USB HID specific requests */
5752
16
        { &hf_usb_hid_request,
5753
16
            { "bRequest", "usbhid.setup.bRequest", FT_UINT8, BASE_HEX,
5754
16
                VALS(setup_request_names_vals), 0x0, NULL, HFILL }},
5755
5756
16
        { &hf_usb_hid_value,
5757
16
            { "wValue", "usbhid.setup.wValue", FT_UINT16, BASE_HEX,
5758
16
                NULL, 0x0, NULL, HFILL }},
5759
5760
16
        { &hf_usb_hid_index,
5761
16
            { "wIndex", "usbhid.setup.wIndex", FT_UINT16, BASE_DEC,
5762
16
                NULL, 0x0, NULL, HFILL }},
5763
5764
16
        { &hf_usb_hid_length,
5765
16
            { "wLength", "usbhid.setup.wLength", FT_UINT16, BASE_DEC,
5766
16
                NULL, 0x0, NULL, HFILL }},
5767
5768
16
        { &hf_usb_hid_report_type,
5769
16
            { "ReportType", "usbhid.setup.ReportType", FT_UINT8, BASE_DEC,
5770
16
                VALS(usb_hid_report_type_vals), 0x0, NULL, HFILL }},
5771
5772
16
        { &hf_usb_hid_report_id,
5773
16
            { "ReportID", "usbhid.setup.ReportID", FT_UINT8, BASE_DEC,
5774
16
                NULL, 0x0, NULL, HFILL }},
5775
5776
16
        { &hf_usb_hid_duration,
5777
16
            { "Duration", "usbhid.setup.Duration", FT_UINT8, BASE_CUSTOM,
5778
16
                CF_FUNC(hid_duration_fmt), 0x0, NULL, HFILL }},
5779
5780
16
        { &hf_usb_hid_zero,
5781
16
            { "(zero)", "usbhid.setup.zero", FT_UINT8, BASE_DEC,
5782
16
                NULL, 0x0, NULL, HFILL }},
5783
5784
16
        { &hf_usb_hid_protocol,
5785
16
            { "Protocol", "usbhid.setup.Protocol", FT_UINT16, BASE_HEX,
5786
16
                VALS(setup_protocol_vals), 0x0, NULL, HFILL }},
5787
5788
        /* components of the HID descriptor */
5789
16
        { &hf_usb_hid_bcdHID,
5790
16
            { "bcdHID", "usbhid.descriptor.hid.bcdHID", FT_UINT16, BASE_HEX,
5791
16
                NULL, 0x0, NULL, HFILL }},
5792
5793
16
        { &hf_usb_hid_bCountryCode,
5794
16
            { "bCountryCode", "usbhid.descriptor.hid.bCountryCode", FT_UINT8, BASE_HEX,
5795
16
                VALS(hid_country_code_vals), 0x0, NULL, HFILL }},
5796
5797
16
        { &hf_usb_hid_bNumDescriptors,
5798
16
            { "bNumDescriptors", "usbhid.descriptor.hid.bNumDescriptors", FT_UINT8, BASE_DEC,
5799
16
                NULL, 0x0, NULL, HFILL }},
5800
5801
16
        { &hf_usb_hid_bDescriptorIndex,
5802
16
            { "bDescriptorIndex", "usbhid.descriptor.hid.bDescriptorIndex", FT_UINT8, BASE_HEX,
5803
16
                NULL, 0x0, NULL, HFILL }},
5804
5805
16
        { &hf_usb_hid_bDescriptorType,
5806
16
            { "bDescriptorType", "usbhid.descriptor.hid.bDescriptorType", FT_UINT8, BASE_HEX|BASE_EXT_STRING,
5807
16
                &hid_descriptor_type_vals_ext, 0x00, NULL, HFILL }},
5808
5809
16
        { &hf_usb_hid_wInterfaceNumber,
5810
16
            { "wInterfaceNumber", "usbhid.descriptor.hid.wInterfaceNumber", FT_UINT16, BASE_DEC,
5811
16
                NULL, 0x0, NULL, HFILL }},
5812
5813
16
        { &hf_usb_hid_wDescriptorLength,
5814
16
            { "wDescriptorLength", "usbhid.descriptor.hid.wDescriptorLength", FT_UINT16, BASE_DEC,
5815
16
                NULL, 0x0, NULL, HFILL }},
5816
5817
16
        { &hf_usbhid_boot_report_keyboard_reserved,
5818
16
            { "Reserved", "usbhid.boot_report.keyboard.reserved", FT_UINT8, BASE_HEX,
5819
16
                NULL, 0x00, NULL, HFILL }},
5820
5821
16
        { &hf_usbhid_boot_report_keyboard_keycode_1,
5822
16
            { "Keycode 1", "usbhid.boot_report.keyboard.keycode_1", FT_UINT8, BASE_HEX|BASE_EXT_STRING,
5823
16
                &keycode_vals_ext, 0x00, NULL, HFILL }},
5824
5825
16
        { &hf_usbhid_boot_report_keyboard_keycode_2,
5826
16
            { "Keycode 2", "usbhid.boot_report.keyboard.keycode_2", FT_UINT8, BASE_HEX|BASE_EXT_STRING,
5827
16
                &keycode_vals_ext, 0x00, NULL, HFILL }},
5828
5829
16
        { &hf_usbhid_boot_report_keyboard_keycode_3,
5830
16
            { "Keycode 3", "usbhid.boot_report.keyboard.keycode_3", FT_UINT8, BASE_HEX|BASE_EXT_STRING,
5831
16
                &keycode_vals_ext, 0x00, NULL, HFILL }},
5832
5833
16
        { &hf_usbhid_boot_report_keyboard_keycode_4,
5834
16
            { "Keycode 4", "usbhid.boot_report.keyboard.keycode_4", FT_UINT8, BASE_HEX|BASE_EXT_STRING,
5835
16
                &keycode_vals_ext, 0x00, NULL, HFILL }},
5836
5837
16
        { &hf_usbhid_boot_report_keyboard_keycode_5,
5838
16
            { "Keycode 5", "usbhid.boot_report.keyboard.keycode_5", FT_UINT8, BASE_HEX|BASE_EXT_STRING,
5839
16
                &keycode_vals_ext, 0x00, NULL, HFILL }},
5840
5841
16
        { &hf_usbhid_boot_report_keyboard_keycode_6,
5842
16
            { "Keycode 6", "usbhid.boot_report.keyboard.keycode_6", FT_UINT8, BASE_HEX|BASE_EXT_STRING,
5843
16
                &keycode_vals_ext, 0x00, NULL, HFILL }},
5844
5845
16
        { &hf_usbhid_boot_report_keyboard_modifier_right_gui,
5846
16
            { "Modifier: RIGHT GUI", "usbhid.boot_report.keyboard.modifier.right_gui", FT_BOOLEAN, 8,
5847
16
                NULL, 0x80, NULL, HFILL }},
5848
5849
16
        { &hf_usbhid_boot_report_keyboard_modifier_right_alt,
5850
16
            { "Modifier: RIGHT ALT", "usbhid.boot_report.keyboard.modifier.right_alt", FT_BOOLEAN, 8,
5851
16
                NULL, 0x40, NULL, HFILL }},
5852
5853
16
        { &hf_usbhid_boot_report_keyboard_modifier_right_shift,
5854
16
            { "Modifier: RIGHT SHIFT", "usbhid.boot_report.keyboard.modifier.right_shift", FT_BOOLEAN, 8,
5855
16
                NULL, 0x20, NULL, HFILL }},
5856
5857
16
        { &hf_usbhid_boot_report_keyboard_modifier_right_ctrl,
5858
16
            { "Modifier: RIGHT CTRL", "usbhid.boot_report.keyboard.modifier.right_ctrl", FT_BOOLEAN, 8,
5859
16
                NULL, 0x10,NULL, HFILL }},
5860
5861
16
        { &hf_usbhid_boot_report_keyboard_modifier_left_gui,
5862
16
            { "Modifier: LEFT GUI", "usbhid.boot_report.keyboard.modifier.left_gui", FT_BOOLEAN, 8,
5863
16
                NULL, 0x08, NULL, HFILL }},
5864
5865
16
        { &hf_usbhid_boot_report_keyboard_modifier_left_alt,
5866
16
            { "Modifier: LEFT ALT", "usbhid.boot_report.keyboard.modifier.left_alt", FT_BOOLEAN, 8,
5867
16
                NULL, 0x04, NULL, HFILL }
5868
16
        },
5869
5870
16
        { &hf_usbhid_boot_report_keyboard_modifier_left_shift,
5871
16
            { "Modifier: LEFT SHIFT", "usbhid.boot_report.keyboard.modifier.left_shift", FT_BOOLEAN, 8,
5872
16
                NULL, 0x02, NULL, HFILL }},
5873
5874
16
        { &hf_usbhid_boot_report_keyboard_modifier_left_ctrl,
5875
16
            { "Modifier: LEFT CTRL", "usbhid.boot_report.keyboard.modifier.left_ctrl", FT_BOOLEAN, 8,
5876
16
                NULL, 0x01, NULL, HFILL }},
5877
5878
16
        { &hf_usbhid_boot_report_keyboard_leds_constants,
5879
16
            { "Constants", "usbhid.boot_report.keyboard.leds.constants", FT_UINT8, BASE_HEX,
5880
16
                NULL, 0xE0, NULL, HFILL }},
5881
5882
16
        { &hf_usbhid_boot_report_keyboard_leds_kana,
5883
16
            { "KANA", "usbhid.boot_report.keyboard.leds.kana", FT_BOOLEAN, 8,
5884
16
                NULL, 0x10, NULL, HFILL }},
5885
5886
16
        { &hf_usbhid_boot_report_keyboard_leds_compose,
5887
16
            { "COMPOSE", "usbhid.boot_report.keyboard.leds.compose", FT_BOOLEAN, 8,
5888
16
                NULL, 0x08, NULL, HFILL }},
5889
5890
16
        { &hf_usbhid_boot_report_keyboard_leds_scroll_lock,
5891
16
            { "SCROLL LOCK", "usbhid.boot_report.keyboard.leds.scroll_lock", FT_BOOLEAN, 8,
5892
16
                NULL, 0x04, NULL, HFILL }},
5893
5894
16
        { &hf_usbhid_boot_report_keyboard_leds_caps_lock,
5895
16
            { "CAPS LOCK", "usbhid.boot_report.keyboard.leds.caps_lock", FT_BOOLEAN, 8,
5896
16
                NULL, 0x02,NULL, HFILL }},
5897
5898
16
        { &hf_usbhid_boot_report_keyboard_leds_num_lock,
5899
16
            { "NUM LOCK",  "usbhid.boot_report.keyboard.leds.num_lock", FT_BOOLEAN, 8,
5900
16
                NULL, 0x01, NULL, HFILL }},
5901
5902
16
        { &hf_usbhid_boot_report_mouse_button_8,
5903
16
            { "Button 8",  "usbhid.boot_report.mouse.button.8", FT_BOOLEAN, 8,
5904
16
                NULL, 0x80, NULL, HFILL }},
5905
5906
16
        { &hf_usbhid_boot_report_mouse_button_7,
5907
16
            { "Button 7",  "usbhid.boot_report.mouse.button.7", FT_BOOLEAN, 8,
5908
16
                NULL, 0x40, NULL, HFILL }},
5909
5910
16
        { &hf_usbhid_boot_report_mouse_button_6,
5911
16
            { "Button 6",  "usbhid.boot_report.mouse.button.6", FT_BOOLEAN, 8,
5912
16
                NULL, 0x20, NULL, HFILL }},
5913
5914
16
        { &hf_usbhid_boot_report_mouse_button_5,
5915
16
            { "Button 5",  "usbhid.boot_report.mouse.button.5", FT_BOOLEAN, 8,
5916
16
                NULL, 0x10, NULL, HFILL }},
5917
5918
16
        { &hf_usbhid_boot_report_mouse_button_4,
5919
16
            { "Button 4",  "usbhid.boot_report.mouse.button.4", FT_BOOLEAN, 8,
5920
16
                NULL, 0x08, NULL, HFILL }},
5921
5922
16
        { &hf_usbhid_boot_report_mouse_button_middle,
5923
16
            { "Button Middle", "usbhid.boot_report.mouse.button.middle", FT_BOOLEAN, 8,
5924
16
                NULL, 0x04, NULL, HFILL }},
5925
5926
16
        { &hf_usbhid_boot_report_mouse_button_right,
5927
16
            { "Button Right",  "usbhid.boot_report.mouse.button.right", FT_BOOLEAN, 8,
5928
16
                NULL, 0x02, NULL, HFILL }},
5929
5930
16
        { &hf_usbhid_boot_report_mouse_button_left,
5931
16
            { "Button Left",   "usbhid.boot_report.mouse.button.left", FT_BOOLEAN, 8,
5932
16
                NULL, 0x01, NULL, HFILL }},
5933
5934
16
        { &hf_usbhid_boot_report_mouse_x_displacement,
5935
16
            { "X Displacement", "usbhid.boot_report.mouse.x_displacement", FT_INT8, BASE_DEC,
5936
16
                NULL, 0x00, NULL, HFILL }},
5937
5938
16
        { &hf_usbhid_boot_report_mouse_y_displacement,
5939
16
            { "Y Displacement", "usbhid.boot_report.mouse.y_displacement", FT_INT8, BASE_DEC,
5940
16
                NULL, 0x00, NULL, HFILL }},
5941
5942
16
        { &hf_usbhid_boot_report_mouse_horizontal_scroll_wheel,
5943
16
            { "Horizontal Scroll Wheel", "usbhid.boot_report.mouse.scroll_wheel.horizontal", FT_INT8, BASE_DEC,
5944
16
                NULL, 0x00, NULL, HFILL }},
5945
5946
16
        { &hf_usbhid_boot_report_mouse_vertical_scroll_wheel,
5947
16
            { "Vertical Scroll Wheel", "usbhid.boot_report.mouse.scroll_wheel.vertical", FT_INT8, BASE_DEC,
5948
16
                NULL, 0x00, NULL, HFILL }},
5949
5950
16
        { &hf_usbhid_data,
5951
16
            { "HID Data", "usbhid.data", FT_BYTES, BASE_NONE,
5952
16
                NULL, 0x00, NULL, HFILL }},
5953
5954
16
        { &hf_usbhid_unknown_data,
5955
16
            { "Unknown", "usbhid.data.unknown", FT_BYTES, BASE_NONE,
5956
16
                NULL, 0x00, NULL, HFILL }},
5957
5958
16
        { &hf_usbhid_vendor_data,
5959
16
            { "Vendor Data", "usbhid.data.vendor", FT_BYTES, BASE_NONE,
5960
16
                NULL, 0x00, NULL, HFILL }},
5961
5962
16
        { &hf_usbhid_report_id,
5963
16
            { "Report ID", "usbhid.data.report_id", FT_UINT8, BASE_HEX,
5964
16
                NULL, 0x00, NULL, HFILL }},
5965
5966
16
        { &hf_usbhid_padding,
5967
16
            { "Padding", "usbhid.data.padding", FT_BYTES, BASE_NONE,
5968
16
                NULL, 0x00, NULL, HFILL }},
5969
5970
16
        { &hf_usbhid_axis_x,
5971
16
            { "X Axis", "usbhid.data.axis.x", FT_INT32, BASE_DEC,
5972
16
                NULL, 0x00, NULL, HFILL }},
5973
5974
16
        { &hf_usbhid_axis_y,
5975
16
            { "Y Axis", "usbhid.data.axis.y", FT_INT32, BASE_DEC,
5976
16
                NULL, 0x00, NULL, HFILL }},
5977
5978
16
        { &hf_usbhid_axis_z,
5979
16
            { "Z Axis", "usbhid.data.axis.z", FT_INT32, BASE_DEC,
5980
16
                NULL, 0x00, NULL, HFILL }},
5981
5982
16
        { &hf_usbhid_axis_rx,
5983
16
            { "Rx Axis", "usbhid.data.axis.rx", FT_INT32, BASE_DEC,
5984
16
                NULL, 0x00, NULL, HFILL }},
5985
5986
16
        { &hf_usbhid_axis_ry,
5987
16
            { "Ry Axis", "usbhid.data.axis.ry", FT_INT32, BASE_DEC,
5988
16
                NULL, 0x00, NULL, HFILL }},
5989
5990
16
        { &hf_usbhid_axis_rz,
5991
16
            { "Rz Axis", "usbhid.data.axis.rz", FT_INT32, BASE_DEC,
5992
16
                NULL, 0x00, NULL, HFILL }},
5993
5994
16
        { &hf_usbhid_axis_slider,
5995
16
            { "Slider Axis", "usbhid.data.axis.slider", FT_INT32, BASE_DEC,
5996
16
                NULL, 0x00, NULL, HFILL }},
5997
5998
16
        { &hf_usbhid_axis_vx,
5999
16
            { "Vx Axis", "usbhid.data.axis.vx", FT_INT32, BASE_DEC,
6000
16
                NULL, 0x00, NULL, HFILL }},
6001
6002
16
        { &hf_usbhid_axis_vy,
6003
16
            { "Vy Axis", "usbhid.data.axis.vy", FT_INT32, BASE_DEC,
6004
16
                NULL, 0x00, NULL, HFILL }},
6005
6006
16
        { &hf_usbhid_axis_vz,
6007
16
            { "Vz Axis", "usbhid.data.axis.vz", FT_INT32, BASE_DEC,
6008
16
                NULL, 0x00, NULL, HFILL }},
6009
6010
16
        { &hf_usbhid_axis_vbrx,
6011
16
            { "Vbrx Axis", "usbhid.data.axis.vbrx", FT_INT32, BASE_DEC,
6012
16
                NULL, 0x00, NULL, HFILL }},
6013
6014
16
        { &hf_usbhid_axis_vbry,
6015
16
            { "Vbry Axis", "usbhid.data.axis.vbry", FT_INT32, BASE_DEC,
6016
16
                NULL, 0x00, NULL, HFILL }},
6017
6018
16
        { &hf_usbhid_axis_vbrz,
6019
16
            { "Vbrz Axis", "usbhid.data.axis.vbrz", FT_INT32, BASE_DEC,
6020
16
                NULL, 0x00, NULL, HFILL }},
6021
6022
16
        { &hf_usbhid_axis_vno,
6023
16
            { "Vno Axis", "usbhid.data.axis.vno", FT_INT32, BASE_DEC,
6024
16
                NULL, 0x00, NULL, HFILL }},
6025
6026
16
        { &hf_usbhid_button,
6027
16
            { "Button", "usbhid.data.button", FT_BOOLEAN, BASE_NONE,
6028
16
                NULL, 0x00, NULL, HFILL }},
6029
6030
16
        { &hf_usbhid_key,
6031
16
            { "Key", "usbhid.data.key.variable", FT_BOOLEAN, BASE_NONE,
6032
16
                NULL, 0x00, NULL, HFILL }},
6033
6034
16
        { &hf_usbhid_array,
6035
16
            { "Array", "usbhid.data.array", FT_BYTES, BASE_NONE,
6036
16
                NULL, 0x00, NULL, HFILL }},
6037
6038
16
        { &hf_usbhid_array_usage,
6039
16
            { "Usage", "usbhid.data.array.usage", FT_BOOLEAN, BASE_NONE,
6040
16
            NULL, 0x00, NULL, HFILL }},
6041
16
    };
6042
6043
16
    static int *usb_hid_ett[] = {
6044
16
        &ett_usb_hid_report,
6045
16
        &ett_usb_hid_item_header,
6046
16
        &ett_usb_hid_wValue,
6047
16
        &ett_usb_hid_descriptor,
6048
16
        &ett_usb_hid_data,
6049
16
        &ett_usb_hid_unknown_data,
6050
16
        &ett_usb_hid_array
6051
16
    };
6052
6053
16
    report_descriptors = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
6054
6055
16
    proto_usb_hid = proto_register_protocol("USB HID", "USBHID", "usbhid");
6056
16
    proto_register_field_array(proto_usb_hid, hf, array_length(hf));
6057
16
    proto_register_subtree_array(usb_hid_ett, array_length(usb_hid_ett));
6058
6059
    /*usb_hid_boot_keyboard_input_report_handle  =*/ register_dissector("usbhid.boot_report.keyboard.input",  dissect_usb_hid_boot_keyboard_input_report,  proto_usb_hid);
6060
16
    /*usb_hid_boot_keyboard_output_report_handle =*/ register_dissector("usbhid.boot_report.keyboard.output", dissect_usb_hid_boot_keyboard_output_report, proto_usb_hid);
6061
16
    /*usb_hid_boot_mouse_input_report_handle     =*/ register_dissector("usbhid.boot_report.mouse.input",     dissect_usb_hid_boot_mouse_input_report,     proto_usb_hid);
6062
16
    usb_hid_control_handle                         = register_dissector("usbhid.control", dissect_usb_hid_control, proto_usb_hid);
6063
16
    usb_hid_interrupt_handle                       = register_dissector("usbhid.data", dissect_usb_hid_data, proto_usb_hid);
6064
16
    usb_hid_descr_handle                           = register_dissector("usbhid.class_descriptors", dissect_usb_hid_class_descriptors, proto_usb_hid);
6065
16
}
6066
6067
void
6068
proto_reg_handoff_usb_hid(void)
6069
16
{
6070
16
    dissector_add_uint("usb.control", IF_CLASS_HID, usb_hid_control_handle);
6071
16
    dissector_add_for_decode_as("usb.device", usb_hid_control_handle);
6072
16
    dissector_add_uint("usb.interrupt", IF_CLASS_HID, usb_hid_interrupt_handle);
6073
16
    dissector_add_uint("usb.descriptor", IF_CLASS_HID, usb_hid_descr_handle);
6074
16
}
6075
6076
/*
6077
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
6078
 *
6079
 * Local variables:
6080
 * c-basic-offset: 4
6081
 * tab-width: 8
6082
 * indent-tabs-mode: nil
6083
 * End:
6084
 *
6085
 * vi: set shiftwidth=4 tabstop=8 expandtab:
6086
 * :indentSize=4:tabSize=8:noTabs=true:
6087
 */