Changeset 1b9c0e2 in mainline
- Timestamp:
- 2011-04-01T14:41:35Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 03eea27, 8e7d724
- Parents:
- 98169ab (diff), e4153ea (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace
- Files:
-
- 1 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbkbd/kbddev.c
r98169ab r1b9c0e2 56 56 #include <usb/classes/hidreq.h> 57 57 #include <usb/classes/hidreport.h> 58 #include <usb/classes/hid/utled.h> 58 59 59 60 #include <usb/devdrv.h> … … 69 70 static const unsigned DEFAULT_ACTIVE_MODS = KM_NUM_LOCK; 70 71 71 /** Boot protocol report size (key part). */ 72 static const size_t BOOTP_REPORT_SIZE = 6; 73 74 /** Boot protocol total report size. */ 75 static const size_t BOOTP_BUFFER_SIZE = 8; 76 77 /** Boot protocol output report size. */ 78 static const size_t BOOTP_BUFFER_OUT_SIZE = 1; 79 80 /** Boot protocol error key code. */ 81 static const uint8_t BOOTP_ERROR_ROLLOVER = 1; 72 ///** Boot protocol report size (key part). */ 73 //static const size_t BOOTP_REPORT_SIZE = 6; 74 75 ///** Boot protocol total report size. */ 76 //static const size_t BOOTP_BUFFER_SIZE = 8; 77 78 ///** Boot protocol output report size. */ 79 //static const size_t BOOTP_BUFFER_OUT_SIZE = 1; 80 81 ///** Boot protocol error key code. */ 82 //static const uint8_t BOOTP_ERROR_ROLLOVER = 1; 83 static const uint8_t ERROR_ROLLOVER = 1; 82 84 83 85 /** Default idle rate for keyboards. */ … … 263 265 static void usb_kbd_set_led(usb_kbd_t *kbd_dev) 264 266 { 265 u int8_t buffer[BOOTP_BUFFER_OUT_SIZE];266 int rc= 0;267 268 memset( buffer, 0, BOOTP_BUFFER_OUT_SIZE);269 uint8_t leds = 0;270 271 if (kbd_dev->mods & KM_NUM_LOCK) {272 leds |= USB_HID_LED_NUM_LOCK;273 }274 275 if (kbd_dev->mods & KM_CAPS_LOCK) {276 leds |= USB_HID_LED_CAPS_LOCK;277 }278 279 if (kbd_dev->mods & KM_SCROLL_LOCK) {280 leds |= USB_HID_LED_SCROLL_LOCK;267 unsigned i = 0; 268 269 /* Reset the LED data. */ 270 memset(kbd_dev->led_data, 0, kbd_dev->led_output_size * sizeof(int32_t)); 271 272 if ((kbd_dev->mods & KM_NUM_LOCK) && (i < kbd_dev->led_output_size)) { 273 kbd_dev->led_data[i++] = USB_HID_LED_NUM_LOCK; 274 } 275 276 if ((kbd_dev->mods & KM_CAPS_LOCK) && (i < kbd_dev->led_output_size)) { 277 kbd_dev->led_data[i++] = USB_HID_LED_CAPS_LOCK; 278 } 279 280 if ((kbd_dev->mods & KM_SCROLL_LOCK) 281 && (i < kbd_dev->led_output_size)) { 282 kbd_dev->led_data[i++] = USB_HID_LED_SCROLL_LOCK; 281 283 } 282 284 … … 284 286 285 287 usb_log_debug("Creating output report.\n"); 286 usb_log_debug("Leds: 0x%x\n", leds); 287 if ((rc = usb_hid_boot_keyboard_output_report( 288 leds, buffer, BOOTP_BUFFER_OUT_SIZE)) != EOK) { 289 usb_log_warning("Error composing output report to the keyboard:" 290 "%s.\n", str_error(rc)); 288 289 int rc = usb_hid_report_output_translate(kbd_dev->parser, 290 kbd_dev->led_path, USB_HID_PATH_COMPARE_END, kbd_dev->output_buffer, 291 kbd_dev->output_size, kbd_dev->led_data, kbd_dev->led_output_size); 292 293 if (rc != EOK) { 294 usb_log_warning("Error translating LED output to output report" 295 ".\n"); 291 296 return; 292 297 } 293 298 294 299 usb_log_debug("Output report buffer: %s\n", 295 usb_debug_str_buffer(buffer, BOOTP_BUFFER_OUT_SIZE, 0)); 296 297 assert(kbd_dev->usb_dev != NULL); 300 usb_debug_str_buffer(kbd_dev->output_buffer, kbd_dev->output_size, 301 0)); 298 302 299 303 usbhid_req_set_report(&kbd_dev->usb_dev->ctrl_pipe, 300 304 kbd_dev->usb_dev->interface_no, USB_HID_REPORT_TYPE_OUTPUT, 301 buffer, BOOTP_BUFFER_OUT_SIZE);305 kbd_dev->output_buffer, kbd_dev->output_size); 302 306 } 303 307 … … 450 454 * First of all, check if the kbd have reported phantom state. 451 455 * 452 * this must be changed as we don't know which keys are modifiers 453 * and which are regular keys. 456 * As there is no way to distinguish keys from modifiers, we do not have 457 * a way to check that 'all keys report Error Rollover'. We thus check 458 * if there is at least one such error and in such case we ignore the 459 * whole input report. 454 460 */ 455 461 i = 0; 456 // all fields should report Error Rollover 457 while (i < count && 458 key_codes[i] == BOOTP_ERROR_ROLLOVER) { 462 while (i < count && key_codes[i] != ERROR_ROLLOVER) { 459 463 ++i; 460 464 } 461 if (i == count) {465 if (i != count) { 462 466 usb_log_debug("Phantom state occured.\n"); 463 467 // phantom state, do nothing … … 586 590 */ 587 591 static void usb_kbd_process_data(usb_kbd_t *kbd_dev, 588 592 uint8_t *buffer, size_t actual_size) 589 593 { 590 594 assert(kbd_dev->initialized == USB_KBD_STATUS_INITIALIZED); … … 760 764 usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count); 761 765 762 kbd_dev->keys = (uint8_t *)calloc( 763 kbd_dev->key_count, sizeof(uint8_t)); 766 kbd_dev->keys = (uint8_t *)calloc(kbd_dev->key_count, sizeof(uint8_t)); 764 767 765 768 if (kbd_dev->keys == NULL) { … … 768 771 } 769 772 773 /* 774 * Output report 775 */ 776 kbd_dev->output_size = 0; 777 kbd_dev->output_buffer = usb_hid_report_output(kbd_dev->parser, 778 &kbd_dev->output_size); 779 if (kbd_dev->output_buffer == NULL) { 780 usb_log_warning("Error creating output report buffer.\n"); 781 free(kbd_dev->keys); 782 return ENOMEM; /* TODO: other error code */ 783 } 784 785 usb_log_debug("Output buffer size: %zu\n", kbd_dev->output_size); 786 787 kbd_dev->led_path = usb_hid_report_path(); 788 usb_hid_report_path_append_item( 789 kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0); 790 791 kbd_dev->led_output_size = usb_hid_report_output_size(kbd_dev->parser, 792 kbd_dev->led_path, USB_HID_PATH_COMPARE_END); 793 794 usb_log_debug("Output report size (in items): %zu\n", 795 kbd_dev->led_output_size); 796 797 kbd_dev->led_data = (int32_t *)calloc( 798 kbd_dev->led_output_size, sizeof(int32_t)); 799 800 if (kbd_dev->led_data == NULL) { 801 usb_log_warning("Error creating buffer for LED output report." 802 "\n"); 803 free(kbd_dev->keys); 804 usb_hid_report_output_free(kbd_dev->output_buffer); 805 return ENOMEM; 806 } 807 808 /* 809 * Modifiers and locks 810 */ 770 811 kbd_dev->modifiers = 0; 771 812 kbd_dev->mods = DEFAULT_ACTIVE_MODS; 772 813 kbd_dev->lock_keys = 0; 773 814 815 /* 816 * Autorepeat 817 */ 774 818 kbd_dev->repeat.key_new = 0; 775 819 kbd_dev->repeat.key_repeated = 0; … … 879 923 } 880 924 925 // free the output buffer 926 usb_hid_report_output_free((*kbd_dev)->output_buffer); 927 881 928 /* TODO: what about the USB device structure?? */ 882 929 -
uspace/drv/usbkbd/kbddev.h
r98169ab r1b9c0e2 94 94 /** Report descriptor size. */ 95 95 size_t report_desc_size; 96 97 uint8_t *output_buffer; 98 99 size_t output_size; 100 101 size_t led_output_size; 102 103 usb_hid_report_path_t *led_path; 104 105 int32_t *led_data; 96 106 97 107 /** HID Report parser. */ -
uspace/lib/usb/include/usb/classes/hidparser.h
r98169ab r1b9c0e2 31 31 */ 32 32 /** @file 33 * @brief USB HID parser.33 * USB HID report descriptor and report data parser 34 34 */ 35 35 #ifndef LIBUSB_HIDPARSER_H_ … … 74 74 #define USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY 4 75 75 76 /** */ 76 77 typedef struct { 78 /** */ 77 79 int32_t usage_page; 80 /** */ 78 81 int32_t usage; 79 82 /** */ 80 83 link_t link; 81 84 } usb_hid_report_usage_path_t; 82 85 86 /** */ 83 87 typedef struct { 88 /** */ 84 89 int depth; 90 91 /** */ 85 92 link_t link; 86 93 } usb_hid_report_path_t; … … 90 97 */ 91 98 typedef struct { 99 /** */ 92 100 int32_t id; 101 /** */ 93 102 int32_t usage_minimum; 103 /** */ 94 104 int32_t usage_maximum; 105 /** */ 95 106 int32_t logical_minimum; 107 /** */ 96 108 int32_t logical_maximum; 109 /** */ 97 110 int32_t size; 111 /** */ 98 112 int32_t count; 113 /** */ 99 114 size_t offset; 115 /** */ 100 116 int32_t delimiter; 101 117 /** */ 102 118 int32_t unit_exponent; 119 /** */ 103 120 int32_t unit; 104 121 105 /* 106 * some not yet used fields 107 */ 122 /** */ 108 123 int32_t string_index; 124 /** */ 109 125 int32_t string_minimum; 126 /** */ 110 127 int32_t string_maximum; 128 /** */ 111 129 int32_t designator_index; 130 /** */ 112 131 int32_t designator_minimum; 132 /** */ 113 133 int32_t designator_maximum; 134 /** */ 114 135 int32_t physical_minimum; 136 /** */ 115 137 int32_t physical_maximum; 116 138 139 /** */ 117 140 uint8_t item_flags; 118 141 142 /** */ 119 143 usb_hid_report_path_t *usage_path; 144 /** */ 120 145 link_t link; 121 146 } usb_hid_report_item_t; … … 124 149 /** HID report parser structure. */ 125 150 typedef struct { 151 /** */ 126 152 link_t input; 153 /** */ 127 154 link_t output; 155 /** */ 128 156 link_t feature; 129 157 } usb_hid_report_parser_t; … … 154 182 } usb_hid_modifiers_t; 155 183 156 typedef enum {157 USB_HID_LED_NUM_LOCK = 0x1,158 USB_HID_LED_CAPS_LOCK = 0x2,159 USB_HID_LED_SCROLL_LOCK = 0x4,160 USB_HID_LED_COMPOSE = 0x8,161 USB_HID_LED_KANA = 0x10,162 USB_HID_LED_COUNT = 5163 } usb_hid_led_t;184 //typedef enum { 185 // USB_HID_LED_NUM_LOCK = 0x1, 186 // USB_HID_LED_CAPS_LOCK = 0x2, 187 // USB_HID_LED_SCROLL_LOCK = 0x4, 188 // USB_HID_LED_COMPOSE = 0x8, 189 // USB_HID_LED_KANA = 0x10, 190 // USB_HID_LED_COUNT = 5 191 //} usb_hid_led_t; 164 192 165 193 static const usb_hid_modifiers_t … … 190 218 191 219 /* 192 * modifiers definitions 193 */ 194 220 * Descriptor parser functions 221 */ 222 /** */ 223 int usb_hid_parser_init(usb_hid_report_parser_t *parser); 224 225 /** */ 226 int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser, 227 const uint8_t *data, size_t size); 228 229 /** */ 230 void usb_hid_free_report_parser(usb_hid_report_parser_t *parser); 231 232 /** */ 233 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser); 234 235 /* 236 * Boot protocol functions 237 */ 238 /** */ 195 239 int usb_hid_boot_keyboard_input_report(const uint8_t *data, size_t size, 196 240 const usb_hid_report_in_callbacks_t *callbacks, void *arg); 197 241 242 /** */ 198 243 int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size); 199 244 200 int usb_hid_parser_init(usb_hid_report_parser_t *parser); 201 int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser, 202 const uint8_t *data, size_t size); 203 245 246 /* 247 * Input report parser functions 248 */ 249 /** */ 204 250 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 205 251 const uint8_t *data, size_t size, … … 207 253 const usb_hid_report_in_callbacks_t *callbacks, void *arg); 208 254 209 int usb_hid_report_input_length(const usb_hid_report_parser_t *parser, 255 /** */ 256 size_t usb_hid_report_input_length(const usb_hid_report_parser_t *parser, 210 257 usb_hid_report_path_t *path, int flags); 211 258 212 259 213 void usb_hid_free_report_parser(usb_hid_report_parser_t *parser); 214 215 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser); 216 217 /* usage path functions*/260 261 /* 262 * usage path functions 263 */ 264 /** */ 218 265 usb_hid_report_path_t *usb_hid_report_path(void); 266 267 /** */ 219 268 void usb_hid_report_path_free(usb_hid_report_path_t *path); 269 270 /** */ 220 271 int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path, int32_t usage_page, int32_t usage); 272 273 /** */ 221 274 void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path); 275 276 /** */ 222 277 void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path); 278 279 /** */ 223 280 void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, int32_t tag, int32_t data); 281 282 /** */ 224 283 int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path, usb_hid_report_path_t *path, int flags); 225 int usb_hid_report_path_clone(usb_hid_report_path_t *new_usage_path, usb_hid_report_path_t *usage_path); 226 227 228 // output 229 // - funkce co vrati cesty poli v output reportu 230 // - funkce co pro danou cestu nastavi data 231 // - finalize 232 284 285 /** */ 286 usb_hid_report_path_t *usb_hid_report_path_clone(usb_hid_report_path_t *usage_path); 287 288 289 /* 290 * Output report parser functions 291 */ 292 /** Allocates output report buffer*/ 293 uint8_t *usb_hid_report_output(usb_hid_report_parser_t *parser, size_t *size); 294 295 /** Frees output report buffer*/ 296 void usb_hid_report_output_free(uint8_t *output); 297 298 /** Returns size of output for given usage path */ 299 size_t usb_hid_report_output_size(usb_hid_report_parser_t *parser, 300 usb_hid_report_path_t *path, int flags); 301 302 /** Updates the output report buffer by translated given data */ 303 int usb_hid_report_output_translate(usb_hid_report_parser_t *parser, 304 usb_hid_report_path_t *path, int flags, 305 uint8_t *buffer, size_t size, 306 int32_t *data, size_t data_size); 233 307 #endif 234 308 /** -
uspace/lib/usb/src/hidparser.c
r98169ab r1b9c0e2 31 31 */ 32 32 /** @file 33 * @brief HIDparser implementation.33 * HID report descriptor and report data parser implementation. 34 34 */ 35 35 #include <usb/classes/hidparser.h> … … 40 40 #include <usb/debug.h> 41 41 42 /** */ 42 43 #define USB_HID_NEW_REPORT_ITEM 1 44 45 /** */ 43 46 #define USB_HID_NO_ACTION 2 47 48 /** */ 44 49 #define USB_HID_UNKNOWN_TAG -99 45 50 46 #define BAD_HACK_USAGE_PAGE 0x07 47 51 /* 52 * Private descriptor parser functions 53 */ 48 54 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size, 49 55 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); … … 58 64 int usb_hid_report_reset_local_items(); 59 65 void usb_hid_free_report_list(link_t *head); 66 67 /* 68 * Data translation private functions 69 */ 60 70 int32_t usb_hid_report_tag_data_int32(const uint8_t *data, size_t size); 61 71 inline size_t usb_hid_count_item_offset(usb_hid_report_item_t * report_item, size_t offset); 62 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); 63 74 int usb_pow(int a, int b); 64 75 65 76 // TODO: tohle ma bejt asi jinde 66 77 int usb_pow(int a, int b) 67 78 { … … 80 91 81 92 /** 82 * 93 * Initialize the report descriptor parser structure 94 * 95 * @param parser Report descriptor parser structure 96 * @return Error code 83 97 */ 84 98 int usb_hid_parser_init(usb_hid_report_parser_t *parser) 85 99 { 86 87 return EINVAL;88 89 90 100 if(parser == NULL) { 101 return EINVAL; 102 } 103 104 list_initialize(&(parser->input)); 91 105 list_initialize(&(parser->output)); 92 106 list_initialize(&(parser->feature)); … … 164 178 // store current usage path 165 179 report_item->usage_path = usage_path; 166 167 // new current usage path168 tmp_usage_path = usb_hid_report_path();169 180 170 // c opy oldpath to the new one171 usb_hid_report_path_clone(tmp_usage_path,usage_path);181 // clone path to the new one 182 tmp_usage_path = usb_hid_report_path_clone(usage_path); 172 183 173 184 // swap … … 304 315 305 316 /** 317 * Parse one tag of the report descriptor 306 318 * 307 319 * @param Tag to parse … … 391 403 * @return Error code 392 404 */ 393 394 405 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size, 395 406 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) … … 520 531 * Prints content of given list of report items. 521 532 * 522 * @param List of report items 533 * @param List of report items (usb_hid_report_item_t) 523 534 * @return void 524 535 */ … … 552 563 path = path->next; 553 564 } 554 555 556 // usb_log_debug("\tUSAGE: %X\n", report_item->usage); 557 // usb_log_debug("\tUSAGE PAGE: %X\n", report_item->usage_page); 565 558 566 usb_log_debug("\tLOGMIN: %X\n", report_item->logical_minimum); 559 567 usb_log_debug("\tLOGMAX: %X\n", report_item->logical_maximum); … … 570 578 } 571 579 /** 572 * Prints content of given descriptor in human readable format.573 * 574 * @param Parsed descriptor to print580 * Prints content of given report descriptor in human readable format. 581 * 582 * @param parser Parsed descriptor to print 575 583 * @return void 576 584 */ … … 595 603 * Releases whole linked list of report items 596 604 * 597 * 605 * @param head Head of list of report descriptor items (usb_hid_report_item_t) 606 * @return void 598 607 */ 599 608 void usb_hid_free_report_list(link_t *head) … … 627 636 } 628 637 629 /** Free the HID reportparser structure638 /** Frees the HID report descriptor parser structure 630 639 * 631 640 * @param parser Opaque HID report parser structure 632 * @return Error code641 * @return void 633 642 */ 634 643 void usb_hid_free_report_parser(usb_hid_report_parser_t *parser) … … 660 669 const usb_hid_report_in_callbacks_t *callbacks, void *arg) 661 670 { 662 /*663 *664 * only key codes (usage page 0x07) will be processed665 * other usages will be ignored666 */667 671 link_t *list_item; 668 672 usb_hid_report_item_t *item; … … 676 680 return EINVAL; 677 681 } 678 679 680 // get the size of result keycodes array 682 683 /* get the size of result array */ 681 684 key_count = usb_hid_report_input_length(parser, path, flags); 682 685 … … 685 688 } 686 689 687 / / read data690 /* read data */ 688 691 list_item = parser->input.next; 689 692 while(list_item != &(parser->input)) { … … 719 722 } 720 723 721 724 /** 725 * Translate data from the report as specified in report descriptor 726 * 727 * @param item Report descriptor item with definition of translation 728 * @param data Data to translate 729 * @param j Index of processed field in report descriptor item 730 * @return Translated data 731 */ 722 732 int usb_hid_translate_data(usb_hid_report_item_t *item, const uint8_t *data, size_t j) 723 733 { … … 796 806 } 797 807 798 int usb_hid_report_input_length(const usb_hid_report_parser_t *parser, 808 /** 809 * 810 * 811 * @param parser 812 * @param path 813 * @param flags 814 * @return 815 */ 816 size_t usb_hid_report_input_length(const usb_hid_report_parser_t *parser, 799 817 usb_hid_report_path_t *path, int flags) 800 818 { 801 int ret = 0;819 size_t ret = 0; 802 820 link_t *item; 803 821 usb_hid_report_item_t *report_item; 804 822 805 823 if(parser == NULL) { 806 return EINVAL;807 } 808 809 item = (&parser->input)->next;824 return 0; 825 } 826 827 item = parser->input.next; 810 828 while(&parser->input != item) { 811 829 report_item = list_get_instance(item, usb_hid_report_item_t, link); … … 824 842 /** 825 843 * 844 * @param usage_path 845 * @param usage_page 846 * @param usage 847 * @return 826 848 */ 827 849 int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path, … … 845 867 /** 846 868 * 869 * @param usage_path 870 * @return 847 871 */ 848 872 void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path) … … 860 884 /** 861 885 * 886 * @param usage_path 887 * @return 862 888 */ 863 889 void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path) … … 873 899 /** 874 900 * 901 * @param usage_path 902 * @param tag 903 * @param data 904 * @return 875 905 */ 876 906 void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, int32_t tag, int32_t data) … … 894 924 895 925 /** 896 * 926 * 927 * 928 * @param report_path 929 * @param path 930 * @param flags 931 * @return 897 932 */ 898 933 int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path, … … 949 984 break; 950 985 951 /* given path must be the end of the report one*/986 /* compare with only the end of path*/ 952 987 case USB_HID_PATH_COMPARE_END: 953 988 report_link = report_path->link.prev; … … 992 1027 /** 993 1028 * 1029 * @return 994 1030 */ 995 1031 usb_hid_report_path_t *usb_hid_report_path(void) … … 1009 1045 /** 1010 1046 * 1047 * @param path 1048 * @return void 1011 1049 */ 1012 1050 void usb_hid_report_path_free(usb_hid_report_path_t *path) … … 1019 1057 1020 1058 /** 1021 * 1022 */ 1023 int usb_hid_report_path_clone(usb_hid_report_path_t *new_usage_path, usb_hid_report_path_t *usage_path) 1059 * Clone content of given usage path to the new one 1060 * 1061 * @param usage_path 1062 * @return 1063 */ 1064 usb_hid_report_path_t *usb_hid_report_path_clone(usb_hid_report_path_t *usage_path) 1024 1065 { 1025 1066 usb_hid_report_usage_path_t *path_item; 1026 1067 link_t *path_link; 1027 1068 usb_hid_report_path_t *new_usage_path = usb_hid_report_path (); 1069 1070 if(new_usage_path == NULL){ 1071 return NULL; 1072 } 1028 1073 1029 1074 if(list_empty(&usage_path->link)){ 1030 return EOK;1075 return new_usage_path; 1031 1076 } 1032 1077 … … 1039 1084 } 1040 1085 1086 return new_usage_path; 1087 } 1088 1089 1090 /*** OUTPUT API **/ 1091 1092 /** Allocates output report buffer 1093 * 1094 * @param parser 1095 * @param size 1096 * @return 1097 */ 1098 uint8_t *usb_hid_report_output(usb_hid_report_parser_t *parser, size_t *size) 1099 { 1100 if(parser == NULL) { 1101 *size = 0; 1102 return NULL; 1103 } 1104 1105 // read the last output report item 1106 usb_hid_report_item_t *last; 1107 link_t *link; 1108 1109 link = parser->output.prev; 1110 if(link != &parser->output) { 1111 last = list_get_instance(link, usb_hid_report_item_t, link); 1112 *size = (last->offset + (last->size * last->count)) / 8; 1113 1114 uint8_t *buffer = malloc(sizeof(uint8_t) * (*size)); 1115 memset(buffer, 0, sizeof(uint8_t) * (*size)); 1116 usb_log_debug("output buffer: %s\n", usb_debug_str_buffer(buffer, *size, 0)); 1117 1118 return buffer; 1119 } 1120 else { 1121 *size = 0; 1122 return NULL; 1123 } 1124 } 1125 1126 1127 /** Frees output report buffer 1128 * 1129 * @param output Output report buffer 1130 * @return 1131 */ 1132 void usb_hid_report_output_free(uint8_t *output) 1133 1134 { 1135 if(output != NULL) { 1136 free (output); 1137 } 1138 } 1139 1140 /** Returns size of output for given usage path 1141 * 1142 * @param parser 1143 * @param path 1144 * @param flags 1145 * @return 1146 */ 1147 size_t usb_hid_report_output_size(usb_hid_report_parser_t *parser, 1148 usb_hid_report_path_t *path, int flags) 1149 { 1150 size_t ret = 0; 1151 link_t *item; 1152 usb_hid_report_item_t *report_item; 1153 1154 if(parser == NULL) { 1155 return 0; 1156 } 1157 1158 item = parser->output.next; 1159 while(&parser->output != item) { 1160 report_item = list_get_instance(item, usb_hid_report_item_t, link); 1161 if(!USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags) && 1162 (usb_hid_report_compare_usage_path(report_item->usage_path, path, flags) == EOK)) { 1163 ret += report_item->count; 1164 } 1165 1166 item = item->next; 1167 } 1168 1169 return ret; 1170 1171 } 1172 1173 /** Updates the output report buffer by translated given data 1174 * 1175 * @param parser 1176 * @param path 1177 * @param flags 1178 * @param buffer 1179 * @param size 1180 * @param data 1181 * @param data_size 1182 * @return 1183 */ 1184 int usb_hid_report_output_translate(usb_hid_report_parser_t *parser, 1185 usb_hid_report_path_t *path, int flags, 1186 uint8_t *buffer, size_t size, 1187 int32_t *data, size_t data_size) 1188 { 1189 usb_hid_report_item_t *report_item; 1190 link_t *item; 1191 size_t idx=0; 1192 int i=0; 1193 int32_t value=0; 1194 int offset; 1195 int length; 1196 int32_t tmp_value; 1197 1198 if(parser == NULL) { 1199 return EINVAL; 1200 } 1201 1202 usb_log_debug("OUTPUT BUFFER: %s\n", usb_debug_str_buffer(buffer,size, 0)); 1203 usb_log_debug("OUTPUT DATA[0]: %d, DATA[1]: %d, DATA[2]: %d\n", data[0], data[1], data[2]); 1204 1205 item = parser->output.next; 1206 while(item != &parser->output) { 1207 report_item = list_get_instance(item, usb_hid_report_item_t, link); 1208 1209 for(i=0; i<report_item->count; i++) { 1210 1211 if(idx >= data_size) { 1212 break; 1213 } 1214 1215 if((USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) || 1216 ((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0))) { 1217 1218 // // variable item 1219 value = usb_hid_translate_data_reverse(report_item, data[idx++]); 1220 offset = report_item->offset + (i * report_item->size); 1221 length = report_item->size; 1222 } 1223 else { 1224 //bitmap 1225 value += usb_hid_translate_data_reverse(report_item, data[idx++]); 1226 offset = report_item->offset; 1227 length = report_item->size * report_item->count; 1228 } 1229 1230 if((offset/8) == ((offset+length-1)/8)) { 1231 // je to v jednom bytu 1232 if(((size_t)(offset/8) >= size) || ((size_t)(offset+length-1)/8) >= size) { 1233 break; // TODO ErrorCode 1234 } 1235 1236 size_t shift = offset%8; 1237 1238 value = value << shift; 1239 value = value & (((1 << length)-1) << shift); 1240 1241 uint8_t mask = 0; 1242 mask = 0xff - (((1 << length) - 1) << shift); 1243 buffer[offset/8] = (buffer[offset/8] & mask) | value; 1244 } 1245 else { 1246 // je to ve dvou!! FIXME: melo by to umet delsi jak 2 1247 1248 // konec prvniho -- dolni x bitu 1249 tmp_value = value; 1250 tmp_value = tmp_value & ((1 << (8-(offset%8)))-1); 1251 tmp_value = tmp_value << (offset%8); 1252 1253 uint8_t mask = 0; 1254 mask = ~(((1 << (8-(offset%8)))-1) << (offset%8)); 1255 buffer[offset/8] = (buffer[offset/8] & mask) | tmp_value; 1256 1257 // a ted druhej -- hornich length-x bitu 1258 value = value >> (8 - (offset % 8)); 1259 value = value & ((1 << (length - (8 - (offset % 8)))) - 1); 1260 1261 mask = ((1 << (length - (8 - (offset % 8)))) - 1); 1262 buffer[(offset+length-1)/8] = (buffer[(offset+length-1)/8] & mask) | value; 1263 } 1264 1265 } 1266 1267 item = item->next; 1268 } 1269 1270 usb_log_debug("OUTPUT BUFFER: %s\n", usb_debug_str_buffer(buffer,size, 0)); 1271 1041 1272 return EOK; 1042 1273 } 1043 1274 1275 /** 1276 * 1277 * @param item 1278 * @param value 1279 * @return 1280 */ 1281 int32_t usb_hid_translate_data_reverse(usb_hid_report_item_t *item, int value) 1282 { 1283 int ret=0; 1284 int resolution; 1285 1286 if(USB_HID_ITEM_FLAG_CONSTANT(item->item_flags)) { 1287 ret = item->logical_minimum; 1288 } 1289 1290 if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0)) { 1291 1292 // variable item 1293 if((item->physical_minimum == 0) && (item->physical_maximum == 0)) { 1294 item->physical_minimum = item->logical_minimum; 1295 item->physical_maximum = item->logical_maximum; 1296 } 1297 1298 if(item->physical_maximum == item->physical_minimum){ 1299 resolution = 1; 1300 } 1301 else { 1302 resolution = (item->logical_maximum - item->logical_minimum) / 1303 ((item->physical_maximum - item->physical_minimum) * 1304 (usb_pow(10,(item->unit_exponent)))); 1305 } 1306 1307 ret = ((value - item->physical_minimum) * resolution) + item->logical_minimum; 1308 } 1309 else { 1310 // bitmapa 1311 if(value == 0) { 1312 ret = 0; 1313 } 1314 else { 1315 size_t bitmap_idx = (value - item->usage_minimum); 1316 ret = 1 << bitmap_idx; 1317 } 1318 } 1319 1320 1321 return ret; 1322 } 1323 1044 1324 1045 1325 /**
Note:
See TracChangeset
for help on using the changeset viewer.