Changes in / [1b9c0e2:98169ab] in mainline
- Location:
- uspace
- Files:
-
- 1 deleted
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbkbd/kbddev.c
r1b9c0e2 r98169ab 56 56 #include <usb/classes/hidreq.h> 57 57 #include <usb/classes/hidreport.h> 58 #include <usb/classes/hid/utled.h>59 58 60 59 #include <usb/devdrv.h> … … 70 69 static const unsigned DEFAULT_ACTIVE_MODS = KM_NUM_LOCK; 71 70 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; 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; 84 82 85 83 /** Default idle rate for keyboards. */ … … 265 263 static void usb_kbd_set_led(usb_kbd_t *kbd_dev) 266 264 { 267 u nsigned 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;265 uint8_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; 283 281 } 284 282 … … 286 284 287 285 usb_log_debug("Creating output report.\n"); 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"); 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)); 296 291 return; 297 292 } 298 293 299 294 usb_log_debug("Output report buffer: %s\n", 300 usb_debug_str_buffer(kbd_dev->output_buffer, kbd_dev->output_size, 301 0)); 295 usb_debug_str_buffer(buffer, BOOTP_BUFFER_OUT_SIZE, 0)); 296 297 assert(kbd_dev->usb_dev != NULL); 302 298 303 299 usbhid_req_set_report(&kbd_dev->usb_dev->ctrl_pipe, 304 300 kbd_dev->usb_dev->interface_no, USB_HID_REPORT_TYPE_OUTPUT, 305 kbd_dev->output_buffer, kbd_dev->output_size);301 buffer, BOOTP_BUFFER_OUT_SIZE); 306 302 } 307 303 … … 454 450 * First of all, check if the kbd have reported phantom state. 455 451 * 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. 452 * this must be changed as we don't know which keys are modifiers 453 * and which are regular keys. 460 454 */ 461 455 i = 0; 462 while (i < count && key_codes[i] != ERROR_ROLLOVER) { 456 // all fields should report Error Rollover 457 while (i < count && 458 key_codes[i] == BOOTP_ERROR_ROLLOVER) { 463 459 ++i; 464 460 } 465 if (i != count) {461 if (i == count) { 466 462 usb_log_debug("Phantom state occured.\n"); 467 463 // phantom state, do nothing … … 590 586 */ 591 587 static void usb_kbd_process_data(usb_kbd_t *kbd_dev, 592 uint8_t *buffer, size_t actual_size)588 uint8_t *buffer, size_t actual_size) 593 589 { 594 590 assert(kbd_dev->initialized == USB_KBD_STATUS_INITIALIZED); … … 764 760 usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count); 765 761 766 kbd_dev->keys = (uint8_t *)calloc(kbd_dev->key_count, sizeof(uint8_t)); 762 kbd_dev->keys = (uint8_t *)calloc( 763 kbd_dev->key_count, sizeof(uint8_t)); 767 764 768 765 if (kbd_dev->keys == NULL) { … … 771 768 } 772 769 773 /*774 * Output report775 */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 locks810 */811 770 kbd_dev->modifiers = 0; 812 771 kbd_dev->mods = DEFAULT_ACTIVE_MODS; 813 772 kbd_dev->lock_keys = 0; 814 773 815 /*816 * Autorepeat817 */818 774 kbd_dev->repeat.key_new = 0; 819 775 kbd_dev->repeat.key_repeated = 0; … … 923 879 } 924 880 925 // free the output buffer926 usb_hid_report_output_free((*kbd_dev)->output_buffer);927 928 881 /* TODO: what about the USB device structure?? */ 929 882 -
uspace/drv/usbkbd/kbddev.h
r1b9c0e2 r98169ab 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;106 96 107 97 /** HID Report parser. */ -
uspace/lib/usb/include/usb/classes/hidparser.h
r1b9c0e2 r98169ab 31 31 */ 32 32 /** @file 33 * USB HID report descriptor and report data parser33 * @brief USB HID parser. 34 34 */ 35 35 #ifndef LIBUSB_HIDPARSER_H_ … … 74 74 #define USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY 4 75 75 76 /** */ 77 typedef struct { 78 /** */ 76 typedef struct { 79 77 int32_t usage_page; 80 /** */81 78 int32_t usage; 82 /** */ 79 83 80 link_t link; 84 81 } usb_hid_report_usage_path_t; 85 82 86 /** */ 87 typedef struct { 88 /** */ 83 typedef struct { 89 84 int depth; 90 91 /** */92 85 link_t link; 93 86 } usb_hid_report_path_t; … … 97 90 */ 98 91 typedef struct { 99 /** */100 92 int32_t id; 101 /** */102 93 int32_t usage_minimum; 103 /** */104 94 int32_t usage_maximum; 105 /** */106 95 int32_t logical_minimum; 107 /** */108 96 int32_t logical_maximum; 109 /** */110 97 int32_t size; 111 /** */112 98 int32_t count; 113 /** */114 99 size_t offset; 115 /** */116 100 int32_t delimiter; 117 /** */ 101 118 102 int32_t unit_exponent; 119 /** */120 103 int32_t unit; 121 104 122 /** */ 105 /* 106 * some not yet used fields 107 */ 123 108 int32_t string_index; 124 /** */125 109 int32_t string_minimum; 126 /** */127 110 int32_t string_maximum; 128 /** */129 111 int32_t designator_index; 130 /** */131 112 int32_t designator_minimum; 132 /** */133 113 int32_t designator_maximum; 134 /** */135 114 int32_t physical_minimum; 136 /** */137 115 int32_t physical_maximum; 138 116 139 /** */140 117 uint8_t item_flags; 141 118 142 /** */143 119 usb_hid_report_path_t *usage_path; 144 /** */145 120 link_t link; 146 121 } usb_hid_report_item_t; … … 149 124 /** HID report parser structure. */ 150 125 typedef struct { 151 /** */152 126 link_t input; 153 /** */154 127 link_t output; 155 /** */156 128 link_t feature; 157 129 } usb_hid_report_parser_t; … … 182 154 } usb_hid_modifiers_t; 183 155 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 = 5191 //} usb_hid_led_t;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 = 5 163 } usb_hid_led_t; 192 164 193 165 static const usb_hid_modifiers_t … … 218 190 219 191 /* 220 * Descriptor parser functions 221 */ 222 /** */ 192 * modifiers definitions 193 */ 194 195 int usb_hid_boot_keyboard_input_report(const uint8_t *data, size_t size, 196 const usb_hid_report_in_callbacks_t *callbacks, void *arg); 197 198 int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size); 199 223 200 int usb_hid_parser_init(usb_hid_report_parser_t *parser); 224 225 /** */226 201 int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser, 227 202 const uint8_t *data, size_t size); 228 203 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 functions237 */238 /** */239 int usb_hid_boot_keyboard_input_report(const uint8_t *data, size_t size,240 const usb_hid_report_in_callbacks_t *callbacks, void *arg);241 242 /** */243 int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size);244 245 246 /*247 * Input report parser functions248 */249 /** */250 204 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 251 205 const uint8_t *data, size_t size, … … 253 207 const usb_hid_report_in_callbacks_t *callbacks, void *arg); 254 208 255 /** */ 256 size_t usb_hid_report_input_length(const usb_hid_report_parser_t *parser, 209 int usb_hid_report_input_length(const usb_hid_report_parser_t *parser, 257 210 usb_hid_report_path_t *path, int flags); 258 211 259 212 260 261 /* 262 * usage path functions 263 */ 264 /* **/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 */ 265 218 usb_hid_report_path_t *usb_hid_report_path(void); 266 267 /** */268 219 void usb_hid_report_path_free(usb_hid_report_path_t *path); 269 270 /** */271 220 int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path, int32_t usage_page, int32_t usage); 272 273 /** */274 221 void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path); 275 276 /** */277 222 void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path); 278 279 /** */280 223 void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, int32_t tag, int32_t data); 281 282 /** */283 224 int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path, usb_hid_report_path_t *path, int flags); 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); 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 307 233 #endif 308 234 /** -
uspace/lib/usb/src/hidparser.c
r1b9c0e2 r98169ab 31 31 */ 32 32 /** @file 33 * HID report descriptor and report dataparser implementation.33 * @brief HID parser implementation. 34 34 */ 35 35 #include <usb/classes/hidparser.h> … … 40 40 #include <usb/debug.h> 41 41 42 /** */43 42 #define USB_HID_NEW_REPORT_ITEM 1 44 45 /** */46 43 #define USB_HID_NO_ACTION 2 47 48 /** */49 44 #define USB_HID_UNKNOWN_TAG -99 50 45 51 /* 52 * Private descriptor parser functions 53 */ 46 #define BAD_HACK_USAGE_PAGE 0x07 47 54 48 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size, 55 49 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); … … 64 58 int usb_hid_report_reset_local_items(); 65 59 void usb_hid_free_report_list(link_t *head); 66 67 /*68 * Data translation private functions69 */70 60 int32_t usb_hid_report_tag_data_int32(const uint8_t *data, size_t size); 71 61 inline size_t usb_hid_count_item_offset(usb_hid_report_item_t * report_item, size_t offset); 72 62 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);74 63 int usb_pow(int a, int b); 75 64 76 // TODO: tohle ma bejt asi jinde 65 77 66 int usb_pow(int a, int b) 78 67 { … … 91 80 92 81 /** 93 * Initialize the report descriptor parser structure 94 * 95 * @param parser Report descriptor parser structure 96 * @return Error code 82 * 97 83 */ 98 84 int usb_hid_parser_init(usb_hid_report_parser_t *parser) 99 85 { 100 101 102 103 104 86 if(parser == NULL) { 87 return EINVAL; 88 } 89 90 list_initialize(&(parser->input)); 105 91 list_initialize(&(parser->output)); 106 92 list_initialize(&(parser->feature)); … … 178 164 // store current usage path 179 165 report_item->usage_path = usage_path; 166 167 // new current usage path 168 tmp_usage_path = usb_hid_report_path(); 180 169 181 // c lonepath to the new one182 tmp_usage_path = usb_hid_report_path_clone(usage_path);170 // copy old path to the new one 171 usb_hid_report_path_clone(tmp_usage_path, usage_path); 183 172 184 173 // swap … … 315 304 316 305 /** 317 * Parse one tag of the report descriptor318 306 * 319 307 * @param Tag to parse … … 403 391 * @return Error code 404 392 */ 393 405 394 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size, 406 395 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) … … 531 520 * Prints content of given list of report items. 532 521 * 533 * @param List of report items (usb_hid_report_item_t)522 * @param List of report items 534 523 * @return void 535 524 */ … … 563 552 path = path->next; 564 553 } 565 554 555 556 // usb_log_debug("\tUSAGE: %X\n", report_item->usage); 557 // usb_log_debug("\tUSAGE PAGE: %X\n", report_item->usage_page); 566 558 usb_log_debug("\tLOGMIN: %X\n", report_item->logical_minimum); 567 559 usb_log_debug("\tLOGMAX: %X\n", report_item->logical_maximum); … … 578 570 } 579 571 /** 580 * Prints content of given reportdescriptor in human readable format.581 * 582 * @param parserParsed descriptor to print572 * Prints content of given descriptor in human readable format. 573 * 574 * @param Parsed descriptor to print 583 575 * @return void 584 576 */ … … 603 595 * Releases whole linked list of report items 604 596 * 605 * @param head Head of list of report descriptor items (usb_hid_report_item_t) 606 * @return void 597 * 607 598 */ 608 599 void usb_hid_free_report_list(link_t *head) … … 636 627 } 637 628 638 /** Free s the HID report descriptorparser structure629 /** Free the HID report parser structure 639 630 * 640 631 * @param parser Opaque HID report parser structure 641 * @return void632 * @return Error code 642 633 */ 643 634 void usb_hid_free_report_parser(usb_hid_report_parser_t *parser) … … 669 660 const usb_hid_report_in_callbacks_t *callbacks, void *arg) 670 661 { 662 /* 663 * 664 * only key codes (usage page 0x07) will be processed 665 * other usages will be ignored 666 */ 671 667 link_t *list_item; 672 668 usb_hid_report_item_t *item; … … 680 676 return EINVAL; 681 677 } 682 683 /* get the size of result array */ 678 679 680 // get the size of result keycodes array 684 681 key_count = usb_hid_report_input_length(parser, path, flags); 685 682 … … 688 685 } 689 686 690 / * read data */687 // read data 691 688 list_item = parser->input.next; 692 689 while(list_item != &(parser->input)) { … … 722 719 } 723 720 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 */ 721 732 722 int usb_hid_translate_data(usb_hid_report_item_t *item, const uint8_t *data, size_t j) 733 723 { … … 806 796 } 807 797 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, 798 int usb_hid_report_input_length(const usb_hid_report_parser_t *parser, 817 799 usb_hid_report_path_t *path, int flags) 818 800 { 819 size_t ret = 0;801 int ret = 0; 820 802 link_t *item; 821 803 usb_hid_report_item_t *report_item; 822 804 823 805 if(parser == NULL) { 824 return 0;825 } 826 827 item = parser->input.next;806 return EINVAL; 807 } 808 809 item = (&parser->input)->next; 828 810 while(&parser->input != item) { 829 811 report_item = list_get_instance(item, usb_hid_report_item_t, link); … … 842 824 /** 843 825 * 844 * @param usage_path845 * @param usage_page846 * @param usage847 * @return848 826 */ 849 827 int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path, … … 867 845 /** 868 846 * 869 * @param usage_path870 * @return871 847 */ 872 848 void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path) … … 884 860 /** 885 861 * 886 * @param usage_path887 * @return888 862 */ 889 863 void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path) … … 899 873 /** 900 874 * 901 * @param usage_path902 * @param tag903 * @param data904 * @return905 875 */ 906 876 void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, int32_t tag, int32_t data) … … 924 894 925 895 /** 926 * 927 * 928 * @param report_path 929 * @param path 930 * @param flags 931 * @return 896 * 932 897 */ 933 898 int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path, … … 984 949 break; 985 950 986 /* compare with only the end of path*/951 /* given path must be the end of the report one*/ 987 952 case USB_HID_PATH_COMPARE_END: 988 953 report_link = report_path->link.prev; … … 1027 992 /** 1028 993 * 1029 * @return1030 994 */ 1031 995 usb_hid_report_path_t *usb_hid_report_path(void) … … 1045 1009 /** 1046 1010 * 1047 * @param path1048 * @return void1049 1011 */ 1050 1012 void usb_hid_report_path_free(usb_hid_report_path_t *path) … … 1057 1019 1058 1020 /** 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) 1021 * 1022 */ 1023 int usb_hid_report_path_clone(usb_hid_report_path_t *new_usage_path, usb_hid_report_path_t *usage_path) 1065 1024 { 1066 1025 usb_hid_report_usage_path_t *path_item; 1067 1026 link_t *path_link; 1068 usb_hid_report_path_t *new_usage_path = usb_hid_report_path (); 1069 1070 if(new_usage_path == NULL){ 1071 return NULL; 1072 } 1027 1073 1028 1074 1029 if(list_empty(&usage_path->link)){ 1075 return new_usage_path;1030 return EOK; 1076 1031 } 1077 1032 … … 1084 1039 } 1085 1040 1086 return new_usage_path;1087 }1088 1089 1090 /*** OUTPUT API **/1091 1092 /** Allocates output report buffer1093 *1094 * @param parser1095 * @param size1096 * @return1097 */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 item1106 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 buffer1128 *1129 * @param output Output report buffer1130 * @return1131 */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 path1141 *1142 * @param parser1143 * @param path1144 * @param flags1145 * @return1146 */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 data1174 *1175 * @param parser1176 * @param path1177 * @param flags1178 * @param buffer1179 * @param size1180 * @param data1181 * @param data_size1182 * @return1183 */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 item1219 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 //bitmap1225 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 bytu1232 if(((size_t)(offset/8) >= size) || ((size_t)(offset+length-1)/8) >= size) {1233 break; // TODO ErrorCode1234 }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 21247 1248 // konec prvniho -- dolni x bitu1249 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 bitu1258 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 1272 1041 return EOK; 1273 1042 } 1274 1043 1275 /**1276 *1277 * @param item1278 * @param value1279 * @return1280 */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 item1293 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 // bitmapa1311 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 1324 1044 1325 1045 /**
Note:
See TracChangeset
for help on using the changeset viewer.