Changeset 8c40822 in mainline
- Timestamp:
- 2011-03-25T14:22:04Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0533b03
- Parents:
- 4acf099 (diff), b53d3b7 (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. - Location:
- uspace
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbkbd/kbddev.c
r4acf099 r8c40822 602 602 // int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size, 603 603 // callbacks, kbd_dev); 604 int rc = usb_hid_parse_report(kbd_dev->parser, buffer, 605 actual_size, callbacks, kbd_dev); 604 usb_hid_report_path_t *path = usb_hid_report_path(); 605 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0); 606 607 int rc = usb_hid_parse_report(kbd_dev->hid_dev->parser, buffer, 608 actual_size, path, USB_HID_PATH_COMPARE_STRICT, callbacks, kbd_dev); 609 610 usb_hid_report_path_free (path); 606 611 607 612 if (rc != EOK) { … … 748 753 */ 749 754 usb_hid_report_path_t path; 750 path.usage_page = USB_HIDUT_PAGE_KEYBOARD; 755 path = usb_hid_report_path(); 756 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0); 751 757 kbd_dev->key_count = usb_hid_report_input_length( 752 kbd_dev->parser, &path); 758 kbd_dev->hid_dev->parser, path, USB_HID_PATH_COMPARE_STRICT); 759 usb_hid_report_path_free (path); 753 760 754 761 usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count); -
uspace/lib/usb/include/usb/classes/hidparser.h
r4acf099 r8c40822 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
r4acf099 r8c40822 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 { … … 84 85 { 85 86 if(parser == NULL) { 86 return -1;87 return EINVAL; 87 88 } 88 89 … … 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; … … 117 120 118 121 122 /* parser structure initialization*/ 123 if(usb_hid_parser_init(parser) != EOK) { 124 return EINVAL; 125 } 126 127 128 /*report item initialization*/ 119 129 if(!(report_item=malloc(sizeof(usb_hid_report_item_t)))){ 120 130 return ENOMEM; 121 131 } 122 132 memset(report_item, 0, sizeof(usb_hid_report_item_t)); 123 124 link_initialize(&(report_item->link)); 125 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 126 140 while(i<size){ 127 141 if(!USB_HID_ITEM_IS_LONG(data[i])){ 128 142 129 143 if((i+USB_HID_ITEM_SIZE(data[i]))>= size){ 130 return -1; // TODO ERROR CODE144 return EINVAL; // TODO ERROR CODE 131 145 } 132 146 … … 141 155 142 156 ret = usb_hid_report_parse_tag(tag,class,data+i+1, 143 item_size,report_item);157 item_size,report_item, usage_path); 144 158 usb_log_debug2("ret: %u\n", ret); 145 159 switch(ret){ 146 160 case USB_HID_NEW_REPORT_ITEM: 147 161 // store report item to report and create the new one 148 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 149 177 150 178 switch(tag) { … … 184 212 link_initialize(&(new_report_item->link)); 185 213 report_item = new_report_item; 186 214 187 215 break; 188 216 case USB_HID_REPORT_TAG_PUSH: … … 284 312 */ 285 313 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 )314 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 287 315 { 288 316 int ret; … … 291 319 case USB_HID_TAG_CLASS_MAIN: 292 320 293 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) { 294 322 return USB_HID_NEW_REPORT_ITEM; 295 323 } … … 301 329 302 330 case USB_HID_TAG_CLASS_GLOBAL: 303 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); 304 332 break; 305 333 306 334 case USB_HID_TAG_CLASS_LOCAL: 307 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); 308 336 break; 309 337 default: … … 323 351 324 352 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 { 353 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 354 { 327 355 switch(tag) 328 356 { … … 335 363 336 364 case USB_HID_REPORT_TAG_COLLECTION: 337 // TODO 365 usb_hid_report_path_append_item(usage_path, 0, 0); 366 338 367 return USB_HID_NO_ACTION; 339 368 break; 340 369 341 370 case USB_HID_REPORT_TAG_END_COLLECTION: 342 /* 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); 343 375 return USB_HID_NO_ACTION; 344 376 break; … … 361 393 362 394 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 )395 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 364 396 { 365 397 // TODO take care about the bit length of data … … 367 399 { 368 400 case USB_HID_REPORT_TAG_USAGE_PAGE: 369 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)); 370 404 break; 371 405 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM: … … 418 452 */ 419 453 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 )454 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 421 455 { 422 456 switch(tag) 423 457 { 424 458 case USB_HID_REPORT_TAG_USAGE: 425 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)); 426 461 break; 427 462 case USB_HID_REPORT_TAG_USAGE_MINIMUM: … … 491 526 { 492 527 usb_hid_report_item_t *report_item; 528 usb_hid_report_usage_path_t *path_item; 529 link_t *path; 493 530 link_t *item; 494 531 … … 507 544 usb_log_debug("\tCONSTANT/VAR: %X\n", USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags)); 508 545 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); 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); 511 558 usb_log_debug("\tLOGMIN: %X\n", report_item->logical_minimum); 512 559 usb_log_debug("\tLOGMAX: %X\n", report_item->logical_maximum); … … 530 577 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser) 531 578 { 579 if(parser == NULL) { 580 return; 581 } 582 532 583 usb_log_debug("INPUT:\n"); 533 584 usb_hid_descriptor_print_list(&parser->input); … … 561 612 562 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 563 620 next = next->next; 564 621 … … 600 657 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 601 658 const uint8_t *data, size_t size, 659 usb_hid_report_path_t *path, int flags, 602 660 const usb_hid_report_in_callbacks_t *callbacks, void *arg) 603 661 { … … 615 673 size_t j=0; 616 674 675 if(parser == NULL) { 676 return EINVAL; 677 } 678 679 617 680 // 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); 681 key_count = usb_hid_report_input_length(parser, path, flags); 621 682 622 683 if(!(keys = malloc(sizeof(uint8_t) * key_count))){ … … 629 690 630 691 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)) {692 if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) && 693 (usb_hid_report_compare_usage_path(item->usage_path, path, flags) == EOK)) { 633 694 for(j=0; j<(size_t)(item->count); j++) { 634 695 if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0) || … … 640 701 // bitmapa 641 702 if((item_value = usb_hid_translate_data(item, data, j)) != 0) { 642 keys[i++] = j+ item->usage_minimum;703 keys[i++] = (item->count - 1 - j) + item->usage_minimum; 643 704 } 644 705 else { … … 736 797 737 798 int usb_hid_report_input_length(const usb_hid_report_parser_t *parser, 738 const usb_hid_report_path_t *path)739 { 799 usb_hid_report_path_t *path, int flags) 800 { 740 801 int ret = 0; 741 802 link_t *item; 742 803 usb_hid_report_item_t *report_item; 743 804 805 if(parser == NULL) { 806 return EINVAL; 807 } 808 744 809 item = (&parser->input)->next; 745 810 while(&parser->input != item) { 746 811 report_item = list_get_instance(item, usb_hid_report_item_t, link); 747 812 if(!USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags) && 748 ( report_item->usage_page == path->usage_page)) {813 (usb_hid_report_compare_usage_path(report_item->usage_path, path, flags) == EOK)) { 749 814 ret += report_item->count; 750 815 } … … 757 822 758 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 759 1044 760 1045 /**
Note:
See TracChangeset
for help on using the changeset viewer.