Changeset d208f3f in mainline for uspace/lib/usbhid/src/hidparser.c
- Timestamp:
- 2011-05-27T12:14:02Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2df648c2
- Parents:
- fb2de0a (diff), 74341ed (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhid/src/hidparser.c
rfb2de0a rd208f3f 31 31 */ 32 32 /** @file 33 * HID report descriptor andreport data parser implementation.33 * USB HID report data parser implementation. 34 34 */ 35 35 #include <usb/hid/hidparser.h> … … 41 41 #include <assert.h> 42 42 43 43 /*---------------------------------------------------------------------------*/ 44 44 /* 45 45 * Data translation private functions 46 46 */ 47 47 uint32_t usb_hid_report_tag_data_uint32(const uint8_t *data, size_t size); 48 //inline size_t usb_hid_count_item_offset(usb_hid_report_item_t * report_item, size_t offset); 48 49 49 int usb_hid_translate_data(usb_hid_report_field_t *item, const uint8_t *data); 50 uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, int32_t value); 50 51 uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, 52 int32_t value); 53 51 54 int usb_pow(int a, int b); 52 55 56 /*---------------------------------------------------------------------------*/ 53 57 54 58 // TODO: tohle ma bejt asi jinde … … 56 60 { 57 61 switch(b) { 58 59 60 61 62 63 64 65 66 67 } 68 } 69 62 case 0: 63 return 1; 64 break; 65 case 1: 66 return a; 67 break; 68 default: 69 return a * usb_pow(a, b-1); 70 break; 71 } 72 } 73 /*---------------------------------------------------------------------------*/ 70 74 71 75 /** Returns size of report of specified report id and type in items … … 94 98 } 95 99 100 /** Returns size of report of specified report id and type in bytes 101 * 102 * @param parser Opaque report parser structure 103 * @param report_id 104 * @param type 105 * @return Number of items in specified report 106 */ 107 size_t usb_hid_report_byte_size(usb_hid_report_t *report, uint8_t report_id, 108 usb_hid_report_type_t type) 109 { 110 usb_hid_report_description_t *report_des; 111 112 if(report == NULL) { 113 return 0; 114 } 115 116 report_des = usb_hid_report_find_description (report, report_id, type); 117 if(report_des == NULL){ 118 return 0; 119 } 120 else { 121 return ((report_des->bit_length + 7) / 8) ; 122 } 123 } 124 /*---------------------------------------------------------------------------*/ 96 125 97 126 /** Parse and act upon a HID report. … … 103 132 * @return Error code. 104 133 */ 105 int usb_hid_parse_report(const usb_hid_report_t *report, 106 const uint8_t *data,size_t size, uint8_t *report_id)134 int usb_hid_parse_report(const usb_hid_report_t *report, const uint8_t *data, 135 size_t size, uint8_t *report_id) 107 136 { 108 137 link_t *list_item; … … 125 154 126 155 report_des = usb_hid_report_find_description(report, *report_id, type); 156 if(report_des == NULL) { 157 return EINVAL; 158 } 127 159 128 160 /* read data */ … … 130 162 while(list_item != &(report_des->report_items)) { 131 163 132 item = list_get_instance(list_item, usb_hid_report_field_t, link); 164 item = list_get_instance(list_item, usb_hid_report_field_t, 165 link); 133 166 134 167 if(USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) == 0) { … … 137 170 138 171 // array 139 item->value = usb_hid_translate_data(item, data); 172 item->value = 173 usb_hid_translate_data(item, data); 140 174 141 item->usage = USB_HID_EXTENDED_USAGE(item->usages[item->value - item->physical_minimum]); 142 item->usage_page = USB_HID_EXTENDED_USAGE_PAGE(item->usages[item->value - item->physical_minimum]); 175 item->usage = USB_HID_EXTENDED_USAGE( 176 item->usages[item->value - item->physical_minimum]); 177 178 item->usage_page = USB_HID_EXTENDED_USAGE_PAGE( 179 item->usages[item->value - item->physical_minimum]); 143 180 144 181 usb_hid_report_set_last_item (item->collection_path, 145 USB_HID_TAG_CLASS_GLOBAL,146 item->usage_page); 182 USB_HID_TAG_CLASS_GLOBAL, item->usage_page); 183 147 184 usb_hid_report_set_last_item (item->collection_path, 148 USB_HID_TAG_CLASS_LOCAL, 149 item->usage); 185 USB_HID_TAG_CLASS_LOCAL, item->usage); 150 186 151 187 } … … 162 198 } 163 199 200 /*---------------------------------------------------------------------------*/ 164 201 /** 165 202 * Translate data from the report as specified in report descriptor item … … 167 204 * @param item Report descriptor item with definition of translation 168 205 * @param data Data to translate 169 * @param j Index of processed field in report descriptor item170 206 * @return Translated data 171 207 */ … … 236 272 } 237 273 238 return (int)(((value - item->logical_minimum) / resolution) + item->physical_minimum); 239 240 } 241 242 /*** OUTPUT API **/ 274 return (int)(((value - item->logical_minimum) / resolution) + 275 item->physical_minimum); 276 277 } 278 279 /*---------------------------------------------------------------------------*/ 280 /* OUTPUT API */ 243 281 244 282 /** … … 250 288 * @return Returns allocated output buffer for specified output 251 289 */ 252 uint8_t *usb_hid_report_output(usb_hid_report_t *report, size_t *size, uint8_t report_id) 290 uint8_t *usb_hid_report_output(usb_hid_report_t *report, size_t *size, 291 uint8_t report_id) 253 292 { 254 293 if(report == NULL) { … … 260 299 usb_hid_report_description_t *report_des = NULL; 261 300 while(report_it != &report->reports) { 262 report_des = list_get_instance(report_it, usb_hid_report_description_t, link); 263 if((report_des->report_id == report_id) && (report_des->type == USB_HID_REPORT_TYPE_OUTPUT)){ 301 report_des = list_get_instance(report_it, 302 usb_hid_report_description_t, link); 303 304 if((report_des->report_id == report_id) && 305 (report_des->type == USB_HID_REPORT_TYPE_OUTPUT)){ 264 306 break; 265 307 } … … 303 345 * @return Error code 304 346 */ 305 int usb_hid_report_output_translate(usb_hid_report_t *report, uint8_t report_id,306 347 int usb_hid_report_output_translate(usb_hid_report_t *report, 348 uint8_t report_id, uint8_t *buffer, size_t size) 307 349 { 308 350 link_t *item; … … 320 362 } 321 363 322 usb_log_debug("OUTPUT BUFFER: %s\n", usb_debug_str_buffer(buffer,size, 0));323 324 364 usb_hid_report_description_t *report_des; 325 report_des = usb_hid_report_find_description (report, report_id, USB_HID_REPORT_TYPE_OUTPUT); 365 report_des = usb_hid_report_find_description (report, report_id, 366 USB_HID_REPORT_TYPE_OUTPUT); 367 326 368 if(report_des == NULL){ 327 369 return EINVAL; … … 333 375 report_item = list_get_instance(item, usb_hid_report_field_t, link); 334 376 335 usb_log_debug("OUTPUT ITEM usage(%x), value(%x)\n", report_item->usage, report_item->value);336 337 377 if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) { 338 378 339 379 // array 340 value = usb_hid_translate_data_reverse(report_item, report_item->value); 380 value = usb_hid_translate_data_reverse(report_item, 381 report_item->value); 382 341 383 offset = report_item->offset; 342 384 length = report_item->size; … … 344 386 else { 345 387 // variable item 346 value = usb_hid_translate_data_reverse(report_item, report_item->value); 388 value = usb_hid_translate_data_reverse(report_item, 389 report_item->value); 390 347 391 offset = report_item->offset; 348 392 length = report_item->size; … … 353 397 if((offset/8) == ((offset+length-1)/8)) { 354 398 // je to v jednom bytu 355 if(((size_t)(offset/8) >= size) || ((size_t)(offset+length-1)/8) >= size) { 399 if(((size_t)(offset/8) >= size) || 400 ((size_t)(offset+length-1)/8) >= size) { 356 401 break; // TODO ErrorCode 357 402 } … … 370 415 if(i == (offset/8)) { 371 416 tmp_value = value; 372 tmp_value = tmp_value & ((1 << (8-(offset%8)))-1); 417 tmp_value = tmp_value & 418 ((1 << (8-(offset%8)))-1); 419 373 420 tmp_value = tmp_value << (offset%8); 374 421 375 mask = ~(((1 << (8-(offset%8)))-1) << (offset%8)); 376 buffer[i] = (buffer[i] & mask) | tmp_value; 422 mask = ~(((1 << (8-(offset%8)))-1) << 423 (offset%8)); 424 425 buffer[i] = (buffer[i] & mask) | 426 tmp_value; 377 427 } 378 428 else if (i == ((offset + length -1)/8)) { 379 429 380 value = value >> (length - ((offset + length) % 8)); 381 value = value & ((1 << (length - ((offset + length) % 8))) - 1); 430 value = value >> (length - 431 ((offset + length) % 8)); 432 433 value = value & ((1 << (length - 434 ((offset + length) % 8))) - 1); 382 435 383 mask = (1 << (length - ((offset + length) % 8))) - 1; 436 mask = (1 << (length - 437 ((offset + length) % 8))) - 1; 438 384 439 buffer[i] = (buffer[i] & mask) | value; 385 440 } … … 396 451 } 397 452 398 usb_log_debug("OUTPUT BUFFER: %s\n", usb_debug_str_buffer(buffer,size, 0));399 400 453 return EOK; 401 454 } 402 455 456 /*---------------------------------------------------------------------------*/ 403 457 /** 404 458 * Translate given data for putting them into the outoput report … … 407 461 * @return ranslated value 408 462 */ 409 uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, int value) 463 uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, 464 int value) 410 465 { 411 466 int ret=0; … … 431 486 } 432 487 433 ret = ((value - item->physical_minimum) * resolution) + item->logical_minimum; 434 usb_log_debug("\tvalue(%x), resolution(%x), phymin(%x) logmin(%x), ret(%x)\n", value, resolution, item->physical_minimum, item->logical_minimum, ret); 488 ret = ((value - item->physical_minimum) * resolution) + 489 item->logical_minimum; 490 491 usb_log_debug("\tvalue(%x), resolution(%x), phymin(%x) logmin(%x), \ 492 ret(%x)\n", value, resolution, item->physical_minimum, 493 item->logical_minimum, ret); 435 494 436 495 if((item->logical_minimum < 0) || (item->logical_maximum < 0)){ … … 440 499 } 441 500 442 usb_hid_report_item_t *usb_hid_report_item_clone(const usb_hid_report_item_t *item) 501 /*---------------------------------------------------------------------------*/ 502 /** 503 * Clones given state table 504 * 505 * @param item State table to clone 506 * @return Pointer to the cloned item 507 */ 508 usb_hid_report_item_t *usb_hid_report_item_clone( 509 const usb_hid_report_item_t *item) 443 510 { 444 511 usb_hid_report_item_t *new_report_item; … … 453 520 } 454 521 455 522 /*---------------------------------------------------------------------------*/ 523 /** 524 * Function for sequence walking through the report. Returns next field in the 525 * report or the first one when no field is given. 526 * 527 * @param report Searched report structure 528 * @param field Current field. If NULL is given, the first one in the report 529 * is returned. Otherwise the next one i nthe list is returned. 530 * @param path Usage path specifying which fields wa are interested in. 531 * @param flags Flags defining mode of usage paths comparison 532 * @param type Type of report we search. 533 * @retval NULL if no field is founded 534 * @retval Pointer to the founded report structure when founded 535 */ 456 536 usb_hid_report_field_t *usb_hid_report_get_sibling(usb_hid_report_t *report, 457 usb_hid_report_field_t *field, 458 usb_hid_report_path_t *path, int flags, 459 usb_hid_report_type_t type) 460 { 461 usb_hid_report_description_t *report_des = usb_hid_report_find_description (report, path->report_id, type); 537 usb_hid_report_field_t *field, usb_hid_report_path_t *path, int flags, 538 usb_hid_report_type_t type) 539 { 540 usb_hid_report_description_t *report_des = 541 usb_hid_report_find_description(report, path->report_id, type); 542 462 543 link_t *field_it; 463 544 … … 467 548 468 549 if(field == NULL){ 469 // vezmu prvni co mathuje podle path!!470 550 field_it = report_des->report_items.next; 471 551 } … … 475 555 476 556 while(field_it != &report_des->report_items) { 477 field = list_get_instance(field_it, usb_hid_report_field_t, link); 557 field = list_get_instance(field_it, usb_hid_report_field_t, 558 link); 478 559 479 560 if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) { 480 usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage); 481 if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK){ 482 usb_hid_report_remove_last_item (field->collection_path); 561 usb_hid_report_path_append_item ( 562 field->collection_path, field->usage_page, 563 field->usage); 564 565 if(usb_hid_report_compare_usage_path( 566 field->collection_path, path, flags) == EOK){ 567 568 usb_hid_report_remove_last_item( 569 field->collection_path); 570 483 571 return field; 484 572 } 485 usb_hid_report_remove_last_item (field->collection_path); 573 usb_hid_report_remove_last_item ( 574 field->collection_path); 486 575 } 487 576 field_it = field_it->next; … … 491 580 } 492 581 493 uint8_t usb_hid_report_get_report_id(usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type) 582 /*---------------------------------------------------------------------------*/ 583 /** 584 * Returns next report_id of report of specified type. If zero is given than 585 * first report_id of specified type is returned (0 is not legal value for 586 * repotr_id) 587 * 588 * @param report_id Current report_id, 0 if there is no current report_id 589 * @param type Type of searched report 590 * @param report Report structure inwhich we search 591 * @retval 0 if report structure is null or there is no specified report 592 * @retval report_id otherwise 593 */ 594 uint8_t usb_hid_get_next_report_id(usb_hid_report_t *report, 595 uint8_t report_id, usb_hid_report_type_t type) 494 596 { 495 597 if(report == NULL){ … … 500 602 link_t *report_it; 501 603 502 if(report_id == 0) { 503 report_it = usb_hid_report_find_description (report, report_id, type)->link.next; 604 if(report_id > 0) { 605 report_it = usb_hid_report_find_description(report, report_id, 606 type)->link.next; 504 607 } 505 608 else { … … 508 611 509 612 while(report_it != &report->reports) { 510 report_des = list_get_instance(report_it, usb_hid_report_description_t, link); 613 report_des = list_get_instance(report_it, 614 usb_hid_report_description_t, link); 615 511 616 if(report_des->type == type){ 512 617 return report_des->report_id; … … 517 622 } 518 623 624 /*---------------------------------------------------------------------------*/ 625 /** 626 * Reset all local items in given state table 627 * 628 * @param report_item State table containing current state of report 629 * descriptor parsing 630 * 631 * @return void 632 */ 519 633 void usb_hid_report_reset_local_items(usb_hid_report_item_t *report_item) 520 634 {
Note:
See TracChangeset
for help on using the changeset viewer.