Changeset 3bacee1 in mainline for uspace/lib/usbhid/src/hiddescriptor.c
- Timestamp:
- 2018-04-12T16:27:17Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 3cf22f9
- Parents:
- 76d0981d
- git-author:
- Jiri Svoboda <jiri@…> (2018-04-11 19:25:33)
- git-committer:
- Jiri Svoboda <jiri@…> (2018-04-12 16:27:17)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhid/src/hiddescriptor.c
r76d0981d r3bacee1 96 96 usb_hid_report_path_t *path = NULL; 97 97 98 if ((report == NULL) || (cmp_path == NULL)) {98 if ((report == NULL) || (cmp_path == NULL)) { 99 99 return NULL; 100 100 } 101 101 102 while (path_it != &report->collection_paths.head) {102 while (path_it != &report->collection_paths.head) { 103 103 path = list_get_instance(path_it, usb_hid_report_path_t, 104 105 106 if (usb_hid_report_compare_usage_path(path, cmp_path,107 USB_HID_PATH_COMPARE_STRICT) == 0){104 cpath_link); 105 106 if (usb_hid_report_compare_usage_path(path, cmp_path, 107 USB_HID_PATH_COMPARE_STRICT) == 0) { 108 108 break; 109 109 } 110 110 path_it = path_it->next; 111 111 } 112 if (path_it == &report->collection_paths.head) {112 if (path_it == &report->collection_paths.head) { 113 113 path = usb_hid_report_path_clone(cmp_path); 114 if (path == NULL) {114 if (path == NULL) { 115 115 return NULL; 116 116 } … … 119 119 120 120 return path; 121 } 122 else { 121 } else { 123 122 return list_get_instance(path_it, usb_hid_report_path_t, 124 123 cpath_link); 125 124 } 126 125 } … … 146 145 147 146 report->use_report_ids = 0; 148 147 return EOK; 149 148 } 150 149 … … 164 163 */ 165 164 errno_t usb_hid_report_append_fields(usb_hid_report_t *report, 166 usb_hid_report_item_t *report_item) { 165 usb_hid_report_item_t *report_item) 166 { 167 167 168 168 usb_hid_report_field_t *field; … … 170 170 171 171 uint32_t *usages; 172 int usages_used =0;173 174 if ((report == NULL) || (report_item == NULL)) {172 int usages_used = 0; 173 174 if ((report == NULL) || (report_item == NULL)) { 175 175 return EINVAL; 176 176 } 177 177 178 if (report_item->usages_count > 0){178 if (report_item->usages_count > 0) { 179 179 usages = malloc(sizeof(uint32_t) * report_item->usages_count); 180 180 memcpy(usages, report_item->usages, sizeof(int32_t) * 181 report_item->usages_count); 182 } 183 else { 181 report_item->usages_count); 182 } else { 184 183 usages = NULL; 185 184 } 186 185 187 186 usb_hid_report_path_t *path = report_item->usage_path; 188 for (i=0; i<report_item->count; i++){187 for (i = 0; i < report_item->count; i++) { 189 188 190 189 field = malloc(sizeof(usb_hid_report_field_t)); 191 if (field == NULL) {190 if (field == NULL) { 192 191 return ENOMEM; 193 192 } … … 202 201 field->physical_maximum = report_item->physical_maximum; 203 202 204 if (USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0){203 if (USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) { 205 204 /* 206 205 Store usage array. The Correct Usage Page and Usage is … … 213 212 field->usages = usages; 214 213 usages_used = 1; 215 } 216 else { 214 } else { 217 215 218 216 /* Fill the correct Usage and Usage Page */ 219 217 int32_t usage; 220 if (i < report_item->usages_count) {218 if (i < report_item->usages_count) { 221 219 usage = report_item->usages[i]; 220 } else { 221 usage = report_item->usages[report_item->usages_count - 1]; 222 222 } 223 else { 224 usage = report_item->usages[ 225 report_item->usages_count- 1]; 226 } 227 228 if(USB_HID_IS_EXTENDED_USAGE(usage)){ 223 224 if (USB_HID_IS_EXTENDED_USAGE(usage)) { 229 225 field->usage = USB_HID_EXTENDED_USAGE(usage); 230 226 field->usage_page = 231 USB_HID_EXTENDED_USAGE_PAGE(usage); 232 } 233 else { 227 USB_HID_EXTENDED_USAGE_PAGE(usage); 228 } else { 234 229 // should not occur 235 230 field->usage = usage; … … 239 234 240 235 usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_GLOBAL, 241 236 field->usage_page); 242 237 usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_LOCAL, 243 238 field->usage); 244 239 245 240 field->collection_path = 246 241 usb_hid_report_path_try_insert(report, path); 247 242 248 243 field->size = report_item->size; … … 250 245 field->offset = report_item->offset + (i * report_item->size); 251 246 252 if (report->use_report_ids != 0) {247 if (report->use_report_ids != 0) { 253 248 field->offset += 8; 254 249 report->use_report_ids = 1; … … 260 255 usb_hid_report_description_t *report_des; 261 256 report_des = usb_hid_report_find_description(report, 262 263 264 if (report_des == NULL){257 report_item->id, report_item->type); 258 259 if (report_des == NULL) { 265 260 report_des = malloc( 266 267 if (report_des == NULL) {261 sizeof(usb_hid_report_description_t)); 262 if (report_des == NULL) { 268 263 return ENOMEM; 269 264 } 270 265 271 266 memset(report_des, 0, 272 267 sizeof(usb_hid_report_description_t)); 273 268 274 269 report_des->type = report_item->type; 275 270 report_des->report_id = report_item->id; 276 if (report_des->report_id != 0) {271 if (report_des->report_id != 0) { 277 272 /* set up the bit length by report_id field */ 278 273 report_des->bit_length = 8; … … 296 291 297 292 // free only when not used!!! 298 if (usages && usages_used == 0) {293 if (usages && usages_used == 0) { 299 294 free(usages); 300 295 } … … 313 308 * @retval NULL If no description is founded 314 309 */ 315 usb_hid_report_description_t * usb_hid_report_find_description( 316 const usb_hid_report_t *report, uint8_t report_id, 317 usb_hid_report_type_t type) { 318 319 if(report == NULL) { 310 usb_hid_report_description_t *usb_hid_report_find_description( 311 const usb_hid_report_t *report, uint8_t report_id, 312 usb_hid_report_type_t type) 313 { 314 315 if (report == NULL) { 320 316 return NULL; 321 317 } … … 324 320 usb_hid_report_description_t, report_des) { 325 321 // if report id not set, return the first of the type 326 if (((report_des->report_id == report_id) || (report_id == 0)) &&327 (report_des->type == type)) {322 if (((report_des->report_id == report_id) || (report_id == 0)) && 323 (report_des->type == type)) { 328 324 return report_des; 329 325 } … … 346 342 const uint8_t *data, size_t size) 347 343 { 348 size_t i =0;349 uint8_t tag =0;350 uint8_t item_size =0;351 int class =0;344 size_t i = 0; 345 uint8_t tag = 0; 346 uint8_t item_size = 0; 347 int class = 0; 352 348 int ret; 353 usb_hid_report_item_t *report_item =0;349 usb_hid_report_item_t *report_item = 0; 354 350 usb_hid_report_item_t *new_report_item; 355 351 usb_hid_report_path_t *usage_path; 356 352 357 size_t offset_input =0;358 size_t offset_output =0;359 size_t offset_feature =0;353 size_t offset_input = 0; 354 size_t offset_output = 0; 355 size_t offset_feature = 0; 360 356 361 357 link_t *item_link; … … 365 361 366 362 /* parser structure initialization*/ 367 if (usb_hid_report_init(report) != EOK) {363 if (usb_hid_report_init(report) != EOK) { 368 364 return EINVAL; 369 365 } 370 366 371 367 /*report item initialization*/ 372 if (!(report_item=malloc(sizeof(usb_hid_report_item_t)))){368 if (!(report_item = malloc(sizeof(usb_hid_report_item_t)))) { 373 369 return ENOMEM; 374 370 } … … 377 373 378 374 /* usage path context initialization */ 379 if (!(usage_path=usb_hid_report_path())){375 if (!(usage_path = usb_hid_report_path())) { 380 376 return ENOMEM; 381 377 } 382 378 usb_hid_report_path_append_item(usage_path, 0, 0); 383 379 384 while (i<size){385 if (!USB_HID_ITEM_IS_LONG(data[i])){386 387 if ((i+USB_HID_ITEM_SIZE(data[i]))>= size){380 while (i < size) { 381 if (!USB_HID_ITEM_IS_LONG(data[i])) { 382 383 if ((i + USB_HID_ITEM_SIZE(data[i])) >= size) { 388 384 return EINVAL; 389 385 } … … 393 389 class = USB_HID_ITEM_TAG_CLASS(data[i]); 394 390 395 ret = usb_hid_report_parse_tag(tag, class,data+i+1,396 item_size,report_item, usage_path);397 398 switch (ret){391 ret = usb_hid_report_parse_tag(tag, class, data + i + 1, 392 item_size, report_item, usage_path); 393 394 switch (ret) { 399 395 case USB_HID_NEW_REPORT_ITEM: 400 396 /* store report item to report and create the … … 404 400 405 401 usb_hid_report_path_set_report_id( 406 407 408 if (report_item->id != 0){402 report_item->usage_path, report_item->id); 403 404 if (report_item->id != 0) { 409 405 report->use_report_ids = 1; 410 406 } 411 407 412 switch (tag) {408 switch (tag) { 413 409 case USB_HID_REPORT_TAG_INPUT: 414 410 report_item->type = … … 435 431 report_item->offset = offset_feature; 436 432 offset_feature += report_item->count * 437 433 report_item->size; 438 434 break; 439 435 … … 441 437 usb_log_debug2( 442 438 "\tjump over - tag %X\n", tag); 443 439 break; 444 440 } 445 441 … … 508 504 /* jump over the processed block */ 509 505 i += 1 + USB_HID_ITEM_SIZE(data[i]); 510 } 511 else{ 506 } else { 512 507 // TBD 513 i += 3 + USB_HID_ITEM_SIZE(data[i +1]);508 i += 3 + USB_HID_ITEM_SIZE(data[i + 1]); 514 509 } 515 510 … … 532 527 */ 533 528 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, 534 size_t item_size, usb_hid_report_item_t *report_item, 535 usb_hid_report_path_t *usage_path) { 529 size_t item_size, usb_hid_report_item_t *report_item, 530 usb_hid_report_path_t *usage_path) 531 { 536 532 537 533 int ret; 538 534 539 switch (class){535 switch (class) { 540 536 case USB_HID_TAG_CLASS_MAIN: 541 537 542 if ((ret=usb_hid_report_parse_main_tag(tag, data, item_size,543 538 if ((ret = usb_hid_report_parse_main_tag(tag, data, item_size, 539 report_item, usage_path)) == 0) { 544 540 545 541 return USB_HID_NEW_REPORT_ITEM; 546 } 547 else { 542 } else { 548 543 return ret; 549 544 } … … 552 547 case USB_HID_TAG_CLASS_GLOBAL: 553 548 return usb_hid_report_parse_global_tag(tag, data, item_size, 554 549 report_item, usage_path); 555 550 break; 556 551 557 552 case USB_HID_TAG_CLASS_LOCAL: 558 553 return usb_hid_report_parse_local_tag(tag, data, item_size, 559 554 report_item, usage_path); 560 555 break; 561 556 … … 576 571 577 572 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, 578 579 573 size_t item_size, usb_hid_report_item_t *report_item, 574 usb_hid_report_path_t *usage_path) 580 575 { 581 576 usb_hid_report_usage_path_t *path_item; 582 577 583 switch(tag) 584 { 578 switch (tag) { 585 579 case USB_HID_REPORT_TAG_INPUT: 586 580 case USB_HID_REPORT_TAG_OUTPUT: … … 594 588 /* store collection atributes */ 595 589 path_item = list_get_instance(list_first(&usage_path->items), 596 590 usb_hid_report_usage_path_t, rpath_items_link); 597 591 path_item->flags = *data; 598 592 599 593 /* set last item */ 600 594 usb_hid_report_set_last_item(usage_path, 601 USB_HID_TAG_CLASS_GLOBAL, 602 USB_HID_EXTENDED_USAGE_PAGE(report_item->usages[ 603 report_item->usages_count-1])); 595 USB_HID_TAG_CLASS_GLOBAL, 596 USB_HID_EXTENDED_USAGE_PAGE(report_item->usages[report_item->usages_count - 1])); 604 597 605 598 usb_hid_report_set_last_item(usage_path, 606 USB_HID_TAG_CLASS_LOCAL, 607 USB_HID_EXTENDED_USAGE(report_item->usages[ 608 report_item->usages_count-1])); 599 USB_HID_TAG_CLASS_LOCAL, 600 USB_HID_EXTENDED_USAGE(report_item->usages[report_item->usages_count - 1])); 609 601 610 602 /* append the new one which will be set by common usage/usage 611 603 * page */ 612 604 usb_hid_report_path_append_item(usage_path, 613 614 report_item->usages[report_item->usages_count-1]);605 report_item->usage_page, 606 report_item->usages[report_item->usages_count - 1]); 615 607 616 608 usb_hid_report_reset_local_items (report_item); … … 640 632 */ 641 633 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, 642 643 usb_hid_report_path_t *usage_path) { 644 645 switch(tag) 646 {634 size_t item_size, usb_hid_report_item_t *report_item, 635 usb_hid_report_path_t *usage_path) 636 { 637 638 switch (tag) { 647 639 case USB_HID_REPORT_TAG_USAGE_PAGE: 648 640 report_item->usage_page = 649 641 usb_hid_report_tag_data_uint32(data, item_size); 650 642 break; 651 643 652 644 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM: 653 645 report_item->logical_minimum = USB_HID_UINT32_TO_INT32( 654 usb_hid_report_tag_data_uint32(data,item_size),655 646 usb_hid_report_tag_data_uint32(data, item_size), 647 item_size * 8); 656 648 break; 657 649 658 650 case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM: 659 651 report_item->logical_maximum = USB_HID_UINT32_TO_INT32( 660 usb_hid_report_tag_data_uint32(data,item_size),661 652 usb_hid_report_tag_data_uint32(data, item_size), 653 item_size * 8); 662 654 break; 663 655 664 656 case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM: 665 657 report_item->physical_minimum = USB_HID_UINT32_TO_INT32( 666 usb_hid_report_tag_data_uint32(data,item_size),667 658 usb_hid_report_tag_data_uint32(data, item_size), 659 item_size * 8); 668 660 break; 669 661 670 662 case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM: 671 663 report_item->physical_maximum = USB_HID_UINT32_TO_INT32( 672 usb_hid_report_tag_data_uint32(data,item_size),673 664 usb_hid_report_tag_data_uint32(data, item_size), 665 item_size * 8); 674 666 break; 675 667 676 668 case USB_HID_REPORT_TAG_UNIT_EXPONENT: 677 669 report_item->unit_exponent = usb_hid_report_tag_data_uint32( 678 data,item_size);670 data, item_size); 679 671 break; 680 672 681 673 case USB_HID_REPORT_TAG_UNIT: 682 674 report_item->unit = usb_hid_report_tag_data_uint32( 683 data,item_size);675 data, item_size); 684 676 break; 685 677 686 678 case USB_HID_REPORT_TAG_REPORT_SIZE: 687 679 report_item->size = usb_hid_report_tag_data_uint32( 688 data,item_size);680 data, item_size); 689 681 break; 690 682 691 683 case USB_HID_REPORT_TAG_REPORT_COUNT: 692 684 report_item->count = usb_hid_report_tag_data_uint32( 693 data,item_size);685 data, item_size); 694 686 break; 695 687 696 688 case USB_HID_REPORT_TAG_REPORT_ID: 697 689 report_item->id = usb_hid_report_tag_data_uint32(data, 698 690 item_size); 699 691 return USB_HID_RESET_OFFSET; 700 692 break; … … 785 777 report_item->extended_usage_page = 786 778 USB_HID_EXTENDED_USAGE_PAGE( 787 usb_hid_report_tag_data_uint32(data, item_size));779 usb_hid_report_tag_data_uint32(data, item_size)); 788 780 789 781 report_item->usage_maximum = 790 782 USB_HID_EXTENDED_USAGE( 791 usb_hid_report_tag_data_uint32(data, item_size));783 usb_hid_report_tag_data_uint32(data, item_size)); 792 784 } else { 793 785 report_item->usage_maximum = 794 usb_hid_report_tag_data_uint32(data, item_size);786 usb_hid_report_tag_data_uint32(data, item_size); 795 787 } 796 788 … … 866 858 867 859 result = 0; 868 for (i=0; i<size; i++) {869 result = (result | (data[i]) << (i *8));860 for (i = 0; i < size; i++) { 861 result = (result | (data[i]) << (i * 8)); 870 862 } 871 863 … … 882 874 void usb_hid_descriptor_print_list(list_t *list) 883 875 { 884 if (list == NULL || list_empty(list)) {885 886 887 } 888 889 890 876 if (list == NULL || list_empty(list)) { 877 usb_log_debug("\tempty"); 878 return; 879 } 880 881 list_foreach(*list, ritems_link, usb_hid_report_field_t, 882 report_item) { 891 883 usb_log_debug("\t\tOFFSET: %u", report_item->offset); 892 884 usb_log_debug("\t\tSIZE: %zu", report_item->size); 893 885 usb_log_debug("\t\tLOGMIN: %d", 894 886 report_item->logical_minimum); 895 887 usb_log_debug("\t\tLOGMAX: %d", 896 888 report_item->logical_maximum); 897 889 usb_log_debug("\t\tPHYMIN: %d", 898 890 report_item->physical_minimum); 899 891 usb_log_debug("\t\tPHYMAX: %d", 900 892 report_item->physical_maximum); 901 893 usb_log_debug("\t\ttUSAGEMIN: %X", 902 894 report_item->usage_minimum); 903 895 usb_log_debug("\t\tUSAGEMAX: %X", 904 896 report_item->usage_maximum); 905 897 usb_log_debug("\t\tUSAGES COUNT: %zu", 906 898 report_item->usages_count); 907 899 908 900 usb_log_debug("\t\tVALUE: %X", report_item->value); … … 932 924 usb_log_debug("\tLength: %zu", report_des->bit_length); 933 925 usb_log_debug("\tB Size: %zu", 934 935 936 926 usb_hid_report_byte_size(report, 927 report_des->report_id, 928 report_des->type)); 937 929 usb_log_debug("\tItems: %zu", report_des->item_length); 938 930 … … 950 942 void usb_hid_report_deinit(usb_hid_report_t *report) 951 943 { 952 if (report == NULL){944 if (report == NULL) { 953 945 return; 954 946 } … … 957 949 link_t *path_link; 958 950 usb_hid_report_path_t *path; 959 while (!list_empty(&report->collection_paths)) {951 while (!list_empty(&report->collection_paths)) { 960 952 path_link = list_first(&report->collection_paths); 961 953 path = list_get_instance(path_link, … … 969 961 usb_hid_report_description_t *report_des; 970 962 usb_hid_report_field_t *field; 971 while (!list_empty(&report->reports)) {963 while (!list_empty(&report->reports)) { 972 964 report_des = list_get_instance(list_first(&report->reports), 973 965 usb_hid_report_description_t, reports_link); 974 966 975 967 list_remove(&report_des->reports_link); 976 968 977 while (!list_empty(&report_des->report_items)) {969 while (!list_empty(&report_des->report_items)) { 978 970 field = list_get_instance( 979 971 list_first(&report_des->report_items),
Note:
See TracChangeset
for help on using the changeset viewer.