Changes in uspace/lib/usb/src/hidparser.c [b53d3b7:c32688d] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/src/hidparser.c
rb53d3b7 rc32688d 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 , usb_hid_report_path_t *usage_path);49 usb_hid_report_item_t *report_item); 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 , usb_hid_report_path_t *usage_path);51 usb_hid_report_item_t *report_item); 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 , usb_hid_report_path_t *usage_path);53 usb_hid_report_item_t *report_item); 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 , usb_hid_report_path_t *usage_path);55 usb_hid_report_item_t *report_item); 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 66 65 int usb_pow(int a, int b) 67 66 { … … 85 84 { 86 85 if(parser == NULL) { 87 return EINVAL;86 return -1; 88 87 } 89 88 … … 111 110 int ret; 112 111 usb_hid_report_item_t *report_item=0; 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; 112 usb_hid_report_item_t *new_report_item; 116 113 117 114 size_t offset_input=0; … … 120 117 121 118 122 /* parser structure initialization*/123 if(usb_hid_parser_init(parser) != EOK) {124 return EINVAL;125 }126 127 128 /*report item initialization*/129 119 if(!(report_item=malloc(sizeof(usb_hid_report_item_t)))){ 130 120 return ENOMEM; 131 121 } 132 122 memset(report_item, 0, sizeof(usb_hid_report_item_t)); 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 123 124 link_initialize(&(report_item->link)); 125 140 126 while(i<size){ 141 127 if(!USB_HID_ITEM_IS_LONG(data[i])){ 142 128 143 129 if((i+USB_HID_ITEM_SIZE(data[i]))>= size){ 144 return EINVAL; // TODO ERROR CODE130 return -1; // TODO ERROR CODE 145 131 } 146 132 … … 155 141 156 142 ret = usb_hid_report_parse_tag(tag,class,data+i+1, 157 item_size,report_item, usage_path);143 item_size,report_item); 158 144 usb_log_debug2("ret: %u\n", ret); 159 145 switch(ret){ 160 146 case USB_HID_NEW_REPORT_ITEM: 161 147 // store report item to report and create the new one 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 148 usb_log_debug("\nNEW REPORT ITEM: %X",tag); 177 149 178 150 switch(tag) { … … 212 184 link_initialize(&(new_report_item->link)); 213 185 report_item = new_report_item; 214 186 215 187 break; 216 188 case USB_HID_REPORT_TAG_PUSH: … … 312 284 */ 313 285 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size, 314 usb_hid_report_item_t *report_item , usb_hid_report_path_t *usage_path)286 usb_hid_report_item_t *report_item) 315 287 { 316 288 int ret; … … 319 291 case USB_HID_TAG_CLASS_MAIN: 320 292 321 if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item , usage_path)) == EOK) {293 if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item)) == EOK) { 322 294 return USB_HID_NEW_REPORT_ITEM; 323 295 } … … 329 301 330 302 case USB_HID_TAG_CLASS_GLOBAL: 331 return usb_hid_report_parse_global_tag(tag,data,item_size,report_item , usage_path);303 return usb_hid_report_parse_global_tag(tag,data,item_size,report_item); 332 304 break; 333 305 334 306 case USB_HID_TAG_CLASS_LOCAL: 335 return usb_hid_report_parse_local_tag(tag,data,item_size,report_item , usage_path);307 return usb_hid_report_parse_local_tag(tag,data,item_size,report_item); 336 308 break; 337 309 default: … … 351 323 352 324 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size, 353 usb_hid_report_item_t *report_item , usb_hid_report_path_t *usage_path)354 { 325 usb_hid_report_item_t *report_item) 326 { 355 327 switch(tag) 356 328 { … … 363 335 364 336 case USB_HID_REPORT_TAG_COLLECTION: 365 usb_hid_report_path_append_item(usage_path, 0, 0); 366 337 // TODO 367 338 return USB_HID_NO_ACTION; 368 339 break; 369 340 370 341 case USB_HID_REPORT_TAG_END_COLLECTION: 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); 342 /* should be ignored */ 375 343 return USB_HID_NO_ACTION; 376 344 break; … … 393 361 394 362 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size, 395 usb_hid_report_item_t *report_item , usb_hid_report_path_t *usage_path)363 usb_hid_report_item_t *report_item) 396 364 { 397 365 // TODO take care about the bit length of data … … 399 367 { 400 368 case USB_HID_REPORT_TAG_USAGE_PAGE: 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)); 369 report_item->usage_page = usb_hid_report_tag_data_int32(data,item_size); 404 370 break; 405 371 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM: … … 452 418 */ 453 419 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size, 454 usb_hid_report_item_t *report_item , usb_hid_report_path_t *usage_path)420 usb_hid_report_item_t *report_item) 455 421 { 456 422 switch(tag) 457 423 { 458 424 case USB_HID_REPORT_TAG_USAGE: 459 usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL, 460 usb_hid_report_tag_data_int32(data,item_size)); 425 report_item->usage = usb_hid_report_tag_data_int32(data,item_size); 461 426 break; 462 427 case USB_HID_REPORT_TAG_USAGE_MINIMUM: … … 526 491 { 527 492 usb_hid_report_item_t *report_item; 528 usb_hid_report_usage_path_t *path_item;529 link_t *path;530 493 link_t *item; 531 494 … … 544 507 usb_log_debug("\tCONSTANT/VAR: %X\n", USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags)); 545 508 usb_log_debug("\tVARIABLE/ARRAY: %X\n", USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags)); 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); 509 usb_log_debug("\tUSAGE: %X\n", report_item->usage); 510 usb_log_debug("\tUSAGE PAGE: %X\n", report_item->usage_page); 558 511 usb_log_debug("\tLOGMIN: %X\n", report_item->logical_minimum); 559 512 usb_log_debug("\tLOGMAX: %X\n", report_item->logical_maximum); … … 577 530 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser) 578 531 { 579 if(parser == NULL) {580 return;581 }582 583 532 usb_log_debug("INPUT:\n"); 584 533 usb_hid_descriptor_print_list(&parser->input); … … 612 561 613 562 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 620 563 next = next->next; 621 564 … … 657 600 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 658 601 const uint8_t *data, size_t size, 659 usb_hid_report_path_t *path, int flags,660 602 const usb_hid_report_in_callbacks_t *callbacks, void *arg) 661 603 { … … 673 615 size_t j=0; 674 616 675 if(parser == NULL) {676 return EINVAL;677 }678 679 680 617 // get the size of result keycodes array 681 key_count = usb_hid_report_input_length(parser, path, flags); 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); 682 621 683 622 if(!(keys = malloc(sizeof(uint8_t) * key_count))){ … … 690 629 691 630 item = list_get_instance(list_item, usb_hid_report_item_t, link); 692 if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) && 693 ( usb_hid_report_compare_usage_path(item->usage_path, path, flags) == EOK)) {631 if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) && 632 (item->usage_page == path.usage_page)) { 694 633 for(j=0; j<(size_t)(item->count); j++) { 695 634 if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0) || … … 701 640 // bitmapa 702 641 if((item_value = usb_hid_translate_data(item, data, j)) != 0) { 703 keys[i++] = (item->count - 1 - j)+ item->usage_minimum;642 keys[i++] = j + item->usage_minimum; 704 643 } 705 644 else { … … 797 736 798 737 int usb_hid_report_input_length(const usb_hid_report_parser_t *parser, 799 usb_hid_report_path_t *path, int flags)800 { 738 const usb_hid_report_path_t *path) 739 { 801 740 int ret = 0; 802 741 link_t *item; 803 742 usb_hid_report_item_t *report_item; 804 743 805 if(parser == NULL) {806 return EINVAL;807 }808 809 744 item = (&parser->input)->next; 810 745 while(&parser->input != item) { 811 746 report_item = list_get_instance(item, usb_hid_report_item_t, link); 812 747 if(!USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags) && 813 ( usb_hid_report_compare_usage_path(report_item->usage_path, path, flags) == EOK)) {748 (report_item->usage_page == path->usage_page)) { 814 749 ret += report_item->count; 815 750 } … … 822 757 823 758 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 1044 759 1045 760 /**
Note:
See TracChangeset
for help on using the changeset viewer.