Changes in / [152ec79:9e929a0] in mainline
- Location:
- uspace
- Files:
-
- 2 added
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbhid/Makefile
r152ec79 r9e929a0 47 47 mouse/mousedev.c \ 48 48 lgtch-ultrax/lgtch-ultrax.c \ 49 lgtch-ultrax/keymap.c \ 49 50 $(STOLEN_LAYOUT_SOURCES) 50 51 -
uspace/drv/usbhid/kbd/conv.c
r152ec79 r9e929a0 99 99 [0x30] = KC_RBRACKET, 100 100 [0x31] = KC_BACKSLASH, 101 //[0x32] = KC_, // TODO: HASH??? maybe some as 0x31 - backslash 101 //[0x32] = KC_, // TODO: HASH??? maybe same as 0x31 - backslash 102 [0x32] = KC_BACKSLASH, 102 103 [0x33] = KC_SEMICOLON, 103 104 [0x34] = KC_QUOTE, // same as APOSTROPHE? (') -
uspace/drv/usbhid/kbd/kbddev.c
r152ec79 r9e929a0 177 177 /*----------------------------------------------------------------------------*/ 178 178 179 static void usb_kbd_process_keycodes(const uint8_t *key_codes, size_t count,180 uint8_t report_id, void *arg);181 182 static const usb_hid_report_in_callbacks_t usb_kbd_parser_callbacks = {183 .keyboard = usb_kbd_process_keycodes184 };179 //static void usb_kbd_process_keycodes(const uint8_t *key_codes, size_t count, 180 // uint8_t report_id, void *arg); 181 182 //static const usb_hid_report_in_callbacks_t usb_kbd_parser_callbacks = { 183 // .keyboard = usb_kbd_process_keycodes 184 //}; 185 185 186 186 /*----------------------------------------------------------------------------*/ … … 203 203 /*----------------------------------------------------------------------------*/ 204 204 /** Mapping of USB modifier key codes to generic modifier key codes. */ 205 static const keycode_t usbhid_modifiers_keycodes[USB_HID_MOD_COUNT] = {206 KC_LCTRL, /* USB_HID_MOD_LCTRL */207 KC_LSHIFT, /* USB_HID_MOD_LSHIFT */208 KC_LALT, /* USB_HID_MOD_LALT */209 0, /* USB_HID_MOD_LGUI */210 KC_RCTRL, /* USB_HID_MOD_RCTRL */211 KC_RSHIFT, /* USB_HID_MOD_RSHIFT */212 KC_RALT, /* USB_HID_MOD_RALT */213 0, /* USB_HID_MOD_RGUI */214 };215 216 typedef enum usbhid_lock_code {217 USB_KBD_LOCK_NUM = 0x53,218 USB_KBD_LOCK_CAPS = 0x39,219 USB_KBD_LOCK_SCROLL = 0x47,220 USB_KBD_LOCK_COUNT = 3221 } usbhid_lock_code;222 223 static const usbhid_lock_code usbhid_lock_codes[USB_KBD_LOCK_COUNT] = {224 USB_KBD_LOCK_NUM,225 USB_KBD_LOCK_CAPS,226 USB_KBD_LOCK_SCROLL227 };205 //static const keycode_t usbhid_modifiers_keycodes[USB_HID_MOD_COUNT] = { 206 // KC_LCTRL, /* USB_HID_MOD_LCTRL */ 207 // KC_LSHIFT, /* USB_HID_MOD_LSHIFT */ 208 // KC_LALT, /* USB_HID_MOD_LALT */ 209 // 0, /* USB_HID_MOD_LGUI */ 210 // KC_RCTRL, /* USB_HID_MOD_RCTRL */ 211 // KC_RSHIFT, /* USB_HID_MOD_RSHIFT */ 212 // KC_RALT, /* USB_HID_MOD_RALT */ 213 // 0, /* USB_HID_MOD_RGUI */ 214 //}; 215 216 //typedef enum usbhid_lock_code { 217 // USB_KBD_LOCK_NUM = 0x53, 218 // USB_KBD_LOCK_CAPS = 0x39, 219 // USB_KBD_LOCK_SCROLL = 0x47, 220 // USB_KBD_LOCK_COUNT = 3 221 //} usbhid_lock_code; 222 223 //static const usbhid_lock_code usbhid_lock_codes[USB_KBD_LOCK_COUNT] = { 224 // USB_KBD_LOCK_NUM, 225 // USB_KBD_LOCK_CAPS, 226 // USB_KBD_LOCK_SCROLL 227 //}; 228 228 229 229 /*----------------------------------------------------------------------------*/ … … 299 299 return; 300 300 } 301 302 unsigned i = 0; 303 301 304 302 /* Reset the LED data. */ 305 303 memset(kbd_dev->led_data, 0, kbd_dev->led_output_size * sizeof(int32_t)); 306 307 if ((kbd_dev->mods & KM_NUM_LOCK) && (i < kbd_dev->led_output_size)) { 308 kbd_dev->led_data[i++] = USB_HID_LED_NUM_LOCK; 309 } 310 311 if ((kbd_dev->mods & KM_CAPS_LOCK) && (i < kbd_dev->led_output_size)) { 312 kbd_dev->led_data[i++] = USB_HID_LED_CAPS_LOCK; 313 } 314 315 if ((kbd_dev->mods & KM_SCROLL_LOCK) 316 && (i < kbd_dev->led_output_size)) { 317 kbd_dev->led_data[i++] = USB_HID_LED_SCROLL_LOCK; 318 } 319 320 // TODO: COMPOSE and KANA 321 322 usb_log_debug("Creating output report.\n"); 323 324 int rc = usb_hid_report_output_translate(hid_dev->parser, 325 kbd_dev->led_path, 326 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 327 kbd_dev->output_buffer, 328 kbd_dev->output_size, kbd_dev->led_data, kbd_dev->led_output_size); 304 usb_log_debug("Creating output report:\n"); 305 306 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 307 hid_dev->report, NULL, kbd_dev->led_path, 308 USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY | USB_HID_PATH_COMPARE_END, 309 USB_HID_REPORT_TYPE_OUTPUT); 310 311 while (field != NULL) { 312 313 if ((field->usage == USB_HID_LED_NUM_LOCK) 314 && (kbd_dev->mods & KM_NUM_LOCK)){ 315 field->value = 1; 316 } 317 318 if ((field->usage == USB_HID_LED_CAPS_LOCK) 319 && (kbd_dev->mods & KM_CAPS_LOCK)){ 320 field->value = 1; 321 } 322 323 if ((field->usage == USB_HID_LED_SCROLL_LOCK) 324 && (kbd_dev->mods & KM_SCROLL_LOCK)){ 325 field->value = 1; 326 } 327 328 field = usb_hid_report_get_sibling(hid_dev->report, field, 329 kbd_dev->led_path, USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY 330 | USB_HID_PATH_COMPARE_END, USB_HID_REPORT_TYPE_OUTPUT); 331 } 332 333 // TODO: what about the Report ID? 334 int rc = usb_hid_report_output_translate(hid_dev->report, 0, 335 kbd_dev->output_buffer, kbd_dev->output_size); 329 336 330 337 if (rc != EOK) { … … 485 492 */ 486 493 static void usb_kbd_check_key_changes(usb_hid_dev_t *hid_dev, 487 usb_kbd_t *kbd_dev , const uint8_t *key_codes, size_t count)494 usb_kbd_t *kbd_dev/*, const uint8_t *key_codes, size_t count*/) 488 495 { 489 496 unsigned int key; … … 499 506 */ 500 507 i = 0; 501 while (i < count && key_codes[i] != ERROR_ROLLOVER) {508 while (i < kbd_dev->key_count && kbd_dev->keys[i] != ERROR_ROLLOVER) { 502 509 ++i; 503 510 } 504 if (i != count) {511 if (i != kbd_dev->key_count) { 505 512 usb_log_debug("Phantom state occured.\n"); 506 513 // phantom state, do nothing 507 514 return; 508 515 } 509 510 /* TODO: quite dummy right now, think of better implementation */511 assert(count == kbd_dev->key_count);512 516 513 517 /* 514 518 * 1) Key releases 515 519 */ 516 for (j = 0; j < count; ++j) {520 for (j = 0; j < kbd_dev->key_count; ++j) { 517 521 // try to find the old key in the new key list 518 522 i = 0; 519 523 while (i < kbd_dev->key_count 520 && k ey_codes[i] != kbd_dev->keys[j]) {524 && kbd_dev->keys[i] != kbd_dev->keys_old[j]) { 521 525 ++i; 522 526 } 523 527 524 if (i == count) {528 if (i == kbd_dev->key_count) { 525 529 // not found, i.e. the key was released 526 key = usbhid_parse_scancode(kbd_dev->keys [j]);530 key = usbhid_parse_scancode(kbd_dev->keys_old[j]); 527 531 if (!usb_kbd_is_lock(key)) { 528 532 usb_kbd_repeat_stop(kbd_dev, key); … … 541 545 // try to find the new key in the old key list 542 546 j = 0; 543 while (j < count && kbd_dev->keys[j] != key_codes[i]) { 547 while (j < kbd_dev->key_count 548 && kbd_dev->keys_old[j] != kbd_dev->keys[i]) { 544 549 ++j; 545 550 } 546 551 547 if (j == count) {552 if (j == kbd_dev->key_count) { 548 553 // not found, i.e. new key pressed 549 key = usbhid_parse_scancode(k ey_codes[i]);554 key = usbhid_parse_scancode(kbd_dev->keys[i]); 550 555 usb_log_debug2("Key pressed: %d (keycode: %d)\n", key, 551 key_codes[i]); 552 usb_kbd_push_ev(hid_dev, kbd_dev, KEY_PRESS, 553 key); 556 kbd_dev->keys[i]); 557 usb_kbd_push_ev(hid_dev, kbd_dev, KEY_PRESS, key); 554 558 if (!usb_kbd_is_lock(key)) { 555 559 usb_kbd_repeat_start(kbd_dev, key); … … 560 564 } 561 565 562 memcpy(kbd_dev->keys, key_codes, count); 563 564 usb_log_debug("New stored keycodes: %s\n", 565 usb_debug_str_buffer(kbd_dev->keys, kbd_dev->key_count, 0)); 566 // usb_log_debug("Old keys: "); 567 // for (i = 0; i < kbd_dev->key_count; ++i) { 568 // usb_log_debug("%d ", kbd_dev->keys_old[i]); 569 // } 570 // usb_log_debug("\n"); 571 572 573 // usb_log_debug("New keys: "); 574 // for (i = 0; i < kbd_dev->key_count; ++i) { 575 // usb_log_debug("%d ", kbd_dev->keys[i]); 576 // } 577 // usb_log_debug("\n"); 578 579 memcpy(kbd_dev->keys_old, kbd_dev->keys, kbd_dev->key_count * 4); 580 581 usb_log_debug2("New stored keys: "); 582 for (i = 0; i < kbd_dev->key_count; ++i) { 583 usb_log_debug2("%d ", kbd_dev->keys_old[i]); 584 } 585 usb_log_debug2("\n"); 566 586 } 567 587 … … 585 605 * @sa usb_kbd_check_key_changes(), usb_kbd_check_modifier_changes() 586 606 */ 587 static void usb_kbd_process_keycodes(const uint8_t *key_codes, size_t count,588 uint8_t report_id, void *arg)589 {590 if (arg == NULL) {591 usb_log_warning("Missing argument in callback "592 "usbhid_process_keycodes().\n");593 return;594 }595 596 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;597 598 if (hid_dev->data == NULL) {599 usb_log_warning("Missing KBD device structure in callback.\n");600 return;601 }602 603 usb_kbd_t *kbd_dev = (usb_kbd_t *)hid_dev->data;604 605 usb_log_debug("Got keys from parser (report id: %u): %s\n",606 report_id, usb_debug_str_buffer(key_codes, count, 0));607 608 if (count != kbd_dev->key_count) {609 usb_log_warning("Number of received keycodes (%zu) differs from"610 " expected (%zu).\n", count, kbd_dev->key_count);611 return;612 }613 614 ///usb_kbd_check_modifier_changes(kbd_dev, key_codes, count);615 usb_kbd_check_key_changes(hid_dev, kbd_dev, key_codes, count);616 }607 //static void usb_kbd_process_keycodes(const uint8_t *key_codes, size_t count, 608 // uint8_t report_id, void *arg) 609 //{ 610 // if (arg == NULL) { 611 // usb_log_warning("Missing argument in callback " 612 // "usbhid_process_keycodes().\n"); 613 // return; 614 // } 615 616 // usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg; 617 618 // if (hid_dev->data == NULL) { 619 // usb_log_warning("Missing KBD device structure in callback.\n"); 620 // return; 621 // } 622 623 // usb_kbd_t *kbd_dev = (usb_kbd_t *)hid_dev->data; 624 625 // usb_log_debug("Got keys from parser (report id: %u): %s\n", 626 // report_id, usb_debug_str_buffer(key_codes, count, 0)); 627 628 // if (count != kbd_dev->key_count) { 629 // usb_log_warning("Number of received keycodes (%zu) differs from" 630 // " expected (%zu).\n", count, kbd_dev->key_count); 631 // return; 632 // } 633 634 // ///usb_kbd_check_modifier_changes(kbd_dev, key_codes, count); 635 // usb_kbd_check_key_changes(hid_dev, kbd_dev, key_codes, count); 636 //} 617 637 618 638 /*----------------------------------------------------------------------------*/ … … 638 658 uint8_t *buffer, size_t actual_size) 639 659 { 640 assert(hid_dev->parser != NULL); 660 assert(hid_dev->report != NULL); 661 assert(hid_dev != NULL); 662 assert(hid_dev->data != NULL); 663 664 usb_kbd_t *kbd_dev = (usb_kbd_t *)hid_dev->data; 641 665 642 666 usb_log_debug("Calling usb_hid_parse_report() with " … … 648 672 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0); 649 673 //usb_hid_report_path_set_report_id(path, 0); 650 651 int rc = usb_hid_parse_report(hid_dev->parser, buffer, 652 actual_size, path, 674 675 uint8_t report_id; 676 int rc = usb_hid_parse_report(hid_dev->report, buffer, actual_size, 677 &report_id); 678 679 if (rc != EOK) { 680 usb_log_warning("Error in usb_hid_parse_report():" 681 "%s\n", str_error(rc)); 682 } 683 684 usb_hid_report_path_set_report_id (path, report_id); 685 686 // fill in the currently pressed keys 687 688 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 689 hid_dev->report, NULL, path, 653 690 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 654 &usb_kbd_parser_callbacks, hid_dev); 655 691 USB_HID_REPORT_TYPE_INPUT); 692 unsigned i = 0; 693 694 while (field != NULL) { 695 usb_log_debug2("FIELD (%p) - VALUE(%d) USAGE(%u)\n", 696 field, field->value, field->usage); 697 698 assert(i < kbd_dev->key_count); 699 // if (i == kbd_dev->key_count) { 700 // break; 701 // } 702 703 // save the key usage 704 /* TODO: maybe it's not good to save value, nor usage 705 * as the value may be e.g. 1 for LEDs and usage may be 706 * value of the LED. On the other hand, in case of normal 707 * keys, the usage is more important and we must check 708 * that. One possible solution: distinguish between those 709 * two parts of the Report somehow. 710 */ 711 if (field->value != 0) { 712 kbd_dev->keys[i] = field->usage; 713 } 714 else { 715 kbd_dev->keys[i] = 0; 716 } 717 usb_log_debug2("Saved %u. key usage %d\n", i, kbd_dev->keys[i]); 718 719 ++i; 720 field = usb_hid_report_get_sibling(hid_dev->report, field, path, 721 USB_HID_PATH_COMPARE_END 722 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 723 USB_HID_REPORT_TYPE_INPUT); 724 } 725 656 726 usb_hid_report_path_free(path); 657 727 658 if (rc != EOK) { 659 usb_log_warning("Error in usb_hid_boot_keyboard_input_report():" 660 "%s\n", str_error(rc)); 661 } 728 usb_kbd_check_key_changes(hid_dev, kbd_dev); 662 729 } 663 730 … … 747 814 748 815 kbd_dev->key_count = usb_hid_report_input_length( 749 hid_dev-> parser, path,816 hid_dev->report, path, 750 817 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY); 751 818 usb_hid_report_path_free(path); … … 753 820 usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count); 754 821 755 kbd_dev->keys = ( uint8_t *)calloc(kbd_dev->key_count, sizeof(uint8_t));822 kbd_dev->keys = (int32_t *)calloc(kbd_dev->key_count, sizeof(int32_t)); 756 823 757 824 if (kbd_dev->keys == NULL) { … … 761 828 } 762 829 830 kbd_dev->keys_old = 831 (int32_t *)calloc(kbd_dev->key_count, sizeof(int32_t)); 832 833 if (kbd_dev->keys_old == NULL) { 834 usb_log_fatal("No memory!\n"); 835 free(kbd_dev->keys); 836 free(kbd_dev); 837 return ENOMEM; 838 } 839 763 840 /* 764 841 * Output report 765 842 */ 766 843 kbd_dev->output_size = 0; 767 kbd_dev->output_buffer = usb_hid_report_output(hid_dev-> parser,768 &kbd_dev->output_size );769 if (kbd_dev->output_buffer == NULL && kbd_dev->output_size != 0) {844 kbd_dev->output_buffer = usb_hid_report_output(hid_dev->report, 845 &kbd_dev->output_size, 0); 846 if (kbd_dev->output_buffer == NULL) { 770 847 usb_log_warning("Error creating output report buffer.\n"); 771 848 free(kbd_dev->keys); 772 free(kbd_dev); 773 return ENOMEM; 849 return ENOMEM; /* TODO: other error code */ 774 850 } 775 851 … … 780 856 kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0); 781 857 782 kbd_dev->led_output_size = usb_hid_report_output_size(hid_dev-> parser,858 kbd_dev->led_output_size = usb_hid_report_output_size(hid_dev->report, 783 859 kbd_dev->led_path, 784 860 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY); … … 908 984 } 909 985 910 // free the output buffer 911 usb_hid_report_output_free((*kbd_dev)->output_buffer); 986 // free all buffers 987 if ((*kbd_dev)->keys != NULL) { 988 free((*kbd_dev)->keys); 989 } 990 if ((*kbd_dev)->keys_old != NULL) { 991 free((*kbd_dev)->keys_old); 992 } 993 if ((*kbd_dev)->led_data != NULL) { 994 free((*kbd_dev)->led_data); 995 } 996 if ((*kbd_dev)->output_buffer != NULL) { 997 free((*kbd_dev)->output_buffer); 998 } 999 if ((*kbd_dev)->led_path != NULL) { 1000 usb_hid_report_path_free((*kbd_dev)->led_path); 1001 } 1002 if ((*kbd_dev)->output_buffer != NULL) { 1003 usb_hid_report_output_free((*kbd_dev)->output_buffer); 1004 } 912 1005 913 1006 free(*kbd_dev); … … 929 1022 } else { 930 1023 usb_kbd_free(&kbd_dev); 1024 hid_dev->data = NULL; 931 1025 } 932 1026 } … … 937 1031 int usb_kbd_set_boot_protocol(usb_hid_dev_t *hid_dev) 938 1032 { 939 int rc = usb_hid_parse_report_descriptor(hid_dev-> parser,1033 int rc = usb_hid_parse_report_descriptor(hid_dev->report, 940 1034 USB_KBD_BOOT_REPORT_DESCRIPTOR, 941 1035 USB_KBD_BOOT_REPORT_DESCRIPTOR_SIZE); -
uspace/drv/usbhid/kbd/kbddev.h
r152ec79 r9e929a0 65 65 */ 66 66 typedef struct usb_kbd_t { 67 /** Previously pressed keys (not translated to key codes). */ 68 int32_t *keys_old; 67 69 /** Currently pressed keys (not translated to key codes). */ 68 uint8_t *keys;70 int32_t *keys; 69 71 /** Count of stored keys (i.e. number of keys in the report). */ 70 72 size_t key_count; -
uspace/drv/usbhid/lgtch-ultrax/lgtch-ultrax.c
r152ec79 r9e929a0 38 38 #include "lgtch-ultrax.h" 39 39 #include "../usbhid.h" 40 #include "keymap.h" 40 41 41 42 #include <usb/classes/hidparser.h> 42 43 #include <usb/debug.h> 44 #include <usb/classes/hidut.h> 45 43 46 #include <errno.h> 44 47 #include <str_error.h> 45 48 49 #include <ipc/kbd.h> 50 #include <io/console.h> 51 46 52 #define NAME "lgtch-ultrax" 47 53 48 /*----------------------------------------------------------------------------*/ 49 50 static void usb_lgtch_process_keycodes(const uint8_t *key_codes, size_t count, 51 uint8_t report_id, void *arg); 52 53 static const usb_hid_report_in_callbacks_t usb_lgtch_parser_callbacks = { 54 .keyboard = usb_lgtch_process_keycodes 54 typedef enum usb_lgtch_flags { 55 USB_LGTCH_STATUS_UNINITIALIZED = 0, 56 USB_LGTCH_STATUS_INITIALIZED = 1, 57 USB_LGTCH_STATUS_TO_DESTROY = -1 58 } usb_lgtch_flags; 59 60 61 /*----------------------------------------------------------------------------*/ 62 /** 63 * Default handler for IPC methods not handled by DDF. 64 * 65 * Currently recognizes only one method (IPC_M_CONNECT_TO_ME), in which case it 66 * assumes the caller is the console and thus it stores IPC phone to it for 67 * later use by the driver to notify about key events. 68 * 69 * @param fun Device function handling the call. 70 * @param icallid Call id. 71 * @param icall Call data. 72 */ 73 static void default_connection_handler(ddf_fun_t *fun, 74 ipc_callid_t icallid, ipc_call_t *icall) 75 { 76 usb_log_debug(NAME " default_connection_handler()\n"); 77 78 sysarg_t method = IPC_GET_IMETHOD(*icall); 79 80 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 81 82 if (hid_dev == NULL || hid_dev->data == NULL) { 83 async_answer_0(icallid, EINVAL); 84 return; 85 } 86 87 assert(hid_dev != NULL); 88 assert(hid_dev->data != NULL); 89 usb_lgtch_ultrax_t *lgtch_dev = (usb_lgtch_ultrax_t *)hid_dev->data; 90 91 if (method == IPC_M_CONNECT_TO_ME) { 92 int callback = IPC_GET_ARG5(*icall); 93 94 if (lgtch_dev->console_phone != -1) { 95 async_answer_0(icallid, ELIMIT); 96 return; 97 } 98 99 lgtch_dev->console_phone = callback; 100 usb_log_debug(NAME " Saved phone to console: %d\n", callback); 101 async_answer_0(icallid, EOK); 102 return; 103 } 104 105 async_answer_0(icallid, EINVAL); 106 } 107 108 /*----------------------------------------------------------------------------*/ 109 110 static ddf_dev_ops_t lgtch_ultrax_ops = { 111 .default_handler = default_connection_handler 55 112 }; 56 113 57 114 /*----------------------------------------------------------------------------*/ 58 115 59 static void usb_lgtch_process_keycodes(const uint8_t *key_codes, size_t count, 60 uint8_t report_id, void *arg) 61 { 62 // TODO: checks 63 64 usb_log_debug(NAME " Got keys from parser (report id: %u): %s\n", 65 report_id, usb_debug_str_buffer(key_codes, count, 0)); 116 //static void usb_lgtch_process_keycodes(const uint8_t *key_codes, size_t count, 117 // uint8_t report_id, void *arg); 118 119 //static const usb_hid_report_in_callbacks_t usb_lgtch_parser_callbacks = { 120 // .keyboard = usb_lgtch_process_keycodes 121 //}; 122 123 ///*----------------------------------------------------------------------------*/ 124 125 //static void usb_lgtch_process_keycodes(const uint8_t *key_codes, size_t count, 126 // uint8_t report_id, void *arg) 127 //{ 128 // // TODO: checks 129 130 // usb_log_debug(NAME " Got keys from parser (report id: %u): %s\n", 131 // report_id, usb_debug_str_buffer(key_codes, count, 0)); 132 //} 133 134 /*----------------------------------------------------------------------------*/ 135 /** 136 * Processes key events. 137 * 138 * @note This function was copied from AT keyboard driver and modified to suit 139 * USB keyboard. 140 * 141 * @note Lock keys are not sent to the console, as they are completely handled 142 * in the driver. It may, however, be required later that the driver 143 * sends also these keys to application (otherwise it cannot use those 144 * keys at all). 145 * 146 * @param hid_dev 147 * @param lgtch_dev 148 * @param type Type of the event (press / release). Recognized values: 149 * KEY_PRESS, KEY_RELEASE 150 * @param key Key code of the key according to HID Usage Tables. 151 */ 152 static void usb_lgtch_push_ev(usb_hid_dev_t *hid_dev, int type, 153 unsigned int key) 154 { 155 assert(hid_dev != NULL); 156 assert(hid_dev->data != NULL); 157 158 usb_lgtch_ultrax_t *lgtch_dev = (usb_lgtch_ultrax_t *)hid_dev->data; 159 160 console_event_t ev; 161 162 ev.type = type; 163 ev.key = key; 164 ev.mods = 0; 165 166 ev.c = 0; 167 168 usb_log_debug2(NAME " Sending key %d to the console\n", ev.key); 169 if (lgtch_dev->console_phone < 0) { 170 usb_log_warning( 171 "Connection to console not ready, key discarded.\n"); 172 return; 173 } 174 175 async_msg_4(lgtch_dev->console_phone, KBD_EVENT, ev.type, ev.key, 176 ev.mods, ev.c); 177 } 178 179 /*----------------------------------------------------------------------------*/ 180 181 static void usb_lgtch_free(usb_lgtch_ultrax_t **lgtch_dev) 182 { 183 if (lgtch_dev == NULL || *lgtch_dev == NULL) { 184 return; 185 } 186 187 // hangup phone to the console 188 async_hangup((*lgtch_dev)->console_phone); 189 190 // if ((*lgtch_dev)->repeat_mtx != NULL) { 191 // /* TODO: replace by some check and wait */ 192 // assert(!fibril_mutex_is_locked((*lgtch_dev)->repeat_mtx)); 193 // free((*lgtch_dev)->repeat_mtx); 194 // } 195 196 // free all buffers 197 if ((*lgtch_dev)->keys != NULL) { 198 free((*lgtch_dev)->keys); 199 } 200 if ((*lgtch_dev)->keys_old != NULL) { 201 free((*lgtch_dev)->keys_old); 202 } 203 204 free(*lgtch_dev); 205 *lgtch_dev = NULL; 206 } 207 208 /*----------------------------------------------------------------------------*/ 209 210 int usb_lgtch_init(struct usb_hid_dev *hid_dev) 211 { 212 if (hid_dev == NULL || hid_dev->usb_dev == NULL) { 213 return EINVAL; /*! @todo Other return code? */ 214 } 215 216 usb_log_debug(NAME " Initializing HID/lgtch_ultrax structure...\n"); 217 218 usb_lgtch_ultrax_t *lgtch_dev = (usb_lgtch_ultrax_t *)malloc( 219 sizeof(usb_lgtch_ultrax_t)); 220 if (lgtch_dev == NULL) { 221 return ENOMEM; 222 } 223 224 lgtch_dev->console_phone = -1; 225 226 usb_hid_report_path_t *path = usb_hid_report_path(); 227 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0); 228 229 usb_hid_report_path_set_report_id(path, 1); 230 231 lgtch_dev->key_count = usb_hid_report_input_length( 232 hid_dev->report, path, 233 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY); 234 usb_hid_report_path_free(path); 235 236 usb_log_debug(NAME " Size of the input report: %zu\n", 237 lgtch_dev->key_count); 238 239 lgtch_dev->keys = (int32_t *)calloc(lgtch_dev->key_count, 240 sizeof(int32_t)); 241 242 if (lgtch_dev->keys == NULL) { 243 usb_log_fatal("No memory!\n"); 244 free(lgtch_dev); 245 return ENOMEM; 246 } 247 248 lgtch_dev->keys_old = 249 (int32_t *)calloc(lgtch_dev->key_count, sizeof(int32_t)); 250 251 if (lgtch_dev->keys_old == NULL) { 252 usb_log_fatal("No memory!\n"); 253 free(lgtch_dev->keys); 254 free(lgtch_dev); 255 return ENOMEM; 256 } 257 258 /*! @todo Autorepeat */ 259 260 // save the KBD device structure into the HID device structure 261 hid_dev->data = lgtch_dev; 262 263 /* Create the function exposed under /dev/devices. */ 264 ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 265 NAME); 266 if (fun == NULL) { 267 usb_log_error("Could not create DDF function node.\n"); 268 return ENOMEM; 269 } 270 271 lgtch_dev->initialized = USB_LGTCH_STATUS_INITIALIZED; 272 usb_log_debug(NAME " HID/lgtch_ultrax device structure initialized.\n"); 273 274 /* 275 * Store the initialized HID device and HID ops 276 * to the DDF function. 277 */ 278 fun->ops = &lgtch_ultrax_ops; 279 fun->driver_data = hid_dev; // TODO: maybe change to hid_dev->data 280 281 /* 282 * 1) subdriver vytvori vlastnu ddf_fun, vlastne ddf_dev_ops, ktore da 283 * do nej. 284 * 2) do tych ops do .interfaces[DEV_IFACE_USBHID (asi)] priradi 285 * vyplnenu strukturu usbhid_iface_t. 286 * 3) klientska aplikacia - musi si rucne vytvorit telefon 287 * (devman_device_connect() - cesta k zariadeniu (/hw/pci0/...) az 288 * k tej fcii. 289 * pouzit usb/classes/hid/iface.h - prvy int je telefon 290 */ 291 292 int rc = ddf_fun_bind(fun); 293 if (rc != EOK) { 294 usb_log_error("Could not bind DDF function: %s.\n", 295 str_error(rc)); 296 // TODO: Can / should I destroy the DDF function? 297 ddf_fun_destroy(fun); 298 usb_lgtch_free(&lgtch_dev); 299 return rc; 300 } 301 302 rc = ddf_fun_add_to_class(fun, "keyboard"); 303 if (rc != EOK) { 304 usb_log_error( 305 "Could not add DDF function to class 'keyboard': %s.\n", 306 str_error(rc)); 307 // TODO: Can / should I destroy the DDF function? 308 ddf_fun_destroy(fun); 309 usb_lgtch_free(&lgtch_dev); 310 return rc; 311 } 312 313 usb_log_debug(NAME " HID/lgtch_ultrax structure initialized.\n"); 314 315 return EOK; 316 } 317 318 /*----------------------------------------------------------------------------*/ 319 320 void usb_lgtch_deinit(struct usb_hid_dev *hid_dev) 321 { 322 if (hid_dev == NULL) { 323 return; 324 } 325 326 if (hid_dev->data != NULL) { 327 usb_lgtch_ultrax_t *lgtch_dev = 328 (usb_lgtch_ultrax_t *)hid_dev->data; 329 // if (usb_kbd_is_initialized(kbd_dev)) { 330 // usb_kbd_mark_unusable(kbd_dev); 331 // } else { 332 usb_lgtch_free(&lgtch_dev); 333 hid_dev->data = NULL; 334 // } 335 } 66 336 } 67 337 … … 81 351 usb_hid_report_path_t *path = usb_hid_report_path(); 82 352 usb_hid_report_path_append_item(path, 0xc, 0); 83 usb_hid_report_path_set_report_id(path, 1); 84 85 int rc = usb_hid_parse_report(hid_dev->parser, buffer, 86 buffer_size, path, 87 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 88 &usb_lgtch_parser_callbacks, hid_dev); 353 354 uint8_t report_id; 355 356 int rc = usb_hid_parse_report(hid_dev->report, buffer, buffer_size, 357 &report_id); 358 usb_hid_report_path_set_report_id(path, report_id); 359 360 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 361 hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END 362 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 363 USB_HID_REPORT_TYPE_INPUT); 364 365 unsigned int key; 366 367 /*! @todo Is this iterating OK if done multiple times? 368 * @todo The parsing is not OK 369 */ 370 while (field != NULL) { 371 usb_log_debug(NAME " KEY VALUE(%X) USAGE(%X)\n", field->value, 372 field->usage); 373 374 key = usb_lgtch_map_usage(field->usage); 375 usb_lgtch_push_ev(hid_dev, KEY_PRESS, key); 376 377 field = usb_hid_report_get_sibling( 378 hid_dev->report, field, path, USB_HID_PATH_COMPARE_END 379 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 380 USB_HID_REPORT_TYPE_INPUT); 381 } 89 382 90 383 usb_hid_report_path_free(path); 91 384 92 385 if (rc != EOK) { 93 usb_log_warning( "Error in usb_hid_boot_keyboard_input_report():"386 usb_log_warning(NAME "Error in usb_hid_boot_keyboard_input_report():" 94 387 "%s\n", str_error(rc)); 95 388 } -
uspace/drv/usbhid/lgtch-ultrax/lgtch-ultrax.h
r152ec79 r9e929a0 40 40 41 41 struct usb_hid_dev; 42 //struct usb_hid_subdriver_mapping; 42 43 /*----------------------------------------------------------------------------*/ 44 /** 45 * USB/HID keyboard device type. 46 * 47 * Holds a reference to generic USB/HID device structure and keyboard-specific 48 * data, such as currently pressed keys, modifiers and lock keys. 49 * 50 * Also holds a IPC phone to the console (since there is now no other way to 51 * communicate with it). 52 * 53 * @note Storing active lock keys in this structure results in their setting 54 * being device-specific. 55 */ 56 typedef struct usb_lgtch_ultrax_t { 57 /** Previously pressed keys (not translated to key codes). */ 58 int32_t *keys_old; 59 /** Currently pressed keys (not translated to key codes). */ 60 int32_t *keys; 61 /** Count of stored keys (i.e. number of keys in the report). */ 62 size_t key_count; 63 64 /** IPC phone to the console device (for sending key events). */ 65 int console_phone; 66 67 /** Information for auto-repeat of keys. */ 68 // usb_kbd_repeat_t repeat; 69 70 /** Mutex for accessing the information about auto-repeat. */ 71 // fibril_mutex_t *repeat_mtx; 72 73 /** State of the structure (for checking before use). 74 * 75 * 0 - not initialized 76 * 1 - initialized 77 * -1 - ready for destroying 78 */ 79 int initialized; 80 } usb_lgtch_ultrax_t; 43 81 44 82 /*----------------------------------------------------------------------------*/ 45 83 46 //extern struct usb_hid_subdriver_mapping usb_lgtch_mapping;84 int usb_lgtch_init(struct usb_hid_dev *hid_dev); 47 85 48 /*----------------------------------------------------------------------------*/ 49 50 //int usb_lgtch_init(struct usb_hid_dev *hid_dev); 86 void usb_lgtch_deinit(struct usb_hid_dev *hid_dev); 51 87 52 88 bool usb_lgtch_polling_callback(struct usb_hid_dev *hid_dev, uint8_t *buffer, -
uspace/drv/usbhid/main.c
r152ec79 r9e929a0 114 114 hid_fun->ops = &hid_dev->ops; 115 115 hid_fun->driver_data = hid_dev; // TODO: maybe change to hid_dev->data 116 117 /* 118 * 1) subdriver vytvori vlastnu ddf_fun, vlastne ddf_dev_ops, ktore da 119 * do nej. 120 * 2) do tych ops do .interfaces[DEV_IFACE_USBHID (asi)] priradi 121 * vyplnenu strukturu usbhid_iface_t. 122 * 3) klientska aplikacia - musi si rucne vytvorit telefon 123 * (devman_device_connect() - cesta k zariadeniu (/hw/pci0/...) az 124 * k tej fcii. 125 * pouzit usb/classes/hid/iface.h - prvy int je telefon 126 */ 116 127 117 128 rc = ddf_fun_bind(hid_fun); -
uspace/drv/usbhid/mouse/mousedev.c
r152ec79 r9e929a0 296 296 int usb_mouse_set_boot_protocol(usb_hid_dev_t *hid_dev) 297 297 { 298 int rc = usb_hid_parse_report_descriptor(hid_dev-> parser,298 int rc = usb_hid_parse_report_descriptor(hid_dev->report, 299 299 USB_MOUSE_BOOT_REPORT_DESCRIPTOR, 300 300 USB_MOUSE_BOOT_REPORT_DESCRIPTOR_SIZE); -
uspace/drv/usbhid/subdrivers.c
r152ec79 r9e929a0 55 55 USB_HID_PATH_COMPARE_END 56 56 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 57 0,58 0,57 -1, 58 -1, 59 59 { 60 60 .init = usb_kbd_init, … … 73 73 0xc30e, 74 74 { 75 .init = NULL,76 .deinit = NULL,75 .init = usb_lgtch_init, 76 .deinit = usb_lgtch_deinit, 77 77 .poll = usb_lgtch_polling_callback, 78 78 .poll_end = NULL 79 79 } 80 80 }, 81 {NULL, -1, 0, 0, 0, {NULL, NULL, NULL, NULL}}81 {NULL, -1, 0, -1, -1, {NULL, NULL, NULL, NULL}} 82 82 }; 83 83 -
uspace/drv/usbhid/subdrivers.h
r152ec79 r9e929a0 56 56 int report_id; 57 57 int compare; 58 uint16_t vendor_id;59 uint16_t product_id;58 int vendor_id; 59 int product_id; 60 60 usb_hid_subdriver_t subdriver; 61 61 } usb_hid_subdriver_mapping_t; -
uspace/drv/usbhid/usbhid.c
r152ec79 r9e929a0 158 158 const usb_hid_subdriver_mapping_t *mapping) 159 159 { 160 return false; 160 assert(hid_dev != NULL); 161 assert(hid_dev->usb_dev != NULL); 162 163 return (hid_dev->usb_dev->descriptors.device.vendor_id 164 == mapping->vendor_id 165 && hid_dev->usb_dev->descriptors.device.product_id 166 == mapping->product_id); 161 167 } 162 168 … … 192 198 } 193 199 194 assert(hid_dev-> parser!= NULL);200 assert(hid_dev->report != NULL); 195 201 196 202 usb_log_debug("Compare flags: %d\n", mapping->compare); 197 size_t size = usb_hid_report_input_length(hid_dev-> parser, usage_path,203 size_t size = usb_hid_report_input_length(hid_dev->report, usage_path, 198 204 mapping->compare); 199 205 usb_log_debug("Size of the input report: %zuB\n", size); … … 251 257 while (count < USB_HID_MAX_SUBDRIVERS && 252 258 (mapping->usage_path != NULL 253 || mapping->vendor_id != 0 || mapping->product_id != 0)) {259 || mapping->vendor_id >= 0 || mapping->product_id >= 0)) { 254 260 // check the vendor & product ID 255 if (mapping->vendor_id != 0 && mapping->product_id ==0) {256 usb_log_warning("Missing Product ID for Vendor ID % u\n",261 if (mapping->vendor_id >= 0 && mapping->product_id < 0) { 262 usb_log_warning("Missing Product ID for Vendor ID %d\n", 257 263 mapping->vendor_id); 258 264 return EINVAL; 259 265 } 260 if (mapping->product_id != 0 && mapping->vendor_id ==0) {261 usb_log_warning("Missing Vendor ID for Product ID % u\n",266 if (mapping->product_id >= 0 && mapping->vendor_id < 0) { 267 usb_log_warning("Missing Vendor ID for Product ID %d\n", 262 268 mapping->product_id); 263 269 return EINVAL; … … 267 273 matched = false; 268 274 269 if (mapping->vendor_id != 0) {270 assert(mapping->product_id != 0);275 if (mapping->vendor_id >= 0) { 276 assert(mapping->product_id >= 0); 271 277 usb_log_debug("Comparing device against vendor ID %u" 272 278 " and product ID %u.\n", mapping->vendor_id, … … 341 347 } 342 348 343 hid_dev-> parser = (usb_hid_report_parser_t *)(malloc(sizeof(344 usb_hid_report_ parser_t)));345 if (hid_dev-> parser== NULL) {349 hid_dev->report = (usb_hid_report_t *)(malloc(sizeof( 350 usb_hid_report_t))); 351 if (hid_dev->report == NULL) { 346 352 usb_log_fatal("No memory!\n"); 347 353 free(hid_dev); … … 382 388 return rc; 383 389 } 384 385 /* Initialize the report parser. */ 386 rc = usb_hid_parser_init(hid_dev->parser); 387 if (rc != EOK) { 388 usb_log_error("Failed to initialize report parser.\n"); 389 //usb_hid_free(&hid_dev); 390 return rc; 391 } 392 390 393 391 /* Get the report descriptor and parse it. */ 394 392 rc = usb_hid_process_report_descriptor(hid_dev->usb_dev, 395 hid_dev-> parser);393 hid_dev->report); 396 394 397 395 bool fallback = false; … … 591 589 592 590 // destroy the parser 593 if ((*hid_dev)-> parser!= NULL) {594 usb_hid_free_report _parser((*hid_dev)->parser);591 if ((*hid_dev)->report != NULL) { 592 usb_hid_free_report((*hid_dev)->report); 595 593 } 596 594 -
uspace/drv/usbhid/usbhid.h
r152ec79 r9e929a0 91 91 92 92 /** HID Report parser. */ 93 usb_hid_report_ parser_t *parser;93 usb_hid_report_t *report; 94 94 95 95 /** Arbitrary data (e.g. a special structure for handling keyboard). */ -
uspace/drv/usbkbd/kbddev.c
r152ec79 r9e929a0 128 128 0x15, 0x00, // Logical Minimum (0), 129 129 0x25, 0x01, // Logical Maximum (1), 130 //0x85, 0x00, // Report ID, 131 //0xA4, // Push 130 132 0x81, 0x02, // Input (Data, Variable, Absolute), ; Modifier byte 131 0x95, 0x01, // Report Count (1), 132 0x75, 0x08, // Report Size (8), 133 //0xB4, // Pop 134 0x75, 0x08, // Report Size (1), 135 0x95, 0x01, // Report Count (8), 133 136 0x81, 0x01, // Input (Constant), ; Reserved byte 134 137 0x95, 0x05, // Report Count (5), … … 268 271 return; 269 272 } 270 273 271 274 unsigned i = 0; 272 275 … … 290 293 291 294 usb_log_debug("Creating output report.\n"); 292 293 int rc = usb_hid_report_output_translate(kbd_dev->parser,294 kbd_dev->led_path,295 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,296 kbd_dev->output_buffer,297 kbd_dev->output_ size, kbd_dev->led_data, kbd_dev->led_output_size);295 296 usb_hid_report_output_set_data(kbd_dev->parser, kbd_dev->led_path, 297 USB_HID_PATH_COMPARE_END , kbd_dev->led_data, 298 kbd_dev->led_output_size); 299 int rc = usb_hid_report_output_translate(kbd_dev->parser, 0, 300 kbd_dev->output_buffer, kbd_dev->output_size); 298 301 299 302 if (rc != EOK) { … … 563 566 assert(kbd_dev != NULL); 564 567 565 usb_log_debug("Got keys from parser (report id: % u): %s\n",566 report_id,usb_debug_str_buffer(key_codes, count, 0));568 usb_log_debug("Got keys from parser (report id: %d): %s\n", report_id, 569 usb_debug_str_buffer(key_codes, count, 0)); 567 570 568 571 if (count != kbd_dev->key_count) { … … 614 617 usb_hid_report_path_t *path = usb_hid_report_path(); 615 618 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0); 616 usb_hid_report_path_set_report_id(path, 0); 617 618 int rc = usb_hid_parse_report(kbd_dev->parser, buffer, 619 actual_size, path, 620 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 621 callbacks, kbd_dev); 619 620 uint8_t report_id; 621 int rc = usb_hid_parse_report(kbd_dev->parser, buffer, actual_size, &report_id); 622 usb_hid_descriptor_print (kbd_dev->parser); 622 623 623 624 usb_hid_report_path_free (path); … … 663 664 memset(kbd_dev, 0, sizeof(usb_kbd_t)); 664 665 665 kbd_dev->parser = (usb_hid_report_ parser_t *)(malloc(sizeof(666 usb_hid_report_ parser_t)));666 kbd_dev->parser = (usb_hid_report_t *)(malloc(sizeof( 667 usb_hid_report_t))); 667 668 if (kbd_dev->parser == NULL) { 668 669 usb_log_fatal("No memory!\n"); … … 732 733 733 734 /* Initialize the report parser. */ 734 rc = usb_hid_parser_init(kbd_dev->parser);735 if (rc != EOK) {736 usb_log_error("Failed to initialize report parser.\n");737 return rc;738 }735 //rc = usb_hid_parser_init(kbd_dev->parser); 736 //if (rc != EOK) { 737 // usb_log_error("Failed to initialize report parser.\n"); 738 // return rc; 739 //} 739 740 740 741 /* Get the report descriptor and parse it. */ … … 771 772 772 773 kbd_dev->key_count = usb_hid_report_input_length( 773 kbd_dev->parser, path, 774 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY); 774 kbd_dev->parser, path, USB_HID_PATH_COMPARE_END); 775 775 usb_hid_report_path_free (path); 776 776 … … 789 789 kbd_dev->output_size = 0; 790 790 kbd_dev->output_buffer = usb_hid_report_output(kbd_dev->parser, 791 &kbd_dev->output_size );792 if (kbd_dev->output_buffer == NULL && kbd_dev->output_size != 0) {791 &kbd_dev->output_size, 0x00); 792 if (kbd_dev->output_buffer == NULL) { 793 793 usb_log_warning("Error creating output report buffer.\n"); 794 794 free(kbd_dev->keys); … … 801 801 usb_hid_report_path_append_item( 802 802 kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0); 803 usb_hid_report_path_set_report_id(kbd_dev->led_path, 0x00); 803 804 804 805 kbd_dev->led_output_size = usb_hid_report_output_size(kbd_dev->parser, … … 849 850 * Set Idle rate 850 851 */ 851 usb_kbd_set_led(kbd_dev); 852 usb_kbd_set_led(kbd_dev); 852 853 853 854 usbhid_req_set_idle(&kbd_dev->usb_dev->ctrl_pipe, … … 934 935 // destroy the parser 935 936 if ((*kbd_dev)->parser != NULL) { 936 usb_hid_free_report _parser((*kbd_dev)->parser);937 usb_hid_free_report((*kbd_dev)->parser); 937 938 } 938 939 -
uspace/drv/usbkbd/kbddev.h
r152ec79 r9e929a0 106 106 107 107 /** HID Report parser. */ 108 usb_hid_report_ parser_t *parser;108 usb_hid_report_t *parser; 109 109 110 110 /** State of the structure (for checking before use). -
uspace/lib/usb/include/usb/classes/hid.h
r152ec79 r9e929a0 50 50 USB_HIDREQ_SET_PROTOCOL = 11 51 51 } usb_hid_request_t; 52 53 typedef enum {54 USB_HID_REPORT_TYPE_INPUT = 1,55 USB_HID_REPORT_TYPE_OUTPUT = 2,56 USB_HID_REPORT_TYPE_FEATURE = 357 } usb_hid_report_type_t;58 52 59 53 typedef enum { -
uspace/lib/usb/include/usb/classes/hidparser.h
r152ec79 r9e929a0 73 73 #define USB_HID_PATH_COMPARE_END 1 74 74 #define USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY 4 75 76 /** */ 77 typedef struct { 78 /** */ 79 int32_t usage_page; 80 /** */ 81 int32_t usage; 75 #define USB_HID_PATH_COMPARE_COLLECTION_ONLY 2 /* porovnava jenom cestu z Kolekci */ 76 77 78 #define USB_HID_MAX_USAGES 20 79 80 typedef enum { 81 USB_HID_REPORT_TYPE_INPUT = 1, 82 USB_HID_REPORT_TYPE_OUTPUT = 2, 83 USB_HID_REPORT_TYPE_FEATURE = 3 84 } usb_hid_report_type_t; 85 86 /** Collection usage path structure */ 87 typedef struct { 88 /** */ 89 uint32_t usage_page; 90 /** */ 91 uint32_t usage; 92 93 uint8_t flags; 82 94 /** */ 83 95 link_t link; … … 91 103 92 104 /** */ 105 link_t link; /* list */ 106 107 link_t head; /* head of list of usage paths */ 108 109 } usb_hid_report_path_t; 110 111 112 typedef struct { 113 /** */ 114 int report_count; 115 link_t reports; /** list of usb_hid_report_description_t */ 116 117 link_t collection_paths; 118 int collection_paths_count; 119 120 int use_report_ids; 121 uint8_t last_report_id; 122 123 } usb_hid_report_t; 124 125 typedef struct { 126 uint8_t report_id; 127 usb_hid_report_type_t type; 128 129 size_t bit_length; 130 size_t item_length; 131 132 link_t report_items; /** list of report items (fields) */ 133 93 134 link_t link; 94 95 } usb_hid_report_path_t; 96 97 /** 98 * Description of report items 99 */ 100 typedef struct { 101 /** */ 135 } usb_hid_report_description_t; 136 137 typedef struct { 138 139 int offset; 140 size_t size; 141 142 uint16_t usage_page; 143 uint16_t usage; 144 145 uint8_t item_flags; 146 usb_hid_report_path_t *collection_path; 147 148 int32_t logical_minimum; 149 int32_t logical_maximum; 150 int32_t physical_minimum; 151 int32_t physical_maximum; 152 uint32_t usage_minimum; 153 uint32_t usage_maximum; 154 uint32_t unit; 155 uint32_t unit_exponent; 156 157 158 int32_t value; 159 160 link_t link; 161 } usb_hid_report_field_t; 162 163 164 165 /** 166 * state table 167 */ 168 typedef struct { 169 /** report id */ 102 170 int32_t id; 103 /** */ 104 int32_t usage_minimum; 105 /** */ 106 int32_t usage_maximum; 171 172 /** */ 173 uint16_t extended_usage_page; 174 uint32_t usages[USB_HID_MAX_USAGES]; 175 int usages_count; 176 177 /** */ 178 uint32_t usage_page; 179 180 /** */ 181 uint32_t usage_minimum; 182 /** */ 183 uint32_t usage_maximum; 107 184 /** */ 108 185 int32_t logical_minimum; … … 116 193 size_t offset; 117 194 /** */ 118 int32_t delimiter;119 /** */120 195 int32_t unit_exponent; 121 196 /** */ … … 123 198 124 199 /** */ 125 int32_t string_index;126 /** */ 127 int32_t string_minimum;128 /** */ 129 int32_t string_maximum;130 /** */ 131 int32_t designator_index;132 /** */ 133 int32_t designator_minimum;134 /** */ 135 int32_t designator_maximum;200 uint32_t string_index; 201 /** */ 202 uint32_t string_minimum; 203 /** */ 204 uint32_t string_maximum; 205 /** */ 206 uint32_t designator_index; 207 /** */ 208 uint32_t designator_minimum; 209 /** */ 210 uint32_t designator_maximum; 136 211 /** */ 137 212 int32_t physical_minimum; … … 142 217 uint8_t item_flags; 143 218 144 /** */ 219 usb_hid_report_type_t type; 220 221 /** current collection path*/ 145 222 usb_hid_report_path_t *usage_path; 146 223 /** */ 147 224 link_t link; 148 225 } usb_hid_report_item_t; 149 150 151 /** HID report parser structure. */152 typedef struct {153 /** */154 link_t input;155 /** */156 link_t output;157 /** */158 link_t feature;159 160 int use_report_id;161 162 /** */163 link_t stack;164 } usb_hid_report_parser_t;165 166 226 167 227 /** HID parser callbacks for IN items. */ … … 189 249 } usb_hid_modifiers_t; 190 250 191 //typedef enum {192 // USB_HID_LED_NUM_LOCK = 0x1,193 // USB_HID_LED_CAPS_LOCK = 0x2,194 // USB_HID_LED_SCROLL_LOCK = 0x4,195 // USB_HID_LED_COMPOSE = 0x8,196 // USB_HID_LED_KANA = 0x10,197 // USB_HID_LED_COUNT = 5198 //} usb_hid_led_t;199 200 251 static const usb_hid_modifiers_t 201 252 usb_hid_modifiers_consts[USB_HID_MOD_COUNT] = { … … 210 261 }; 211 262 212 //static const usb_hid_led_t usb_hid_led_consts[USB_HID_LED_COUNT] = {213 // USB_HID_LED_NUM_LOCK,214 // USB_HID_LED_CAPS_LOCK,215 // USB_HID_LED_SCROLL_LOCK,216 // USB_HID_LED_COMPOSE,217 // USB_HID_LED_KANA218 //};219 220 //#define USB_HID_BOOT_KEYBOARD_NUM_LOCK 0x01221 //#define USB_HID_BOOT_KEYBOARD_CAPS_LOCK 0x02222 //#define USB_HID_BOOT_KEYBOARD_SCROLL_LOCK 0x04223 //#define USB_HID_BOOT_KEYBOARD_COMPOSE 0x08224 //#define USB_HID_BOOT_KEYBOARD_KANA 0x10225 226 263 /* 227 264 * Descriptor parser functions 228 265 */ 229 /** */ 230 int usb_hid_parser_init(usb_hid_report_parser_t *parser); 231 232 /** */ 233 int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser, 266 267 /** */ 268 int usb_hid_parse_report_descriptor(usb_hid_report_t *report, 234 269 const uint8_t *data, size_t size); 235 270 236 271 /** */ 237 void usb_hid_free_report_parser(usb_hid_report_parser_t *parser); 238 239 /** */ 240 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser); 241 242 /* 243 * Boot protocol functions 244 */ 245 /** */ 246 int usb_hid_boot_keyboard_input_report(const uint8_t *data, size_t size, 247 const usb_hid_report_in_callbacks_t *callbacks, void *arg); 248 249 /** */ 250 int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size); 272 void usb_hid_free_report(usb_hid_report_t *report); 273 274 /** */ 275 void usb_hid_descriptor_print(usb_hid_report_t *report); 251 276 252 277 … … 255 280 */ 256 281 /** */ 257 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 258 const uint8_t *data, size_t size, 259 usb_hid_report_path_t *path, int flags, 260 const usb_hid_report_in_callbacks_t *callbacks, void *arg); 261 262 /** */ 263 size_t usb_hid_report_input_length(const usb_hid_report_parser_t *parser, 282 int usb_hid_parse_report(const usb_hid_report_t *report, const uint8_t *data, size_t size, uint8_t *report_id); 283 284 /** */ 285 size_t usb_hid_report_input_length(const usb_hid_report_t *report, 264 286 usb_hid_report_path_t *path, int flags); 265 287 … … 296 318 usb_hid_report_path_t *usb_hid_report_path_clone(usb_hid_report_path_t *usage_path); 297 319 320 usb_hid_report_field_t *usb_hid_report_get_sibling(usb_hid_report_t *report, usb_hid_report_field_t *field, usb_hid_report_path_t *path, int flags, usb_hid_report_type_t type); 321 322 uint8_t usb_hid_report_get_report_id(usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type); 323 298 324 299 325 /* … … 301 327 */ 302 328 /** Allocates output report buffer*/ 303 uint8_t *usb_hid_report_output(usb_hid_report_ parser_t *parser, size_t *size);329 uint8_t *usb_hid_report_output(usb_hid_report_t *report, size_t *size, uint8_t report_id); 304 330 305 331 /** Frees output report buffer*/ … … 307 333 308 334 /** Returns size of output for given usage path */ 309 size_t usb_hid_report_output_size(usb_hid_report_ parser_t *parser,335 size_t usb_hid_report_output_size(usb_hid_report_t *report, 310 336 usb_hid_report_path_t *path, int flags); 311 337 312 /** Updates the output report buffer by translated given data */ 313 int usb_hid_report_output_translate(usb_hid_report_parser_t *parser, 314 usb_hid_report_path_t *path, int flags, 315 uint8_t *buffer, size_t size, 316 int32_t *data, size_t data_size); 338 /** Sets data in report structure */ 339 int usb_hid_report_output_set_data(usb_hid_report_t *report, 340 usb_hid_report_path_t *path, int flags, 341 int *data, size_t data_size); 342 343 /** Makes the output report buffer by translated given data */ 344 int usb_hid_report_output_translate(usb_hid_report_t *report, uint8_t report_id, uint8_t *buffer, size_t size); 317 345 #endif 318 346 /** -
uspace/lib/usb/include/usb/classes/hidreport.h
r152ec79 r9e929a0 57 57 */ 58 58 int usb_hid_process_report_descriptor(usb_device_t *dev, 59 usb_hid_report_ parser_t *parser);59 usb_hid_report_t *report); 60 60 61 61 #endif /* LIBUSB_HIDREPORT_H_ */ -
uspace/lib/usb/include/usb/classes/hidut.h
r152ec79 r9e929a0 46 46 USB_HIDUT_PAGE_KEYBOARD = 7, 47 47 USB_HIDUT_PAGE_LED = 8, 48 USB_HIDUT_PAGE_BUTTON = 9 49 /* USB_HIDUT_PAGE_ = , */ 48 USB_HIDUT_PAGE_BUTTON = 9, 49 USB_HIDUT_PAGE_ORDINAL = 0x0a, 50 USB_HIDUT_PAGE_TELEPHONY_DEVICE = 0x0b, 51 USB_HIDUT_PAGE_CONSUMER = 0x0c 50 52 } usb_hidut_usage_page_t; 51 53 -
uspace/lib/usb/src/hidparser.c
r152ec79 r9e929a0 39 39 #include <mem.h> 40 40 #include <usb/debug.h> 41 42 /** */ 41 #include <assert.h> 42 43 /** The new report item flag. Used to determine when the item is completly 44 * configured and should be added to the report structure 45 */ 43 46 #define USB_HID_NEW_REPORT_ITEM 1 44 47 45 /** */ 46 #define USB_HID_NO_ACTION 2 47 48 /** */ 48 /** No special action after the report descriptor tag is processed should be 49 * done 50 */ 51 #define USB_HID_NO_ACTION 2 52 53 #define USB_HID_RESET_OFFSET 3 54 55 /** Unknown tag was founded in report descriptor data*/ 49 56 #define USB_HID_UNKNOWN_TAG -99 50 57 … … 52 59 * Private descriptor parser functions 53 60 */ 61 int usb_hid_report_init(usb_hid_report_t *report); 62 int usb_hid_report_append_fields(usb_hid_report_t *report, usb_hid_report_item_t *report_item); 63 usb_hid_report_description_t * usb_hid_report_find_description(const usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type); 54 64 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size, 55 65 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); … … 61 71 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); 62 72 73 void usb_hid_print_usage_path(usb_hid_report_path_t *path); 63 74 void usb_hid_descriptor_print_list(link_t *head); 64 int usb_hid_report_reset_local_items();75 void usb_hid_report_reset_local_items(usb_hid_report_item_t *report_item); 65 76 void usb_hid_free_report_list(link_t *head); 66 77 usb_hid_report_item_t *usb_hid_report_item_clone(const usb_hid_report_item_t *item); … … 68 79 * Data translation private functions 69 80 */ 70 int32_t usb_hid_report_tag_data_int32(const uint8_t *data, size_t size);81 uint32_t usb_hid_report_tag_data_uint32(const uint8_t *data, size_t size); 71 82 inline size_t usb_hid_count_item_offset(usb_hid_report_item_t * report_item, size_t offset); 72 int usb_hid_translate_data(usb_hid_report_ item_t *item, const uint8_t *data, size_t j);73 int32_t usb_hid_translate_data_reverse(usb_hid_report_item_t *item, int32_t value);83 int usb_hid_translate_data(usb_hid_report_field_t *item, const uint8_t *data); 84 uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, int32_t value); 74 85 int usb_pow(int a, int b); 75 86 87 #define USB_HID_UINT32_TO_INT32(x, size) ((((x) & (1 << ((size) - 1))) != 0) ? -(~(x - 1) & ((1 << size) - 1)) : (x)) //(-(~((x) - 1))) 88 #define USB_HID_INT32_TO_UINT32(x, size) (((x) < 0 ) ? ((1 << (size)) + (x)) : (x)) 76 89 // TODO: tohle ma bejt asi jinde 77 90 int usb_pow(int a, int b) … … 96 109 * @return Error code 97 110 */ 98 int usb_hid_ parser_init(usb_hid_report_parser_t *parser)99 { 100 if( parser== NULL) {111 int usb_hid_report_init(usb_hid_report_t *report) 112 { 113 if(report == NULL) { 101 114 return EINVAL; 102 115 } 103 116 104 list_initialize(&(parser->input)); 105 list_initialize(&(parser->output)); 106 list_initialize(&(parser->feature)); 107 108 list_initialize(&(parser->stack)); 109 110 parser->use_report_id = 0; 117 memset(report, 0, sizeof(usb_hid_report_t)); 118 list_initialize(&report->reports); 119 list_initialize(&report->collection_paths); 120 121 report->use_report_ids = 0; 111 122 return EOK; 112 123 } 113 124 125 int usb_hid_report_append_fields(usb_hid_report_t *report, usb_hid_report_item_t *report_item) 126 { 127 usb_hid_report_field_t *field; 128 int i; 129 130 131 /* find or append current collection path to the list */ 132 link_t *path_it = report->collection_paths.next; 133 usb_hid_report_path_t *path = NULL; 134 while(path_it != &report->collection_paths) { 135 path = list_get_instance(path_it, usb_hid_report_path_t, link); 136 137 if(usb_hid_report_compare_usage_path(path, report_item->usage_path, USB_HID_PATH_COMPARE_STRICT) == EOK){ 138 break; 139 } 140 path_it = path_it->next; 141 } 142 if(path_it == &report->collection_paths) { 143 path = usb_hid_report_path_clone(report_item->usage_path); 144 list_append(&path->link, &report->collection_paths); 145 report->collection_paths_count++; 146 } 147 148 for(i=0; i<report_item->usages_count; i++){ 149 usb_log_debug("usages (%d) - %x\n", i, report_item->usages[i]); 150 } 151 152 153 for(i=0; i<report_item->count; i++){ 154 155 field = malloc(sizeof(usb_hid_report_field_t)); 156 memset(field, 0, sizeof(usb_hid_report_field_t)); 157 list_initialize(&field->link); 158 159 /* fill the attributes */ 160 field->collection_path = path; 161 field->logical_minimum = report_item->logical_minimum; 162 field->logical_maximum = report_item->logical_maximum; 163 field->physical_minimum = report_item->physical_minimum; 164 field->physical_maximum = report_item->physical_maximum; 165 166 field->usage_minimum = report_item->usage_minimum; 167 field->usage_maximum = report_item->usage_maximum; 168 if(report_item->extended_usage_page != 0){ 169 field->usage_page = report_item->extended_usage_page; 170 } 171 else { 172 field->usage_page = report_item->usage_page; 173 } 174 175 if(report_item->usages_count > 0 && ((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0))) { 176 uint32_t usage; 177 if(report_item->type != USB_HID_REPORT_TYPE_INPUT) { 178 if(i < report_item->usages_count){ 179 usage = report_item->usages[i]; 180 } 181 else { 182 usage = report_item->usages[report_item->usages_count - 1]; 183 } 184 } 185 else { 186 if((report_item->count - i - 1) < report_item->usages_count){ 187 usage = report_item->usages[(report_item->count - i - 1)]; 188 } 189 else { 190 usage = report_item->usages[report_item->usages_count - 1]; 191 } 192 } 193 194 195 if((usage & 0xFFFF0000) != 0){ 196 field->usage_page = (usage >> 16); 197 field->usage = (usage & 0xFFFF); 198 } 199 else { 200 field->usage = usage; 201 } 202 203 204 } 205 206 if((USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) != 0) && (!((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0)))) { 207 if(report_item->type == USB_HID_REPORT_TYPE_INPUT) { 208 field->usage = report_item->usage_maximum - i; 209 } 210 else { 211 field->usage = report_item->usage_minimum + i; 212 } 213 214 } 215 216 field->size = report_item->size; 217 field->offset = report_item->offset + (i * report_item->size); 218 if(report_item->id != 0) { 219 field->offset += 8; 220 report->use_report_ids = 1; 221 } 222 field->item_flags = report_item->item_flags; 223 224 /* find the right report list*/ 225 usb_hid_report_description_t *report_des; 226 report_des = usb_hid_report_find_description(report, report_item->id, report_item->type); 227 if(report_des == NULL){ 228 report_des = malloc(sizeof(usb_hid_report_description_t)); 229 memset(report_des, 0, sizeof(usb_hid_report_description_t)); 230 231 report_des->type = report_item->type; 232 report_des->report_id = report_item->id; 233 list_initialize (&report_des->link); 234 list_initialize (&report_des->report_items); 235 236 list_append(&report_des->link, &report->reports); 237 report->report_count++; 238 } 239 240 /* append this field to the end of founded report list */ 241 list_append (&field->link, &report_des->report_items); 242 243 /* update the sizes */ 244 report_des->bit_length += field->size; 245 report_des->item_length++; 246 247 } 248 249 250 return EOK; 251 } 252 253 usb_hid_report_description_t * usb_hid_report_find_description(const usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type) 254 { 255 link_t *report_it = report->reports.next; 256 usb_hid_report_description_t *report_des = NULL; 257 258 while(report_it != &report->reports) { 259 report_des = list_get_instance(report_it, usb_hid_report_description_t, link); 260 261 if((report_des->report_id == report_id) && (report_des->type == type)){ 262 return report_des; 263 } 264 265 report_it = report_it->next; 266 } 267 268 return NULL; 269 } 114 270 115 271 /** Parse HID report descriptor. … … 119 275 * @return Error code. 120 276 */ 121 int usb_hid_parse_report_descriptor(usb_hid_report_ parser_t *parser,277 int usb_hid_parse_report_descriptor(usb_hid_report_t *report, 122 278 const uint8_t *data, size_t size) 123 279 { … … 130 286 usb_hid_report_item_t *new_report_item; 131 287 usb_hid_report_path_t *usage_path; 132 usb_hid_report_path_t *tmp_usage_path;133 288 134 289 size_t offset_input=0; 135 290 size_t offset_output=0; 136 291 size_t offset_feature=0; 137 292 293 link_t stack; 294 list_initialize(&stack); 138 295 139 296 /* parser structure initialization*/ 140 if(usb_hid_ parser_init(parser) != EOK) {297 if(usb_hid_report_init(report) != EOK) { 141 298 return EINVAL; 142 299 } 143 300 144 145 301 /*report item initialization*/ 146 302 if(!(report_item=malloc(sizeof(usb_hid_report_item_t)))){ … … 159 315 160 316 if((i+USB_HID_ITEM_SIZE(data[i]))>= size){ 161 return EINVAL; // TODO ERROR CODE317 return EINVAL; 162 318 } 163 319 … … 165 321 item_size = USB_HID_ITEM_SIZE(data[i]); 166 322 class = USB_HID_ITEM_TAG_CLASS(data[i]); 167 168 usb_log_debug2(169 "i(%zu) data(%X) value(%X): TAG %d, class %u, size %u - ", i,170 data[i], usb_hid_report_tag_data_int32(data+i+1,item_size),171 tag, class, item_size);172 323 173 324 ret = usb_hid_report_parse_tag(tag,class,data+i+1, 174 325 item_size,report_item, usage_path); 175 usb_log_debug2("ret: %u\n", ret);176 326 switch(ret){ 177 327 case USB_HID_NEW_REPORT_ITEM: 178 328 // store report item to report and create the new one 179 usb_log_debug("\nNEW REPORT ITEM: %X",ret); 180 181 // store current usage path 329 // store current collection path 182 330 report_item->usage_path = usage_path; 183 331 184 // clone path to the new one185 tmp_usage_path = usb_hid_report_path_clone(usage_path);186 187 // swap188 usage_path = tmp_usage_path;189 tmp_usage_path = NULL;190 191 332 usb_hid_report_path_set_report_id(report_item->usage_path, report_item->id); 192 333 if(report_item->id != 0){ 193 parser->use_report_id= 1;334 report->use_report_ids = 1; 194 335 } 195 336 196 337 switch(tag) { 197 338 case USB_HID_REPORT_TAG_INPUT: 339 report_item->type = USB_HID_REPORT_TYPE_INPUT; 198 340 report_item->offset = offset_input; 199 341 offset_input += report_item->count * report_item->size; 200 usb_log_debug(" - INPUT\n");201 list_append(&(report_item->link), &(parser->input));202 342 break; 203 343 case USB_HID_REPORT_TAG_OUTPUT: 344 report_item->type = USB_HID_REPORT_TYPE_OUTPUT; 204 345 report_item->offset = offset_output; 205 346 offset_output += report_item->count * report_item->size; 206 usb_log_debug(" - OUTPUT\n");207 list_append(&(report_item->link), &(parser->output));208 347 209 348 break; 210 349 case USB_HID_REPORT_TAG_FEATURE: 350 report_item->type = USB_HID_REPORT_TYPE_FEATURE; 211 351 report_item->offset = offset_feature; 212 352 offset_feature += report_item->count * report_item->size; 213 usb_log_debug(" - FEATURE\n");214 list_append(&(report_item->link), &(parser->feature));215 353 break; 216 354 default: … … 218 356 break; 219 357 } 220 221 /* clone current state table to the new item */222 if(!(new_report_item = malloc(sizeof(usb_hid_report_item_t)))) {223 return ENOMEM;224 }225 memcpy(new_report_item,report_item, sizeof(usb_hid_report_item_t));226 link_initialize(&(new_report_item->link));227 358 359 /* 360 * append new fields to the report 361 * structure 362 */ 363 usb_hid_report_append_fields(report, report_item); 364 228 365 /* reset local items */ 229 new_report_item->usage_minimum = 0; 230 new_report_item->usage_maximum = 0; 231 new_report_item->designator_index = 0; 232 new_report_item->designator_minimum = 0; 233 new_report_item->designator_maximum = 0; 234 new_report_item->string_index = 0; 235 new_report_item->string_minimum = 0; 236 new_report_item->string_maximum = 0; 237 238 /* reset usage from current usage path */ 239 usb_hid_report_usage_path_t *path = list_get_instance(&usage_path->link, usb_hid_report_usage_path_t, link); 240 path->usage = 0; 241 242 report_item = new_report_item; 243 366 usb_hid_report_reset_local_items (report_item); 367 244 368 break; 369 370 case USB_HID_RESET_OFFSET: 371 offset_input = 0; 372 offset_output = 0; 373 offset_feature = 0; 374 usb_hid_report_path_set_report_id (usage_path, report_item->id); 375 break; 376 245 377 case USB_HID_REPORT_TAG_PUSH: 246 378 // push current state to stack 247 379 new_report_item = usb_hid_report_item_clone(report_item); 248 list_prepend (&parser->stack, &new_report_item->link); 249 380 usb_hid_report_path_t *tmp_path = usb_hid_report_path_clone(usage_path); 381 new_report_item->usage_path = tmp_path; 382 383 list_prepend (&new_report_item->link, &stack); 250 384 break; 251 385 case USB_HID_REPORT_TAG_POP: 252 386 // restore current state from stack 253 if(list_empty (& parser->stack)) {387 if(list_empty (&stack)) { 254 388 return EINVAL; 255 389 } 390 free(report_item); 391 392 report_item = list_get_instance(stack.next, usb_hid_report_item_t, link); 256 393 257 report_item = list_get_instance(&parser->stack, usb_hid_report_item_t, link); 258 list_remove (parser->stack.next); 394 usb_hid_report_usage_path_t *tmp_usage_path; 395 tmp_usage_path = list_get_instance(report_item->usage_path->link.prev, usb_hid_report_usage_path_t, link); 396 397 usb_hid_report_set_last_item(usage_path, tmp_usage_path->usage_page, tmp_usage_path->usage); 398 399 usb_hid_report_path_free(report_item->usage_path); 400 list_initialize(&report_item->usage_path->link); 401 list_remove (stack.next); 259 402 260 403 break; … … 279 422 } 280 423 281 282 /**283 * Parse input report.284 *285 * @param data Data for report286 * @param size Size of report287 * @param callbacks Callbacks for report actions288 * @param arg Custom arguments289 *290 * @return Error code291 */292 int usb_hid_boot_keyboard_input_report(const uint8_t *data, size_t size,293 const usb_hid_report_in_callbacks_t *callbacks, void *arg)294 {295 int i;296 usb_hid_report_item_t item;297 298 /* fill item due to the boot protocol report descriptor */299 // modifier keys are in the first byte300 uint8_t modifiers = data[0];301 302 item.offset = 2; /* second byte is reserved */303 item.size = 8;304 item.count = 6;305 item.usage_minimum = 0;306 item.usage_maximum = 255;307 item.logical_minimum = 0;308 item.logical_maximum = 255;309 310 if (size != 8) {311 return -1; //ERANGE;312 }313 314 uint8_t keys[6];315 for (i = 0; i < item.count; i++) {316 keys[i] = data[i + item.offset];317 }318 319 callbacks->keyboard(keys, 6, modifiers, arg);320 return EOK;321 }322 323 /**324 * Makes output report for keyboard boot protocol325 *326 * @param leds327 * @param output Output report data buffer328 * @param size Size of the output buffer329 * @return Error code330 */331 int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size)332 {333 if(size != 1){334 return -1;335 }336 337 /* used only first five bits, others are only padding*/338 *data = leds;339 return EOK;340 }341 424 342 425 /** … … 401 484 402 485 case USB_HID_REPORT_TAG_COLLECTION: 403 usb_hid_report_path_append_item(usage_path, 0, 0); 404 486 // TODO usage_path->flags = *data; 487 usb_hid_report_path_append_item(usage_path, report_item->usage_page, report_item->usages[report_item->usages_count-1]); 488 usb_hid_report_reset_local_items (report_item); 405 489 return USB_HID_NO_ACTION; 406 490 break; 407 491 408 492 case USB_HID_REPORT_TAG_END_COLLECTION: 409 // TODO410 // znici posledni uroven ve vsech usage paths411 // otazka jestli nema nicit dve, respektive novou posledni vynulovat?412 493 usb_hid_report_remove_last_item(usage_path); 413 494 return USB_HID_NO_ACTION; … … 436 517 { 437 518 case USB_HID_REPORT_TAG_USAGE_PAGE: 438 // zmeni to jenom v poslednim poli aktualni usage path 439 usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL, 440 usb_hid_report_tag_data_int32(data,item_size)); 519 report_item->usage_page = usb_hid_report_tag_data_uint32(data, item_size); 441 520 break; 442 521 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM: 443 report_item->logical_minimum = usb_hid_report_tag_data_int32(data,item_size);522 report_item->logical_minimum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8); 444 523 break; 445 524 case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM: 446 report_item->logical_maximum = usb_hid_report_tag_data_int32(data,item_size);525 report_item->logical_maximum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8); 447 526 break; 448 527 case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM: 449 report_item->physical_minimum = usb_hid_report_tag_data_int32(data,item_size);528 report_item->physical_minimum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8); 450 529 break; 451 530 case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM: 452 report_item->physical_maximum = usb_hid_report_tag_data_int32(data,item_size); 531 report_item->physical_maximum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8); 532 453 533 break; 454 534 case USB_HID_REPORT_TAG_UNIT_EXPONENT: 455 report_item->unit_exponent = usb_hid_report_tag_data_ int32(data,item_size);535 report_item->unit_exponent = usb_hid_report_tag_data_uint32(data,item_size); 456 536 break; 457 537 case USB_HID_REPORT_TAG_UNIT: 458 report_item->unit = usb_hid_report_tag_data_ int32(data,item_size);538 report_item->unit = usb_hid_report_tag_data_uint32(data,item_size); 459 539 break; 460 540 case USB_HID_REPORT_TAG_REPORT_SIZE: 461 report_item->size = usb_hid_report_tag_data_ int32(data,item_size);541 report_item->size = usb_hid_report_tag_data_uint32(data,item_size); 462 542 break; 463 543 case USB_HID_REPORT_TAG_REPORT_COUNT: 464 report_item->count = usb_hid_report_tag_data_ int32(data,item_size);544 report_item->count = usb_hid_report_tag_data_uint32(data,item_size); 465 545 break; 466 546 case USB_HID_REPORT_TAG_REPORT_ID: 467 report_item->id = usb_hid_report_tag_data_int32(data,item_size); 547 report_item->id = usb_hid_report_tag_data_uint32(data,item_size); 548 return USB_HID_RESET_OFFSET; 468 549 break; 469 550 case USB_HID_REPORT_TAG_PUSH: 470 551 case USB_HID_REPORT_TAG_POP: 552 /* 553 * stack operations are done in top level parsing 554 * function 555 */ 471 556 return tag; 472 557 break; … … 475 560 return USB_HID_NO_ACTION; 476 561 } 477 562 478 563 return EOK; 479 564 } … … 494 579 { 495 580 case USB_HID_REPORT_TAG_USAGE: 496 usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL,497 usb_hid_report_tag_data_int32(data,item_size));581 report_item->usages[report_item->usages_count] = usb_hid_report_tag_data_uint32(data,item_size); 582 report_item->usages_count++; 498 583 break; 499 584 case USB_HID_REPORT_TAG_USAGE_MINIMUM: 500 report_item->usage_minimum = usb_hid_report_tag_data_int32(data,item_size); 585 if (item_size == 3) { 586 // usage extended usages 587 report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16; 588 report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size) & 0xFF; 589 } 590 else { 591 report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size); 592 } 501 593 break; 502 594 case USB_HID_REPORT_TAG_USAGE_MAXIMUM: 503 report_item->usage_maximum = usb_hid_report_tag_data_int32(data,item_size); 595 if (item_size == 3) { 596 // usage extended usages 597 report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16; 598 report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size) & 0xFF; 599 } 600 else { 601 report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size); 602 } 504 603 break; 505 604 case USB_HID_REPORT_TAG_DESIGNATOR_INDEX: 506 report_item->designator_index = usb_hid_report_tag_data_ int32(data,item_size);605 report_item->designator_index = usb_hid_report_tag_data_uint32(data,item_size); 507 606 break; 508 607 case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM: 509 report_item->designator_minimum = usb_hid_report_tag_data_ int32(data,item_size);608 report_item->designator_minimum = usb_hid_report_tag_data_uint32(data,item_size); 510 609 break; 511 610 case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM: 512 report_item->designator_maximum = usb_hid_report_tag_data_ int32(data,item_size);611 report_item->designator_maximum = usb_hid_report_tag_data_uint32(data,item_size); 513 612 break; 514 613 case USB_HID_REPORT_TAG_STRING_INDEX: 515 report_item->string_index = usb_hid_report_tag_data_ int32(data,item_size);614 report_item->string_index = usb_hid_report_tag_data_uint32(data,item_size); 516 615 break; 517 616 case USB_HID_REPORT_TAG_STRING_MINIMUM: 518 report_item->string_minimum = usb_hid_report_tag_data_ int32(data,item_size);617 report_item->string_minimum = usb_hid_report_tag_data_uint32(data,item_size); 519 618 break; 520 619 case USB_HID_REPORT_TAG_STRING_MAXIMUM: 521 report_item->string_maximum = usb_hid_report_tag_data_ int32(data,item_size);620 report_item->string_maximum = usb_hid_report_tag_data_uint32(data,item_size); 522 621 break; 523 622 case USB_HID_REPORT_TAG_DELIMITER: 524 report_item->delimiter = usb_hid_report_tag_data_int32(data,item_size); 623 //report_item->delimiter = usb_hid_report_tag_data_uint32(data,item_size); 624 //TODO: 625 // DELIMITER STUFF 525 626 break; 526 627 … … 533 634 534 635 /** 535 * Converts raw data to int32 (thats the maximum length of short item data)636 * Converts raw data to uint32 (thats the maximum length of short item data) 536 637 * 537 638 * @param Data buffer … … 539 640 * @return Converted int32 number 540 641 */ 541 int32_t usb_hid_report_tag_data_int32(const uint8_t *data, size_t size)642 uint32_t usb_hid_report_tag_data_uint32(const uint8_t *data, size_t size) 542 643 { 543 644 unsigned int i; 544 int32_t result;645 uint32_t result; 545 646 546 647 result = 0; … … 552 653 } 553 654 554 555 556 655 /** 557 656 * Prints content of given list of report items. … … 562 661 void usb_hid_descriptor_print_list(link_t *head) 563 662 { 564 usb_hid_report_item_t *report_item; 565 usb_hid_report_usage_path_t *path_item; 566 link_t *path; 663 usb_hid_report_field_t *report_item; 567 664 link_t *item; 568 665 666 569 667 if(head == NULL || list_empty(head)) { 570 668 usb_log_debug("\tempty\n"); … … 574 672 for(item = head->next; item != head; item = item->next) { 575 673 576 report_item = list_get_instance(item, usb_hid_report_item_t, link); 577 578 usb_log_debug("\tOFFSET: %zX\n", report_item->offset); 579 usb_log_debug("\tCOUNT: %X\n", report_item->count); 580 usb_log_debug("\tSIZE: %X\n", report_item->size); 581 usb_log_debug("\tCONSTANT/VAR: %X\n", USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags)); 582 usb_log_debug("\tVARIABLE/ARRAY: %X\n", USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags)); 583 usb_log_debug("\tUSAGE PATH:\n"); 584 585 path = report_item->usage_path->link.next; 586 while(path != &report_item->usage_path->link) { 587 path_item = list_get_instance(path, usb_hid_report_usage_path_t, link); 588 usb_log_debug("\t\tUSAGE PAGE: %X, USAGE: %X\n", path_item->usage_page, path_item->usage); 589 path = path->next; 590 } 591 592 usb_log_debug("\tLOGMIN: %X\n", report_item->logical_minimum); 593 usb_log_debug("\tLOGMAX: %X\n", report_item->logical_maximum); 594 usb_log_debug("\tPHYMIN: %X\n", report_item->physical_minimum); 595 usb_log_debug("\tPHYMAX: %X\n", report_item->physical_maximum); 596 usb_log_debug("\tUSAGEMIN: %X\n", report_item->usage_minimum); 597 usb_log_debug("\tUSAGEMAX: %X\n", report_item->usage_maximum); 598 599 usb_log_debug("\n"); 674 report_item = list_get_instance(item, usb_hid_report_field_t, link); 675 676 usb_log_debug("\t\tOFFSET: %X\n", report_item->offset); 677 usb_log_debug("\t\tSIZE: %X\n", report_item->size); 678 usb_log_debug("\t\tLOGMIN: %d\n", report_item->logical_minimum); 679 usb_log_debug("\t\tLOGMAX: %d\n", report_item->logical_maximum); 680 usb_log_debug("\t\tPHYMIN: %d\n", report_item->physical_minimum); 681 usb_log_debug("\t\tPHYMAX: %d\n", report_item->physical_maximum); 682 usb_log_debug("\t\ttUSAGEMIN: %X\n", report_item->usage_minimum); 683 usb_log_debug("\t\tUSAGEMAX: %X\n", report_item->usage_maximum); 684 685 usb_log_debug("\t\tVALUE: %X\n", report_item->value); 686 usb_log_debug("\t\ttUSAGE: %X\n", report_item->usage); 687 usb_log_debug("\t\tUSAGE PAGE: %X\n", report_item->usage_page); 688 689 // usb_log_debug("\n"); 600 690 601 691 } … … 609 699 * @return void 610 700 */ 611 void usb_hid_descriptor_print(usb_hid_report_ parser_t *parser)612 { 613 if( parser== NULL) {701 void usb_hid_descriptor_print(usb_hid_report_t *report) 702 { 703 if(report == NULL) { 614 704 return; 615 705 } 616 617 usb_log_debug("INPUT:\n"); 618 usb_hid_descriptor_print_list(&parser->input); 619 620 usb_log_debug("OUTPUT: \n"); 621 usb_hid_descriptor_print_list(&parser->output); 622 623 usb_log_debug("FEATURE:\n"); 624 usb_hid_descriptor_print_list(&parser->feature); 625 706 707 link_t *report_it = report->reports.next; 708 usb_hid_report_description_t *report_des; 709 710 while(report_it != &report->reports) { 711 report_des = list_get_instance(report_it, usb_hid_report_description_t, link); 712 usb_log_debug("Report ID: %d\n", report_des->report_id); 713 usb_log_debug("\tType: %d\n", report_des->type); 714 usb_log_debug("\tLength: %d\n", report_des->bit_length); 715 usb_log_debug("\tItems: %d\n", report_des->item_length); 716 717 usb_hid_descriptor_print_list(&report_des->report_items); 718 719 720 link_t *path_it = report->collection_paths.next; 721 while(path_it != &report->collection_paths) { 722 usb_hid_print_usage_path (list_get_instance(path_it, usb_hid_report_path_t, link)); 723 path_it = path_it->next; 724 } 725 726 report_it = report_it->next; 727 } 626 728 } 627 729 … … 667 769 * @return void 668 770 */ 669 void usb_hid_free_report _parser(usb_hid_report_parser_t *parser)670 { 671 if( parser== NULL){771 void usb_hid_free_report(usb_hid_report_t *report) 772 { 773 if(report == NULL){ 672 774 return; 673 775 } 674 776 675 parser->use_report_id = 0; 676 677 usb_hid_free_report_list(&parser->input); 678 usb_hid_free_report_list(&parser->output); 679 usb_hid_free_report_list(&parser->feature); 680 777 // free collection paths 778 usb_hid_report_path_t *path; 779 while(!list_empty(&report->collection_paths)) { 780 path = list_get_instance(report->collection_paths.next, usb_hid_report_path_t, link); 781 usb_hid_report_path_free(path); 782 } 783 784 // free report items 785 usb_hid_report_description_t *report_des; 786 usb_hid_report_field_t *field; 787 while(!list_empty(&report->reports)) { 788 report_des = list_get_instance(report->reports.next, usb_hid_report_description_t, link); 789 list_remove(&report_des->link); 790 791 while(!list_empty(&report_des->report_items)) { 792 field = list_get_instance(report_des->report_items.next, usb_hid_report_field_t, link); 793 list_remove(&field->link); 794 795 free(field); 796 } 797 798 free(report_des); 799 } 800 681 801 return; 682 802 } … … 688 808 * @param parser Opaque HID report parser structure. 689 809 * @param data Data for the report. 690 * @param callbacks Callbacks for report actions.691 * @param arg Custom argument (passed through to the callbacks).692 810 * @return Error code. 693 811 */ 694 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 695 const uint8_t *data, size_t size, 696 usb_hid_report_path_t *path, int flags, 697 const usb_hid_report_in_callbacks_t *callbacks, void *arg) 812 int usb_hid_parse_report(const usb_hid_report_t *report, 813 const uint8_t *data, size_t size, uint8_t *report_id) 698 814 { 699 815 link_t *list_item; 700 usb_hid_report_item_t *item; 701 uint8_t *keys; 702 uint8_t item_value; 703 size_t key_count=0; 704 size_t i=0; 705 size_t j=0; 706 uint8_t report_id = 0; 707 708 if(parser == NULL) { 816 usb_hid_report_field_t *item; 817 818 usb_hid_report_description_t *report_des; 819 usb_hid_report_type_t type = USB_HID_REPORT_TYPE_INPUT; 820 821 if(report == NULL) { 709 822 return EINVAL; 710 823 } 711 712 /* get the size of result array */ 713 key_count = usb_hid_report_input_length(parser, path, flags); 714 715 if(!(keys = malloc(sizeof(uint8_t) * key_count))){ 716 return ENOMEM; 717 } 718 719 if(parser->use_report_id != 0) { 720 report_id = data[0]; 721 usb_hid_report_path_set_report_id(path, report_id); 722 } 824 825 if(report->use_report_ids != 0) { 826 *report_id = data[0]; 827 } 828 else { 829 *report_id = 0; 830 } 831 832 833 report_des = usb_hid_report_find_description(report, *report_id, type); 723 834 724 835 /* read data */ 725 list_item = parser->input.next; 726 while(list_item != &(parser->input)) { 727 728 item = list_get_instance(list_item, usb_hid_report_item_t, link); 729 730 if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) && 731 (usb_hid_report_compare_usage_path(item->usage_path, path, flags) == EOK)) { 732 for(j=0; j<(size_t)(item->count); j++) { 733 if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0) || 734 ((item->usage_minimum == 0) && (item->usage_maximum == 0))) { 735 // variable item 736 keys[i++] = usb_hid_translate_data(item, data,j); 737 } 738 else { 739 // bitmapa 740 if((item_value = usb_hid_translate_data(item, data, j)) != 0) { 741 keys[i++] = (item->count - 1 - j) + item->usage_minimum; 742 } 743 else { 744 keys[i++] = 0; 745 } 746 } 747 } 836 list_item = report_des->report_items.next; 837 while(list_item != &(report_des->report_items)) { 838 839 item = list_get_instance(list_item, usb_hid_report_field_t, link); 840 841 if(USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) == 0) { 842 843 if(USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0) { 844 845 // array 846 item->value = usb_hid_translate_data(item, data); 847 item->usage = (item->value - item->physical_minimum) + item->usage_minimum; 848 } 849 else { 850 // variable item 851 item->value = usb_hid_translate_data(item, data); 852 } 748 853 } 749 854 list_item = list_item->next; 750 855 } 751 752 callbacks->keyboard(keys, key_count, report_id, arg);753 856 754 free(keys);755 857 return EOK; 756 858 … … 758 860 759 861 /** 760 * Translate data from the report as specified in report descriptor 862 * Translate data from the report as specified in report descriptor item 761 863 * 762 864 * @param item Report descriptor item with definition of translation … … 765 867 * @return Translated data 766 868 */ 767 int usb_hid_translate_data(usb_hid_report_ item_t *item, const uint8_t *data, size_t j)869 int usb_hid_translate_data(usb_hid_report_field_t *item, const uint8_t *data) 768 870 { 769 871 int resolution; … … 771 873 int part_size; 772 874 773 int32_t value ;875 int32_t value=0; 774 876 int32_t mask; 775 877 const uint8_t *foo; 776 878 777 // now only common numbersllowed879 // now only shot tags are allowed 778 880 if(item->size > 32) { 779 881 return 0; 780 882 } 781 883 782 if((item->physical_minimum == 0) && (item->physical_maximum == 0)) 884 if((item->physical_minimum == 0) && (item->physical_maximum == 0)){ 783 885 item->physical_minimum = item->logical_minimum; 784 item->physical_maximum = item->logical_maximum; 785 } 886 item->physical_maximum = item->logical_maximum; 887 } 888 786 889 787 890 if(item->physical_maximum == item->physical_minimum){ … … 794 897 } 795 898 796 offset = item->offset + (j * item->size); 797 if(item->id != 0) { 798 offset += 8; 799 usb_log_debug("MOVED OFFSET BY 1Byte, REPORT_ID(%d)\n", item->id); 800 } 801 899 offset = item->offset; 802 900 // FIXME 803 if((offset/8) != ((offset+item->size)/8)) { 804 usb_log_debug2("offset %d\n", offset); 901 if((size_t)(offset/8) != (size_t)((offset+item->size-1)/8)) { 805 902 806 903 part_size = ((offset+item->size)%8); 807 usb_log_debug2("part size %d\n",part_size); 808 809 // the higher one 810 foo = data+(offset/8); 811 mask = ((1 << (item->size-part_size))-1); 812 value = (*foo & mask) << part_size; 813 814 usb_log_debug2("hfoo %x\n", *foo); 815 usb_log_debug2("hmaska %x\n", mask); 816 usb_log_debug2("hval %d\n", value); 817 818 // the lower one 819 foo = data+((offset+item->size)/8); 820 mask = ((1 << part_size)-1) << (8-part_size); 821 value += ((*foo & mask) >> (8-part_size)); 822 823 usb_log_debug2("lfoo %x\n", *foo); 824 usb_log_debug2("lmaska %x\n", mask); 825 usb_log_debug2("lval %d\n", ((*foo & mask) >> (8-(item->size-part_size)))); 826 usb_log_debug2("val %d\n", value); 827 828 904 905 size_t i=0; 906 for(i=(size_t)(offset/8); i<=(size_t)(offset+item->size-1)/8; i++){ 907 if(i == (size_t)(offset/8)) { 908 // the higher one 909 foo = data + i; 910 mask = ((1 << (item->size-part_size))-1); 911 value = (*foo & mask) << part_size; 912 } 913 else if(i == ((offset+item->size-1)/8)){ 914 // the lower one 915 foo = data + i; 916 mask = ((1 << part_size)-1) << (8-part_size); 917 value += ((*foo & mask) >> (8-part_size)); 918 } 919 else { 920 value = value << 8; 921 value += *(data + 1); 922 } 923 } 829 924 } 830 925 else { … … 832 927 mask = ((1 << item->size)-1) << (8-((offset%8)+item->size)); 833 928 value = (*foo & mask) >> (8-((offset%8)+item->size)); 834 835 usb_log_debug2("offset %d\n", offset); 836 837 usb_log_debug2("foo %x\n", *foo); 838 usb_log_debug2("maska %x\n", mask); 839 usb_log_debug2("val %d\n", value); 840 } 841 842 usb_log_debug2("---\n\n"); 929 } 930 931 if((item->logical_minimum < 0) || (item->logical_maximum < 0)){ 932 value = USB_HID_UINT32_TO_INT32(value, item->size); 933 } 843 934 844 935 return (int)(((value - item->logical_minimum) / resolution) + item->physical_minimum); … … 847 938 848 939 /** 849 * 850 * 851 * @param parser 852 * @param path 853 * @param flags 854 * @return 855 */ 856 size_t usb_hid_report_input_length(const usb_hid_report_ parser_t *parser,940 * Returns number of items in input report which are accessible by given usage path 941 * 942 * @param parser Opaque report descriptor structure 943 * @param path Usage path specification 944 * @param flags Usage path comparison flags 945 * @return Number of items in input report 946 */ 947 size_t usb_hid_report_input_length(const usb_hid_report_t *report, 857 948 usb_hid_report_path_t *path, int flags) 858 949 { 950 859 951 size_t ret = 0; 860 link_t *item; 861 usb_hid_report_item_t *report_item; 862 863 if(parser == NULL) { 952 953 if(report == NULL) { 864 954 return 0; 865 955 } 866 867 item = parser->input.next; 868 while(&parser->input != item) { 869 report_item = list_get_instance(item, usb_hid_report_item_t, link); 870 if(!USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags) && 871 (usb_hid_report_compare_usage_path(report_item->usage_path, path, flags) == EOK)) { 872 ret += report_item->count; 873 } 874 875 item = item->next; 876 } 956 957 usb_hid_report_description_t *report_des; 958 report_des = usb_hid_report_find_description (report, path->report_id, USB_HID_REPORT_TYPE_INPUT); 959 if(report_des == NULL) { 960 return 0; 961 } 962 963 link_t *field_it = report_des->report_items.next; 964 usb_hid_report_field_t *field; 965 while(field_it != &report_des->report_items) { 966 967 field = list_get_instance(field_it, usb_hid_report_field_t, link); 968 if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) { 969 970 usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage); 971 if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK) { 972 ret++; 973 } 974 usb_hid_report_remove_last_item (field->collection_path); 975 } 976 977 field_it = field_it->next; 978 } 877 979 878 980 return ret; 879 } 880 881 882 /** 883 * 884 * @param usage_path 885 * @param usage_page 886 * @param usage 887 * @return 981 } 982 983 984 /** 985 * Appends one item (couple of usage_path and usage) into the usage path 986 * structure 987 * 988 * @param usage_path Usage path structure 989 * @param usage_page Usage page constant 990 * @param usage Usage constant 991 * @return Error code 888 992 */ 889 993 int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path, … … 899 1003 item->usage = usage; 900 1004 item->usage_page = usage_page; 901 902 usb_log_debug("Appending usage %d, usage page %d\n", usage, usage_page); 903 904 list_append (&usage_path->link, &item->link); 1005 item->flags = 0; 1006 1007 list_append (&item->link, &usage_path->head); 905 1008 usage_path->depth++; 906 1009 return EOK; … … 908 1011 909 1012 /** 910 * 911 * @param usage_path 912 * @return 1013 * Removes last item from the usage path structure 1014 * @param usage_path 1015 * @return void 913 1016 */ 914 1017 void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path) … … 916 1019 usb_hid_report_usage_path_t *item; 917 1020 918 if(!list_empty(&usage_path-> link)){919 item = list_get_instance(usage_path-> link.prev, usb_hid_report_usage_path_t, link);920 list_remove(usage_path-> link.prev);1021 if(!list_empty(&usage_path->head)){ 1022 item = list_get_instance(usage_path->head.prev, usb_hid_report_usage_path_t, link); 1023 list_remove(usage_path->head.prev); 921 1024 usage_path->depth--; 922 1025 free(item); … … 925 1028 926 1029 /** 1030 * Nulls last item of the usage path structure. 927 1031 * 928 1032 * @param usage_path 929 * @return 1033 * @return void 930 1034 */ 931 1035 void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path) … … 933 1037 usb_hid_report_usage_path_t *item; 934 1038 935 if(!list_empty(&usage_path-> link)){936 item = list_get_instance(usage_path-> link.prev, usb_hid_report_usage_path_t, link);1039 if(!list_empty(&usage_path->head)){ 1040 item = list_get_instance(usage_path->head.prev, usb_hid_report_usage_path_t, link); 937 1041 memset(item, 0, sizeof(usb_hid_report_usage_path_t)); 938 1042 } … … 940 1044 941 1045 /** 942 * 943 * @param usage_path 944 * @param tag 945 * @param data 946 * @return 1046 * Modifies last item of usage path structure by given usage page or usage 1047 * 1048 * @param usage_path Opaque usage path structure 1049 * @param tag Class of currently processed tag (Usage page tag falls into Global 1050 * class but Usage tag into the Local) 1051 * @param data Value of the processed tag 1052 * @return void 947 1053 */ 948 1054 void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, int32_t tag, int32_t data) … … 950 1056 usb_hid_report_usage_path_t *item; 951 1057 952 if(!list_empty(&usage_path-> link)){953 item = list_get_instance(usage_path-> link.prev, usb_hid_report_usage_path_t, link);1058 if(!list_empty(&usage_path->head)){ 1059 item = list_get_instance(usage_path->head.prev, usb_hid_report_usage_path_t, link); 954 1060 955 1061 switch(tag) { … … 965 1071 } 966 1072 967 /** 968 * 969 * 970 * @param report_path 971 * @param path 972 * @param flags 973 * @return 1073 1074 void usb_hid_print_usage_path(usb_hid_report_path_t *path) 1075 { 1076 usb_log_debug("USAGE_PATH FOR RId(%d):\n", path->report_id); 1077 usb_log_debug("\tLENGTH: %d\n", path->depth); 1078 1079 link_t *item = path->head.next; 1080 usb_hid_report_usage_path_t *path_item; 1081 while(item != &path->head) { 1082 1083 path_item = list_get_instance(item, usb_hid_report_usage_path_t, link); 1084 usb_log_debug("\tUSAGE_PAGE: %X\n", path_item->usage_page); 1085 usb_log_debug("\tUSAGE: %X\n", path_item->usage); 1086 usb_log_debug("\tFLAGS: %d\n", path_item->flags); 1087 1088 item = item->next; 1089 } 1090 } 1091 1092 /** 1093 * Compares two usage paths structures 1094 * 1095 * If USB_HID_PATH_COMPARE_COLLECTION_ONLY flag is given, the last item in report_path structure is forgotten 1096 * 1097 * @param report_path usage path structure to compare 1098 * @param path usage patrh structure to compare 1099 * @param flags Flags determining the mode of comparison 1100 * @return EOK if both paths are identical, non zero number otherwise 974 1101 */ 975 1102 int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path, … … 1005 1132 } 1006 1133 1007 report_link = report_path-> link.next;1008 path_link = path-> link.next;1134 report_link = report_path->head.next; 1135 path_link = path->head.next; 1009 1136 1010 while((report_link != &report_path-> link) && (path_link != &path->link)) {1137 while((report_link != &report_path->head) && (path_link != &path->head)) { 1011 1138 report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link); 1012 1139 path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link); … … 1022 1149 } 1023 1150 1024 if((report_link == &report_path->link) && (path_link == &path->link)) { 1151 if(((report_link == &report_path->head) && (path_link == &path->head)) || 1152 (((flags & USB_HID_PATH_COMPARE_COLLECTION_ONLY) != 0) && (path_link = &path->head) && (report_link == report_path->head.prev))) { 1025 1153 return EOK; 1026 1154 } … … 1032 1160 /* compare with only the end of path*/ 1033 1161 case USB_HID_PATH_COMPARE_END: 1034 report_link = report_path->link.prev; 1035 path_link = path->link.prev; 1036 1037 if(list_empty(&path->link)){ 1162 1163 if((flags & USB_HID_PATH_COMPARE_COLLECTION_ONLY) != 0) { 1164 report_link = report_path->head.prev->prev; 1165 } 1166 else { 1167 report_link = report_path->head.prev; 1168 } 1169 path_link = path->head.prev; 1170 1171 if(list_empty(&path->head)){ 1038 1172 return EOK; 1039 1173 } 1040 1174 1041 while((report_link != &report_path-> link) && (path_link != &path->link)) {1175 while((report_link != &report_path->head) && (path_link != &path->head)) { 1042 1176 report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link); 1043 1177 path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link); … … 1053 1187 } 1054 1188 1055 if(path_link == &path-> link) {1189 if(path_link == &path->head) { 1056 1190 return EOK; 1057 1191 } … … 1072 1206 1073 1207 /** 1074 * 1075 * @return 1208 * Allocates and initializes new usage path structure. 1209 * 1210 * @return Initialized usage path structure 1076 1211 */ 1077 1212 usb_hid_report_path_t *usb_hid_report_path(void) … … 1079 1214 usb_hid_report_path_t *path; 1080 1215 path = malloc(sizeof(usb_hid_report_path_t)); 1081 if( !path){1216 if(path == NULL){ 1082 1217 return NULL; 1083 1218 } … … 1086 1221 path->report_id = 0; 1087 1222 list_initialize(&path->link); 1223 list_initialize(&path->head); 1088 1224 return path; 1089 1225 } … … 1091 1227 1092 1228 /** 1093 * 1094 * @param path 1229 * Releases given usage path structure. 1230 * 1231 * @param path usage path structure to release 1095 1232 * @return void 1096 1233 */ 1097 1234 void usb_hid_report_path_free(usb_hid_report_path_t *path) 1098 1235 { 1099 while(!list_empty(&path-> link)){1236 while(!list_empty(&path->head)){ 1100 1237 usb_hid_report_remove_last_item(path); 1101 1238 } 1239 1240 list_remove(&path->link); 1241 free(path); 1102 1242 } 1103 1243 … … 1106 1246 * Clone content of given usage path to the new one 1107 1247 * 1108 * @param usage_path 1109 * @return 1248 * @param usage_path Usage path structure to clone 1249 * @return New copy of given usage path structure 1110 1250 */ 1111 1251 usb_hid_report_path_t *usb_hid_report_path_clone(usb_hid_report_path_t *usage_path) 1112 1252 { 1253 link_t *path_link; 1113 1254 usb_hid_report_usage_path_t *path_item; 1114 link_t *path_link;1255 usb_hid_report_usage_path_t *new_path_item; 1115 1256 usb_hid_report_path_t *new_usage_path = usb_hid_report_path (); 1116 1257 … … 1118 1259 return NULL; 1119 1260 } 1120 1121 if(list_empty(&usage_path->link)){ 1261 1262 new_usage_path->report_id = usage_path->report_id; 1263 1264 if(list_empty(&usage_path->head)){ 1122 1265 return new_usage_path; 1123 1266 } 1124 1267 1125 path_link = usage_path-> link.next;1126 while(path_link != &usage_path-> link) {1268 path_link = usage_path->head.next; 1269 while(path_link != &usage_path->head) { 1127 1270 path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link); 1128 usb_hid_report_path_append_item (new_usage_path, path_item->usage_page, path_item->usage); 1271 new_path_item = malloc(sizeof(usb_hid_report_usage_path_t)); 1272 if(new_path_item == NULL) { 1273 return NULL; 1274 } 1275 1276 list_initialize (&new_path_item->link); 1277 new_path_item->usage_page = path_item->usage_page; 1278 new_path_item->usage = path_item->usage; 1279 new_path_item->flags = path_item->flags; 1280 1281 list_append(&new_path_item->link, &new_usage_path->head); 1282 new_usage_path->depth++; 1129 1283 1130 1284 path_link = path_link->next; … … 1137 1291 /*** OUTPUT API **/ 1138 1292 1139 /** Allocates output report buffer 1140 * 1141 * @param parser 1142 * @param size 1143 * @return 1144 */ 1145 uint8_t *usb_hid_report_output(usb_hid_report_parser_t *parser, size_t *size) 1146 { 1147 if(parser == NULL) { 1293 /** 1294 * Allocates output report buffer for output report 1295 * 1296 * @param parser Report parsed structure 1297 * @param size Size of returned buffer 1298 * @param report_id Report id of created output report 1299 * @return Returns allocated output buffer for specified output 1300 */ 1301 uint8_t *usb_hid_report_output(usb_hid_report_t *report, size_t *size, uint8_t report_id) 1302 { 1303 if(report == NULL) { 1148 1304 *size = 0; 1149 1305 return NULL; 1150 1306 } 1151 1152 // read the last output report item1153 usb_hid_report_ item_t *last;1154 link_t *link;1155 1156 link = parser->output.prev;1157 if(link != &parser->output) {1158 last = list_get_instance(link, usb_hid_report_item_t, link);1159 *size = (last->offset + (last->size * last->count)) / 8; 1160 1161 uint8_t *buffer = malloc(sizeof(uint8_t) * (*size));1162 memset(buffer, 0, sizeof(uint8_t) * (*size)); 1163 usb_log_debug("output buffer: %s\n", usb_debug_str_buffer(buffer, *size, 0));1164 1165 return buffer;1307 1308 link_t *report_it = report->reports.next; 1309 usb_hid_report_description_t *report_des = NULL; 1310 while(report_it != &report->reports) { 1311 report_des = list_get_instance(report_it, usb_hid_report_description_t, link); 1312 if((report_des->report_id == report_id) && (report_des->type == USB_HID_REPORT_TYPE_OUTPUT)){ 1313 break; 1314 } 1315 1316 report_it = report_it->next; 1317 } 1318 1319 if(report_des == NULL){ 1320 *size = 0; 1321 return NULL; 1166 1322 } 1167 1323 else { 1168 *size = 0; 1169 return NULL; 1324 *size = (report_des->bit_length + (8 - 1))/8; 1325 uint8_t *ret = malloc((*size) * sizeof(uint8_t)); 1326 memset(ret, 0, (*size) * sizeof(uint8_t)); 1327 return ret; 1170 1328 } 1171 1329 } … … 1175 1333 * 1176 1334 * @param output Output report buffer 1177 * @return 1335 * @return void 1178 1336 */ 1179 1337 void usb_hid_report_output_free(uint8_t *output) … … 1187 1345 /** Returns size of output for given usage path 1188 1346 * 1189 * @param parser 1190 * @param path 1191 * @param flags 1192 * @return 1193 */ 1194 size_t usb_hid_report_output_size(usb_hid_report_ parser_t *parser,1347 * @param parser Opaque report parser structure 1348 * @param path Usage path specified which items will be thought for the output 1349 * @param flags Flags of usage path structure comparison 1350 * @return Number of items matching the given usage path 1351 */ 1352 size_t usb_hid_report_output_size(usb_hid_report_t *report, 1195 1353 usb_hid_report_path_t *path, int flags) 1196 1354 { 1197 size_t ret = 0; 1198 link_t *item; 1199 usb_hid_report_item_t *report_item; 1200 1201 if(parser == NULL) { 1355 size_t ret = 0; 1356 usb_hid_report_description_t *report_des; 1357 1358 if(report == NULL) { 1202 1359 return 0; 1203 1360 } 1204 1361 1205 item = parser->output.next; 1206 while(&parser->output != item) { 1207 report_item = list_get_instance(item, usb_hid_report_item_t, link); 1208 if(!USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags) && 1209 (usb_hid_report_compare_usage_path(report_item->usage_path, path, flags) == EOK)) { 1210 ret += report_item->count; 1211 } 1212 1213 item = item->next; 1214 } 1362 report_des = usb_hid_report_find_description (report, path->report_id, USB_HID_REPORT_TYPE_OUTPUT); 1363 if(report_des == NULL){ 1364 return 0; 1365 } 1366 1367 link_t *field_it = report_des->report_items.next; 1368 usb_hid_report_field_t *field; 1369 while(field_it != &report_des->report_items) { 1370 1371 field = list_get_instance(field_it, usb_hid_report_field_t, link); 1372 if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0){ 1373 usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage); 1374 if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK) { 1375 ret++; 1376 } 1377 usb_hid_report_remove_last_item (field->collection_path); 1378 } 1379 1380 field_it = field_it->next; 1381 } 1215 1382 1216 1383 return ret; … … 1218 1385 } 1219 1386 1220 /** Updates the output report buffer by translated given data 1221 * 1222 * @param parser 1223 * @param path 1224 * @param flags 1225 * @param buffer 1226 * @param size 1227 * @param data 1228 * @param data_size 1229 * @return 1230 */ 1231 int usb_hid_report_output_translate(usb_hid_report_parser_t *parser, 1232 usb_hid_report_path_t *path, int flags, 1233 uint8_t *buffer, size_t size, 1234 int32_t *data, size_t data_size) 1235 { 1236 usb_hid_report_item_t *report_item; 1387 /** Makes the output report buffer for data given in the report structure 1388 * 1389 * @param parser Opaque report parser structure 1390 * @param path Usage path specifing which parts of output will be set 1391 * @param flags Usage path structure comparison flags 1392 * @param buffer Output buffer 1393 * @param size Size of output buffer 1394 * @return Error code 1395 */ 1396 int usb_hid_report_output_translate(usb_hid_report_t *report, uint8_t report_id, 1397 uint8_t *buffer, size_t size) 1398 { 1237 1399 link_t *item; 1238 size_t idx=0;1239 int i=0;1240 1400 int32_t value=0; 1241 1401 int offset; 1242 1402 int length; 1243 1403 int32_t tmp_value; 1244 size_t offset_prefix = 0; 1245 1246 if(parser == NULL) { 1404 1405 if(report == NULL) { 1247 1406 return EINVAL; 1248 1407 } 1249 1408 1250 if(parser->use_report_id != 0) { 1251 buffer[0] = path->report_id; 1252 offset_prefix = 8; 1409 if(report->use_report_ids != 0) { 1410 buffer[0] = report_id; 1253 1411 } 1254 1412 1255 1413 usb_log_debug("OUTPUT BUFFER: %s\n", usb_debug_str_buffer(buffer,size, 0)); 1256 usb_log_debug("OUTPUT DATA[0]: %d, DATA[1]: %d, DATA[2]: %d\n", data[0], data[1], data[2]); 1257 1258 item = parser->output.next; 1259 while(item != &parser->output) { 1260 report_item = list_get_instance(item, usb_hid_report_item_t, link); 1261 1262 for(i=0; i<report_item->count; i++) { 1263 1264 if(idx >= data_size) { 1265 break; 1266 } 1267 1268 if((USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) || 1269 ((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0))) { 1414 1415 usb_hid_report_description_t *report_des; 1416 report_des = usb_hid_report_find_description (report, report_id, USB_HID_REPORT_TYPE_OUTPUT); 1417 if(report_des == NULL){ 1418 return EINVAL; 1419 } 1420 1421 usb_hid_report_field_t *report_item; 1422 item = report_des->report_items.next; 1423 while(item != &report_des->report_items) { 1424 report_item = list_get_instance(item, usb_hid_report_field_t, link); 1425 1426 if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) { 1270 1427 1271 // // variable item 1272 value = usb_hid_translate_data_reverse(report_item, data[idx++]);1273 offset = report_item->offset + (i * report_item->size) + offset_prefix;1428 // array 1429 value = usb_hid_translate_data_reverse(report_item, report_item->value); 1430 offset = report_item->offset; 1274 1431 length = report_item->size; 1275 1432 } 1276 1433 else { 1277 // bitmap1278 value += usb_hid_translate_data_reverse(report_item, data[idx++]);1279 offset = report_item->offset + offset_prefix;1280 length = report_item->size * report_item->count;1434 // variable item 1435 value = usb_hid_translate_data_reverse(report_item, report_item->value); 1436 offset = report_item->offset; 1437 length = report_item->size; 1281 1438 } 1282 1439 … … 1297 1454 } 1298 1455 else { 1299 // je to ve dvou!! FIXME: melo by to umet delsi jak 2 1300 1301 // konec prvniho -- dolni x bitu 1302 tmp_value = value; 1303 tmp_value = tmp_value & ((1 << (8-(offset%8)))-1); 1304 tmp_value = tmp_value << (offset%8); 1305 1456 int i = 0; 1306 1457 uint8_t mask = 0; 1307 mask = ~(((1 << (8-(offset%8)))-1) << (offset%8)); 1308 buffer[offset/8] = (buffer[offset/8] & mask) | tmp_value; 1309 1310 // a ted druhej -- hornich length-x bitu 1311 value = value >> (8 - (offset % 8)); 1312 value = value & ((1 << (length - (8 - (offset % 8)))) - 1); 1458 for(i = (offset/8); i <= ((offset+length-1)/8); i++) { 1459 if(i == (offset/8)) { 1460 tmp_value = value; 1461 tmp_value = tmp_value & ((1 << (8-(offset%8)))-1); 1462 tmp_value = tmp_value << (offset%8); 1463 1464 mask = ~(((1 << (8-(offset%8)))-1) << (offset%8)); 1465 buffer[i] = (buffer[i] & mask) | tmp_value; 1466 } 1467 else if (i == ((offset + length -1)/8)) { 1468 1469 value = value >> (length - ((offset + length) % 8)); 1470 value = value & ((1 << (length - ((offset + length) % 8))) - 1); 1313 1471 1314 mask = ((1 << (length - (8 - (offset % 8)))) - 1); 1315 buffer[(offset+length-1)/8] = (buffer[(offset+length-1)/8] & mask) | value; 1316 } 1317 1318 } 1319 1472 mask = (1 << (length - ((offset + length) % 8))) - 1; 1473 buffer[i] = (buffer[i] & mask) | value; 1474 } 1475 else { 1476 buffer[i] = value & (0xFF << i); 1477 } 1478 } 1479 } 1480 1481 1482 // reset value 1483 report_item->value = 0; 1484 1320 1485 item = item->next; 1321 1486 } 1322 1487 1323 1488 usb_log_debug("OUTPUT BUFFER: %s\n", usb_debug_str_buffer(buffer,size, 0)); 1324 1489 … … 1327 1492 1328 1493 /** 1329 * 1330 * @param item 1331 * @param value 1332 * @return 1333 */ 1334 int32_t usb_hid_translate_data_reverse(usb_hid_report_item_t *item, int value)1494 * Translate given data for putting them into the outoput report 1495 * @param item Report item structure 1496 * @param value Value to translate 1497 * @return ranslated value 1498 */ 1499 uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, int value) 1335 1500 { 1336 1501 int ret=0; … … 1341 1506 } 1342 1507 1508 if((item->physical_minimum == 0) && (item->physical_maximum == 0)){ 1509 item->physical_minimum = item->logical_minimum; 1510 item->physical_maximum = item->logical_maximum; 1511 } 1512 1513 1343 1514 if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0)) { 1344 1515 1345 1516 // variable item 1346 if((item->physical_minimum == 0) && (item->physical_maximum == 0)) {1347 item->physical_minimum = item->logical_minimum;1348 item->physical_maximum = item->logical_maximum;1349 }1350 1351 1517 if(item->physical_maximum == item->physical_minimum){ 1352 1518 resolution = 1; … … 1371 1537 } 1372 1538 1373 1374 return ret; 1375 } 1376 1377 1539 if((item->logical_minimum < 0) || (item->logical_maximum < 0)){ 1540 return USB_HID_INT32_TO_UINT32(ret, item->size); 1541 } 1542 return (int32_t)ret; 1543 } 1544 1545 /** 1546 * Sets report id in usage path structure 1547 * 1548 * @param path Usage path structure 1549 * @param report_id Report id to set 1550 * @return Error code 1551 */ 1378 1552 int usb_hid_report_path_set_report_id(usb_hid_report_path_t *path, uint8_t report_id) 1379 1553 { … … 1383 1557 1384 1558 path->report_id = report_id; 1559 return EOK; 1560 } 1561 1562 /** 1563 * 1564 * 1565 * 1566 * 1567 * 1568 */ 1569 int usb_hid_report_output_set_data(usb_hid_report_t *report, 1570 usb_hid_report_path_t *path, int flags, 1571 int *data, size_t data_size) 1572 { 1573 size_t data_idx = 0; 1574 if(report == NULL){ 1575 return EINVAL; 1576 } 1577 1578 usb_hid_report_description_t *report_des; 1579 report_des = usb_hid_report_find_description (report, path->report_id, 1580 USB_HID_REPORT_TYPE_OUTPUT); 1581 if(report_des == NULL){ 1582 return EINVAL; 1583 } 1584 1585 usb_hid_report_field_t *field; 1586 link_t *field_it = report_des->report_items.next; 1587 while(field_it != &report_des->report_items){ 1588 1589 field = list_get_instance(field_it, usb_hid_report_field_t, link); 1590 if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) { 1591 usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage); 1592 if(usb_hid_report_compare_usage_path (field->collection_path, path, 1593 flags) == EOK) { 1594 if(data_idx < data_size) { 1595 if((data[data_idx] >= field->physical_minimum) && (data[data_idx] >= field->physical_minimum)) { 1596 field->value = data[data_idx]; 1597 } 1598 else { 1599 return ERANGE; 1600 } 1601 1602 data_idx++; 1603 } 1604 else { 1605 field->value = 0; 1606 } 1607 } 1608 usb_hid_report_remove_last_item (field->collection_path); 1609 } 1610 1611 field_it = field_it->next; 1612 } 1613 1385 1614 return EOK; 1386 1615 } … … 1400 1629 } 1401 1630 1631 1632 usb_hid_report_field_t *usb_hid_report_get_sibling(usb_hid_report_t *report, 1633 usb_hid_report_field_t *field, 1634 usb_hid_report_path_t *path, int flags, 1635 usb_hid_report_type_t type) 1636 { 1637 usb_hid_report_description_t *report_des = usb_hid_report_find_description (report, path->report_id, type); 1638 link_t *field_it; 1639 1640 if(report_des == NULL){ 1641 return NULL; 1642 } 1643 1644 if(field == NULL){ 1645 // vezmu prvni co mathuje podle path!! 1646 field_it = report_des->report_items.next; 1647 } 1648 else { 1649 field_it = field->link.next; 1650 } 1651 1652 while(field_it != &report_des->report_items) { 1653 field = list_get_instance(field_it, usb_hid_report_field_t, link); 1654 1655 if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) { 1656 usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage); 1657 if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK){ 1658 usb_hid_report_remove_last_item (field->collection_path); 1659 return field; 1660 } 1661 usb_hid_report_remove_last_item (field->collection_path); 1662 } 1663 field_it = field_it->next; 1664 } 1665 1666 return NULL; 1667 } 1668 1669 uint8_t usb_hid_report_get_report_id(usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type) 1670 { 1671 if(report == NULL){ 1672 return 0; 1673 } 1674 1675 usb_hid_report_description_t *report_des; 1676 link_t *report_it; 1677 1678 if(report_id == 0) { 1679 report_it = usb_hid_report_find_description (report, report_id, type)->link.next; 1680 } 1681 else { 1682 report_it = report->reports.next; 1683 } 1684 1685 while(report_it != &report->reports) { 1686 report_des = list_get_instance(report_it, usb_hid_report_description_t, link); 1687 if(report_des->type == type){ 1688 return report_des->report_id; 1689 } 1690 } 1691 1692 return 0; 1693 } 1694 1695 void usb_hid_report_reset_local_items(usb_hid_report_item_t *report_item) 1696 { 1697 if(report_item == NULL) { 1698 return; 1699 } 1700 1701 report_item->usages_count = 0; 1702 memset(report_item->usages, 0, USB_HID_MAX_USAGES); 1703 1704 report_item->extended_usage_page = 0; 1705 report_item->usage_minimum = 0; 1706 report_item->usage_maximum = 0; 1707 report_item->designator_index = 0; 1708 report_item->designator_minimum = 0; 1709 report_item->designator_maximum = 0; 1710 report_item->string_index = 0; 1711 report_item->string_minimum = 0; 1712 report_item->string_maximum = 0; 1713 1714 return; 1715 } 1402 1716 /** 1403 1717 * @} -
uspace/lib/usb/src/hidreport.c
r152ec79 r9e929a0 164 164 165 165 int usb_hid_process_report_descriptor(usb_device_t *dev, 166 usb_hid_report_ parser_t *parser)166 usb_hid_report_t *report) 167 167 { 168 if (dev == NULL || parser== NULL) {168 if (dev == NULL || report == NULL) { 169 169 usb_log_error("Failed to process Report descriptor: wrong " 170 170 "parameters given.\n"); … … 189 189 assert(report_desc != NULL); 190 190 191 rc = usb_hid_parse_report_descriptor( parser, report_desc, report_size);191 rc = usb_hid_parse_report_descriptor(report, report_desc, report_size); 192 192 if (rc != EOK) { 193 193 usb_log_error("Problem parsing Report descriptor: %s.\n", … … 197 197 } 198 198 199 usb_hid_descriptor_print( parser);199 usb_hid_descriptor_print(report); 200 200 free(report_desc); 201 201
Note:
See TracChangeset
for help on using the changeset viewer.