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 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 430 TEST_GROUP(HID){ 431 void setup(void){ 432 } 433 }; 434 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 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 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 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 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 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 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 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 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 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 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 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 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 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