Changes in uspace/lib/usb/src/hidparser.c [ad4562c2:c32688d] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/src/hidparser.c
rad4562c2 rc32688d 36 36 #include <errno.h> 37 37 #include <stdio.h> 38 #include <malloc.h> 39 #include <mem.h> 40 #include <usb/debug.h> 41 42 #define USB_HID_NEW_REPORT_ITEM 1 43 #define USB_HID_NO_ACTION 2 44 #define USB_HID_UNKNOWN_TAG -99 45 46 #define BAD_HACK_USAGE_PAGE 0x07 47 48 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size, 49 usb_hid_report_item_t *report_item); 50 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size, 51 usb_hid_report_item_t *report_item); 52 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size, 53 usb_hid_report_item_t *report_item); 54 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size, 55 usb_hid_report_item_t *report_item); 56 57 void usb_hid_descriptor_print_list(link_t *head); 58 int usb_hid_report_reset_local_items(); 59 void usb_hid_free_report_list(link_t *head); 60 int32_t usb_hid_report_tag_data_int32(const uint8_t *data, size_t size); 61 inline size_t usb_hid_count_item_offset(usb_hid_report_item_t * report_item, size_t offset); 62 int usb_hid_translate_data(usb_hid_report_item_t *item, const uint8_t *data, size_t j); 63 int usb_pow(int a, int b); 64 65 int usb_pow(int a, int b) 66 { 67 switch(b) { 68 case 0: 69 return 1; 70 break; 71 case 1: 72 return a; 73 break; 74 default: 75 return a * usb_pow(a, b-1); 76 break; 77 } 78 } 79 80 /** 81 * 82 */ 83 int usb_hid_parser_init(usb_hid_report_parser_t *parser) 84 { 85 if(parser == NULL) { 86 return -1; 87 } 88 89 list_initialize(&(parser->input)); 90 list_initialize(&(parser->output)); 91 list_initialize(&(parser->feature)); 92 93 return EOK; 94 } 95 38 96 39 97 /** Parse HID report descriptor. … … 46 104 const uint8_t *data, size_t size) 47 105 { 48 return ENOTSUP; 106 size_t i=0; 107 uint8_t tag=0; 108 uint8_t item_size=0; 109 int class=0; 110 int ret; 111 usb_hid_report_item_t *report_item=0; 112 usb_hid_report_item_t *new_report_item; 113 114 size_t offset_input=0; 115 size_t offset_output=0; 116 size_t offset_feature=0; 117 118 119 if(!(report_item=malloc(sizeof(usb_hid_report_item_t)))){ 120 return ENOMEM; 121 } 122 memset(report_item, 0, sizeof(usb_hid_report_item_t)); 123 124 link_initialize(&(report_item->link)); 125 126 while(i<size){ 127 if(!USB_HID_ITEM_IS_LONG(data[i])){ 128 129 if((i+USB_HID_ITEM_SIZE(data[i]))>= size){ 130 return -1; // TODO ERROR CODE 131 } 132 133 tag = USB_HID_ITEM_TAG(data[i]); 134 item_size = USB_HID_ITEM_SIZE(data[i]); 135 class = USB_HID_ITEM_TAG_CLASS(data[i]); 136 137 usb_log_debug2( 138 "i(%u) data(%X) value(%X): TAG %u, class %u, size %u - ", i, 139 data[i], usb_hid_report_tag_data_int32(data+i+1,item_size), 140 tag, class, item_size); 141 142 ret = usb_hid_report_parse_tag(tag,class,data+i+1, 143 item_size,report_item); 144 usb_log_debug2("ret: %u\n", ret); 145 switch(ret){ 146 case USB_HID_NEW_REPORT_ITEM: 147 // store report item to report and create the new one 148 usb_log_debug("\nNEW REPORT ITEM: %X",tag); 149 150 switch(tag) { 151 case USB_HID_REPORT_TAG_INPUT: 152 report_item->offset = offset_input; 153 offset_input += report_item->count * report_item->size; 154 usb_log_debug(" - INPUT\n"); 155 list_append(&(report_item->link), &(parser->input)); 156 break; 157 case USB_HID_REPORT_TAG_OUTPUT: 158 report_item->offset = offset_output; 159 offset_output += report_item->count * report_item->size; 160 usb_log_debug(" - OUTPUT\n"); 161 list_append(&(report_item->link), &(parser->output)); 162 163 break; 164 case USB_HID_REPORT_TAG_FEATURE: 165 report_item->offset = offset_feature; 166 offset_feature += report_item->count * report_item->size; 167 usb_log_debug(" - FEATURE\n"); 168 list_append(&(report_item->link), &(parser->feature)); 169 break; 170 default: 171 usb_log_debug("\tjump over - tag %X\n", tag); 172 break; 173 } 174 175 /* clone current state table to the new item */ 176 if(!(new_report_item = malloc(sizeof(usb_hid_report_item_t)))) { 177 return ENOMEM; 178 } 179 memcpy(new_report_item,report_item, sizeof(usb_hid_report_item_t)); 180 /* reset local items */ 181 new_report_item->usage_minimum = 0; 182 new_report_item->usage_maximum = 0; 183 184 link_initialize(&(new_report_item->link)); 185 report_item = new_report_item; 186 187 break; 188 case USB_HID_REPORT_TAG_PUSH: 189 // push current state to stack 190 // not yet implemented 191 break; 192 case USB_HID_REPORT_TAG_POP: 193 // restore current state from stack 194 // not yet implemented 195 break; 196 197 default: 198 // nothing special to do 199 break; 200 } 201 202 /* jump over the processed block */ 203 i += 1 + USB_HID_ITEM_SIZE(data[i]); 204 } 205 else{ 206 // TBD 207 i += 3 + USB_HID_ITEM_SIZE(data[i+1]); 208 } 209 210 211 } 212 213 return EOK; 214 } 215 216 217 /** 218 * Parse input report. 219 * 220 * @param data Data for report 221 * @param size Size of report 222 * @param callbacks Callbacks for report actions 223 * @param arg Custom arguments 224 * 225 * @return Error code 226 */ 227 int usb_hid_boot_keyboard_input_report(const uint8_t *data, size_t size, 228 const usb_hid_report_in_callbacks_t *callbacks, void *arg) 229 { 230 int i; 231 usb_hid_report_item_t item; 232 233 /* fill item due to the boot protocol report descriptor */ 234 // modifier keys are in the first byte 235 uint8_t modifiers = data[0]; 236 237 item.offset = 2; /* second byte is reserved */ 238 item.size = 8; 239 item.count = 6; 240 item.usage_minimum = 0; 241 item.usage_maximum = 255; 242 item.logical_minimum = 0; 243 item.logical_maximum = 255; 244 245 if (size != 8) { 246 return -1; //ERANGE; 247 } 248 249 uint8_t keys[6]; 250 for (i = 0; i < item.count; i++) { 251 keys[i] = data[i + item.offset]; 252 } 253 254 callbacks->keyboard(keys, 6, modifiers, arg); 255 return EOK; 256 } 257 258 /** 259 * Makes output report for keyboard boot protocol 260 * 261 * @param leds 262 * @param output Output report data buffer 263 * @param size Size of the output buffer 264 * @return Error code 265 */ 266 int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size) 267 { 268 if(size != 1){ 269 return -1; 270 } 271 272 /* used only first five bits, others are only padding*/ 273 *data = leds; 274 return EOK; 275 } 276 277 /** 278 * 279 * @param Tag to parse 280 * @param Report descriptor buffer 281 * @param Size of data belongs to this tag 282 * @param Current report item structe 283 * @return Code of action to be done next 284 */ 285 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size, 286 usb_hid_report_item_t *report_item) 287 { 288 int ret; 289 290 switch(class){ 291 case USB_HID_TAG_CLASS_MAIN: 292 293 if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item)) == EOK) { 294 return USB_HID_NEW_REPORT_ITEM; 295 } 296 else { 297 /*TODO process the error */ 298 return ret; 299 } 300 break; 301 302 case USB_HID_TAG_CLASS_GLOBAL: 303 return usb_hid_report_parse_global_tag(tag,data,item_size,report_item); 304 break; 305 306 case USB_HID_TAG_CLASS_LOCAL: 307 return usb_hid_report_parse_local_tag(tag,data,item_size,report_item); 308 break; 309 default: 310 return USB_HID_NO_ACTION; 311 } 312 } 313 314 /** 315 * Parse main tags of report descriptor 316 * 317 * @param Tag identifier 318 * @param Data buffer 319 * @param Length of data buffer 320 * @param Current state table 321 * @return Error code 322 */ 323 324 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size, 325 usb_hid_report_item_t *report_item) 326 { 327 switch(tag) 328 { 329 case USB_HID_REPORT_TAG_INPUT: 330 case USB_HID_REPORT_TAG_OUTPUT: 331 case USB_HID_REPORT_TAG_FEATURE: 332 report_item->item_flags = *data; 333 return EOK; 334 break; 335 336 case USB_HID_REPORT_TAG_COLLECTION: 337 // TODO 338 return USB_HID_NO_ACTION; 339 break; 340 341 case USB_HID_REPORT_TAG_END_COLLECTION: 342 /* should be ignored */ 343 return USB_HID_NO_ACTION; 344 break; 345 default: 346 return USB_HID_NO_ACTION; 347 } 348 349 return EOK; 350 } 351 352 /** 353 * Parse global tags of report descriptor 354 * 355 * @param Tag identifier 356 * @param Data buffer 357 * @param Length of data buffer 358 * @param Current state table 359 * @return Error code 360 */ 361 362 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size, 363 usb_hid_report_item_t *report_item) 364 { 365 // TODO take care about the bit length of data 366 switch(tag) 367 { 368 case USB_HID_REPORT_TAG_USAGE_PAGE: 369 report_item->usage_page = usb_hid_report_tag_data_int32(data,item_size); 370 break; 371 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM: 372 report_item->logical_minimum = usb_hid_report_tag_data_int32(data,item_size); 373 break; 374 case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM: 375 report_item->logical_maximum = usb_hid_report_tag_data_int32(data,item_size); 376 break; 377 case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM: 378 report_item->physical_minimum = usb_hid_report_tag_data_int32(data,item_size); 379 break; 380 case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM: 381 report_item->physical_maximum = usb_hid_report_tag_data_int32(data,item_size); 382 break; 383 case USB_HID_REPORT_TAG_UNIT_EXPONENT: 384 report_item->unit_exponent = usb_hid_report_tag_data_int32(data,item_size); 385 break; 386 case USB_HID_REPORT_TAG_UNIT: 387 report_item->unit = usb_hid_report_tag_data_int32(data,item_size); 388 break; 389 case USB_HID_REPORT_TAG_REPORT_SIZE: 390 report_item->size = usb_hid_report_tag_data_int32(data,item_size); 391 break; 392 case USB_HID_REPORT_TAG_REPORT_COUNT: 393 report_item->count = usb_hid_report_tag_data_int32(data,item_size); 394 break; 395 case USB_HID_REPORT_TAG_REPORT_ID: 396 report_item->id = usb_hid_report_tag_data_int32(data,item_size); 397 break; 398 case USB_HID_REPORT_TAG_PUSH: 399 case USB_HID_REPORT_TAG_POP: 400 return tag; 401 break; 402 403 default: 404 return USB_HID_NO_ACTION; 405 } 406 407 return EOK; 408 } 409 410 /** 411 * Parse local tags of report descriptor 412 * 413 * @param Tag identifier 414 * @param Data buffer 415 * @param Length of data buffer 416 * @param Current state table 417 * @return Error code 418 */ 419 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size, 420 usb_hid_report_item_t *report_item) 421 { 422 switch(tag) 423 { 424 case USB_HID_REPORT_TAG_USAGE: 425 report_item->usage = usb_hid_report_tag_data_int32(data,item_size); 426 break; 427 case USB_HID_REPORT_TAG_USAGE_MINIMUM: 428 report_item->usage_minimum = usb_hid_report_tag_data_int32(data,item_size); 429 break; 430 case USB_HID_REPORT_TAG_USAGE_MAXIMUM: 431 report_item->usage_maximum = usb_hid_report_tag_data_int32(data,item_size); 432 break; 433 case USB_HID_REPORT_TAG_DESIGNATOR_INDEX: 434 report_item->designator_index = usb_hid_report_tag_data_int32(data,item_size); 435 break; 436 case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM: 437 report_item->designator_minimum = usb_hid_report_tag_data_int32(data,item_size); 438 break; 439 case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM: 440 report_item->designator_maximum = usb_hid_report_tag_data_int32(data,item_size); 441 break; 442 case USB_HID_REPORT_TAG_STRING_INDEX: 443 report_item->string_index = usb_hid_report_tag_data_int32(data,item_size); 444 break; 445 case USB_HID_REPORT_TAG_STRING_MINIMUM: 446 report_item->string_minimum = usb_hid_report_tag_data_int32(data,item_size); 447 break; 448 case USB_HID_REPORT_TAG_STRING_MAXIMUM: 449 report_item->string_maximum = usb_hid_report_tag_data_int32(data,item_size); 450 break; 451 case USB_HID_REPORT_TAG_DELIMITER: 452 report_item->delimiter = usb_hid_report_tag_data_int32(data,item_size); 453 break; 454 455 default: 456 return USB_HID_NO_ACTION; 457 } 458 459 return EOK; 460 } 461 462 /** 463 * Converts raw data to int32 (thats the maximum length of short item data) 464 * 465 * @param Data buffer 466 * @param Size of buffer 467 * @return Converted int32 number 468 */ 469 int32_t usb_hid_report_tag_data_int32(const uint8_t *data, size_t size) 470 { 471 unsigned int i; 472 int32_t result; 473 474 result = 0; 475 for(i=0; i<size; i++) { 476 result = (result | (data[i]) << (i*8)); 477 } 478 479 return result; 480 } 481 482 483 484 /** 485 * Prints content of given list of report items. 486 * 487 * @param List of report items 488 * @return void 489 */ 490 void usb_hid_descriptor_print_list(link_t *head) 491 { 492 usb_hid_report_item_t *report_item; 493 link_t *item; 494 495 if(head == NULL || list_empty(head)) { 496 usb_log_debug("\tempty\n"); 497 return; 498 } 499 500 for(item = head->next; item != head; item = item->next) { 501 502 report_item = list_get_instance(item, usb_hid_report_item_t, link); 503 504 usb_log_debug("\tOFFSET: %X\n", report_item->offset); 505 usb_log_debug("\tCOUNT: %X\n", report_item->count); 506 usb_log_debug("\tSIZE: %X\n", report_item->size); 507 usb_log_debug("\tCONSTANT/VAR: %X\n", USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags)); 508 usb_log_debug("\tVARIABLE/ARRAY: %X\n", USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags)); 509 usb_log_debug("\tUSAGE: %X\n", report_item->usage); 510 usb_log_debug("\tUSAGE PAGE: %X\n", report_item->usage_page); 511 usb_log_debug("\tLOGMIN: %X\n", report_item->logical_minimum); 512 usb_log_debug("\tLOGMAX: %X\n", report_item->logical_maximum); 513 usb_log_debug("\tPHYMIN: %X\n", report_item->physical_minimum); 514 usb_log_debug("\tPHYMAX: %X\n", report_item->physical_maximum); 515 usb_log_debug("\tUSAGEMIN: %X\n", report_item->usage_minimum); 516 usb_log_debug("\tUSAGEMAX: %X\n", report_item->usage_maximum); 517 518 usb_log_debug("\n"); 519 520 } 521 522 523 } 524 /** 525 * Prints content of given descriptor in human readable format. 526 * 527 * @param Parsed descriptor to print 528 * @return void 529 */ 530 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser) 531 { 532 usb_log_debug("INPUT:\n"); 533 usb_hid_descriptor_print_list(&parser->input); 534 535 usb_log_debug("OUTPUT: \n"); 536 usb_hid_descriptor_print_list(&parser->output); 537 538 usb_log_debug("FEATURE:\n"); 539 usb_hid_descriptor_print_list(&parser->feature); 540 541 } 542 543 /** 544 * Releases whole linked list of report items 545 * 546 * 547 */ 548 void usb_hid_free_report_list(link_t *head) 549 { 550 return; 551 552 usb_hid_report_item_t *report_item; 553 link_t *next; 554 555 if(head == NULL || list_empty(head)) { 556 return; 557 } 558 559 next = head->next; 560 while(next != head) { 561 562 report_item = list_get_instance(next, usb_hid_report_item_t, link); 563 next = next->next; 564 565 free(report_item); 566 } 567 568 return; 569 570 } 571 572 /** Free the HID report parser structure 573 * 574 * @param parser Opaque HID report parser structure 575 * @return Error code 576 */ 577 void usb_hid_free_report_parser(usb_hid_report_parser_t *parser) 578 { 579 if(parser == NULL){ 580 return; 581 } 582 583 usb_hid_free_report_list(&parser->input); 584 usb_hid_free_report_list(&parser->output); 585 usb_hid_free_report_list(&parser->feature); 586 587 return; 49 588 } 50 589 … … 58 597 * @param arg Custom argument (passed through to the callbacks). 59 598 * @return Error code. 60 */ 599 */ 61 600 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 62 601 const uint8_t *data, size_t size, 63 602 const usb_hid_report_in_callbacks_t *callbacks, void *arg) 64 603 { 65 int i; 66 67 /* main parsing loop */ 68 while(0){ 69 } 70 71 72 uint8_t keys[6]; 73 74 for (i = 0; i < 6; ++i) { 75 keys[i] = data[i]; 76 } 77 78 callbacks->keyboard(keys, 6, 0, arg); 79 604 /* 605 * 606 * only key codes (usage page 0x07) will be processed 607 * other usages will be ignored 608 */ 609 link_t *list_item; 610 usb_hid_report_item_t *item; 611 uint8_t *keys; 612 uint8_t item_value; 613 size_t key_count=0; 614 size_t i=0; 615 size_t j=0; 616 617 // get the size of result keycodes array 618 usb_hid_report_path_t path; 619 path.usage_page = BAD_HACK_USAGE_PAGE; 620 key_count = usb_hid_report_input_length(parser, &path); 621 622 if(!(keys = malloc(sizeof(uint8_t) * key_count))){ 623 return ENOMEM; 624 } 625 626 // read data 627 list_item = parser->input.next; 628 while(list_item != &(parser->input)) { 629 630 item = list_get_instance(list_item, usb_hid_report_item_t, link); 631 if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) && 632 (item->usage_page == path.usage_page)) { 633 for(j=0; j<(size_t)(item->count); j++) { 634 if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0) || 635 ((item->usage_minimum == 0) && (item->usage_maximum == 0))) { 636 // variable item 637 keys[i++] = usb_hid_translate_data(item, data,j); 638 } 639 else { 640 // bitmapa 641 if((item_value = usb_hid_translate_data(item, data, j)) != 0) { 642 keys[i++] = j + item->usage_minimum; 643 } 644 else { 645 keys[i++] = 0; 646 } 647 } 648 } 649 } 650 list_item = list_item->next; 651 } 652 653 callbacks->keyboard(keys, key_count, 0, arg); 654 655 free(keys); 80 656 return EOK; 81 } 82 83 /** Free the HID report parser structure 84 * 85 * @param parser Opaque HID report parser structure 86 * @return Error code 87 */ 88 int usb_hid_free_report_parser(usb_hid_report_parser_t *parser) 89 { 90 91 return EOK; 92 } 93 94 95 /** 96 * Parse input report. 97 * 98 * @param data Data for report 99 * @param size Size of report 100 * @param callbacks Callbacks for report actions 101 * @param arg Custom arguments 102 * 103 * @return Error code 104 */ 105 int usb_hid_boot_keyboard_input_report(const uint8_t *data, size_t size, 106 const usb_hid_report_in_callbacks_t *callbacks, void *arg) 107 { 108 int i; 109 usb_hid_report_item_t item; 110 111 /* fill item due to the boot protocol report descriptor */ 112 // modifier keys are in the first byte 113 uint8_t modifiers = data[0]; 114 115 item.offset = 2; /* second byte is reserved */ 116 item.size = 8; 117 item.count = 6; 118 item.usage_min = 0; 119 item.usage_max = 255; 120 item.logical_min = 0; 121 item.logical_max = 255; 122 123 if (size != 8) { 124 return ERANGE; 125 } 126 127 uint8_t keys[6]; 128 for (i = 0; i < item.count; i++) { 129 keys[i] = data[i + item.offset]; 130 } 131 132 callbacks->keyboard(keys, 6, modifiers, arg); 133 return EOK; 134 } 135 136 /** 137 * Makes output report for keyboard boot protocol 138 * 139 * @param leds 140 * @param output Output report data buffer 141 * @param size Size of the output buffer 142 * @return Error code 143 */ 144 int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size) 145 { 146 if (size < 1){ 147 return -1; 148 } 149 150 data[0] = leds; 151 return EOK; 152 } 657 658 } 659 660 661 int usb_hid_translate_data(usb_hid_report_item_t *item, const uint8_t *data, size_t j) 662 { 663 int resolution; 664 int offset; 665 int part_size; 666 667 int32_t value; 668 int32_t mask; 669 const uint8_t *foo; 670 671 // now only common numbers llowed 672 if(item->size > 32) { 673 return 0; 674 } 675 676 if((item->physical_minimum == 0) && (item->physical_maximum == 0)) { 677 item->physical_minimum = item->logical_minimum; 678 item->physical_maximum = item->logical_maximum; 679 } 680 681 if(item->physical_maximum == item->physical_minimum){ 682 resolution = 1; 683 } 684 else { 685 resolution = (item->logical_maximum - item->logical_minimum) / 686 ((item->physical_maximum - item->physical_minimum) * 687 (usb_pow(10,(item->unit_exponent)))); 688 } 689 offset = item->offset + (j * item->size); 690 691 // FIXME 692 if((offset/8) != ((offset+item->size)/8)) { 693 usb_log_debug2("offset %d\n", offset); 694 695 part_size = ((offset+item->size)%8); 696 usb_log_debug2("part size %d\n",part_size); 697 698 // the higher one 699 foo = data+(offset/8); 700 mask = ((1 << (item->size-part_size))-1); 701 value = (*foo & mask) << part_size; 702 703 usb_log_debug2("hfoo %x\n", *foo); 704 usb_log_debug2("hmaska %x\n", mask); 705 usb_log_debug2("hval %d\n", value); 706 707 // the lower one 708 foo = data+((offset+item->size)/8); 709 mask = ((1 << part_size)-1) << (8-part_size); 710 value += ((*foo & mask) >> (8-part_size)); 711 712 usb_log_debug2("lfoo %x\n", *foo); 713 usb_log_debug2("lmaska %x\n", mask); 714 usb_log_debug2("lval %d\n", ((*foo & mask) >> (8-(item->size-part_size)))); 715 usb_log_debug2("val %d\n", value); 716 717 718 } 719 else { 720 foo = data+(offset/8); 721 mask = ((1 << item->size)-1) << (8-((offset%8)+item->size)); 722 value = (*foo & mask) >> (8-((offset%8)+item->size)); 723 724 usb_log_debug2("offset %d\n", offset); 725 726 usb_log_debug2("foo %x\n", *foo); 727 usb_log_debug2("maska %x\n", mask); 728 usb_log_debug2("val %d\n", value); 729 } 730 731 usb_log_debug2("---\n\n"); 732 733 return (int)(((value - item->logical_minimum) / resolution) + item->physical_minimum); 734 735 } 736 737 int usb_hid_report_input_length(const usb_hid_report_parser_t *parser, 738 const usb_hid_report_path_t *path) 739 { 740 int ret = 0; 741 link_t *item; 742 usb_hid_report_item_t *report_item; 743 744 item = (&parser->input)->next; 745 while(&parser->input != item) { 746 report_item = list_get_instance(item, usb_hid_report_item_t, link); 747 if(!USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags) && 748 (report_item->usage_page == path->usage_page)) { 749 ret += report_item->count; 750 } 751 752 item = item->next; 753 } 754 755 return ret; 756 } 757 758 153 759 154 760 /**
Note:
See TracChangeset
for help on using the changeset viewer.