1// Copyright 2017 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include <assert.h> 6#include <stdio.h> 7 8#include <hid-parser/item.h> 9#include <hid-parser/parser.h> 10#include <hid-parser/usages.h> 11 12#include <unistd.h> 13#include <unittest/unittest.h> 14 15// See hid-report-data.cpp for the definitions of the test data. 16extern "C" const uint8_t boot_mouse_r_desc[50]; 17extern "C" const uint8_t trinket_r_desc[173]; 18extern "C" const uint8_t ps3_ds_r_desc[148]; 19extern "C" const uint8_t acer12_touch_r_desc[660]; 20extern "C" const uint8_t eve_tablet_r_desc[28]; 21extern "C" const uint8_t asus_touch_desc[945]; 22 23namespace { 24struct Stats { 25 int input_count; 26 int collection[2]; 27}; 28 29size_t ItemizeHIDReportDesc(const uint8_t* rpt_desc, size_t desc_len, Stats* stats) { 30 const uint8_t* buf = rpt_desc; 31 size_t len = desc_len; 32 while (len > 0) { 33 size_t actual = 0; 34 auto item = hid::Item::ReadNext(buf, len, &actual); 35 if ((actual > len) || (actual == 0)) 36 break; 37 38 if (item.tag() == hid::Item::Tag::kEndCollection) 39 stats->collection[1]++; 40 else if (item.tag() == hid::Item::Tag::kCollection) 41 stats->collection[0]++; 42 43 if (item.type() == hid::Item::Type::kMain && item.tag() == hid::Item::Tag::kInput) 44 stats->input_count++; 45 46 len -= actual; 47 buf += actual; 48 } 49 50 return (desc_len - len); 51} 52 53} // namespace. 54 55static bool itemize_acer12_rpt1() { 56 BEGIN_TEST; 57 58 Stats stats = {}; 59 auto len = sizeof(acer12_touch_r_desc); 60 auto consumed = ItemizeHIDReportDesc(acer12_touch_r_desc, len, &stats); 61 62 ASSERT_EQ(consumed, len); 63 ASSERT_EQ(stats.input_count, 45); 64 ASSERT_EQ(stats.collection[0], 13); 65 ASSERT_EQ(stats.collection[1], 13); 66 67 END_TEST; 68} 69 70static bool itemize_eve_tablet_rpt() { 71 BEGIN_TEST; 72 73 Stats stats = {}; 74 auto len = sizeof(eve_tablet_r_desc); 75 auto consumed = ItemizeHIDReportDesc(eve_tablet_r_desc, len, &stats); 76 77 ASSERT_EQ(consumed, len); 78 ASSERT_EQ(stats.input_count, 2); 79 ASSERT_EQ(stats.collection[0], 1); 80 ASSERT_EQ(stats.collection[1], 1); 81 82 END_TEST; 83} 84 85 86static bool parse_boot_mouse() { 87 BEGIN_TEST; 88 89 hid::DeviceDescriptor* dev = nullptr; 90 auto res = hid::ParseReportDescriptor( 91 boot_mouse_r_desc, sizeof(boot_mouse_r_desc), &dev); 92 93 ASSERT_EQ(res, hid::ParseResult::kParseOk); 94 95 // A single report with id zero, this means no report id. 96 ASSERT_EQ(dev->rep_count, 1u); 97 EXPECT_EQ(dev->report[0].report_id, 0); 98 99 // The only report has 6 fields. 100 EXPECT_EQ(dev->report[0].count, 6); 101 const auto fields = dev->report[0].first_field; 102 103 // All fields are input type with report id = 0. 104 for (uint8_t ix = 0; ix != dev->report[0].count; ++ix) { 105 EXPECT_EQ(fields[ix].report_id, 0); 106 EXPECT_EQ(fields[ix].type, hid::kInput); 107 } 108 109 // First 3 fields are the buttons, with usages 1, 2, 3, in the button page. 110 auto expected_flags = hid::kData | hid::kAbsolute | hid::kScalar; 111 112 for (uint8_t ix = 0; ix != 3; ++ix) { 113 EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kButton); 114 EXPECT_EQ(fields[ix].attr.usage.usage, uint32_t(ix + 1)); 115 EXPECT_EQ(fields[ix].attr.bit_sz, 1); 116 EXPECT_EQ(fields[ix].attr.logc_mm.min, 0); 117 EXPECT_EQ(fields[ix].attr.logc_mm.max, 1); 118 EXPECT_EQ(expected_flags & fields[ix].flags, expected_flags); 119 } 120 121 // Next field is 5 bits constant. Aka padding. 122 EXPECT_EQ(fields[3].attr.bit_sz, 5); 123 EXPECT_EQ(hid::kConstant & fields[3].flags, hid::kConstant); 124 125 // Next comes 'X' field, 8 bits data, relative. 126 expected_flags = hid::kData | hid::kRelative | hid::kScalar; 127 128 EXPECT_EQ(fields[4].attr.usage.page, hid::usage::Page::kGenericDesktop); 129 EXPECT_EQ(fields[4].attr.usage.usage, hid::usage::GenericDesktop::kX); 130 EXPECT_EQ(fields[4].attr.bit_sz, 8); 131 EXPECT_EQ(fields[4].attr.logc_mm.min, -127); 132 EXPECT_EQ(fields[4].attr.logc_mm.max, 127); 133 EXPECT_EQ(fields[4].attr.phys_mm.min, 0); 134 EXPECT_EQ(fields[4].attr.phys_mm.max, 0); 135 EXPECT_EQ(expected_flags & fields[4].flags, expected_flags); 136 137 // Last comes 'Y' field, same as 'X'. 138 EXPECT_EQ(fields[5].attr.usage.page, hid::usage::Page::kGenericDesktop); 139 EXPECT_EQ(fields[5].attr.usage.usage, hid::usage::GenericDesktop::kY); 140 EXPECT_EQ(fields[5].attr.bit_sz, 8); 141 EXPECT_EQ(fields[5].attr.logc_mm.min, -127); 142 EXPECT_EQ(fields[5].attr.logc_mm.max, 127); 143 EXPECT_EQ(fields[5].attr.phys_mm.min, 0); 144 EXPECT_EQ(fields[5].attr.phys_mm.max, 0); 145 EXPECT_EQ(expected_flags & fields[4].flags, expected_flags); 146 147 // Now test the collections. 148 // Inner collection is physical GeneticDesktop|Pointer. 149 auto collection = fields[0].col; 150 ASSERT_TRUE(collection != nullptr); 151 EXPECT_EQ(collection->type, hid::CollectionType::kPhysical); 152 EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop); 153 EXPECT_EQ(collection->usage.usage, hid::usage::GenericDesktop::kPointer); 154 155 // Outer collection is the application. 156 collection = collection->parent; 157 ASSERT_TRUE(collection != nullptr); 158 EXPECT_EQ(collection->type, hid::CollectionType::kApplication); 159 EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop); 160 EXPECT_EQ(collection->usage.usage, hid::usage::GenericDesktop::kMouse); 161 162 // No parent collection. 163 EXPECT_TRUE(collection->parent == nullptr); 164 165 // Test the helpers. 166 size_t count_first_input = 0; 167 auto first_input = hid::GetFirstInputField(dev, &count_first_input); 168 EXPECT_EQ(first_input, dev->report[0].first_field); 169 EXPECT_EQ(6u, count_first_input); 170 171 auto app_col = hid::GetAppCollection(first_input); 172 EXPECT_EQ(app_col, collection); 173 174 175 hid::FreeDeviceDescriptor(dev); 176 END_TEST; 177} 178 179static bool parse_adaf_trinket() { 180 BEGIN_TEST; 181 182 hid::DeviceDescriptor* dev = nullptr; 183 auto res = hid::ParseReportDescriptor( 184 trinket_r_desc, sizeof(trinket_r_desc), &dev); 185 186 ASSERT_EQ(res, hid::ParseResult::kParseOk); 187 188 // Four different reports 189 ASSERT_EQ(dev->rep_count, 4u); 190 191 ////////////////////////////////////////////////////////////////////////////////// 192 // First report is the same as boot_mouse, except for the report id. 193 EXPECT_EQ(dev->report[0].report_id, 1); 194 ASSERT_EQ(dev->report[0].count, 6); 195 const hid::ReportField* fields = dev->report[0].first_field; 196 197 // All fields are scalar input type with report id = 0. 198 for (uint8_t ix = 0; ix != dev->report[0].count; ++ix) { 199 EXPECT_EQ(fields[ix].report_id, 1); 200 EXPECT_EQ(fields[ix].type, hid::kInput); 201 EXPECT_EQ(hid::kScalar & fields[ix].flags, hid::kScalar); 202 } 203 204 // First 3 fields are the buttons, with usages 1, 2, 3, in the button page. 205 auto expected_flags = hid::kData | hid::kAbsolute; 206 207 for (uint8_t ix = 0; ix != 3; ++ix) { 208 EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kButton); 209 EXPECT_EQ(fields[ix].attr.usage.usage, uint32_t(ix + 1)); 210 EXPECT_EQ(fields[ix].attr.bit_sz, 1); 211 EXPECT_EQ(fields[ix].attr.logc_mm.min, 0); 212 EXPECT_EQ(fields[ix].attr.logc_mm.max, 1); 213 EXPECT_EQ(expected_flags & fields[ix].flags, expected_flags); 214 } 215 216 // Next field is 5 bits constant. Aka padding. 217 EXPECT_EQ(fields[3].attr.bit_sz, 5); 218 EXPECT_EQ(hid::kConstant & fields[3].flags, hid::kConstant); 219 220 // Next comes 'X' field, 8 bits data, relative. 221 expected_flags = hid::kData | hid::kRelative; 222 223 EXPECT_EQ(fields[4].attr.usage.page, hid::usage::Page::kGenericDesktop); 224 EXPECT_EQ(fields[4].attr.usage.usage, hid::usage::GenericDesktop::kX); 225 EXPECT_EQ(fields[4].attr.bit_sz, 8); 226 EXPECT_EQ(fields[4].attr.logc_mm.min, -127); 227 EXPECT_EQ(fields[4].attr.logc_mm.max, 127); 228 EXPECT_EQ(expected_flags & fields[4].flags, expected_flags); 229 230 // Last comes 'Y' field, same as 'X'. 231 EXPECT_EQ(fields[5].attr.usage.page, hid::usage::Page::kGenericDesktop); 232 EXPECT_EQ(fields[5].attr.usage.usage, hid::usage::GenericDesktop::kY); 233 EXPECT_EQ(fields[5].attr.bit_sz, 8); 234 EXPECT_EQ(fields[5].attr.logc_mm.min, -127); 235 EXPECT_EQ(fields[5].attr.logc_mm.max, 127); 236 EXPECT_EQ(expected_flags & fields[4].flags, expected_flags); 237 238 // Now test the collections. 239 // Inner collection is physical GeneticDesktop|Pointer. 240 auto collection = fields[0].col; 241 ASSERT_TRUE(collection != nullptr); 242 EXPECT_EQ(collection->type, hid::CollectionType::kPhysical); 243 EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop); 244 EXPECT_EQ(collection->usage.usage, hid::usage::GenericDesktop::kPointer); 245 246 // Outer collection is the application. 247 collection = collection->parent; 248 ASSERT_TRUE(collection != nullptr); 249 EXPECT_EQ(collection->type, hid::CollectionType::kApplication); 250 EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop); 251 EXPECT_EQ(collection->usage.usage, hid::usage::GenericDesktop::kMouse); 252 253 // No parent collection. 254 EXPECT_TRUE(collection->parent == nullptr); 255 256 ////////////////////////////////////////////////////////////////////////////////// 257 // Second report is a keyboard with 20 fields. 258 EXPECT_EQ(dev->report[1].report_id, 2); 259 ASSERT_EQ(dev->report[1].count, 20); 260 261 fields = dev->report[1].first_field; 262 263 // First 8 are input bits with usages 0xe0 to 0xe7 on the keyboard page. 264 expected_flags = hid::kData | hid::kAbsolute | hid::kScalar; 265 266 for (uint8_t ix = 0; ix != 8; ++ix) { 267 EXPECT_EQ(fields[ix].type, hid::kInput); 268 EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kKeyboardKeypad); 269 EXPECT_EQ(fields[ix].attr.usage.usage, uint32_t(ix + 0xe0)); 270 EXPECT_EQ(fields[ix].attr.bit_sz, 1); 271 EXPECT_EQ(fields[ix].attr.logc_mm.min, 0); 272 EXPECT_EQ(fields[ix].attr.logc_mm.max, 1); 273 EXPECT_EQ(expected_flags & fields[ix].flags, expected_flags); 274 } 275 276 // Next field is 8 bits padding (input). 277 EXPECT_EQ(fields[8].attr.bit_sz, 8); 278 EXPECT_EQ(fields[8].type, hid::kInput); 279 EXPECT_EQ(hid::kConstant & fields[8].flags, hid::kConstant); 280 281 // Next 5 fields are the LED bits output, with usages NumLock(1) to Kana(5). 282 auto led_usage = static_cast<uint16_t>(hid::usage::LEDs::kNumLock); 283 284 for (uint8_t ix = 9; ix != 14; ++ix) { 285 EXPECT_EQ(fields[ix].type, hid::kOutput); 286 EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kLEDs); 287 EXPECT_EQ(fields[ix].attr.bit_sz, 1); 288 EXPECT_EQ(fields[ix].attr.usage.usage, led_usage++); 289 EXPECT_EQ(expected_flags & fields[ix].flags, expected_flags); 290 } 291 292 // Next field is 3 bits padding (output). 293 EXPECT_EQ(fields[14].attr.bit_sz, 3); 294 EXPECT_EQ(fields[14].type, hid::kOutput); 295 EXPECT_EQ(hid::kConstant & fields[14].flags, hid::kConstant); 296 297 // Next 5 fields are byte-sized key input array. 298 expected_flags = hid::kData | hid::kAbsolute | hid::kArray; 299 300 for (uint8_t ix = 15; ix != 20; ++ix) { 301 EXPECT_EQ(fields[ix].type, hid::kInput); 302 EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kKeyboardKeypad); 303 EXPECT_EQ(fields[ix].attr.bit_sz, 8); 304 EXPECT_EQ(fields[ix].attr.usage.usage, 0); 305 EXPECT_EQ(fields[ix].attr.logc_mm.min, 0); 306 EXPECT_EQ(fields[ix].attr.logc_mm.max, 164); 307 EXPECT_EQ(expected_flags & fields[ix].flags, expected_flags); 308 } 309 310 // All fields belong to the same collection 311 collection = fields[0].col; 312 313 for (uint8_t ix = 1; ix != 20; ++ix) { 314 EXPECT_TRUE(fields[ix].col == collection); 315 } 316 317 ASSERT_TRUE(collection != nullptr); 318 EXPECT_EQ(collection->type, hid::CollectionType::kApplication); 319 EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop); 320 EXPECT_EQ(collection->usage.usage, hid::usage::GenericDesktop::kKeyboard); 321 // No parent collection. 322 EXPECT_TRUE(collection->parent == nullptr); 323 324 ////////////////////////////////////////////////////////////////////////////////// 325 // Third report, single 16 bit input array field (consumer control). 326 EXPECT_EQ(dev->report[2].report_id, 3); 327 ASSERT_EQ(dev->report[2].count, 1); 328 329 fields = dev->report[2].first_field; 330 331 expected_flags = hid::kData | hid::kAbsolute | hid::kArray; 332 333 EXPECT_EQ(fields[0].type, hid::kInput); 334 EXPECT_EQ(fields[0].attr.usage.page, hid::usage::Page::kConsumer); 335 EXPECT_EQ(fields[0].attr.usage.usage, 0); 336 EXPECT_EQ(fields[0].attr.logc_mm.min, 0); 337 EXPECT_EQ(fields[0].attr.logc_mm.max, 572); 338 EXPECT_EQ(fields[0].attr.bit_sz, 16); 339 EXPECT_EQ(expected_flags & fields[0].flags, expected_flags); 340 341 collection = fields[0].col; 342 ASSERT_TRUE(collection != nullptr); 343 EXPECT_EQ(collection->type, hid::CollectionType::kApplication); 344 EXPECT_EQ(collection->usage.page, hid::usage::Page::kConsumer); 345 EXPECT_EQ(collection->usage.usage, hid::usage::Consumer::kConsumerControl); 346 // No parent collection. 347 EXPECT_TRUE(collection->parent == nullptr); 348 349 ////////////////////////////////////////////////////////////////////////////////// 350 // Fourth report is a 2 bit input (system control: sleep, wake-up, power-down) 351 352 EXPECT_EQ(dev->report[3].report_id, 4); 353 ASSERT_EQ(dev->report[3].count, 2); 354 355 fields = dev->report[3].first_field; 356 357 // First field is a 2 bit input array. 358 expected_flags = hid::kData | hid::kAbsolute | hid::kArray; 359 360 EXPECT_EQ(fields[0].type, hid::kInput); 361 EXPECT_EQ(fields[0].attr.usage.page, hid::usage::Page::kGenericDesktop); 362 // TODO(cpu): The |usage.usage| as parsed is incorrect. In this particular 363 // case as the array input 1,2,3 should map to 0x82, 0x81, 0x83 which is not currently 364 // supported in the model. 365 EXPECT_EQ(fields[0].attr.usage.usage, hid::usage::GenericDesktop::kSystemSleep); 366 EXPECT_EQ(fields[0].attr.logc_mm.min, 1); 367 EXPECT_EQ(fields[0].attr.logc_mm.max, 3); 368 EXPECT_EQ(fields[0].attr.bit_sz, 2); 369 EXPECT_EQ(expected_flags & fields[0].flags, expected_flags); 370 371 // Last field is 6 bits padding (output). 372 EXPECT_EQ(fields[1].attr.bit_sz, 6); 373 EXPECT_EQ(fields[1].type, hid::kInput); 374 EXPECT_EQ(hid::kConstant & fields[1].flags, hid::kConstant); 375 376 collection = fields[0].col; 377 ASSERT_TRUE(collection != nullptr); 378 EXPECT_EQ(collection->type, hid::CollectionType::kApplication); 379 EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop); 380 EXPECT_EQ(collection->usage.usage, hid::usage::GenericDesktop::kSystemControl); 381 // No parent collection. 382 EXPECT_TRUE(collection->parent == nullptr); 383 384 hid::FreeDeviceDescriptor(dev); 385 END_TEST; 386} 387 388static bool parse_ps3_controller() { 389 BEGIN_TEST; 390 391 hid::DeviceDescriptor* dev = nullptr; 392 auto res = hid::ParseReportDescriptor( 393 ps3_ds_r_desc, sizeof(ps3_ds_r_desc), &dev); 394 395 ASSERT_EQ(res, hid::ParseResult::kParseOk); 396 // Four different reports 397 ASSERT_EQ(dev->rep_count, 4u); 398 399 ////////////////////////////////////////////////////////////////////////////////// 400 // First report has 172 fields!! 401 EXPECT_EQ(dev->report[0].report_id, 1); 402 ASSERT_EQ(dev->report[0].count, 172); 403 const hid::ReportField* fields = dev->report[0].first_field; 404 405 // First field is 8 bits, constant GenericDesktop page, but no usage described. 406 // being it is a version number? 407 auto expected_flags = hid::kConstant | hid::kAbsolute | hid::kScalar; 408 409 EXPECT_EQ(fields[0].type, hid::kInput); 410 EXPECT_EQ(fields[0].attr.usage.page, hid::usage::Page::kGenericDesktop); 411 EXPECT_EQ(fields[0].attr.usage.usage, 0); 412 EXPECT_EQ(fields[0].attr.logc_mm.min, 0); 413 EXPECT_EQ(fields[0].attr.logc_mm.max, 255); 414 EXPECT_EQ(fields[0].attr.bit_sz, 8); 415 EXPECT_EQ(expected_flags & fields[0].flags, expected_flags); 416 417 // Next 19 fields are one-bit input representing the buttons. 418 expected_flags = hid::kData | hid::kAbsolute | hid::kScalar; 419 420 for (uint8_t ix = 1; ix != 20; ++ix) { 421 EXPECT_EQ(fields[ix].type, hid::kInput); 422 EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kButton); 423 EXPECT_EQ(fields[ix].attr.usage.usage, ix); 424 EXPECT_EQ(fields[ix].attr.bit_sz, 1); 425 EXPECT_EQ(fields[ix].attr.logc_mm.min, 0); 426 EXPECT_EQ(fields[ix].attr.logc_mm.max, 1); 427 EXPECT_EQ(fields[ix].attr.phys_mm.min, 0); 428 EXPECT_EQ(fields[ix].attr.phys_mm.max, 1); 429 EXPECT_EQ(expected_flags & fields[ix].flags, expected_flags); 430 } 431 432 // The next 13 fields are 13 bits of constant, vendor-defined. Probably padding. 433 for (uint8_t ix = 20; ix != 33; ++ix) { 434 EXPECT_EQ(fields[ix].type, hid::kInput); 435 EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kVendorDefinedStart); 436 EXPECT_EQ(fields[ix].attr.usage.usage, 0); 437 EXPECT_EQ(fields[ix].attr.bit_sz, 1); 438 EXPECT_EQ(hid::kConstant & fields[ix].flags, hid::kConstant); 439 } 440 441 expected_flags = hid::kData | hid::kAbsolute | hid::kScalar; 442 443 // Next four 8-bit input fields are X,Y, Z and Rz. 444 for (uint8_t ix = 33; ix != 37; ++ix) { 445 EXPECT_EQ(fields[ix].type, hid::kInput); 446 EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kGenericDesktop); 447 EXPECT_EQ(fields[ix].attr.bit_sz, 8); 448 EXPECT_EQ(fields[ix].attr.logc_mm.min, 0); 449 EXPECT_EQ(fields[ix].attr.logc_mm.max, 255); 450 EXPECT_EQ(fields[ix].attr.phys_mm.min, 0); 451 EXPECT_EQ(fields[ix].attr.phys_mm.max, 255); 452 EXPECT_EQ(expected_flags & fields[ix].flags, expected_flags); 453 } 454 455 EXPECT_EQ(fields[33].attr.usage.usage, hid::usage::GenericDesktop::kX); 456 EXPECT_EQ(fields[34].attr.usage.usage, hid::usage::GenericDesktop::kY); 457 EXPECT_EQ(fields[35].attr.usage.usage, hid::usage::GenericDesktop::kZ); 458 EXPECT_EQ(fields[36].attr.usage.usage, hid::usage::GenericDesktop::kRz); 459 460 // Next 39 fields are input, 8-bit pointer scalar data. 461 for (uint8_t ix = 37; ix != 76; ++ix) { 462 EXPECT_EQ(fields[ix].type, hid::kInput); 463 EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kGenericDesktop); 464 EXPECT_EQ(fields[ix].attr.usage.usage, hid::usage::GenericDesktop::kPointer); 465 EXPECT_EQ(fields[ix].attr.bit_sz, 8); 466 EXPECT_EQ(expected_flags & fields[ix].flags, expected_flags); 467 } 468 469 // Next 48 are 8-bit scalar output pointer data. 470 for (uint8_t ix = 76; ix != 124; ++ix) { 471 EXPECT_EQ(fields[ix].type, hid::kOutput); 472 EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kGenericDesktop); 473 EXPECT_EQ(fields[ix].attr.usage.usage, hid::usage::GenericDesktop::kPointer); 474 EXPECT_EQ(fields[ix].attr.bit_sz, 8); 475 EXPECT_EQ(expected_flags & fields[ix].flags, expected_flags); 476 } 477 478 // Last 48 are 8-bit scalar feature pointer data. 479 for (uint8_t ix = 124; ix != 172; ++ix) { 480 EXPECT_EQ(fields[ix].type, hid::kFeature); 481 EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kGenericDesktop); 482 EXPECT_EQ(fields[ix].attr.usage.usage, hid::usage::GenericDesktop::kPointer); 483 EXPECT_EQ(fields[ix].attr.bit_sz, 8); 484 EXPECT_EQ(expected_flags & fields[ix].flags, expected_flags); 485 } 486 487 ////////////////////////////////////////////////////////////////////////////////// 488 // Second report has 48 fields. It is pretty much identical to last 48 fields 489 // of the first report. 490 491 EXPECT_EQ(dev->report[1].report_id, 2); 492 ASSERT_EQ(dev->report[1].count, 48); 493 fields = dev->report[1].first_field; 494 495 expected_flags = hid::kData | hid::kAbsolute | hid::kScalar; 496 497 for (uint8_t ix = 0; ix != 48; ++ix) { 498 EXPECT_EQ(fields[ix].type, hid::kFeature); 499 EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kGenericDesktop); 500 EXPECT_EQ(fields[ix].attr.usage.usage, hid::usage::GenericDesktop::kPointer); 501 EXPECT_EQ(fields[ix].attr.bit_sz, 8); 502 EXPECT_EQ(expected_flags & fields[ix].flags, expected_flags); 503 } 504 505 ////////////////////////////////////////////////////////////////////////////////// 506 // Third report is same as the second one except for report id. 507 508 EXPECT_EQ(dev->report[2].report_id, 0xee); 509 ASSERT_EQ(dev->report[2].count, 48); 510 fields = dev->report[2].first_field; 511 512 for (uint8_t ix = 0; ix != 48; ++ix) { 513 EXPECT_EQ(fields[ix].type, hid::kFeature); 514 EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kGenericDesktop); 515 EXPECT_EQ(fields[ix].attr.usage.usage, hid::usage::GenericDesktop::kPointer); 516 EXPECT_EQ(fields[ix].attr.bit_sz, 8); 517 EXPECT_EQ(expected_flags & fields[ix].flags, expected_flags); 518 } 519 520 ////////////////////////////////////////////////////////////////////////////////// 521 // Fourth report is same as the second one except for report id. 522 523 EXPECT_EQ(dev->report[3].report_id, 0xef); 524 ASSERT_EQ(dev->report[3].count, 48); 525 fields = dev->report[3].first_field; 526 527 for (uint8_t ix = 0; ix != 48; ++ix) { 528 EXPECT_EQ(fields[ix].type, hid::kFeature); 529 EXPECT_EQ(fields[ix].attr.usage.page, hid::usage::Page::kGenericDesktop); 530 EXPECT_EQ(fields[ix].attr.usage.usage, hid::usage::GenericDesktop::kPointer); 531 EXPECT_EQ(fields[ix].attr.bit_sz, 8); 532 EXPECT_EQ(expected_flags & fields[ix].flags, expected_flags); 533 } 534 535 // Collections test 536 // 537 // In the first report, The X,Y,Z, Rz fields are in a 3-level 538 // deep collection physical -> logical -> app. Test that. 539 auto collection = dev->report[0].first_field[33].col; 540 541 ASSERT_TRUE(collection != nullptr); 542 EXPECT_EQ(collection->type, hid::CollectionType::kPhysical); 543 EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop); 544 EXPECT_EQ(collection->usage.usage, hid::usage::GenericDesktop::kPointer); 545 546 collection = collection->parent; 547 ASSERT_TRUE(collection != nullptr); 548 EXPECT_EQ(collection->type, hid::CollectionType::kLogical); 549 EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop); 550 EXPECT_EQ(collection->usage.usage, 0); 551 552 collection = collection->parent; 553 ASSERT_TRUE(collection != nullptr); 554 EXPECT_EQ(collection->type, hid::CollectionType::kApplication); 555 EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop); 556 EXPECT_EQ(collection->usage.usage, hid::usage::GenericDesktop::kJoystick); 557 EXPECT_TRUE(collection->parent == nullptr); 558 559 // The second report first field is in a logical -> app collection. 560 collection = dev->report[1].first_field[0].col; 561 562 ASSERT_TRUE(collection != nullptr); 563 EXPECT_EQ(collection->type, hid::CollectionType::kLogical); 564 EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop); 565 EXPECT_EQ(collection->usage.usage, 0); 566 567 collection = collection->parent; 568 ASSERT_TRUE(collection != nullptr); 569 EXPECT_EQ(collection->type, hid::CollectionType::kApplication); 570 EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop); 571 EXPECT_EQ(collection->usage.usage, hid::usage::GenericDesktop::kJoystick); 572 EXPECT_TRUE(collection->parent == nullptr); 573 574 // The third report is the same as the second. This seems a trivial test 575 // but previous parsers failed this one. 576 collection = dev->report[2].first_field[0].col; 577 578 ASSERT_TRUE(collection != nullptr); 579 EXPECT_EQ(collection->type, hid::CollectionType::kLogical); 580 EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop); 581 EXPECT_EQ(collection->usage.usage, 0); 582 583 collection = collection->parent; 584 ASSERT_TRUE(collection != nullptr); 585 EXPECT_EQ(collection->type, hid::CollectionType::kApplication); 586 EXPECT_EQ(collection->usage.page, hid::usage::Page::kGenericDesktop); 587 EXPECT_EQ(collection->usage.usage, hid::usage::GenericDesktop::kJoystick); 588 EXPECT_TRUE(collection->parent == nullptr); 589 590 size_t ff_count = 0u; 591 auto top_col = hid::GetAppCollection(hid::GetFirstInputField(dev, &ff_count)); 592 ASSERT_TRUE(top_col != nullptr); 593 EXPECT_EQ(top_col, collection); 594 EXPECT_EQ(ff_count, 172); 595 596 hid::FreeDeviceDescriptor(dev); 597 END_TEST; 598} 599 600static bool parse_acer12_touch() { 601 BEGIN_TEST; 602 603 hid::DeviceDescriptor* dd = nullptr; 604 auto res = hid::ParseReportDescriptor( 605 acer12_touch_r_desc, sizeof(acer12_touch_r_desc), &dd); 606 607 EXPECT_EQ(res, hid::ParseResult::kParseOk); 608 609 hid::FreeDeviceDescriptor(dd); 610 END_TEST; 611} 612 613static bool parse_eve_tablet() { 614 BEGIN_TEST; 615 616 hid::DeviceDescriptor* dev = nullptr; 617 auto res = hid::ParseReportDescriptor( 618 eve_tablet_r_desc, sizeof(eve_tablet_r_desc), &dev); 619 620 EXPECT_EQ(res, hid::ParseResult::kParseOk); 621 622 // A single report, no id. 623 ASSERT_EQ(dev->rep_count, 1u); 624 EXPECT_EQ(dev->report[0].report_id, 0); 625 626 // Report has two fields. 627 ASSERT_EQ(dev->report[0].count, 2u); 628 629 const hid::ReportField* fields = dev->report[0].first_field; 630 631 // First field is 1 bit, (tablet / no-tablet) 632 auto expected_flags = hid::kData | hid::kAbsolute | hid::kScalar; 633 634 EXPECT_EQ(fields[0].type, hid::kInput); 635 EXPECT_EQ(fields[0].attr.usage.page, hid::usage::Page::kGenericDesktop); 636 EXPECT_EQ(fields[0].attr.usage.usage, 0xff000001); 637 EXPECT_EQ(fields[0].attr.bit_sz, 1); 638 EXPECT_EQ(expected_flags & fields[0].flags, expected_flags); 639 640 // Second field is padding, 7 bits. 641 expected_flags = hid::kConstant | hid::kAbsolute | hid::kScalar; 642 643 EXPECT_EQ(fields[1].type, hid::kInput); 644 EXPECT_EQ(fields[1].attr.usage.page, hid::usage::Page::kGenericDesktop); 645 EXPECT_EQ(fields[1].attr.usage.usage, 0); 646 EXPECT_EQ(fields[1].attr.bit_sz, 7); 647 EXPECT_EQ(expected_flags & fields[1].flags, expected_flags); 648 649 hid::FreeDeviceDescriptor(dev); 650 END_TEST; 651} 652 653static bool parse_asus_touch() { 654 BEGIN_TEST; 655 hid::DeviceDescriptor* dev = nullptr; 656 auto res = hid::ParseReportDescriptor(asus_touch_desc, sizeof(asus_touch_desc), &dev); 657 ASSERT_EQ(res, hid::ParseResult::kParseOk); 658 END_TEST; 659} 660 661BEGIN_TEST_CASE(hidparser_tests) 662RUN_TEST(itemize_acer12_rpt1) 663RUN_TEST(itemize_eve_tablet_rpt) 664RUN_TEST(parse_boot_mouse) 665RUN_TEST(parse_adaf_trinket) 666RUN_TEST(parse_ps3_controller) 667RUN_TEST(parse_acer12_touch) 668RUN_TEST(parse_eve_tablet) 669RUN_TEST(parse_asus_touch) 670END_TEST_CASE(hidparser_tests) 671 672int main(int argc, char** argv) { 673 bool success = unittest_run_all_tests(argc, argv); 674 return success ? 0 : -1; 675} 676