Changeset b53d3b7 in mainline
- Timestamp:
- 2011-03-25T13:40:00Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 8c40822, 96bfe76
- Parents:
- 55e388a1
- Location:
- uspace
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbhid/kbddev.c
r55e388a1 rb53d3b7 585 585 // int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size, 586 586 // callbacks, kbd_dev); 587 usb_hid_report_path_t *path = usb_hid_report_path(); 588 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0); 589 587 590 int rc = usb_hid_parse_report(kbd_dev->hid_dev->parser, buffer, 588 actual_size, callbacks, kbd_dev); 591 actual_size, path, USB_HID_PATH_COMPARE_STRICT, callbacks, kbd_dev); 592 593 usb_hid_report_path_free (path); 589 594 590 595 if (rc != EOK) { … … 694 699 // kbd_dev->key_count = BOOTP_REPORT_SIZE; 695 700 696 usb_hid_report_path_t path; 697 path.usage_page = USB_HIDUT_PAGE_KEYBOARD; 701 usb_hid_report_path_t *path; 702 path = usb_hid_report_path(); 703 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0); 698 704 kbd_dev->key_count = usb_hid_report_input_length( 699 kbd_dev->hid_dev->parser, &path); 705 kbd_dev->hid_dev->parser, path, USB_HID_PATH_COMPARE_STRICT); 706 usb_hid_report_path_free (path); 700 707 701 708 usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count); -
uspace/lib/usb/include/usb/classes/hidparser.h
r55e388a1 rb53d3b7 70 70 * Description of path of usage pages and usages in report descriptor 71 71 */ 72 #define USB_HID_PATH_COMPARE_STRICT 0 73 #define USB_HID_PATH_COMPARE_END 1 74 #define USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY 4 75 72 76 typedef struct { 73 77 int32_t usage_page; 78 int32_t usage; 79 80 link_t link; 81 } usb_hid_report_usage_path_t; 82 83 typedef struct { 84 int depth; 85 link_t link; 74 86 } usb_hid_report_path_t; 75 87 … … 79 91 typedef struct { 80 92 int32_t id; 81 int32_t usage_page;82 int32_t usage;83 93 int32_t usage_minimum; 84 94 int32_t usage_maximum; … … 107 117 uint8_t item_flags; 108 118 119 usb_hid_report_path_t *usage_path; 109 120 link_t link; 110 121 } usb_hid_report_item_t; … … 117 128 link_t feature; 118 129 } usb_hid_report_parser_t; 119 120 130 121 131 … … 194 204 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 195 205 const uint8_t *data, size_t size, 206 usb_hid_report_path_t *path, int flags, 196 207 const usb_hid_report_in_callbacks_t *callbacks, void *arg); 197 208 198 209 int usb_hid_report_input_length(const usb_hid_report_parser_t *parser, 199 const usb_hid_report_path_t *path);210 usb_hid_report_path_t *path, int flags); 200 211 201 212 … … 204 215 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser); 205 216 217 /* usage path functions */ 218 usb_hid_report_path_t *usb_hid_report_path(void); 219 void usb_hid_report_path_free(usb_hid_report_path_t *path); 220 int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path, int32_t usage_page, int32_t usage); 221 void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path); 222 void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path); 223 void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, int32_t tag, int32_t data); 224 int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path, usb_hid_report_path_t *path, int flags); 225 int usb_hid_report_path_clone(usb_hid_report_path_t *new_usage_path, usb_hid_report_path_t *usage_path); 226 227 228 // output 229 // - funkce co vrati cesty poli v output reportu 230 // - funkce co pro danou cestu nastavi data 231 // - finalize 232 206 233 #endif 207 234 /** -
uspace/lib/usb/src/hidparser.c
r55e388a1 rb53d3b7 47 47 48 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 );49 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); 50 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 );51 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); 52 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 );53 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); 54 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 );55 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); 56 56 57 57 void usb_hid_descriptor_print_list(link_t *head); … … 63 63 int usb_pow(int a, int b); 64 64 65 65 66 int usb_pow(int a, int b) 66 67 { … … 110 111 int ret; 111 112 usb_hid_report_item_t *report_item=0; 112 usb_hid_report_item_t *new_report_item; 113 usb_hid_report_item_t *new_report_item; 114 usb_hid_report_path_t *usage_path; 115 usb_hid_report_path_t *tmp_usage_path; 113 116 114 117 size_t offset_input=0; 115 118 size_t offset_output=0; 116 119 size_t offset_feature=0; 117 120 121 122 /* parser structure initialization*/ 118 123 if(usb_hid_parser_init(parser) != EOK) { 119 124 return EINVAL; … … 121 126 122 127 128 /*report item initialization*/ 123 129 if(!(report_item=malloc(sizeof(usb_hid_report_item_t)))){ 124 130 return ENOMEM; 125 131 } 126 132 memset(report_item, 0, sizeof(usb_hid_report_item_t)); 127 128 link_initialize(&(report_item->link)); 129 133 list_initialize(&(report_item->link)); 134 135 /* usage path context initialization */ 136 if(!(usage_path=usb_hid_report_path())){ 137 return ENOMEM; 138 } 139 130 140 while(i<size){ 131 141 if(!USB_HID_ITEM_IS_LONG(data[i])){ … … 145 155 146 156 ret = usb_hid_report_parse_tag(tag,class,data+i+1, 147 item_size,report_item);157 item_size,report_item, usage_path); 148 158 usb_log_debug2("ret: %u\n", ret); 149 159 switch(ret){ 150 160 case USB_HID_NEW_REPORT_ITEM: 151 161 // store report item to report and create the new one 152 usb_log_debug("\nNEW REPORT ITEM: %X",tag); 162 usb_log_debug("\nNEW REPORT ITEM: %X",ret); 163 164 // store current usage path 165 report_item->usage_path = usage_path; 166 167 // new current usage path 168 tmp_usage_path = usb_hid_report_path(); 169 170 // copy old path to the new one 171 usb_hid_report_path_clone(tmp_usage_path, usage_path); 172 173 // swap 174 usage_path = tmp_usage_path; 175 tmp_usage_path = NULL; 176 153 177 154 178 switch(tag) { … … 188 212 link_initialize(&(new_report_item->link)); 189 213 report_item = new_report_item; 190 214 191 215 break; 192 216 case USB_HID_REPORT_TAG_PUSH: … … 288 312 */ 289 313 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size, 290 usb_hid_report_item_t *report_item )314 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 291 315 { 292 316 int ret; … … 295 319 case USB_HID_TAG_CLASS_MAIN: 296 320 297 if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item )) == EOK) {321 if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item, usage_path)) == EOK) { 298 322 return USB_HID_NEW_REPORT_ITEM; 299 323 } … … 305 329 306 330 case USB_HID_TAG_CLASS_GLOBAL: 307 return usb_hid_report_parse_global_tag(tag,data,item_size,report_item );331 return usb_hid_report_parse_global_tag(tag,data,item_size,report_item, usage_path); 308 332 break; 309 333 310 334 case USB_HID_TAG_CLASS_LOCAL: 311 return usb_hid_report_parse_local_tag(tag,data,item_size,report_item );335 return usb_hid_report_parse_local_tag(tag,data,item_size,report_item, usage_path); 312 336 break; 313 337 default: … … 327 351 328 352 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size, 329 usb_hid_report_item_t *report_item )330 { 353 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 354 { 331 355 switch(tag) 332 356 { … … 339 363 340 364 case USB_HID_REPORT_TAG_COLLECTION: 341 // TODO 365 usb_hid_report_path_append_item(usage_path, 0, 0); 366 342 367 return USB_HID_NO_ACTION; 343 368 break; 344 369 345 370 case USB_HID_REPORT_TAG_END_COLLECTION: 346 /* should be ignored */ 371 // TODO 372 // znici posledni uroven ve vsech usage paths 373 // otazka jestli nema nicit dve, respektive novou posledni vynulovat? 374 usb_hid_report_remove_last_item(usage_path); 347 375 return USB_HID_NO_ACTION; 348 376 break; … … 365 393 366 394 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size, 367 usb_hid_report_item_t *report_item )395 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 368 396 { 369 397 // TODO take care about the bit length of data … … 371 399 { 372 400 case USB_HID_REPORT_TAG_USAGE_PAGE: 373 report_item->usage_page = usb_hid_report_tag_data_int32(data,item_size); 401 // zmeni to jenom v poslednim poli aktualni usage path 402 usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL, 403 usb_hid_report_tag_data_int32(data,item_size)); 374 404 break; 375 405 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM: … … 422 452 */ 423 453 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size, 424 usb_hid_report_item_t *report_item )454 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 425 455 { 426 456 switch(tag) 427 457 { 428 458 case USB_HID_REPORT_TAG_USAGE: 429 report_item->usage = usb_hid_report_tag_data_int32(data,item_size); 459 usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL, 460 usb_hid_report_tag_data_int32(data,item_size)); 430 461 break; 431 462 case USB_HID_REPORT_TAG_USAGE_MINIMUM: … … 495 526 { 496 527 usb_hid_report_item_t *report_item; 528 usb_hid_report_usage_path_t *path_item; 529 link_t *path; 497 530 link_t *item; 498 531 … … 511 544 usb_log_debug("\tCONSTANT/VAR: %X\n", USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags)); 512 545 usb_log_debug("\tVARIABLE/ARRAY: %X\n", USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags)); 513 usb_log_debug("\tUSAGE: %X\n", report_item->usage); 514 usb_log_debug("\tUSAGE PAGE: %X\n", report_item->usage_page); 546 usb_log_debug("\tUSAGE PATH:\n"); 547 548 path = report_item->usage_path->link.next; 549 while(path != &report_item->usage_path->link) { 550 path_item = list_get_instance(path, usb_hid_report_usage_path_t, link); 551 usb_log_debug("\t\tUSAGE PAGE: %X, USAGE: %X\n", path_item->usage_page, path_item->usage); 552 path = path->next; 553 } 554 555 556 // usb_log_debug("\tUSAGE: %X\n", report_item->usage); 557 // usb_log_debug("\tUSAGE PAGE: %X\n", report_item->usage_page); 515 558 usb_log_debug("\tLOGMIN: %X\n", report_item->logical_minimum); 516 559 usb_log_debug("\tLOGMAX: %X\n", report_item->logical_maximum); … … 569 612 570 613 report_item = list_get_instance(next, usb_hid_report_item_t, link); 614 615 while(!list_empty(&report_item->usage_path->link)) { 616 usb_hid_report_remove_last_item(report_item->usage_path); 617 } 618 619 571 620 next = next->next; 572 621 … … 608 657 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 609 658 const uint8_t *data, size_t size, 659 usb_hid_report_path_t *path, int flags, 610 660 const usb_hid_report_in_callbacks_t *callbacks, void *arg) 611 661 { … … 629 679 630 680 // get the size of result keycodes array 631 usb_hid_report_path_t path; 632 path.usage_page = BAD_HACK_USAGE_PAGE; 633 key_count = usb_hid_report_input_length(parser, &path); 681 key_count = usb_hid_report_input_length(parser, path, flags); 634 682 635 683 if(!(keys = malloc(sizeof(uint8_t) * key_count))){ … … 642 690 643 691 item = list_get_instance(list_item, usb_hid_report_item_t, link); 644 if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) && 645 ( item->usage_page == path.usage_page)) {692 if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) && 693 (usb_hid_report_compare_usage_path(item->usage_path, path, flags) == EOK)) { 646 694 for(j=0; j<(size_t)(item->count); j++) { 647 695 if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0) || … … 653 701 // bitmapa 654 702 if((item_value = usb_hid_translate_data(item, data, j)) != 0) { 655 keys[i++] = j+ item->usage_minimum;703 keys[i++] = (item->count - 1 - j) + item->usage_minimum; 656 704 } 657 705 else { … … 749 797 750 798 int usb_hid_report_input_length(const usb_hid_report_parser_t *parser, 751 const usb_hid_report_path_t *path)799 usb_hid_report_path_t *path, int flags) 752 800 { 753 801 int ret = 0; … … 763 811 report_item = list_get_instance(item, usb_hid_report_item_t, link); 764 812 if(!USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags) && 765 ( report_item->usage_page == path->usage_page)) {813 (usb_hid_report_compare_usage_path(report_item->usage_path, path, flags) == EOK)) { 766 814 ret += report_item->count; 767 815 } … … 774 822 775 823 824 /** 825 * 826 */ 827 int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path, 828 int32_t usage_page, int32_t usage) 829 { 830 usb_hid_report_usage_path_t *item; 831 832 if(!(item=malloc(sizeof(usb_hid_report_usage_path_t)))) { 833 return ENOMEM; 834 } 835 list_initialize(&item->link); 836 837 item->usage = usage; 838 item->usage_page = usage_page; 839 840 list_append (&usage_path->link, &item->link); 841 usage_path->depth++; 842 return EOK; 843 } 844 845 /** 846 * 847 */ 848 void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path) 849 { 850 usb_hid_report_usage_path_t *item; 851 852 if(!list_empty(&usage_path->link)){ 853 item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link); 854 list_remove(usage_path->link.prev); 855 usage_path->depth--; 856 free(item); 857 } 858 } 859 860 /** 861 * 862 */ 863 void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path) 864 { 865 usb_hid_report_usage_path_t *item; 866 867 if(!list_empty(&usage_path->link)){ 868 item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link); 869 memset(item, 0, sizeof(usb_hid_report_usage_path_t)); 870 } 871 } 872 873 /** 874 * 875 */ 876 void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, int32_t tag, int32_t data) 877 { 878 usb_hid_report_usage_path_t *item; 879 880 if(!list_empty(&usage_path->link)){ 881 item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link); 882 883 switch(tag) { 884 case USB_HID_TAG_CLASS_GLOBAL: 885 item->usage_page = data; 886 break; 887 case USB_HID_TAG_CLASS_LOCAL: 888 item->usage = data; 889 break; 890 } 891 } 892 893 } 894 895 /** 896 * 897 */ 898 int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path, 899 usb_hid_report_path_t *path, 900 int flags) 901 { 902 usb_hid_report_usage_path_t *report_item; 903 usb_hid_report_usage_path_t *path_item; 904 905 link_t *report_link; 906 link_t *path_link; 907 908 int only_page; 909 910 if(path->depth == 0){ 911 return EOK; 912 } 913 914 915 if((only_page = flags & USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY) != 0){ 916 flags -= USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY; 917 } 918 919 switch(flags){ 920 /* path must be completly identical */ 921 case USB_HID_PATH_COMPARE_STRICT: 922 if(report_path->depth != path->depth){ 923 return 1; 924 } 925 926 report_link = report_path->link.next; 927 path_link = path->link.next; 928 929 while((report_link != &report_path->link) && (path_link != &path->link)) { 930 report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link); 931 path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link); 932 933 if((report_item->usage_page != path_item->usage_page) || 934 ((only_page == 0) && (report_item->usage != path_item->usage))) { 935 return 1; 936 } else { 937 report_link = report_link->next; 938 path_link = path_link->next; 939 } 940 941 } 942 943 if((report_link == &report_path->link) && (path_link == &path->link)) { 944 return EOK; 945 } 946 else { 947 return 1; 948 } 949 break; 950 951 /* given path must be the end of the report one*/ 952 case USB_HID_PATH_COMPARE_END: 953 report_link = report_path->link.prev; 954 path_link = path->link.prev; 955 956 if(list_empty(&path->link)){ 957 return EOK; 958 } 959 960 while((report_link != &report_path->link) && (path_link != &path->link)) { 961 report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link); 962 path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link); 963 964 if((report_item->usage_page != path_item->usage_page) || 965 ((only_page == 0) && (report_item->usage != path_item->usage))) { 966 return 1; 967 } else { 968 report_link = report_link->prev; 969 path_link = path_link->prev; 970 } 971 972 } 973 974 if(path_link == &path->link) { 975 return EOK; 976 } 977 else { 978 return 1; 979 } 980 981 break; 982 983 default: 984 return EINVAL; 985 } 986 987 988 989 990 } 991 992 /** 993 * 994 */ 995 usb_hid_report_path_t *usb_hid_report_path(void) 996 { 997 usb_hid_report_path_t *path; 998 path = malloc(sizeof(usb_hid_report_path_t)); 999 if(!path){ 1000 return NULL; 1001 } 1002 else { 1003 path->depth = 0; 1004 list_initialize(&path->link); 1005 return path; 1006 } 1007 } 1008 1009 /** 1010 * 1011 */ 1012 void usb_hid_report_path_free(usb_hid_report_path_t *path) 1013 { 1014 while(!list_empty(&path->link)){ 1015 usb_hid_report_remove_last_item(path); 1016 } 1017 } 1018 1019 1020 /** 1021 * 1022 */ 1023 int usb_hid_report_path_clone(usb_hid_report_path_t *new_usage_path, usb_hid_report_path_t *usage_path) 1024 { 1025 usb_hid_report_usage_path_t *path_item; 1026 link_t *path_link; 1027 1028 1029 if(list_empty(&usage_path->link)){ 1030 return EOK; 1031 } 1032 1033 path_link = usage_path->link.next; 1034 while(path_link != &usage_path->link) { 1035 path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link); 1036 usb_hid_report_path_append_item (new_usage_path, path_item->usage_page, path_item->usage); 1037 1038 path_link = path_link->next; 1039 } 1040 1041 return EOK; 1042 } 1043 776 1044 777 1045 /**
Note:
See TracChangeset
for help on using the changeset viewer.