1
2 // *****************************************************************************
3 //
4 // HID Parser Test
5 //
6 // *****************************************************************************
7
8
9 #include <stdint.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13
14 #include "CppUTest/TestHarness.h"
15 #include "CppUTest/CommandLineTestRunner.h"
16
17 #include "btstack_hid_parser.h"
18 #include "hci_dump_posix_fs.h"
19 #include "hci_dump_posix_stdout.h"
20
21 const uint8_t mouse_descriptor_without_report_id[] = {
22 0x05, 0x01, /* Usage Page (Desktop), */
23 0x09, 0x02, /* Usage (Mouse), */
24 0xA1, 0x01, /* Collection (Application), */
25 0x09, 0x01, /* Usage (Pointer), */
26 0xA0, /* Collection (Physical), */
27 0x05, 0x09, /* Usage Page (Button), */
28 0x19, 0x01, /* Usage Minimum (01h), */
29 0x29, 0x03, /* Usage Maximum (03h), */
30 0x14, /* Logical Minimum (0), */
31 0x25, 0x01, /* Logical Maximum (1), */
32 0x75, 0x01, /* Report Size (1), */
33 0x95, 0x03, /* Report Count (3), */
34 0x81, 0x02, /* Input (Variable), */
35 0x75, 0x05, /* Report Size (5), */
36 0x95, 0x01, /* Report Count (1), */
37 0x81, 0x01, /* Input (Constant), */
38 0x05, 0x01, /* Usage Page (Desktop), */
39 0x09, 0x30, /* Usage (X), */
40 0x09, 0x31, /* Usage (Y), */
41 0x15, 0x81, /* Logical Minimum (-127), */
42 0x25, 0x7F, /* Logical Maximum (127), */
43 0x75, 0x08, /* Report Size (8), */
44 0x95, 0x02, /* Report Count (2), */
45 0x81, 0x06, /* Input (Variable, Relative), */
46 0xC0, /* End Collection, */
47 0xC0 /* End Collection */
48 };
49
50 const uint8_t mouse_descriptor_with_report_id[] = {
51 0x05, 0x01, /* Usage Page (Desktop), */
52 0x09, 0x02, /* Usage (Mouse), */
53 0xA1, 0x01, /* Collection (Application), */
54
55 0x85, 0x01, // Report ID 1
56
57 0x09, 0x01, /* Usage (Pointer), */
58 0xA0, /* Collection (Physical), */
59 0x05, 0x09, /* Usage Page (Button), */
60 0x19, 0x01, /* Usage Minimum (01h), */
61 0x29, 0x03, /* Usage Maximum (03h), */
62 0x14, /* Logical Minimum (0), */
63 0x25, 0x01, /* Logical Maximum (1), */
64 0x75, 0x01, /* Report Size (1), */
65 0x95, 0x03, /* Report Count (3), */
66 0x81, 0x02, /* Input (Variable), */
67 0x75, 0x05, /* Report Size (5), */
68 0x95, 0x01, /* Report Count (1), */
69 0x81, 0x01, /* Input (Constant), */
70 0x05, 0x01, /* Usage Page (Desktop), */
71 0x09, 0x30, /* Usage (X), */
72 0x09, 0x31, /* Usage (Y), */
73 0x15, 0x81, /* Logical Minimum (-127), */
74 0x25, 0x7F, /* Logical Maximum (127), */
75 0x75, 0x08, /* Report Size (8), */
76 0x95, 0x02, /* Report Count (2), */
77 0x81, 0x06, /* Input (Variable, Relative), */
78 0xC0, /* End Collection, */
79 0xC0 /* End Collection */
80 };
81
82 // from USB HID Specification 1.1, Appendix B.1
83 const uint8_t hid_descriptor_keyboard_boot_mode[] = {
84
85 0x05, 0x01, // Usage Page (Generic Desktop)
86 0x09, 0x06, // Usage (Keyboard)
87 0xa1, 0x01, // Collection (Application)
88
89 // Modifier byte
90
91 0x75, 0x01, // Report Size (1)
92 0x95, 0x08, // Report Count (8)
93 0x05, 0x07, // Usage Page (Key codes)
94 0x19, 0xe0, // Usage Minimum (Keyboard LeftControl)
95 0x29, 0xe7, // Usage Maxium (Keyboard Right GUI)
96 0x15, 0x00, // Logical Minimum (0)
97 0x25, 0x01, // Logical Maximum (1)
98 0x81, 0x02, // Input (Data, Variable, Absolute)
99
100 // Reserved byte
101
102 0x75, 0x01, // Report Size (1)
103 0x95, 0x08, // Report Count (8)
104 0x81, 0x03, // Input (Constant, Variable, Absolute)
105
106 // LED report + padding
107
108 0x95, 0x05, // Report Count (5)
109 0x75, 0x01, // Report Size (1)
110 0x05, 0x08, // Usage Page (LEDs)
111 0x19, 0x01, // Usage Minimum (Num Lock)
112 0x29, 0x05, // Usage Maxium (Kana)
113 0x91, 0x02, // Output (Data, Variable, Absolute)
114
115 0x95, 0x01, // Report Count (1)
116 0x75, 0x03, // Report Size (3)
117 0x91, 0x03, // Output (Constant, Variable, Absolute)
118
119 // Keycodes
120
121 0x95, 0x06, // Report Count (6)
122 0x75, 0x08, // Report Size (8)
123 0x15, 0x00, // Logical Minimum (0)
124 0x25, 0xff, // Logical Maximum (1)
125 0x05, 0x07, // Usage Page (Key codes)
126 0x19, 0x00, // Usage Minimum (Reserved (no event indicated))
127 0x29, 0xff, // Usage Maxium (Reserved)
128 0x81, 0x00, // Input (Data, Array)
129
130 0xc0, // End collection
131 };
132
133 const uint8_t combo_descriptor_with_report_ids[] = {
134
135 0x05, 0x01, /* Usage Page (Desktop), */
136 0x09, 0x02, /* Usage (Mouse), */
137 0xA1, 0x01, /* Collection (Application), */
138
139 0x85, 0x01, // Report ID 1
140
141 0x09, 0x01, /* Usage (Pointer), */
142 0xA0, /* Collection (Physical), */
143 0x05, 0x09, /* Usage Page (Button), */
144 0x19, 0x01, /* Usage Minimum (01h), */
145 0x29, 0x03, /* Usage Maximum (03h), */
146 0x14, /* Logical Minimum (0), */
147 0x25, 0x01, /* Logical Maximum (1), */
148 0x75, 0x01, /* Report Size (1), */
149 0x95, 0x03, /* Report Count (3), */
150 0x81, 0x02, /* Input (Variable), */
151 0x75, 0x05, /* Report Size (5), */
152 0x95, 0x01, /* Report Count (1), */
153 0x81, 0x01, /* Input (Constant), */
154 0x05, 0x01, /* Usage Page (Desktop), */
155 0x09, 0x30, /* Usage (X), */
156 0x09, 0x31, /* Usage (Y), */
157 0x15, 0x81, /* Logical Minimum (-127), */
158 0x25, 0x7F, /* Logical Maximum (127), */
159 0x75, 0x08, /* Report Size (8), */
160 0x95, 0x02, /* Report Count (2), */
161 0x81, 0x06, /* Input (Variable, Relative), */
162 0xC0, /* End Collection, */
163 0xC0, /* End Collection */
164
165 0xa1, 0x01, // Collection (Application)
166
167 0x85, 0x02, // Report ID 2
168
169 // Modifier byte
170
171 0x75, 0x01, // Report Size (1)
172 0x95, 0x08, // Report Count (8)
173 0x05, 0x07, // Usage Page (Key codes)
174 0x19, 0xe0, // Usage Minimum (Keyboard LeftControl)
175 0x29, 0xe7, // Usage Maxium (Keyboard Right GUI)
176 0x15, 0x00, // Logical Minimum (0)
177 0x25, 0x01, // Logical Maximum (1)
178 0x81, 0x02, // Input (Data, Variable, Absolute)
179
180 // Reserved byte
181
182 0x75, 0x01, // Report Size (1)
183 0x95, 0x08, // Report Count (8)
184 0x81, 0x03, // Input (Constant, Variable, Absolute)
185
186 // LED report + padding
187
188 0x95, 0x05, // Report Count (5)
189 0x75, 0x01, // Report Size (1)
190 0x05, 0x08, // Usage Page (LEDs)
191 0x19, 0x01, // Usage Minimum (Num Lock)
192 0x29, 0x05, // Usage Maxium (Kana)
193 0x91, 0x02, // Output (Data, Variable, Absolute)
194
195 0x95, 0x01, // Report Count (1)
196 0x75, 0x03, // Report Size (3)
197 0x91, 0x03, // Output (Constant, Variable, Absolute)
198
199 // Keycodes
200
201 0x95, 0x06, // Report Count (6)
202 0x75, 0x08, // Report Size (8)
203 0x15, 0x00, // Logical Minimum (0)
204 0x25, 0xff, // Logical Maximum (1)
205 0x05, 0x07, // Usage Page (Key codes)
206 0x19, 0x00, // Usage Minimum (Reserved (no event indicated))
207 0x29, 0xff, // Usage Maxium (Reserved)
208 0x81, 0x00, // Input (Data, Array)
209
210 0xc0, // En
211
212 };
213
214 // https://tank-mouse.com/
215 const uint8_t tank_mouse_descriptor[] = {
216 0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
217 0x09, 0x02, // Usage (Mouse)
218 0xA1, 0x01, // Collection (Application)
219 0x85, 0x03, // Report ID (3)
220 0x09, 0x01, // Usage (Pointer)
221 0xA1, 0x00, // Collection (Physical)
222 0x05, 0x09, // Usage Page (Button)
223 0x19, 0x01, // Usage Minimum (0x01)
224 0x29, 0x03, // Usage Maximum (0x03)
225 0x15, 0x00, // Logical Minimum (0)
226 0x25, 0x01, // Logical Maximum (1)
227 0x75, 0x01, // Report Size (1)
228 0x95, 0x05, // Report Count (5)
229 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
230 0x75, 0x03, // Report Size (3)
231 0x95, 0x01, // Report Count (1)
232 0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
233 0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
234 0x09, 0x30, // Usage (X)
235 0x09, 0x31, // Usage (Y)
236 0x16, 0x01, 0x80, // Logical Minimum (-32767)
237 0x26, 0xFF, 0x7F, // Logical Maximum (32767)
238 0x75, 0x10, // Report Size (16)
239 0x95, 0x02, // Report Count (2)
240 0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
241 0x09, 0x38, // Usage (Wheel)
242 0x15, 0x81, // Logical Minimum (-127)
243 0x25, 0x7F, // Logical Maximum (127)
244 0x75, 0x08, // Report Size (8)
245 0x95, 0x01, // Report Count (1)
246 0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
247 0xC0, // End Collection
248 0xC0, // End Collection
249 0x06, 0x01, 0xFF, // Usage Page (Vendor Defined 0xFF01)
250 0x09, 0x01, // Usage (0x01)
251 0xA1, 0x01, // Collection (Application)
252 0x85, 0x05, // Report ID (5)
253 0x09, 0x05, // Usage (0x05)
254 0x15, 0x00, // Logical Minimum (0)
255 0x26, 0xFF, 0x00, // Logical Maximum (255)
256 0x75, 0x08, // Report Size (8)
257 0x95, 0x04, // Report Count (4)
258 0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
259 0xC0, // End Collection
260 // 89 bytes
261 };
262
263 // Xbox Wireless Controller FW 5.17.3202.0
264 const uint8_t xbox_wireless_descriptor[] = {
265 0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
266 0x09, 0x05, // Usage (Game Pad)
267 0xA1, 0x01, // Collection (Application)
268 0x85, 0x01, // Report ID (1)
269 0x09, 0x01, // Usage (Pointer)
270 0xA1, 0x00, // Collection (Physical)
271 0x09, 0x30, // Usage (X)
272 0x09, 0x31, // Usage (Y)
273 0x15, 0x00, // Logical Minimum (0)
274 0x27, 0xFF, 0xFF, 0x00, 0x00, // Logical Maximum (65534)
275 0x95, 0x02, // Report Count (2)
276 0x75, 0x10, // Report Size (16)
277 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
278 0xC0, // End Collection
279 0x09, 0x01, // Usage (Pointer)
280 0xA1, 0x00, // Collection (Physical)
281 0x09, 0x32, // Usage (Z)
282 0x09, 0x35, // Usage (Rz)
283 0x15, 0x00, // Logical Minimum (0)
284 0x27, 0xFF, 0xFF, 0x00, 0x00, // Logical Maximum (65534)
285 0x95, 0x02, // Report Count (2)
286 0x75, 0x10, // Report Size (16)
287 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
288 0xC0, // End Collection
289 0x05, 0x02, // Usage Page (Sim Ctrls)
290 0x09, 0xC5, // Usage (Brake)
291 0x15, 0x00, // Logical Minimum (0)
292 0x26, 0xFF, 0x03, // Logical Maximum (1023)
293 0x95, 0x01, // Report Count (1)
294 0x75, 0x0A, // Report Size (10)
295 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
296 0x15, 0x00, // Logical Minimum (0)
297 0x25, 0x00, // Logical Maximum (0)
298 0x75, 0x06, // Report Size (6)
299 0x95, 0x01, // Report Count (1)
300 0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
301 0x05, 0x02, // Usage Page (Sim Ctrls)
302 0x09, 0xC4, // Usage (Accelerator)
303 0x15, 0x00, // Logical Minimum (0)
304 0x26, 0xFF, 0x03, // Logical Maximum (1023)
305 0x95, 0x01, // Report Count (1)
306 0x75, 0x0A, // Report Size (10)
307 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
308 0x15, 0x00, // Logical Minimum (0)
309 0x25, 0x00, // Logical Maximum (0)
310 0x75, 0x06, // Report Size (6)
311 0x95, 0x01, // Report Count (1)
312 0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
313 0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
314 0x09, 0x39, // Usage (Hat switch)
315 0x15, 0x01, // Logical Minimum (1)
316 0x25, 0x08, // Logical Maximum (8)
317 0x35, 0x00, // Physical Minimum (0)
318 0x46, 0x3B, 0x01, // Physical Maximum (315)
319 0x66, 0x14, 0x00, // Unit (System: English Rotation, Length: Centimeter)
320 0x75, 0x04, // Report Size (4)
321 0x95, 0x01, // Report Count (1)
322 0x81, 0x42, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,Null State)
323 0x75, 0x04, // Report Size (4)
324 0x95, 0x01, // Report Count (1)
325 0x15, 0x00, // Logical Minimum (0)
326 0x25, 0x00, // Logical Maximum (0)
327 0x35, 0x00, // Physical Minimum (0)
328 0x45, 0x00, // Physical Maximum (0)
329 0x65, 0x00, // Unit (None)
330 0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
331 0x05, 0x09, // Usage Page (Button)
332 0x19, 0x01, // Usage Minimum (0x01)
333 0x29, 0x0F, // Usage Maximum (0x0F)
334 0x15, 0x00, // Logical Minimum (0)
335 0x25, 0x01, // Logical Maximum (1)
336 0x75, 0x01, // Report Size (1)
337 0x95, 0x0F, // Report Count (15)
338 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
339 0x15, 0x00, // Logical Minimum (0)
340 0x25, 0x00, // Logical Maximum (0)
341 0x75, 0x01, // Report Size (1)
342 0x95, 0x01, // Report Count (1)
343 0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
344 0x05, 0x0C, // Usage Page (Consumer)
345 0x0A, 0xB2, 0x00, // Usage (Record)
346 0x15, 0x00, // Logical Minimum (0)
347 0x25, 0x01, // Logical Maximum (1)
348 0x95, 0x01, // Report Count (1)
349 0x75, 0x01, // Report Size (1)
350 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
351 0x15, 0x00, // Logical Minimum (0)
352 0x25, 0x00, // Logical Maximum (0)
353 0x75, 0x07, // Report Size (7)
354 0x95, 0x01, // Report Count (1)
355 0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
356 0x05, 0x0F, // Usage Page (PID Page)
357 0x09, 0x21, // Usage (0x21)
358 0x85, 0x03, // Report ID (3)
359 0xA1, 0x02, // Collection (Logical)
360 0x09, 0x97, // Usage (0x97)
361 0x15, 0x00, // Logical Minimum (0)
362 0x25, 0x01, // Logical Maximum (1)
363 0x75, 0x04, // Report Size (4)
364 0x95, 0x01, // Report Count (1)
365 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
366 0x15, 0x00, // Logical Minimum (0)
367 0x25, 0x00, // Logical Maximum (0)
368 0x75, 0x04, // Report Size (4)
369 0x95, 0x01, // Report Count (1)
370 0x91, 0x03, // Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
371 0x09, 0x70, // Usage (0x70)
372 0x15, 0x00, // Logical Minimum (0)
373 0x25, 0x64, // Logical Maximum (100)
374 0x75, 0x08, // Report Size (8)
375 0x95, 0x04, // Report Count (4)
376 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
377 0x09, 0x50, // Usage (0x50)
378 0x66, 0x01, 0x10, // Unit (System: SI Linear, Time: Seconds)
379 0x55, 0x0E, // Unit Exponent (-2)
380 0x15, 0x00, // Logical Minimum (0)
381 0x26, 0xFF, 0x00, // Logical Maximum (255)
382 0x75, 0x08, // Report Size (8)
383 0x95, 0x01, // Report Count (1)
384 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
385 0x09, 0xA7, // Usage (0xA7)
386 0x15, 0x00, // Logical Minimum (0)
387 0x26, 0xFF, 0x00, // Logical Maximum (255)
388 0x75, 0x08, // Report Size (8)
389 0x95, 0x01, // Report Count (1)
390 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
391 0x65, 0x00, // Unit (None)
392 0x55, 0x00, // Unit Exponent (0)
393 0x09, 0x7C, // Usage (0x7C)
394 0x15, 0x00, // Logical Minimum (0)
395 0x26, 0xFF, 0x00, // Logical Maximum (255)
396 0x75, 0x08, // Report Size (8)
397 0x95, 0x01, // Report Count (1)
398 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
399 0xC0, // End Collection
400 0xC0, // End Collection
401 // 283 bytes
402 };
403
404 const uint8_t mouse_report_without_id_positive_xy[] = { 0x03, 0x02, 0x03 };
405 const uint8_t mouse_report_without_id_negative_xy[] = { 0x03, 0xFE, 0xFD };
406 const uint8_t mouse_report_with_id_1[] = { 0x01, 0x03, 0x02, 0x03 };
407
408 const uint8_t keyboard_report1[] = { 0x01, 0x00, 0x04, 0x05, 0x06, 0x00, 0x00, 0x00 };
409
410 const uint8_t combo_report1[] = { 0x01, 0x03, 0x02, 0x03 };
411 const uint8_t combo_report2[] = { 0x02, 0x01, 0x00, 0x04, 0x05, 0x06, 0x00, 0x00, 0x00 };
412
413 const uint8_t tank_mouse_report[] = { 0x03, 0x03, 0xFD, 0xFF, 0xF6, 0xFF, 0x00};
414 const uint8_t xbox_wireless_report[] = {0x01, 0xB9, 0xF0, 0xFB, 0xC3, 0xE3, 0x80, 0x97, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00};
415
416
expect_field(btstack_hid_parser_t * parser,uint16_t expected_usage_page,uint16_t expected_usage,int32_t expected_value)417 static void expect_field(btstack_hid_parser_t * parser, uint16_t expected_usage_page, uint16_t expected_usage, int32_t expected_value){
418 // printf("expected - usage page %02x, usage %04x, value %02x\n", expected_usage_page, expected_usage, expected_value);
419 CHECK_EQUAL(1, btstack_hid_parser_has_more(parser));
420 uint16_t usage_page;
421 uint16_t usage;
422 int32_t value;
423 btstack_hid_parser_get_field(parser, &usage_page, &usage, &value);
424 CHECK_EQUAL(expected_usage_page, usage_page);
425 CHECK_EQUAL(expected_usage, usage);
426 CHECK_EQUAL(expected_value, value);
427 }
428
429 // test
TEST_GROUP(HID)430 TEST_GROUP(HID){
431 void setup(void){
432 }
433 };
434
TEST(HID,MouseWithoutReportID)435 TEST(HID, MouseWithoutReportID){
436 static btstack_hid_parser_t hid_parser;
437 btstack_hid_parser_init(&hid_parser, mouse_descriptor_without_report_id, sizeof(mouse_descriptor_without_report_id), HID_REPORT_TYPE_INPUT, mouse_report_without_id_positive_xy, sizeof(mouse_report_without_id_positive_xy));
438 expect_field(&hid_parser, 9, 1, 1);
439 expect_field(&hid_parser, 9, 2, 1);
440 expect_field(&hid_parser, 9, 3, 0);
441 expect_field(&hid_parser, 1, 0x30, 2);
442 expect_field(&hid_parser, 1, 0x31, 3);
443 CHECK_EQUAL(0, btstack_hid_parser_has_more(&hid_parser));
444 }
445
TEST(HID,MouseWithoutReportIDSigned)446 TEST(HID, MouseWithoutReportIDSigned){
447 static btstack_hid_parser_t hid_parser;
448 btstack_hid_parser_init(&hid_parser, mouse_descriptor_without_report_id, sizeof(mouse_descriptor_without_report_id), HID_REPORT_TYPE_INPUT, mouse_report_without_id_negative_xy, sizeof(mouse_report_without_id_negative_xy));
449 expect_field(&hid_parser, 9, 1, 1);
450 expect_field(&hid_parser, 9, 2, 1);
451 expect_field(&hid_parser, 9, 3, 0);
452 expect_field(&hid_parser, 1, 0x30, -2);
453 expect_field(&hid_parser, 1, 0x31, -3);
454 CHECK_EQUAL(0, btstack_hid_parser_has_more(&hid_parser));
455 }
456
TEST(HID,MouseWithReportID)457 TEST(HID, MouseWithReportID){
458 static btstack_hid_parser_t hid_parser;
459 CHECK_EQUAL(3, btstack_hid_get_report_size_for_id(1, HID_REPORT_TYPE_INPUT, mouse_descriptor_with_report_id,
460 sizeof(mouse_descriptor_with_report_id)));
461 btstack_hid_parser_init(&hid_parser, mouse_descriptor_with_report_id, sizeof(mouse_descriptor_with_report_id), HID_REPORT_TYPE_INPUT, mouse_report_with_id_1, sizeof(mouse_report_with_id_1));
462 expect_field(&hid_parser, 9, 1, 1);
463 expect_field(&hid_parser, 9, 2, 1);
464 expect_field(&hid_parser, 9, 3, 0);
465 expect_field(&hid_parser, 1, 0x30, 2);
466 expect_field(&hid_parser, 1, 0x31, 3);
467 CHECK_EQUAL(0, btstack_hid_parser_has_more(&hid_parser));
468 }
469
TEST(HID,BootKeyboard)470 TEST(HID, BootKeyboard){
471 static btstack_hid_parser_t hid_parser;
472 btstack_hid_parser_init(&hid_parser, hid_descriptor_keyboard_boot_mode, sizeof(hid_descriptor_keyboard_boot_mode), HID_REPORT_TYPE_INPUT, keyboard_report1, sizeof(keyboard_report1));
473 expect_field(&hid_parser, 7, 0xe0, 1);
474 expect_field(&hid_parser, 7, 0xe1, 0);
475 expect_field(&hid_parser, 7, 0xe2, 0);
476 expect_field(&hid_parser, 7, 0xe3, 0);
477 expect_field(&hid_parser, 7, 0xe4, 0);
478 expect_field(&hid_parser, 7, 0xe5, 0);
479 expect_field(&hid_parser, 7, 0xe6, 0);
480 expect_field(&hid_parser, 7, 0xe7, 0);
481 expect_field(&hid_parser, 7, 0x04, 1);
482 expect_field(&hid_parser, 7, 0x05, 1);
483 expect_field(&hid_parser, 7, 0x06, 1);
484 expect_field(&hid_parser, 7, 0x00, 1);
485 expect_field(&hid_parser, 7, 0x00, 1);
486 expect_field(&hid_parser, 7, 0x00, 1);
487 CHECK_EQUAL(0, btstack_hid_parser_has_more(&hid_parser));
488 }
489
TEST(HID,Combo1)490 TEST(HID, Combo1){
491 static btstack_hid_parser_t hid_parser;
492 btstack_hid_parser_init(&hid_parser, combo_descriptor_with_report_ids, sizeof(combo_descriptor_with_report_ids), HID_REPORT_TYPE_INPUT, combo_report1, sizeof(combo_report1));
493 expect_field(&hid_parser, 9, 1, 1);
494 expect_field(&hid_parser, 9, 2, 1);
495 expect_field(&hid_parser, 9, 3, 0);
496 expect_field(&hid_parser, 1, 0x30, 2);
497 expect_field(&hid_parser, 1, 0x31, 3);
498 CHECK_EQUAL(0, btstack_hid_parser_has_more(&hid_parser));
499 }
500
TEST(HID,Combo2)501 TEST(HID, Combo2){
502 static btstack_hid_parser_t hid_parser;
503 btstack_hid_parser_init(&hid_parser, combo_descriptor_with_report_ids, sizeof(combo_descriptor_with_report_ids), HID_REPORT_TYPE_INPUT, combo_report2, sizeof(combo_report2));
504 expect_field(&hid_parser, 7, 0xe0, 1);
505 expect_field(&hid_parser, 7, 0xe1, 0);
506 expect_field(&hid_parser, 7, 0xe2, 0);
507 expect_field(&hid_parser, 7, 0xe3, 0);
508 expect_field(&hid_parser, 7, 0xe4, 0);
509 expect_field(&hid_parser, 7, 0xe5, 0);
510 expect_field(&hid_parser, 7, 0xe6, 0);
511 expect_field(&hid_parser, 7, 0xe7, 0);
512 expect_field(&hid_parser, 7, 0x04, 1);
513 expect_field(&hid_parser, 7, 0x05, 1);
514 expect_field(&hid_parser, 7, 0x06, 1);
515 expect_field(&hid_parser, 7, 0x00, 1);
516 expect_field(&hid_parser, 7, 0x00, 1);
517 expect_field(&hid_parser, 7, 0x00, 1);
518 CHECK_EQUAL(0, btstack_hid_parser_has_more(&hid_parser));
519 }
520
TEST(HID,TankMouse)521 TEST(HID, TankMouse){
522 static btstack_hid_parser_t hid_parser;
523 CHECK_EQUAL(6, btstack_hid_get_report_size_for_id(3, HID_REPORT_TYPE_INPUT, tank_mouse_descriptor,
524 sizeof(tank_mouse_descriptor)));
525 btstack_hid_parser_init(&hid_parser, tank_mouse_descriptor, sizeof(tank_mouse_descriptor), HID_REPORT_TYPE_INPUT, tank_mouse_report, sizeof(tank_mouse_report));
526 expect_field(&hid_parser, 9, 1, 1);
527 expect_field(&hid_parser, 9, 2, 1);
528 expect_field(&hid_parser, 9, 3, 0);
529 // no usages for 4th and 5th report as usage min..max only allows for 3 button
530 expect_field(&hid_parser, 1, 0x30, -3);
531 expect_field(&hid_parser, 1, 0x31, -10);
532 expect_field(&hid_parser, 1, 0x38, 0);
533 CHECK_EQUAL(0, btstack_hid_parser_has_more(&hid_parser));
534 }
535
TEST(HID,XboxWireless)536 TEST(HID, XboxWireless){
537 static btstack_hid_parser_t hid_parser;
538 CHECK_EQUAL(16, btstack_hid_get_report_size_for_id(1, HID_REPORT_TYPE_INPUT, xbox_wireless_descriptor,
539 sizeof(xbox_wireless_descriptor)));
540 btstack_hid_parser_init(&hid_parser, xbox_wireless_descriptor, sizeof(xbox_wireless_descriptor), HID_REPORT_TYPE_INPUT, xbox_wireless_report, sizeof(xbox_wireless_report));
541 expect_field(&hid_parser, 1, 0x30, 0xf0b9);
542 expect_field(&hid_parser, 1, 0x31, 0xc3fb);
543 expect_field(&hid_parser, 1, 0x32, 0x80e3);
544 expect_field(&hid_parser, 1, 0x35, 0x8197);
545 expect_field(&hid_parser, 2, 0xc5, 0);
546 expect_field(&hid_parser, 2, 0xc4, 0);
547 expect_field(&hid_parser, 1, 0x39, 0);
548 expect_field(&hid_parser, 9, 1, 0);
549 expect_field(&hid_parser, 9, 2, 0);
550 expect_field(&hid_parser, 9, 3, 0);
551 expect_field(&hid_parser, 9, 4, 0);
552 expect_field(&hid_parser, 9, 5, 0);
553 expect_field(&hid_parser, 9, 6, 0);
554 expect_field(&hid_parser, 9, 7, 0);
555 expect_field(&hid_parser, 9, 8, 0);
556 expect_field(&hid_parser, 9, 9, 0);
557 expect_field(&hid_parser, 9, 10, 0);
558 expect_field(&hid_parser, 9, 11, 0);
559 expect_field(&hid_parser, 9, 12, 0);
560 expect_field(&hid_parser, 9, 13, 0);
561 expect_field(&hid_parser, 9, 14, 1);
562 expect_field(&hid_parser, 9, 15, 0);
563 expect_field(&hid_parser, 12, 0xb2, 0);
564 CHECK_EQUAL(0, btstack_hid_parser_has_more(&hid_parser));
565 }
566
TEST(HID,GetReportSize)567 TEST(HID, GetReportSize){
568 int report_size = 0;
569 const uint8_t * hid_descriptor = combo_descriptor_with_report_ids;
570 uint16_t hid_descriptor_len = sizeof(combo_descriptor_with_report_ids);
571 report_size = btstack_hid_get_report_size_for_id(1, HID_REPORT_TYPE_INPUT, hid_descriptor, hid_descriptor_len);
572 CHECK_EQUAL(3, report_size);
573
574 hid_descriptor = hid_descriptor_keyboard_boot_mode;
575 hid_descriptor_len = sizeof(hid_descriptor_keyboard_boot_mode);
576 report_size = btstack_hid_get_report_size_for_id(HID_REPORT_ID_UNDEFINED, HID_REPORT_TYPE_OUTPUT, hid_descriptor,
577 hid_descriptor_len);
578 CHECK_EQUAL(1, report_size);
579 report_size = btstack_hid_get_report_size_for_id(HID_REPORT_ID_UNDEFINED, HID_REPORT_TYPE_INPUT, hid_descriptor,
580 hid_descriptor_len);
581 CHECK_EQUAL(8, report_size);
582 }
583
TEST(HID,UsageIteratorBootKeyboard)584 TEST(HID, UsageIteratorBootKeyboard){
585 const uint8_t * hid_descriptor = hid_descriptor_keyboard_boot_mode;
586 uint16_t hid_descriptor_len = sizeof(hid_descriptor_keyboard_boot_mode);
587 btstack_hid_usage_iterator_t iterator;
588 btstack_hid_usage_iterator_init(&iterator, hid_descriptor, hid_descriptor_len, HID_REPORT_TYPE_INPUT);
589 while (btstack_hid_usage_iterator_has_more(&iterator)){
590 btstack_hid_usage_item_t item;
591 btstack_hid_usage_iterator_get_item(&iterator, &item);
592 // printf("Report ID 0x%04x, bitpos %3u, usage page 0x%04x, usage 0x%04x, size %u\n", item.report_id, item.bit_pos, item.usage_page, item.usage, item.size);
593 }
594 }
595
TEST(HID,UsageIteratorCombo1)596 TEST(HID, UsageIteratorCombo1){
597 const uint8_t * hid_descriptor = combo_descriptor_with_report_ids;
598 uint16_t hid_descriptor_len = sizeof(combo_descriptor_with_report_ids);
599 btstack_hid_usage_iterator_t iterator;
600 btstack_hid_usage_iterator_init(&iterator, hid_descriptor, hid_descriptor_len, HID_REPORT_TYPE_INPUT);
601 while (btstack_hid_usage_iterator_has_more(&iterator)){
602 btstack_hid_usage_item_t item;
603 btstack_hid_usage_iterator_get_item(&iterator, &item);
604 // printf("Report ID 0x%04x, bitpos %3u, usage page 0x%04x, usage 0x%04x, size %u\n", item.report_id, item.bit_pos, item.usage_page, item.usage, item.size);
605 }
606 }
607
TEST(HID,ValidateReportIdBootKeyboard)608 TEST(HID, ValidateReportIdBootKeyboard){
609 const uint8_t * hid_descriptor = hid_descriptor_keyboard_boot_mode;
610 uint16_t hid_descriptor_len = sizeof(hid_descriptor_keyboard_boot_mode);
611 CHECK_EQUAL(HID_REPORT_ID_VALID, btstack_hid_report_id_valid(HID_REPORT_ID_UNDEFINED, hid_descriptor, hid_descriptor_len));
612 CHECK_EQUAL(HID_REPORT_ID_UNDECLARED, btstack_hid_report_id_valid(1, hid_descriptor, hid_descriptor_len));
613 }
614
TEST(HID,ValidateReportIdMouseWithReportId)615 TEST(HID, ValidateReportIdMouseWithReportId){
616 const uint8_t * hid_descriptor = mouse_descriptor_with_report_id;
617 uint16_t hid_descriptor_len = sizeof(mouse_descriptor_with_report_id);
618 CHECK_EQUAL(HID_REPORT_ID_UNDECLARED, btstack_hid_report_id_valid(HID_REPORT_ID_UNDEFINED, hid_descriptor, hid_descriptor_len));
619 CHECK_EQUAL(HID_REPORT_ID_VALID, btstack_hid_report_id_valid(1, hid_descriptor, hid_descriptor_len));
620 }
621
main(int argc,const char * argv[])622 int main (int argc, const char * argv[]){
623 #if 1
624 // log into file using HCI_DUMP_PACKETLOGGER format
625 const char * pklg_path = "hci_dump.pklg";
626 hci_dump_posix_fs_open(pklg_path, HCI_DUMP_PACKETLOGGER);
627 hci_dump_init(hci_dump_posix_fs_get_instance());
628 printf("Packet Log: %s\n", pklg_path);
629 #else
630 hci_dump_init(hci_dump_posix_stdout_get_instance());
631 #endif
632 return CommandLineTestRunner::RunAllTests(argc, argv);
633 }
634