4 * By Adam Nielsen <a.nielsen@shikadi.net> 2009
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include <epan/packet.h>
26 #include "packet-usb.h"
27 #include "packet-usb-hid.h"
28 #include "packet-btsdp.h"
31 void proto_register_usb_hid(void);
32 void proto_reg_handoff_usb_hid(void);
34 /* protocols and header fields */
35 static int proto_usb_hid = -1;
36 static int hf_usb_hid_item_bSize = -1;
37 static int hf_usb_hid_item_bType = -1;
38 static int hf_usb_hid_mainitem_bTag = -1;
39 static int hf_usb_hid_globalitem_bTag = -1;
40 static int hf_usb_hid_localitem_bTag = -1;
41 static int hf_usb_hid_longitem_bTag = -1;
42 static int hf_usb_hid_item_bDataSize = -1;
43 static int hf_usb_hid_item_bLongItemTag = -1;
44 static int hf_usb_hid_item_unk_data = -1;
46 static int hf_usb_hid_mainitem_bit0 = -1;
47 static int hf_usb_hid_mainitem_bit1 = -1;
48 static int hf_usb_hid_mainitem_bit2 = -1;
49 static int hf_usb_hid_mainitem_bit3 = -1;
50 static int hf_usb_hid_mainitem_bit4 = -1;
51 static int hf_usb_hid_mainitem_bit5 = -1;
52 static int hf_usb_hid_mainitem_bit6 = -1;
53 static int hf_usb_hid_mainitem_bit7 = -1;
54 static int hf_usb_hid_mainitem_bit7_input = -1;
55 static int hf_usb_hid_mainitem_bit8 = -1;
56 static int hf_usb_hid_mainitem_colltype = -1;
58 static int hf_usb_hid_globalitem_usage = -1;
59 static int hf_usb_hid_globalitem_log_min = -1;
60 static int hf_usb_hid_globalitem_log_max = -1;
61 static int hf_usb_hid_globalitem_phy_min = -1;
62 static int hf_usb_hid_globalitem_phy_max = -1;
63 static int hf_usb_hid_globalitem_unit_exp = -1;
64 static int hf_usb_hid_globalitem_unit_sys = -1;
65 static int hf_usb_hid_globalitem_unit_len = -1;
66 static int hf_usb_hid_globalitem_unit_mass = -1;
67 static int hf_usb_hid_globalitem_unit_time = -1;
68 static int hf_usb_hid_globalitem_unit_temp = -1;
69 static int hf_usb_hid_globalitem_unit_current = -1;
70 static int hf_usb_hid_globalitem_unit_brightness = -1;
71 static int hf_usb_hid_globalitem_report_size = -1;
72 static int hf_usb_hid_globalitem_report_id = -1;
73 static int hf_usb_hid_globalitem_report_count = -1;
74 static int hf_usb_hid_globalitem_push = -1;
75 static int hf_usb_hid_globalitem_pop = -1;
77 static int hf_usb_hid_localitem_usage = -1;
78 static int hf_usb_hid_localitem_usage_min = -1;
79 /* static int hf_usb_hid_localitem_usage_max = -1; */
80 static int hf_usb_hid_localitem_desig_index = -1;
81 static int hf_usb_hid_localitem_desig_min = -1;
82 static int hf_usb_hid_localitem_desig_max = -1;
83 static int hf_usb_hid_localitem_string_index = -1;
84 static int hf_usb_hid_localitem_string_min = -1;
85 static int hf_usb_hid_localitem_string_max = -1;
86 static int hf_usb_hid_localitem_delimiter = -1;
88 static gint ett_usb_hid_report = -1;
89 static gint ett_usb_hid_item_header = -1;
90 static gint ett_usb_hid_wValue = -1;
91 static gint ett_usb_hid_descriptor = -1;
93 static int hf_usb_hid_request = -1;
94 static int hf_usb_hid_value = -1;
95 static int hf_usb_hid_index = -1;
96 static int hf_usb_hid_length = -1;
97 static int hf_usb_hid_report_type = -1;
98 static int hf_usb_hid_report_id = -1;
99 static int hf_usb_hid_duration = -1;
100 static int hf_usb_hid_zero = -1;
102 static int hf_usb_hid_bcdHID = -1;
103 static int hf_usb_hid_bCountryCode = -1;
104 static int hf_usb_hid_bNumDescriptors = -1;
105 static int hf_usb_hid_bDescriptorIndex = -1;
106 static int hf_usb_hid_bDescriptorType = -1;
107 static int hf_usb_hid_wInterfaceNumber = -1;
108 static int hf_usb_hid_wDescriptorLength = -1;
110 static int hf_usbhid_boot_report_keyboard_modifier_right_gui = -1;
111 static int hf_usbhid_boot_report_keyboard_modifier_right_alt = -1;
112 static int hf_usbhid_boot_report_keyboard_modifier_right_shift = -1;
113 static int hf_usbhid_boot_report_keyboard_modifier_right_ctrl = -1;
114 static int hf_usbhid_boot_report_keyboard_modifier_left_gui = -1;
115 static int hf_usbhid_boot_report_keyboard_modifier_left_alt = -1;
116 static int hf_usbhid_boot_report_keyboard_modifier_left_shift = -1;
117 static int hf_usbhid_boot_report_keyboard_modifier_left_ctrl = -1;
118 static int hf_usbhid_boot_report_keyboard_reserved = -1;
119 static int hf_usbhid_boot_report_keyboard_keycode_1 = -1;
120 static int hf_usbhid_boot_report_keyboard_keycode_2 = -1;
121 static int hf_usbhid_boot_report_keyboard_keycode_3 = -1;
122 static int hf_usbhid_boot_report_keyboard_keycode_4 = -1;
123 static int hf_usbhid_boot_report_keyboard_keycode_5 = -1;
124 static int hf_usbhid_boot_report_keyboard_keycode_6 = -1;
125 static int hf_usbhid_boot_report_keyboard_leds_constants = -1;
126 static int hf_usbhid_boot_report_keyboard_leds_kana = -1;
127 static int hf_usbhid_boot_report_keyboard_leds_compose = -1;
128 static int hf_usbhid_boot_report_keyboard_leds_scroll_lock = -1;
129 static int hf_usbhid_boot_report_keyboard_leds_caps_lock = -1;
130 static int hf_usbhid_boot_report_keyboard_leds_num_lock = -1;
131 static int hf_usbhid_boot_report_mouse_button_8 = -1;
132 static int hf_usbhid_boot_report_mouse_button_7 = -1;
133 static int hf_usbhid_boot_report_mouse_button_6 = -1;
134 static int hf_usbhid_boot_report_mouse_button_5 = -1;
135 static int hf_usbhid_boot_report_mouse_button_4 = -1;
136 static int hf_usbhid_boot_report_mouse_button_middle = -1;
137 static int hf_usbhid_boot_report_mouse_button_right = -1;
138 static int hf_usbhid_boot_report_mouse_button_left = -1;
139 static int hf_usbhid_boot_report_mouse_x_displacement = -1;
140 static int hf_usbhid_boot_report_mouse_y_displacement = -1;
141 static int hf_usbhid_boot_report_mouse_horizontal_scroll_wheel = -1;
142 static int hf_usbhid_boot_report_mouse_vertical_scroll_wheel = -1;
143 static int hf_usbhid_data = -1;
145 static const true_false_string tfs_mainitem_bit0 = {"Constant", "Data"};
146 static const true_false_string tfs_mainitem_bit1 = {"Variable", "Array"};
147 static const true_false_string tfs_mainitem_bit2 = {"Relative", "Absolute"};
148 static const true_false_string tfs_mainitem_bit3 = {"Wrap", "No Wrap"};
149 static const true_false_string tfs_mainitem_bit4 = {"Non Linear", "Linear"};
150 static const true_false_string tfs_mainitem_bit5 = {"No Preferred", "Preferred State"};
151 static const true_false_string tfs_mainitem_bit6 = {"Null state", "No Null position"};
152 static const true_false_string tfs_mainitem_bit7 = {"Volatile", "Non Volatile"};
153 static const true_false_string tfs_mainitem_bit8 = {"Buffered Bytes", "Bit Field"};
156 struct usb_hid_global_state {
157 unsigned int usage_page;
161 /* HID class specific descriptor types */
162 #define USB_DT_HID 0x21
163 #define USB_DT_HID_REPORT 0x22
164 static const value_string hid_descriptor_type_vals[] = {
166 {USB_DT_HID_REPORT, "HID Report"},
169 static value_string_ext hid_descriptor_type_vals_ext =
170 VALUE_STRING_EXT_INIT(hid_descriptor_type_vals);
173 #define USBHID_SIZE_MASK 0x03
174 #define USBHID_TYPE_MASK 0x0C
175 #define USBHID_TAG_MASK 0xF0
177 static const value_string usb_hid_item_bSize_vals[] = {
185 #define USBHID_ITEMTYPE_MAIN 0
186 #define USBHID_ITEMTYPE_GLOBAL 1
187 #define USBHID_ITEMTYPE_LOCAL 2
188 #define USBHID_ITEMTYPE_LONG 3
189 static const value_string usb_hid_item_bType_vals[] = {
190 {USBHID_ITEMTYPE_MAIN, "Main"},
191 {USBHID_ITEMTYPE_GLOBAL, "Global"},
192 {USBHID_ITEMTYPE_LOCAL, "Local"},
193 {USBHID_ITEMTYPE_LONG, "Long item"},
197 #define USBHID_MAINITEM_TAG_INPUT 8
198 #define USBHID_MAINITEM_TAG_OUTPUT 9
199 #define USBHID_MAINITEM_TAG_FEATURE 11
200 #define USBHID_MAINITEM_TAG_COLLECTION 10
201 #define USBHID_MAINITEM_TAG_ENDCOLLECTION 12
202 static const value_string usb_hid_mainitem_bTag_vals[] = {
203 {USBHID_MAINITEM_TAG_INPUT, "Input"},
204 {USBHID_MAINITEM_TAG_OUTPUT, "Output"},
205 {USBHID_MAINITEM_TAG_FEATURE, "Feature"},
206 {USBHID_MAINITEM_TAG_COLLECTION, "Collection"},
207 {USBHID_MAINITEM_TAG_ENDCOLLECTION, "End collection"},
210 #define USBHID_GLOBALITEM_TAG_USAGE_PAGE 0
211 #define USBHID_GLOBALITEM_TAG_LOG_MIN 1
212 #define USBHID_GLOBALITEM_TAG_LOG_MAX 2
213 #define USBHID_GLOBALITEM_TAG_PHY_MIN 3
214 #define USBHID_GLOBALITEM_TAG_PHY_MAX 4
215 #define USBHID_GLOBALITEM_TAG_UNIT_EXP 5
216 #define USBHID_GLOBALITEM_TAG_UNIT 6
217 #define USBHID_GLOBALITEM_TAG_REPORT_SIZE 7
218 #define USBHID_GLOBALITEM_TAG_REPORT_ID 8
219 #define USBHID_GLOBALITEM_TAG_REPORT_COUNT 9
220 #define USBHID_GLOBALITEM_TAG_PUSH 10
221 #define USBHID_GLOBALITEM_TAG_POP 11
222 static const value_string usb_hid_globalitem_bTag_vals[] = {
223 {USBHID_GLOBALITEM_TAG_USAGE_PAGE, "Usage"},
224 {USBHID_GLOBALITEM_TAG_LOG_MIN, "Logical minimum"},
225 {USBHID_GLOBALITEM_TAG_LOG_MAX, "Logical maximum"},
226 {USBHID_GLOBALITEM_TAG_PHY_MIN, "Physical minimum"},
227 {USBHID_GLOBALITEM_TAG_PHY_MAX, "Physical maximum"},
228 {USBHID_GLOBALITEM_TAG_UNIT_EXP, "Unit exponent"},
229 {USBHID_GLOBALITEM_TAG_UNIT, "Units"},
230 {USBHID_GLOBALITEM_TAG_REPORT_SIZE, "Report size"},
231 {USBHID_GLOBALITEM_TAG_REPORT_ID, "Report ID"},
232 {USBHID_GLOBALITEM_TAG_REPORT_COUNT, "Report count"},
233 {USBHID_GLOBALITEM_TAG_PUSH, "Push"},
234 {USBHID_GLOBALITEM_TAG_POP, "Pop"},
241 #define USBHID_LOCALITEM_TAG_USAGE_PAGE 0
242 #define USBHID_LOCALITEM_TAG_USAGE_MIN 1
243 #define USBHID_LOCALITEM_TAG_USAGE_MAX 2
244 #define USBHID_LOCALITEM_TAG_DESIG_INDEX 3
245 #define USBHID_LOCALITEM_TAG_DESIG_MIN 4
246 #define USBHID_LOCALITEM_TAG_DESIG_MAX 5
248 #define USBHID_LOCALITEM_TAG_STRING_INDEX 7
249 #define USBHID_LOCALITEM_TAG_STRING_MIN 8
250 #define USBHID_LOCALITEM_TAG_STRING_MAX 9
251 #define USBHID_LOCALITEM_TAG_DELIMITER 10 /* Also listed as reserved in spec! */
252 static const value_string usb_hid_localitem_bTag_vals[] = {
253 {USBHID_LOCALITEM_TAG_USAGE_PAGE, "Usage"},
254 {USBHID_LOCALITEM_TAG_USAGE_MIN, "Usage minimum"},
255 {USBHID_LOCALITEM_TAG_USAGE_MAX, "Usage maximum"},
256 {USBHID_LOCALITEM_TAG_DESIG_INDEX, "Designator index"},
257 {USBHID_LOCALITEM_TAG_DESIG_MIN, "Designator minimum"},
258 {USBHID_LOCALITEM_TAG_DESIG_MAX, "Designator maximum"},
259 {USBHID_LOCALITEM_TAG_STRING_INDEX, "String index"},
260 {USBHID_LOCALITEM_TAG_STRING_MIN, "String minimum"},
261 {USBHID_LOCALITEM_TAG_STRING_MAX, "String maximum"},
262 {USBHID_LOCALITEM_TAG_DELIMITER, "Delimiter"},
270 static const value_string usb_hid_longitem_bTag_vals[] = {
275 static const range_string usb_hid_mainitem_colltype_vals[] = {
276 {0x00, 0x00, "Physical"},
277 {0x01, 0x01, "Application"},
278 {0x02, 0x02, "Logical"},
279 {0x03, 0x03, "Report"},
280 {0x04, 0x04, "Named array"},
281 {0x05, 0x05, "Usage switch"},
282 {0x06, 0x06, "Usage modifier"},
283 {0x07, 0x7F, "[Reserved]"},
284 {0x80, 0xFF, "[Vendor-defined]"},
288 static const value_string usb_hid_globalitem_unit_exp_vals[] = {
307 static const range_string usb_hid_item_usage_vals[] = {
308 {0x00, 0x00, "Undefined"},
309 {0x01, 0x01, "Generic desktop controls"},
310 {0x02, 0x02, "Simulation controls"},
311 {0x03, 0x03, "VR controls"},
312 {0x04, 0x04, "Sport controls"},
313 {0x05, 0x05, "Game controls"},
314 {0x06, 0x06, "Generic device controls"},
315 {0x07, 0x07, "Keyboard/keypad"},
316 {0x08, 0x08, "LEDs"},
317 {0x09, 0x09, "Button"},
318 {0x0A, 0x0A, "Ordinal"},
319 {0x0B, 0x0B, "Telephony"},
320 {0x0C, 0x0C, "Consumer"},
321 {0x0D, 0x0D, "Digitizer"},
322 {0x0E, 0x0E, "[Reserved]"},
323 {0x0F, 0x0F, "Physical Interface Device (PID) page"},
324 {0x10, 0x10, "Unicode"},
325 {0x11, 0x13, "[Reserved]"},
326 {0x14, 0x14, "Alphanumeric display"},
327 {0x15, 0x3F, "[Reserved]"},
328 {0x40, 0x40, "Medical instruments"},
329 {0x41, 0x7F, "[Reserved]"},
330 {0x80, 0x83, "Monitor page"},
331 {0x84, 0x87, "Power page"},
332 {0x88, 0x8B, "[Reserved]"},
333 {0x8C, 0x8C, "Bar code scanner page"},
334 {0x8D, 0x8D, "Scale page"},
335 {0x8E, 0x8E, "Magnetic Stripe Reading (MSR) devices"},
336 {0x8F, 0x8F, "[Reserved Point of Sale page]"},
337 {0x90, 0x90, "Camera control page"},
338 {0x91, 0x91, "Arcade page"},
339 {0x92, 0xFEFF, "[Reserved]"},
340 {0xFF00, 0xFFFF, "[Vendor-defined]"},
344 static const value_string keycode_vals[] = {
345 { 0x00, "<ACTION KEY UP>" },
346 { 0x01, "ErrorRollOver" },
347 { 0x02, "POSTFail" },
348 { 0x03, "ErrorUndefined" },
390 { 0x2A, "Backspace" },
392 { 0x2C, "Spacebar" },
399 { 0x32, "NonUS #/~" },
406 { 0x39, "CapsLock" },
419 { 0x46, "PrintScreen" },
420 { 0x47, "ScrollLock" },
425 { 0x4C, "DeleteForward" },
427 { 0x4E, "PageDown" },
428 { 0x4F, "RightArrow" },
429 { 0x50, "LeftArrow" },
430 { 0x51, "DownArrow" },
435 { 0x54, "Keypad /" },
436 { 0x55, "Keypad *" },
437 { 0x56, "Keypad -" },
438 { 0x57, "Keypad +" },
439 { 0x58, "Keypad ENTER" },
440 { 0x59, "Keypad 1" },
441 { 0x5A, "Keypad 2" },
442 { 0x5B, "Keypad 3" },
443 { 0x5C, "Keypad 4" },
444 { 0x5D, "Keypad 5" },
445 { 0x5E, "Keypad 6" },
446 { 0x5F, "Keypad 7" },
447 { 0x60, "Keypad 8" },
448 { 0x61, "Keypad 9" },
449 { 0x62, "Keypad 0" },
450 { 0x63, "Keypad ." },
453 { 0x64, "NonUS \\/|" },
454 { 0x65, "Application" },
456 { 0x67, "Keypad =" },
483 { 0x80, "VolumeUp" },
484 { 0x81, "VolumeDown" },
485 { 0x82, "Locking CapsLock" },
486 { 0x83, "Locking NumLock" },
487 { 0x84, "Locking ScrollLock" },
488 { 0x85, "Keypad Comma" },
489 { 0x86, "Keypad EqualSign" },
490 { 0x87, "International1" },
491 { 0x88, "International2" },
492 { 0x89, "International3" },
493 { 0x8A, "International4" },
494 { 0x8B, "International5" },
495 { 0x8C, "International6" },
496 { 0x8D, "International7" },
497 { 0x8E, "International8" },
498 { 0x8F, "International9" },
509 { 0x99, "AlternateErase" },
510 { 0x9A, "SysReq/Attention" },
515 { 0x9F, "Separator" },
519 { 0xA2, "Clear/Again" },
520 { 0xA3, "CrSel/Props" },
522 /* 0xA5..0xAF - reserved */
523 { 0xB0, "Keypad 00" },
524 { 0xB1, "Keypad 000" },
525 { 0xB2, "ThousandsSeparator" },
526 { 0xB3, "DecimalSeparator" },
527 { 0xB4, "CurrencyUnit" },
528 { 0xB5, "CurrencySubunit" },
529 { 0xB6, "Keypad (" },
530 { 0xB7, "Keypad )" },
531 { 0xB8, "Keypad {" },
532 { 0xB9, "Keypad }" },
533 { 0xBA, "Keypad Tab" },
534 { 0xBB, "Keypad Backspace" },
535 { 0xBC, "Keypad A" },
536 { 0xBD, "Keypad B" },
537 { 0xBE, "Keypad C" },
538 { 0xBF, "Keypad D" },
540 { 0xC0, "Keypad E" },
541 { 0xC1, "Keypad F" },
542 { 0xC2, "Keypad XOR" },
543 { 0xC3, "Keypad ^" },
544 { 0xC4, "Keypad %" },
545 { 0xC5, "Keypad <" },
546 { 0xC6, "Keypad >" },
547 { 0xC7, "Keypad &" },
548 { 0xC8, "Keypad &&" },
549 { 0xC9, "Keypad |" },
550 { 0xCA, "Keypad ||" },
551 { 0xCB, "Keypad :" },
552 { 0xCC, "Keypad #" },
553 { 0xCD, "Keypad Space" },
554 { 0xCE, "Keypad @" },
555 { 0xCF, "Keypad !" },
557 { 0xD0, "Keypad Memory Store" },
558 { 0xD1, "Keypad Memory Recall" },
559 { 0xD2, "Keypad Memory Clear" },
560 { 0xD3, "Keypad Memory Add" },
561 { 0xD4, "Keypad Memory Subtract" },
562 { 0xD5, "Keypad Memory Multiply" },
563 { 0xD6, "Keypad Memory Divide" },
564 { 0xD7, "Keypad +/-" },
565 { 0xD8, "Keypad Clear" },
566 { 0xD9, "Keypad Clear Entry" },
567 { 0xDA, "Keypad Binary" },
568 { 0xDB, "Keypad Octal" },
569 { 0xDC, "Keypad Decimal" },
570 { 0xDD, "Keypad Hexadecimal" },
571 /* 0xDE..0xDF - reserved, */
572 { 0xE0, "LeftControl" },
573 { 0xE1, "LeftShift" },
576 { 0xE4, "RightControl" },
577 { 0xE5, "RightShift" },
578 { 0xE6, "RightAlt" },
579 { 0xE7, "RightGUI" },
583 value_string_ext keycode_vals_ext = VALUE_STRING_EXT_INIT(keycode_vals);
585 /* Dissector for the data in a HID main report. */
587 dissect_usb_hid_report_mainitem_data(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, unsigned int bSize, unsigned int bTag)
590 case USBHID_MAINITEM_TAG_INPUT:
591 case USBHID_MAINITEM_TAG_OUTPUT:
592 case USBHID_MAINITEM_TAG_FEATURE:
593 proto_tree_add_item(tree, hf_usb_hid_mainitem_bit0, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
594 proto_tree_add_item(tree, hf_usb_hid_mainitem_bit1, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
595 proto_tree_add_item(tree, hf_usb_hid_mainitem_bit2, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
596 proto_tree_add_item(tree, hf_usb_hid_mainitem_bit3, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
597 proto_tree_add_item(tree, hf_usb_hid_mainitem_bit4, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
598 proto_tree_add_item(tree, hf_usb_hid_mainitem_bit5, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
599 proto_tree_add_item(tree, hf_usb_hid_mainitem_bit6, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
600 if (bTag == USBHID_MAINITEM_TAG_INPUT) {
601 proto_tree_add_item(tree, hf_usb_hid_mainitem_bit7_input, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
603 proto_tree_add_item(tree, hf_usb_hid_mainitem_bit7, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
606 proto_tree_add_item(tree, hf_usb_hid_mainitem_bit8, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
608 proto_tree_add_boolean_format_value(tree, hf_usb_hid_mainitem_bit8, tvb, offset, 0, FALSE, "Buffered bytes (default, no second byte present)");
611 case USBHID_MAINITEM_TAG_COLLECTION:
612 proto_tree_add_item(tree, hf_usb_hid_mainitem_colltype, tvb, offset, 1, ENC_LITTLE_ENDIAN);
614 case USBHID_MAINITEM_TAG_ENDCOLLECTION:
618 proto_tree_add_item(tree, hf_usb_hid_item_unk_data, tvb, offset, bSize, ENC_NA);
625 /* Dissector for the data in a HID main report. */
627 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)
630 case USBHID_GLOBALITEM_TAG_USAGE_PAGE:
632 case 1: global->usage_page = tvb_get_guint8(tvb, offset); break;
633 case 2: global->usage_page = tvb_get_letohs(tvb, offset); break;
634 case 3: global->usage_page = tvb_get_letoh24(tvb, offset); break;
635 case 4: global->usage_page = tvb_get_letohl(tvb, offset); break;
636 default: global->usage_page = 0; break;
638 proto_tree_add_item(tree, hf_usb_hid_globalitem_usage, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
640 case USBHID_GLOBALITEM_TAG_LOG_MIN:
641 proto_tree_add_item(tree, hf_usb_hid_globalitem_log_min, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
643 case USBHID_GLOBALITEM_TAG_LOG_MAX:
644 proto_tree_add_item(tree, hf_usb_hid_globalitem_log_max, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
646 case USBHID_GLOBALITEM_TAG_PHY_MIN:
647 proto_tree_add_item(tree, hf_usb_hid_globalitem_phy_min, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
649 case USBHID_GLOBALITEM_TAG_PHY_MAX:
650 proto_tree_add_item(tree, hf_usb_hid_globalitem_phy_max, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
652 case USBHID_GLOBALITEM_TAG_UNIT_EXP:
653 proto_tree_add_item(tree, hf_usb_hid_globalitem_unit_exp, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
655 case USBHID_GLOBALITEM_TAG_UNIT:
656 proto_tree_add_item(tree, hf_usb_hid_globalitem_unit_sys, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
657 proto_tree_add_item(tree, hf_usb_hid_globalitem_unit_len, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
658 proto_tree_add_item(tree, hf_usb_hid_globalitem_unit_mass, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
659 proto_tree_add_item(tree, hf_usb_hid_globalitem_unit_time, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
660 proto_tree_add_item(tree, hf_usb_hid_globalitem_unit_temp, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
661 proto_tree_add_item(tree, hf_usb_hid_globalitem_unit_current, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
662 proto_tree_add_item(tree, hf_usb_hid_globalitem_unit_brightness, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
664 case USBHID_GLOBALITEM_TAG_REPORT_SIZE:
665 proto_tree_add_item(tree, hf_usb_hid_globalitem_report_size, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
667 case USBHID_GLOBALITEM_TAG_REPORT_ID:
668 proto_tree_add_item(tree, hf_usb_hid_globalitem_report_id, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
670 case USBHID_GLOBALITEM_TAG_REPORT_COUNT:
671 proto_tree_add_item(tree, hf_usb_hid_globalitem_report_count, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
673 case USBHID_GLOBALITEM_TAG_PUSH:
674 proto_tree_add_item(tree, hf_usb_hid_globalitem_push, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
676 case USBHID_GLOBALITEM_TAG_POP:
677 proto_tree_add_item(tree, hf_usb_hid_globalitem_pop, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
680 proto_tree_add_item(tree, hf_usb_hid_item_unk_data, tvb, offset, bSize, ENC_NA);
687 /* Dissector for the data in a HID main report. */
689 dissect_usb_hid_report_localitem_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)
691 unsigned int usage_page = 0xffffffff; /* in case bSize == 0 */
694 case USBHID_LOCALITEM_TAG_USAGE_PAGE:
697 proto_tree_add_item(tree, hf_usb_hid_localitem_usage, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
699 /* Only lower few bits given, need to combine with last global ID */
701 usage_page = (global->usage_page & 0xFFFFFF00) | tvb_get_guint8(tvb, offset);
703 usage_page = (global->usage_page & 0xFFFF0000) | tvb_get_ntohs(tvb, offset);
704 proto_tree_add_uint(tree, hf_usb_hid_localitem_usage, tvb, offset, bSize, usage_page);
707 case USBHID_LOCALITEM_TAG_USAGE_MIN:
708 proto_tree_add_item(tree, hf_usb_hid_localitem_usage_min, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
710 case USBHID_LOCALITEM_TAG_USAGE_MAX:
711 proto_tree_add_item(tree, hf_usb_hid_localitem_usage, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
713 case USBHID_LOCALITEM_TAG_DESIG_INDEX:
714 proto_tree_add_item(tree, hf_usb_hid_localitem_desig_index, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
716 case USBHID_LOCALITEM_TAG_DESIG_MIN:
717 proto_tree_add_item(tree, hf_usb_hid_localitem_desig_min, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
719 case USBHID_LOCALITEM_TAG_DESIG_MAX:
720 proto_tree_add_item(tree, hf_usb_hid_localitem_desig_max, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
722 case USBHID_LOCALITEM_TAG_STRING_INDEX:
723 proto_tree_add_item(tree, hf_usb_hid_localitem_string_index, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
725 case USBHID_LOCALITEM_TAG_STRING_MIN:
726 proto_tree_add_item(tree, hf_usb_hid_localitem_string_min, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
728 case USBHID_LOCALITEM_TAG_STRING_MAX:
729 proto_tree_add_item(tree, hf_usb_hid_localitem_string_max, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
731 case USBHID_LOCALITEM_TAG_DELIMITER:
732 proto_tree_add_item(tree, hf_usb_hid_localitem_delimiter, tvb, offset, bSize, ENC_LITTLE_ENDIAN);
735 proto_tree_add_item(tree, hf_usb_hid_item_unk_data, tvb, offset, bSize, ENC_NA);
742 /* Dissector for individual HID report items. Recursive. */
744 dissect_usb_hid_report_item(packet_info *pinfo _U_, proto_tree *parent_tree, tvbuff_t *tvb, int offset, usb_conv_info_t *usb_conv_info _U_, const struct usb_hid_global_state *global)
747 proto_tree *tree, *subtree;
750 unsigned int bSize, bType, bTag;
751 const value_string *usb_hid_cur_bTag_vals;
752 int hf_usb_hid_curitem_bTag;
753 struct usb_hid_global_state cur_global;
754 memcpy(&cur_global, global, sizeof(struct usb_hid_global_state));
756 while (tvb_reported_length_remaining(tvb, offset) > 0)
760 tmp = tvb_get_guint8(tvb, offset);
761 bSize = tmp & USBHID_SIZE_MASK;
762 if (bSize == 3) bSize++; /* 3 == four bytes */
763 bType = (tmp & USBHID_TYPE_MASK) >> 2;
764 bTag = (tmp & USBHID_TAG_MASK) >> 4;
767 case USBHID_ITEMTYPE_MAIN:
768 hf_usb_hid_curitem_bTag = hf_usb_hid_mainitem_bTag;
769 usb_hid_cur_bTag_vals = usb_hid_mainitem_bTag_vals;
771 case USBHID_ITEMTYPE_GLOBAL:
772 hf_usb_hid_curitem_bTag = hf_usb_hid_globalitem_bTag;
773 usb_hid_cur_bTag_vals = usb_hid_globalitem_bTag_vals;
775 case USBHID_ITEMTYPE_LOCAL:
776 hf_usb_hid_curitem_bTag = hf_usb_hid_localitem_bTag;
777 usb_hid_cur_bTag_vals = usb_hid_localitem_bTag_vals;
779 default: /* Only USBHID_ITEMTYPE_LONG, but keep compiler happy */
780 hf_usb_hid_curitem_bTag = hf_usb_hid_longitem_bTag;
781 usb_hid_cur_bTag_vals = usb_hid_longitem_bTag_vals;
785 subtree = proto_tree_add_subtree_format(parent_tree, tvb, offset, bSize + 1,
786 ett_usb_hid_item_header, &subitem, "%s item (%s)",
787 val_to_str(bType, usb_hid_item_bType_vals, "Unknown/%u"),
788 val_to_str(bTag, usb_hid_cur_bTag_vals, "Unknown/%u tag")
791 tree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_usb_hid_item_header, NULL, "Header");
792 proto_tree_add_item(tree, hf_usb_hid_item_bSize, tvb, offset, 1, ENC_LITTLE_ENDIAN);
793 proto_tree_add_item(tree, hf_usb_hid_item_bType, tvb, offset, 1, ENC_LITTLE_ENDIAN);
794 proto_tree_add_item(tree, hf_usb_hid_curitem_bTag, tvb, offset, 1, ENC_LITTLE_ENDIAN);
796 if ((bType == 3) && (bTag == 16)) {
798 bSize = tvb_get_guint8(tvb, offset);
799 proto_tree_add_item(subtree, hf_usb_hid_item_bDataSize, tvb, offset, 1, ENC_LITTLE_ENDIAN);
801 proto_tree_add_item(subtree, hf_usb_hid_item_bLongItemTag, tvb, offset, 1, ENC_LITTLE_ENDIAN);
803 proto_tree_add_item(subtree, hf_usb_hid_item_unk_data, tvb, offset, bSize, ENC_NA);
808 case USBHID_ITEMTYPE_MAIN:
809 offset = dissect_usb_hid_report_mainitem_data(pinfo, subtree, tvb, offset, bSize, bTag);
811 case USBHID_ITEMTYPE_GLOBAL:
812 offset = dissect_usb_hid_report_globalitem_data(pinfo, subtree, tvb, offset, bSize, bTag, &cur_global);
814 case USBHID_ITEMTYPE_LOCAL:
815 offset = dissect_usb_hid_report_localitem_data(pinfo, subtree, tvb, offset, bSize, bTag, &cur_global);
817 default: /* Only USBHID_ITEMTYPE_LONG, but keep compiler happy */
818 proto_tree_add_item(subtree, hf_usb_hid_item_unk_data, tvb, offset, bSize, ENC_NA);
824 if (bType == USBHID_ITEMTYPE_MAIN) {
825 if (bTag == USBHID_MAINITEM_TAG_COLLECTION) {
826 /* Begin collection, nest following elements under us */
827 offset = dissect_usb_hid_report_item(pinfo, subtree, tvb, offset, usb_conv_info, &cur_global);
828 proto_item_set_len(subitem, offset-old_offset);
829 } else if (bTag == USBHID_MAINITEM_TAG_ENDCOLLECTION) {
830 /* End collection, break out to parent tree item */
838 /* Dissector for HID "GET DESCRIPTOR" subtype. */
840 dissect_usb_hid_get_report_descriptor(packet_info *pinfo _U_, proto_tree *parent_tree, tvbuff_t *tvb, int offset, usb_conv_info_t *usb_conv_info)
844 int old_offset=offset;
845 struct usb_hid_global_state initial_global;
847 memset(&initial_global, 0, sizeof(struct usb_hid_global_state));
849 item = proto_tree_add_protocol_format(parent_tree, proto_usb_hid, tvb, offset,
851 tree = proto_item_add_subtree(item, ett_usb_hid_report);
852 offset = dissect_usb_hid_report_item(pinfo, tree, tvb, offset, usb_conv_info, &initial_global);
854 proto_item_set_len(item, offset-old_offset);
859 /* Dissector for HID GET_REPORT request. See USBHID 1.11, Chapter 7.2.1 Get_Report Request */
861 dissect_usb_hid_get_report(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean is_request, usb_conv_info_t *usb_conv_info _U_)
869 item = proto_tree_add_item(tree, hf_usb_hid_value, tvb, offset, 2, ENC_LITTLE_ENDIAN);
870 subtree = proto_item_add_subtree(item, ett_usb_hid_wValue);
872 /* Report Type in the high byte, Report ID in the low byte */
873 proto_tree_add_item(subtree, hf_usb_hid_report_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
875 proto_tree_add_item(subtree, hf_usb_hid_report_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
878 proto_tree_add_item(tree, hf_usb_hid_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
881 proto_tree_add_item(tree, hf_usb_hid_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
885 /* Dissector for HID SET_REPORT request. See USBHID 1.11, Chapter 7.2.2 Set_Report Request */
887 dissect_usb_hid_set_report(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean is_request, usb_conv_info_t *usb_conv_info _U_)
895 item = proto_tree_add_item(tree, hf_usb_hid_value, tvb, offset, 2, ENC_LITTLE_ENDIAN);
896 subtree = proto_item_add_subtree(item, ett_usb_hid_wValue);
898 proto_tree_add_item(subtree, hf_usb_hid_report_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
900 proto_tree_add_item(subtree, hf_usb_hid_report_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
903 proto_tree_add_item(tree, hf_usb_hid_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
906 proto_tree_add_item(tree, hf_usb_hid_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
911 /* Dissector for HID GET_IDLE request. See USBHID 1.11, Chapter 7.2.3 Get_Idle Request */
913 dissect_usb_hid_get_idle(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean is_request, usb_conv_info_t *usb_conv_info _U_)
921 item = proto_tree_add_item(tree, hf_usb_hid_value, tvb, offset, 2, ENC_LITTLE_ENDIAN);
922 subtree = proto_item_add_subtree(item, ett_usb_hid_wValue);
924 proto_tree_add_item(subtree, hf_usb_hid_report_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
926 proto_tree_add_item(subtree, hf_usb_hid_zero, tvb, offset, 1, ENC_LITTLE_ENDIAN);
929 proto_tree_add_item(tree, hf_usb_hid_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
932 proto_tree_add_item(tree, hf_usb_hid_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
936 /* Dissector for HID SET_IDLE request. See USBHID 1.11, Chapter 7.2.4 Set_Idle Request */
938 dissect_usb_hid_set_idle(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean is_request, usb_conv_info_t *usb_conv_info _U_)
946 item = proto_tree_add_item(tree, hf_usb_hid_value, tvb, offset, 2, ENC_LITTLE_ENDIAN);
947 subtree = proto_item_add_subtree(item, ett_usb_hid_wValue);
949 /* Duration in the high byte, Report ID in the low byte */
950 proto_tree_add_item(subtree, hf_usb_hid_report_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
952 proto_tree_add_item(subtree, hf_usb_hid_duration, tvb, offset, 1, ENC_LITTLE_ENDIAN);
955 proto_tree_add_item(tree, hf_usb_hid_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
958 proto_tree_add_item(tree, hf_usb_hid_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
962 /* Dissector for HID GET_PROTOCOL request. See USBHID 1.11, Chapter 7.2.5 Get_Protocol Request */
964 dissect_usb_hid_get_protocol(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean is_request, usb_conv_info_t *usb_conv_info _U_)
969 proto_tree_add_item(tree, hf_usb_hid_value, tvb, offset, 2, ENC_LITTLE_ENDIAN);
972 proto_tree_add_item(tree, hf_usb_hid_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
975 proto_tree_add_item(tree, hf_usb_hid_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
979 /* Dissector for HID SET_PROTOCOL request. See USBHID 1.11, Chapter 7.2.6 Set_Protocol Request */
981 dissect_usb_hid_set_protocol(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean is_request, usb_conv_info_t *usb_conv_info _U_)
986 proto_tree_add_item(tree, hf_usb_hid_value, tvb, offset, 2, ENC_LITTLE_ENDIAN);
989 proto_tree_add_item(tree, hf_usb_hid_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
992 proto_tree_add_item(tree, hf_usb_hid_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
997 typedef void (*usb_setup_dissector)(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean is_request, usb_conv_info_t *usb_conv_info);
999 typedef struct _usb_setup_dissector_table_t {
1001 usb_setup_dissector dissector;
1002 } usb_setup_dissector_table_t;
1005 /* USBHID 1.11, Chapter 7.2 Class-Specific Requests */
1006 #define USB_HID_SETUP_GET_REPORT 0x01
1007 #define USB_HID_SETUP_GET_IDLE 0x02
1008 #define USB_HID_SETUP_GET_PROTOCOL 0x03
1009 /* 0x04..0x08: Reserved */
1010 #define USB_HID_SETUP_SET_REPORT 0x09
1011 #define USB_HID_SETUP_SET_IDLE 0x0A
1012 #define USB_HID_SETUP_SET_PROTOCOL 0x0B
1014 static const usb_setup_dissector_table_t setup_dissectors[] = {
1015 { USB_HID_SETUP_GET_REPORT, dissect_usb_hid_get_report },
1016 { USB_HID_SETUP_GET_IDLE, dissect_usb_hid_get_idle },
1017 { USB_HID_SETUP_GET_PROTOCOL, dissect_usb_hid_get_protocol },
1018 { USB_HID_SETUP_SET_REPORT, dissect_usb_hid_set_report },
1019 { USB_HID_SETUP_SET_IDLE, dissect_usb_hid_set_idle },
1020 { USB_HID_SETUP_SET_PROTOCOL, dissect_usb_hid_set_protocol },
1024 static const value_string setup_request_names_vals[] = {
1025 { USB_HID_SETUP_GET_REPORT, "GET_REPORT" },
1026 { USB_HID_SETUP_GET_IDLE, "GET_IDLE" },
1027 { USB_HID_SETUP_GET_PROTOCOL, "GET_PROTOCOL" },
1028 { USB_HID_SETUP_SET_REPORT, "SET_REPORT" },
1029 { USB_HID_SETUP_SET_IDLE, "SET_IDLE" },
1030 { USB_HID_SETUP_SET_PROTOCOL, "SET_PROTOCOL" },
1034 static const value_string usb_hid_report_type_vals[] = {
1042 dissect_usb_hid_boot_keyboard_input_report(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1045 gboolean shortcut_helper = FALSE;
1049 proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_modifier_right_gui, tvb, offset, 1, ENC_BIG_ENDIAN);
1050 proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_modifier_right_alt, tvb, offset, 1, ENC_BIG_ENDIAN);
1051 proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_modifier_right_shift, tvb, offset, 1, ENC_BIG_ENDIAN);
1052 proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_modifier_right_ctrl, tvb, offset, 1, ENC_BIG_ENDIAN);
1053 proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_modifier_left_gui, tvb, offset, 1, ENC_BIG_ENDIAN);
1054 proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_modifier_left_alt, tvb, offset, 1, ENC_BIG_ENDIAN);
1055 proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_modifier_left_shift, tvb, offset, 1, ENC_BIG_ENDIAN);
1056 proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_modifier_left_ctrl, tvb, offset, 1, ENC_BIG_ENDIAN);
1057 modifier = tvb_get_guint8(tvb, offset);
1059 col_append_str(pinfo->cinfo, COL_INFO, " - ");
1060 if (modifier & 0x80) {
1061 col_append_str(pinfo->cinfo, COL_INFO, "RIGHT GUI");
1062 shortcut_helper = TRUE;
1064 if (modifier & 0x40) {
1065 if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
1066 col_append_str(pinfo->cinfo, COL_INFO, "RIGHT ALT");
1067 shortcut_helper = TRUE;
1069 if (modifier & 0x20) {
1070 if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
1071 col_append_str(pinfo->cinfo, COL_INFO, "RIGHT SHIFT");
1072 shortcut_helper = TRUE;
1074 if (modifier & 0x10) {
1075 if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
1076 col_append_str(pinfo->cinfo, COL_INFO, "RIGHT CTRL");
1077 shortcut_helper = TRUE;
1079 if (modifier & 0x08) {
1080 if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
1081 col_append_str(pinfo->cinfo, COL_INFO, "LEFT GUI");
1082 shortcut_helper = TRUE;
1084 if (modifier & 0x04) {
1085 if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
1086 col_append_str(pinfo->cinfo, COL_INFO, "LEFT ALT");
1087 shortcut_helper = TRUE;
1089 if (modifier & 0x02) {
1090 if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
1091 col_append_str(pinfo->cinfo, COL_INFO, "LEFT SHIFT");
1092 shortcut_helper = TRUE;
1094 if (modifier & 0x01) {
1095 if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
1096 col_append_str(pinfo->cinfo, COL_INFO, "LEFT CTRL");
1097 shortcut_helper = TRUE;
1101 proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
1104 proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_keycode_1, tvb, offset, 1, ENC_BIG_ENDIAN);
1105 keycode = tvb_get_guint8(tvb, offset);
1109 if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
1110 col_append_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str_ext(keycode, &keycode_vals_ext, "Unknown"));
1111 shortcut_helper = TRUE;
1114 proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_keycode_2, tvb, offset, 1, ENC_BIG_ENDIAN);
1115 keycode = tvb_get_guint8(tvb, offset);
1119 if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
1120 col_append_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str_ext(keycode, &keycode_vals_ext, "Unknown"));
1121 shortcut_helper = TRUE;
1124 proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_keycode_3, tvb, offset, 1, ENC_BIG_ENDIAN);
1125 keycode = tvb_get_guint8(tvb, offset);
1129 if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
1130 col_append_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str_ext(keycode, &keycode_vals_ext, "Unknown"));
1131 shortcut_helper = TRUE;
1134 proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_keycode_4, tvb, offset, 1, ENC_BIG_ENDIAN);
1135 keycode = tvb_get_guint8(tvb, offset);
1139 if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
1140 col_append_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str_ext(keycode, &keycode_vals_ext, "Unknown"));
1141 shortcut_helper = TRUE;
1144 proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_keycode_5, tvb, offset, 1, ENC_BIG_ENDIAN);
1145 keycode = tvb_get_guint8(tvb, offset);
1149 if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
1150 col_append_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str_ext(keycode, &keycode_vals_ext, "Unknown"));
1151 shortcut_helper = TRUE;
1154 proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_keycode_6, tvb, offset, 1, ENC_BIG_ENDIAN);
1155 keycode = tvb_get_guint8(tvb, offset);
1159 if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
1160 col_append_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str_ext(keycode, &keycode_vals_ext, "Unknown"));
1161 shortcut_helper = TRUE;
1164 if (shortcut_helper == FALSE) {
1165 col_append_str(pinfo->cinfo, COL_INFO, "<action key up>");
1172 dissect_usb_hid_boot_keyboard_output_report(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1175 gboolean shortcut_helper = FALSE;
1178 proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_leds_constants, tvb, offset, 1, ENC_BIG_ENDIAN);
1179 proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_leds_kana, tvb, offset, 1, ENC_BIG_ENDIAN);
1180 proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_leds_compose, tvb, offset, 1, ENC_BIG_ENDIAN);
1181 proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_leds_scroll_lock, tvb, offset, 1, ENC_BIG_ENDIAN);
1182 proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_leds_caps_lock, tvb, offset, 1, ENC_BIG_ENDIAN);
1183 proto_tree_add_item(tree, hf_usbhid_boot_report_keyboard_leds_num_lock, tvb, offset, 1, ENC_BIG_ENDIAN);
1184 leds = tvb_get_guint8(tvb, offset);
1186 col_append_str(pinfo->cinfo, COL_INFO, " - LEDs: ");
1188 col_append_str(pinfo->cinfo, COL_INFO, "NumLock");
1189 shortcut_helper = TRUE;
1192 if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, ", ");
1193 col_append_str(pinfo->cinfo, COL_INFO, "CapsLock");
1194 shortcut_helper = TRUE;
1197 if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, ", ");
1198 col_append_str(pinfo->cinfo, COL_INFO, "ScrollLock");
1199 shortcut_helper = TRUE;
1202 if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, ", ");
1203 col_append_str(pinfo->cinfo, COL_INFO, "Compose");
1204 shortcut_helper = TRUE;
1207 if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, ", ");
1208 col_append_str(pinfo->cinfo, COL_INFO, "Kana");
1209 shortcut_helper = TRUE;
1212 if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, ", ");
1213 col_append_str(pinfo->cinfo, COL_INFO, "Constant1");
1214 shortcut_helper = TRUE;
1217 if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, ", ");
1218 col_append_str(pinfo->cinfo, COL_INFO, "Constant2");
1219 shortcut_helper = TRUE;
1222 if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, ", ");
1223 col_append_str(pinfo->cinfo, COL_INFO, "Constant3");
1224 /*shortcut_helper = TRUE;*/
1227 col_append_str(pinfo->cinfo, COL_INFO, "none");
1236 dissect_usb_hid_boot_mouse_input_report(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1239 gboolean shortcut_helper = FALSE;
1242 proto_tree_add_item(tree, hf_usbhid_boot_report_mouse_button_8, tvb, offset, 1, ENC_BIG_ENDIAN);
1243 proto_tree_add_item(tree, hf_usbhid_boot_report_mouse_button_7, tvb, offset, 1, ENC_BIG_ENDIAN);
1244 proto_tree_add_item(tree, hf_usbhid_boot_report_mouse_button_6, tvb, offset, 1, ENC_BIG_ENDIAN);
1245 proto_tree_add_item(tree, hf_usbhid_boot_report_mouse_button_5, tvb, offset, 1, ENC_BIG_ENDIAN);
1246 proto_tree_add_item(tree, hf_usbhid_boot_report_mouse_button_4, tvb, offset, 1, ENC_BIG_ENDIAN);
1247 proto_tree_add_item(tree, hf_usbhid_boot_report_mouse_button_middle, tvb, offset, 1, ENC_BIG_ENDIAN);
1248 proto_tree_add_item(tree, hf_usbhid_boot_report_mouse_button_right, tvb, offset, 1, ENC_BIG_ENDIAN);
1249 proto_tree_add_item(tree, hf_usbhid_boot_report_mouse_button_left, tvb, offset, 1, ENC_BIG_ENDIAN);
1250 buttons = tvb_get_guint8(tvb, offset);
1253 if (buttons) col_append_str(pinfo->cinfo, COL_INFO, " - ");
1254 if (buttons & 0x01) {
1255 col_append_str(pinfo->cinfo, COL_INFO, "Button LEFT");
1256 shortcut_helper = TRUE;
1258 if (buttons & 0x02) {
1259 if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
1260 col_append_str(pinfo->cinfo, COL_INFO, "Button RIGHT");
1261 shortcut_helper = TRUE;
1263 if (buttons & 0x04) {
1264 if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
1265 col_append_str(pinfo->cinfo, COL_INFO, "Button MIDDLE");
1267 if (buttons & 0x08) {
1268 if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
1269 col_append_str(pinfo->cinfo, COL_INFO, "Button 4");
1270 shortcut_helper = TRUE;
1272 if (buttons & 0x10) {
1273 if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
1274 col_append_str(pinfo->cinfo, COL_INFO, "Button 5");
1275 shortcut_helper = TRUE;
1277 if (buttons & 0x20) {
1278 if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
1279 col_append_str(pinfo->cinfo, COL_INFO, "Button 6");
1280 shortcut_helper = TRUE;
1282 if (buttons & 0x40) {
1283 if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
1284 col_append_str(pinfo->cinfo, COL_INFO, "Button 7");
1285 shortcut_helper = TRUE;
1287 if (buttons & 0x80) {
1288 if (shortcut_helper) col_append_str(pinfo->cinfo, COL_INFO, " + ");
1289 col_append_str(pinfo->cinfo, COL_INFO, "Button 8");
1290 /* Not necessary, this is the last case where it is used
1291 * shortcut_helper = TRUE;
1295 proto_tree_add_item(tree, hf_usbhid_boot_report_mouse_x_displacement, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1298 proto_tree_add_item(tree, hf_usbhid_boot_report_mouse_y_displacement, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1301 /* not really in HID Specification */
1302 if (tvb_reported_length_remaining(tvb, offset)) {
1303 proto_tree_add_item(tree, hf_usbhid_boot_report_mouse_horizontal_scroll_wheel, tvb, offset, 1, ENC_BIG_ENDIAN);
1307 /* not really in HID Specification */
1308 if (tvb_reported_length_remaining(tvb, offset)) {
1309 proto_tree_add_item(tree, hf_usbhid_boot_report_mouse_vertical_scroll_wheel, tvb, offset, 1, ENC_BIG_ENDIAN);
1313 if (tvb_reported_length_remaining(tvb, offset)) {
1314 proto_tree_add_item(tree, hf_usbhid_data, tvb, offset, -1, ENC_NA);
1315 offset += tvb_captured_length_remaining(tvb, offset);
1322 /* dissect a "standard" control message that's sent to an interface */
1324 dissect_usb_hid_control_std_intf(tvbuff_t *tvb, packet_info *pinfo,
1325 proto_tree *tree, usb_conv_info_t *usb_conv_info)
1328 usb_trans_info_t *usb_trans_info;
1331 usb_trans_info = usb_conv_info->usb_trans_info;
1333 /* XXX - can we do some plausibility checks here? */
1335 col_set_str(pinfo->cinfo, COL_PROTOCOL, "USBHID");
1337 /* we can't use usb_conv_info->is_request since usb_conv_info
1338 was replaced with the interface conversation */
1339 if (usb_trans_info->request_in == pinfo->fd->num) {
1340 /* the tvb that we see here is the setup packet
1341 without the request type byte */
1343 req = tvb_get_guint8(tvb, offset);
1344 if (req != USB_SETUP_GET_DESCRIPTOR)
1346 col_clear(pinfo->cinfo, COL_INFO);
1347 col_append_fstr(pinfo->cinfo, COL_INFO, "GET DESCRIPTOR Request");
1350 proto_tree_add_item(tree, hf_usb_hid_bDescriptorIndex, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1351 usb_trans_info->u.get_descriptor.usb_index = tvb_get_guint8(tvb, offset);
1354 proto_tree_add_item(tree, hf_usb_hid_bDescriptorType, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1355 usb_trans_info->u.get_descriptor.type = tvb_get_guint8(tvb, offset);
1356 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
1357 val_to_str_ext(usb_trans_info->u.get_descriptor.type,
1358 &hid_descriptor_type_vals_ext, "Unknown type %u"));
1361 proto_tree_add_item(tree, hf_usb_hid_wInterfaceNumber, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1364 proto_tree_add_item(tree, hf_usb_hid_wDescriptorLength, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1368 col_clear(pinfo->cinfo, COL_INFO);
1369 col_append_fstr(pinfo->cinfo, COL_INFO, "GET DESCRIPTOR Response");
1370 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
1371 val_to_str_ext(usb_trans_info->u.get_descriptor.type,
1372 &hid_descriptor_type_vals_ext, "Unknown type %u"));
1373 if (usb_trans_info->u.get_descriptor.type == USB_DT_HID_REPORT) {
1374 offset = dissect_usb_hid_get_report_descriptor(
1375 pinfo, tree, tvb, offset, usb_conv_info);
1382 /* dissect a class-specific control message that's sent to an interface */
1384 dissect_usb_hid_control_class_intf(tvbuff_t *tvb, packet_info *pinfo,
1385 proto_tree *tree, usb_conv_info_t *usb_conv_info)
1387 usb_trans_info_t *usb_trans_info;
1388 gboolean is_request;
1390 usb_setup_dissector dissector = NULL;
1391 const usb_setup_dissector_table_t *tmp;
1393 usb_trans_info = usb_conv_info->usb_trans_info;
1395 is_request = (pinfo->srcport==NO_ENDPOINT);
1397 /* Check valid values for bmRequestType. See Chapter 7.2 in USBHID 1.11 */
1398 for (tmp = setup_dissectors; tmp->dissector; tmp++) {
1399 if (tmp->request == usb_trans_info->setup.request) {
1400 dissector = tmp->dissector;
1404 /* No, we could not find any class specific dissector for this request
1405 * return 0 and let USB try any of the standard requests.
1411 col_set_str(pinfo->cinfo, COL_PROTOCOL, "USBHID");
1413 col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
1414 val_to_str(usb_trans_info->setup.request, setup_request_names_vals, "Unknown type %x"),
1415 is_request ? "Request" : "Response");
1418 proto_tree_add_item(tree, hf_usb_hid_request, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1422 dissector(pinfo, tree, tvb, offset, is_request, usb_conv_info);
1423 return tvb_captured_length(tvb);
1426 /* Dissector for HID class-specific control request as defined in
1427 * USBHID 1.11, Chapter 7.2.
1428 * returns the number of bytes consumed */
1430 dissect_usb_hid_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1432 usb_conv_info_t *usb_conv_info;
1433 usb_trans_info_t *usb_trans_info;
1436 usb_conv_info = (usb_conv_info_t *)data;
1439 usb_trans_info = usb_conv_info->usb_trans_info;
1440 if (!usb_trans_info)
1443 type = USB_TYPE(usb_trans_info->setup.requesttype);
1444 recip = USB_RECIPIENT(usb_trans_info->setup.requesttype);
1446 if (recip == RQT_SETUP_RECIPIENT_INTERFACE) {
1447 if (type == RQT_SETUP_TYPE_STANDARD) {
1448 return dissect_usb_hid_control_std_intf(
1449 tvb, pinfo, tree, usb_conv_info);
1451 else if (type == RQT_SETUP_TYPE_CLASS) {
1452 return dissect_usb_hid_control_class_intf(
1453 tvb, pinfo, tree, usb_conv_info);
1460 /* dissect a descriptor that is specific to the HID class */
1462 dissect_usb_hid_class_descriptors(tvbuff_t *tvb, packet_info *pinfo _U_,
1463 proto_tree *tree, void *data _U_)
1468 proto_tree *desc_tree;
1472 type = tvb_get_guint8(tvb, 1);
1474 /* for now, we only handle the HID descriptor here */
1475 if (type != USB_DT_HID)
1478 desc_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_usb_hid_descriptor, &ti, "HID DESCRIPTOR");
1480 dissect_usb_descriptor_header(desc_tree, tvb, offset,
1481 &hid_descriptor_type_vals_ext);
1483 proto_tree_add_item(desc_tree, hf_usb_hid_bcdHID,
1484 tvb, offset, 2, ENC_LITTLE_ENDIAN);
1486 proto_tree_add_item(desc_tree, hf_usb_hid_bCountryCode,
1487 tvb, offset, 1, ENC_LITTLE_ENDIAN);
1489 num_desc = tvb_get_guint8(tvb, offset);
1490 proto_tree_add_item(desc_tree, hf_usb_hid_bNumDescriptors,
1491 tvb, offset, 1, ENC_LITTLE_ENDIAN);
1493 for (i=0;i<num_desc;i++) {
1494 proto_tree_add_item(desc_tree, hf_usb_hid_bDescriptorType,
1495 tvb, offset, 1, ENC_LITTLE_ENDIAN);
1497 proto_tree_add_item(desc_tree, hf_usb_hid_wDescriptorLength,
1498 tvb, offset, 2, ENC_LITTLE_ENDIAN);
1502 proto_item_set_len(ti, offset);
1508 proto_register_usb_hid(void)
1510 static hf_register_info hf[] = {
1511 { &hf_usb_hid_item_bSize,
1512 { "bSize", "usbhid.item.bSize", FT_UINT8, BASE_DEC,
1513 VALS(usb_hid_item_bSize_vals), USBHID_SIZE_MASK, NULL, HFILL }},
1515 { &hf_usb_hid_item_bType,
1516 { "bType", "usbhid.item.bType", FT_UINT8, BASE_DEC,
1517 VALS(usb_hid_item_bType_vals), USBHID_TYPE_MASK, NULL, HFILL }},
1519 { &hf_usb_hid_mainitem_bTag,
1520 { "bTag", "usbhid.item.bTag", FT_UINT8, BASE_HEX,
1521 VALS(usb_hid_mainitem_bTag_vals), USBHID_TAG_MASK, NULL, HFILL }},
1523 { &hf_usb_hid_globalitem_bTag,
1524 { "bTag", "usbhid.item.bTag", FT_UINT8, BASE_HEX,
1525 VALS(usb_hid_globalitem_bTag_vals), USBHID_TAG_MASK, NULL, HFILL }},
1527 { &hf_usb_hid_localitem_bTag,
1528 { "bTag", "usbhid.item.bTag", FT_UINT8, BASE_HEX,
1529 VALS(usb_hid_localitem_bTag_vals), USBHID_TAG_MASK, NULL, HFILL }},
1531 { &hf_usb_hid_longitem_bTag,
1532 { "bTag", "usbhid.item.bTag", FT_UINT8, BASE_HEX,
1533 VALS(usb_hid_longitem_bTag_vals), USBHID_TAG_MASK, NULL, HFILL }},
1535 { &hf_usb_hid_item_bDataSize,
1536 { "bDataSize", "usbhid.item.bDataSize", FT_UINT8, BASE_DEC,
1537 NULL, 0, NULL, HFILL }},
1539 { &hf_usb_hid_item_bLongItemTag,
1540 { "bTag", "usbhid.item.bLongItemTag", FT_UINT8, BASE_HEX,
1541 NULL, 0, NULL, HFILL }},
1543 /* Main-report item data */
1545 { &hf_usb_hid_mainitem_bit0,
1546 { "Data/constant", "usbhid.item.main.readonly", FT_BOOLEAN, 9,
1547 TFS(&tfs_mainitem_bit0), 1<<0, NULL, HFILL }},
1549 { &hf_usb_hid_mainitem_bit1,
1550 { "Data type", "usbhid.item.main.variable", FT_BOOLEAN, 9,
1551 TFS(&tfs_mainitem_bit1), 1<<1, NULL, HFILL }},
1553 { &hf_usb_hid_mainitem_bit2,
1554 { "Coordinates", "usbhid.item.main.relative", FT_BOOLEAN, 9,
1555 TFS(&tfs_mainitem_bit2), 1<<2, NULL, HFILL }},
1557 { &hf_usb_hid_mainitem_bit3,
1558 { "Min/max wraparound", "usbhid.item.main.wrap", FT_BOOLEAN, 9,
1559 TFS(&tfs_mainitem_bit3), 1<<3, NULL, HFILL }},
1561 { &hf_usb_hid_mainitem_bit4,
1562 { "Physical relationship to data", "usbhid.item.main.nonlinear", FT_BOOLEAN, 9,
1563 TFS(&tfs_mainitem_bit4), 1<<4, NULL, HFILL }},
1565 { &hf_usb_hid_mainitem_bit5,
1566 { "Preferred state", "usbhid.item.main.no_preferred_state", FT_BOOLEAN, 9,
1567 TFS(&tfs_mainitem_bit5), 1<<5, NULL, HFILL }},
1569 { &hf_usb_hid_mainitem_bit6,
1570 { "Has null position", "usbhid.item.main.nullstate", FT_BOOLEAN, 9,
1571 TFS(&tfs_mainitem_bit6), 1<<6, NULL, HFILL }},
1573 { &hf_usb_hid_mainitem_bit7,
1574 { "(Non)-volatile", "usbhid.item.main.volatile", FT_BOOLEAN, 9,
1575 TFS(&tfs_mainitem_bit7), 1<<7, NULL, HFILL }},
1577 { &hf_usb_hid_mainitem_bit7_input,
1578 { "[Reserved]", "usbhid.item.main.volatile", FT_BOOLEAN, 9,
1579 NULL, 1<<7, NULL, HFILL }},
1581 { &hf_usb_hid_mainitem_bit8,
1582 { "Bits or bytes", "usbhid.item.main.buffered_bytes", FT_BOOLEAN, 9,
1583 TFS(&tfs_mainitem_bit8), 1<<8, NULL, HFILL }},
1585 { &hf_usb_hid_mainitem_colltype,
1586 { "Collection type", "usbhid.item.main.colltype", FT_UINT8, BASE_RANGE_STRING|BASE_HEX,
1587 RVALS(usb_hid_mainitem_colltype_vals), 0, NULL, HFILL }},
1589 /* Global-report item data */
1591 { &hf_usb_hid_globalitem_usage,
1592 { "Usage page", "usbhid.item.global.usage", FT_UINT8, BASE_RANGE_STRING|BASE_HEX,
1593 RVALS(usb_hid_item_usage_vals), 0, NULL, HFILL }},
1595 { &hf_usb_hid_globalitem_log_min,
1596 { "Logical minimum", "usbhid.item.global.log_min", FT_UINT8, BASE_DEC,
1597 NULL, 0, NULL, HFILL }},
1599 { &hf_usb_hid_globalitem_log_max,
1600 { "Logical maximum", "usbhid.item.global.log_max", FT_UINT8, BASE_DEC,
1601 NULL, 0, NULL, HFILL }},
1603 { &hf_usb_hid_globalitem_phy_min,
1604 { "Physical minimum", "usbhid.item.global.phy_min", FT_UINT8, BASE_DEC,
1605 NULL, 0, NULL, HFILL }},
1607 { &hf_usb_hid_globalitem_phy_max,
1608 { "Physical maximum", "usbhid.item.global.phy_max", FT_UINT8, BASE_DEC,
1609 NULL, 0, NULL, HFILL }},
1611 { &hf_usb_hid_globalitem_unit_exp,
1612 { "Unit exponent", "usbhid.item.global.unit_exp", FT_UINT8, BASE_DEC,
1613 NULL, 0, NULL, HFILL }},
1615 { &hf_usb_hid_globalitem_unit_sys,
1616 { "System", "usbhid.item.global.unit.system", FT_UINT32, BASE_HEX,
1617 VALS(usb_hid_globalitem_unit_exp_vals), 0x0000000F, NULL, HFILL }},
1619 { &hf_usb_hid_globalitem_unit_len,
1620 { "Length", "usbhid.item.global.unit.length", FT_UINT32, BASE_HEX,
1621 VALS(usb_hid_globalitem_unit_exp_vals), 0x000000F0, NULL, HFILL }},
1623 { &hf_usb_hid_globalitem_unit_mass,
1624 { "Mass", "usbhid.item.global.unit.mass", FT_UINT32, BASE_HEX,
1625 VALS(usb_hid_globalitem_unit_exp_vals), 0x00000F00, NULL, HFILL }},
1627 { &hf_usb_hid_globalitem_unit_time,
1628 { "Time", "usbhid.item.global.unit.time", FT_UINT32, BASE_HEX,
1629 VALS(usb_hid_globalitem_unit_exp_vals), 0x0000F000, NULL, HFILL }},
1631 { &hf_usb_hid_globalitem_unit_temp,
1632 { "Temperature", "usbhid.item.global.unit.temperature", FT_UINT32, BASE_HEX,
1633 VALS(usb_hid_globalitem_unit_exp_vals), 0x000F0000, NULL, HFILL }},
1635 { &hf_usb_hid_globalitem_unit_current,
1636 { "Current", "usbhid.item.global.unit.current", FT_UINT32, BASE_HEX,
1637 VALS(usb_hid_globalitem_unit_exp_vals), 0x00F00000, NULL, HFILL }},
1639 { &hf_usb_hid_globalitem_unit_brightness,
1640 { "Luminous intensity", "usbhid.item.global.unit.brightness", FT_UINT32, BASE_HEX,
1641 VALS(usb_hid_globalitem_unit_exp_vals), 0x0F000000, NULL, HFILL }},
1643 { &hf_usb_hid_globalitem_report_size,
1644 { "Report size", "usbhid.item.global.report_size", FT_UINT8, BASE_DEC,
1645 NULL, 0, NULL, HFILL }},
1647 { &hf_usb_hid_globalitem_report_id,
1648 { "Report ID", "usbhid.item.global.report_id", FT_UINT8, BASE_HEX,
1649 NULL, 0, NULL, HFILL }},
1651 { &hf_usb_hid_globalitem_report_count,
1652 { "Report count", "usbhid.item.global.report_count", FT_UINT8, BASE_DEC,
1653 NULL, 0, NULL, HFILL }},
1655 { &hf_usb_hid_globalitem_push,
1656 { "Push", "usbhid.item.global.push", FT_UINT8, BASE_HEX,
1657 NULL, 0, NULL, HFILL }},
1659 { &hf_usb_hid_globalitem_pop,
1660 { "Pop", "usbhid.item.global.pop", FT_UINT8, BASE_HEX,
1661 NULL, 0, NULL, HFILL }},
1663 /* Local-report item data */
1665 { &hf_usb_hid_localitem_usage,
1666 { "Usage", "usbhid.item.local.usage", FT_UINT8, BASE_RANGE_STRING|BASE_HEX,
1667 RVALS(usb_hid_item_usage_vals), 0, NULL, HFILL }},
1669 { &hf_usb_hid_localitem_usage_min,
1670 { "Usage minimum", "usbhid.item.local.usage_min", FT_UINT8, BASE_HEX,
1671 NULL, 0, NULL, HFILL }},
1674 { &hf_usb_hid_localitem_usage_max,
1675 { "Usage maximum", "usbhid.item.local.usage_max", FT_UINT8, BASE_HEX,
1676 NULL, 0, NULL, HFILL }},
1679 { &hf_usb_hid_localitem_desig_index,
1680 { "Designator index", "usbhid.item.local.desig_index", FT_UINT8, BASE_HEX,
1681 NULL, 0, NULL, HFILL }},
1683 { &hf_usb_hid_localitem_desig_min,
1684 { "Designator minimum", "usbhid.item.local.desig_min", FT_UINT8, BASE_HEX,
1685 NULL, 0, NULL, HFILL }},
1687 { &hf_usb_hid_localitem_desig_max,
1688 { "Designator maximum", "usbhid.item.local.desig_max", FT_UINT8, BASE_HEX,
1689 NULL, 0, NULL, HFILL }},
1691 { &hf_usb_hid_localitem_string_index,
1692 { "String index", "usbhid.item.local.string_index", FT_UINT8, BASE_HEX,
1693 NULL, 0, NULL, HFILL }},
1695 { &hf_usb_hid_localitem_string_min,
1696 { "String minimum", "usbhid.item.local.string_min", FT_UINT8, BASE_HEX,
1697 NULL, 0, NULL, HFILL }},
1699 { &hf_usb_hid_localitem_string_max,
1700 { "String maximum", "usbhid.item.local.string_max", FT_UINT8, BASE_HEX,
1701 NULL, 0, NULL, HFILL }},
1703 { &hf_usb_hid_localitem_delimiter,
1704 { "Delimiter", "usbhid.item.local.delimiter", FT_UINT8, BASE_HEX,
1705 NULL, 0, NULL, HFILL }},
1708 { &hf_usb_hid_item_unk_data,
1709 { "Item data", "usbhid.item.data", FT_BYTES, BASE_NONE,
1710 NULL, 0, NULL, HFILL }},
1712 /* USB HID specific requests */
1713 { &hf_usb_hid_request,
1714 { "bRequest", "usbhid.setup.bRequest", FT_UINT8, BASE_HEX, VALS(setup_request_names_vals), 0x0,
1717 { &hf_usb_hid_value,
1718 { "wValue", "usbhid.setup.wValue", FT_UINT16, BASE_HEX, NULL, 0x0,
1721 { &hf_usb_hid_index,
1722 { "wIndex", "usbhid.setup.wIndex", FT_UINT16, BASE_DEC, NULL, 0x0,
1725 { &hf_usb_hid_length,
1726 { "wLength", "usbhid.setup.wLength", FT_UINT16, BASE_DEC, NULL, 0x0,
1729 { &hf_usb_hid_report_type,
1730 { "ReportType", "usbhid.setup.ReportType", FT_UINT8, BASE_DEC,
1731 VALS(usb_hid_report_type_vals), 0x0,
1734 { &hf_usb_hid_report_id,
1735 { "ReportID", "usbhid.setup.ReportID", FT_UINT8, BASE_DEC, NULL, 0x0,
1738 { &hf_usb_hid_duration,
1739 { "Duration", "usbhid.setup.Duration", FT_UINT8, BASE_DEC, NULL, 0x0,
1743 { "(zero)", "usbhid.setup.zero", FT_UINT8, BASE_DEC, NULL, 0x0,
1746 /* components of the HID descriptor */
1747 { &hf_usb_hid_bcdHID,
1748 { "bcdHID", "usbhid.descriptor.hid.bcdHID", FT_UINT16, BASE_HEX, NULL, 0x0,
1751 { &hf_usb_hid_bCountryCode,
1752 { "bCountryCode", "usbhid.descriptor.hid.bCountryCode", FT_UINT8,
1753 BASE_HEX, VALS(hid_country_code_vals), 0x0, NULL, HFILL }},
1755 { &hf_usb_hid_bNumDescriptors,
1756 { "bNumDescriptors", "usbhid.descriptor.hid.bNumDescriptors", FT_UINT8,
1757 BASE_DEC, NULL, 0x0, NULL, HFILL }},
1759 { &hf_usb_hid_bDescriptorIndex,
1760 { "bDescriptorIndex", "usbhid.descriptor.hid.bDescriptorIndex", FT_UINT8,
1761 BASE_HEX, NULL, 0x0, NULL, HFILL }},
1763 { &hf_usb_hid_bDescriptorType,
1764 { "bDescriptorType", "usbhid.descriptor.hid.bDescriptorType", FT_UINT8,
1765 BASE_HEX|BASE_EXT_STRING, &hid_descriptor_type_vals_ext,
1766 0x00, NULL, HFILL }},
1768 { &hf_usb_hid_wInterfaceNumber,
1769 { "wInterfaceNumber", "usbhid.descriptor.hid.wInterfaceNumber", FT_UINT16,
1770 BASE_DEC, NULL, 0x0, NULL, HFILL }},
1772 { &hf_usb_hid_wDescriptorLength,
1773 { "wDescriptorLength", "usbhid.descriptor.hid.wDescriptorLength", FT_UINT16,
1774 BASE_DEC, NULL, 0x0, NULL, HFILL }},
1776 { &hf_usbhid_boot_report_keyboard_reserved,
1777 { "Reserved", "usbhid.boot_report.keyboard.reserved",
1778 FT_UINT8, BASE_HEX, NULL, 0x00,
1781 { &hf_usbhid_boot_report_keyboard_keycode_1,
1782 { "Keycode 1", "usbhid.boot_report.keyboard.keycode_1",
1783 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &keycode_vals_ext, 0x00,
1786 { &hf_usbhid_boot_report_keyboard_keycode_2,
1787 { "Keycode 2", "usbhid.boot_report.keyboard.keycode_2",
1788 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &keycode_vals_ext, 0x00,
1791 { &hf_usbhid_boot_report_keyboard_keycode_3,
1792 { "Keycode 3", "usbhid.boot_report.keyboard.keycode_3",
1793 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &keycode_vals_ext, 0x00,
1796 { &hf_usbhid_boot_report_keyboard_keycode_4,
1797 { "Keycode 4", "usbhid.boot_report.keyboard.keycode_4",
1798 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &keycode_vals_ext, 0x00,
1801 { &hf_usbhid_boot_report_keyboard_keycode_5,
1802 { "Keycode 5", "usbhid.boot_report.keyboard.keycode_5",
1803 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &keycode_vals_ext, 0x00,
1806 { &hf_usbhid_boot_report_keyboard_keycode_6,
1807 { "Keycode 6", "usbhid.boot_report.keyboard.keycode_6",
1808 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &keycode_vals_ext, 0x00,
1811 { &hf_usbhid_boot_report_keyboard_modifier_right_gui,
1812 { "Modifier: RIGHT GUI", "usbhid.boot_report.keyboard.modifier.right_gui",
1813 FT_BOOLEAN, 8, NULL, 0x80,
1816 { &hf_usbhid_boot_report_keyboard_modifier_right_alt,
1817 { "Modifier: RIGHT ALT", "usbhid.boot_report.keyboard.modifier.right_alt",
1818 FT_BOOLEAN, 8, NULL, 0x40,
1821 { &hf_usbhid_boot_report_keyboard_modifier_right_shift,
1822 { "Modifier: RIGHT SHIFT", "usbhid.boot_report.keyboard.modifier.right_shift",
1823 FT_BOOLEAN, 8, NULL, 0x20,
1826 { &hf_usbhid_boot_report_keyboard_modifier_right_ctrl,
1827 { "Modifier: RIGHT CTRL", "usbhid.boot_report.keyboard.modifier.right_ctrl",
1828 FT_BOOLEAN, 8, NULL, 0x10,
1831 { &hf_usbhid_boot_report_keyboard_modifier_left_gui,
1832 { "Modifier: LEFT GUI", "usbhid.boot_report.keyboard.modifier.left_gui",
1833 FT_BOOLEAN, 8, NULL, 0x08,
1836 { &hf_usbhid_boot_report_keyboard_modifier_left_alt,
1837 { "Modifier: LEFT ALT", "usbhid.boot_report.keyboard.modifier.left_alt",
1838 FT_BOOLEAN, 8, NULL, 0x04,
1841 { &hf_usbhid_boot_report_keyboard_modifier_left_shift,
1842 { "Modifier: LEFT SHIFT", "usbhid.boot_report.keyboard.modifier.left_shift",
1843 FT_BOOLEAN, 8, NULL, 0x02,
1846 { &hf_usbhid_boot_report_keyboard_modifier_left_ctrl,
1847 { "Modifier: LEFT CTRL", "usbhid.boot_report.keyboard.modifier.left_ctrl",
1848 FT_BOOLEAN, 8, NULL, 0x01,
1851 { &hf_usbhid_boot_report_keyboard_leds_constants,
1852 { "Constants", "usbhid.boot_report.keyboard.leds.constants",
1853 FT_UINT8, BASE_HEX, NULL, 0xE0,
1856 { &hf_usbhid_boot_report_keyboard_leds_kana,
1857 { "KANA", "usbhid.boot_report.keyboard.leds.kana",
1858 FT_BOOLEAN, 8, NULL, 0x10,
1861 { &hf_usbhid_boot_report_keyboard_leds_compose,
1862 { "COMPOSE", "usbhid.boot_report.keyboard.leds.compose",
1863 FT_BOOLEAN, 8, NULL, 0x08,
1866 { &hf_usbhid_boot_report_keyboard_leds_scroll_lock,
1867 { "SCROLL LOCK", "usbhid.boot_report.keyboard.leds.scroll_lock",
1868 FT_BOOLEAN, 8, NULL, 0x04,
1871 { &hf_usbhid_boot_report_keyboard_leds_caps_lock,
1872 { "CAPS LOCK", "usbhid.boot_report.keyboard.leds.caps_lock",
1873 FT_BOOLEAN, 8, NULL, 0x02,
1876 { &hf_usbhid_boot_report_keyboard_leds_num_lock,
1877 { "NUM LOCK", "usbhid.boot_report.keyboard.leds.num_lock",
1878 FT_BOOLEAN, 8, NULL, 0x01,
1881 { &hf_usbhid_boot_report_mouse_button_8,
1882 { "Button 8", "usbhid.boot_report.mouse.button.8",
1883 FT_BOOLEAN, 8, NULL, 0x80,
1886 { &hf_usbhid_boot_report_mouse_button_7,
1887 { "Button 7", "usbhid.boot_report.mouse.button.7",
1888 FT_BOOLEAN, 8, NULL, 0x40,
1891 { &hf_usbhid_boot_report_mouse_button_6,
1892 { "Button 6", "usbhid.boot_report.mouse.button.6",
1893 FT_BOOLEAN, 8, NULL, 0x20,
1896 { &hf_usbhid_boot_report_mouse_button_5,
1897 { "Button 5", "usbhid.boot_report.mouse.button.5",
1898 FT_BOOLEAN, 8, NULL, 0x10,
1901 { &hf_usbhid_boot_report_mouse_button_4,
1902 { "Button 4", "usbhid.boot_report.mouse.button.4",
1903 FT_BOOLEAN, 8, NULL, 0x08,
1906 { &hf_usbhid_boot_report_mouse_button_middle,
1907 { "Button Middle", "usbhid.boot_report.mouse.button.middle",
1908 FT_BOOLEAN, 8, NULL, 0x04,
1911 { &hf_usbhid_boot_report_mouse_button_right,
1912 { "Button Right", "usbhid.boot_report.mouse.button.right",
1913 FT_BOOLEAN, 8, NULL, 0x02,
1916 { &hf_usbhid_boot_report_mouse_button_left,
1917 { "Button Left", "usbhid.boot_report.mouse.button.left",
1918 FT_BOOLEAN, 8, NULL, 0x01,
1921 { &hf_usbhid_boot_report_mouse_x_displacement,
1922 { "X Displacement", "usbhid.boot_report.mouse.x_displacement",
1923 FT_INT8, BASE_DEC, NULL, 0x00,
1926 { &hf_usbhid_boot_report_mouse_y_displacement,
1927 { "Y Displacement", "usbhid.boot_report.mouse.y_displacement",
1928 FT_INT8, BASE_DEC, NULL, 0x00,
1931 { &hf_usbhid_boot_report_mouse_horizontal_scroll_wheel,
1932 { "Horizontal Scroll Wheel", "usbhid.boot_report.mouse.scroll_wheel.horizontal",
1933 FT_INT8, BASE_DEC, NULL, 0x00,
1936 { &hf_usbhid_boot_report_mouse_vertical_scroll_wheel,
1937 { "Vertical Scroll Wheel", "usbhid.boot_report.mouse.scroll_wheel.vertical",
1938 FT_INT8, BASE_DEC, NULL, 0x00,
1942 { "Data", "usbhid.data",
1943 FT_NONE, BASE_NONE, NULL, 0x00,
1948 static gint *usb_hid_subtrees[] = {
1949 &ett_usb_hid_report,
1950 &ett_usb_hid_item_header,
1951 &ett_usb_hid_wValue,
1952 &ett_usb_hid_descriptor
1955 proto_usb_hid = proto_register_protocol("USB HID", "USBHID", "usbhid");
1956 proto_register_field_array(proto_usb_hid, hf, array_length(hf));
1957 proto_register_subtree_array(usb_hid_subtrees, array_length(usb_hid_subtrees));
1959 /*usb_hid_boot_keyboard_input_report_handle =*/ new_register_dissector("usbhid.boot_report.keyboard.input", dissect_usb_hid_boot_keyboard_input_report, proto_usb_hid);
1960 /*usb_hid_boot_keyboard_output_report_handle =*/ new_register_dissector("usbhid.boot_report.keyboard.output", dissect_usb_hid_boot_keyboard_output_report, proto_usb_hid);
1961 /*usb_hid_boot_mouse_input_report_handle =*/ new_register_dissector("usbhid.boot_report.mouse.input", dissect_usb_hid_boot_mouse_input_report, proto_usb_hid);
1966 proto_reg_handoff_usb_hid(void)
1968 dissector_handle_t usb_hid_control_handle, usb_hid_descr_handle;
1970 usb_hid_control_handle = create_dissector_handle(
1971 dissect_usb_hid_control, proto_usb_hid);
1972 dissector_add_uint("usb.control", IF_CLASS_HID, usb_hid_control_handle);
1974 usb_hid_descr_handle = create_dissector_handle(
1975 dissect_usb_hid_class_descriptors, proto_usb_hid);
1976 dissector_add_uint("usb.descriptor", IF_CLASS_HID, usb_hid_descr_handle);
1980 * Editor modelines - http://www.wireshark.org/tools/modelines.html
1985 * indent-tabs-mode: nil
1988 * vi: set shiftwidth=4 tabstop=8 expandtab:
1989 * :indentSize=4:tabSize=8:noTabs=true: