Changes in / [63517c2:da1dd48] in mainline
- Location:
- uspace
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbhid/kbd/kbddev.c
r63517c2 rda1dd48 320 320 // TODO: COMPOSE and KANA 321 321 322 usb_log_debug("Creating output report : %s\n", usb_debug_str_buffer ((uint8_t *)kbd_dev->led_data, kbd_dev->led_output_size * 4, 0));323 324 usb_hid_report_output_set_data(hid_dev->parser, kbd_dev->led_path,325 USB_HID_PATH_COMPARE_END , kbd_dev->led_data,326 kbd_dev->led_output_size);327 int rc = usb_hid_report_output_translate(hid_dev->parser, 0,328 kbd_dev->output_ buffer, kbd_dev->output_size);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); 329 329 330 330 if (rc != EOK) { … … 649 649 //usb_hid_report_path_set_report_id(path, 0); 650 650 651 int rc = usb_hid_parse_report(hid_dev->parser, buffer, actual_size); 652 usb_hid_report_field_t *field = usb_hid_report_get_sibling(hid_dev->parser, 653 NULL, path, USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 654 USB_HID_REPORT_TYPE_INPUT); 655 656 while(field != NULL) { 657 usb_log_debug("FIELD (%X) - VALUE(%X) USAGE(%X)\n", field, field->value, field->usage); 658 field = usb_hid_report_get_sibling(hid_dev->parser, field, path, 659 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 660 USB_HID_REPORT_TYPE_INPUT); 661 } 662 663 651 int rc = usb_hid_parse_report(hid_dev->parser, buffer, 652 actual_size, path, 653 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 654 &usb_kbd_parser_callbacks, hid_dev); 655 664 656 usb_hid_report_path_free(path); 665 657 … … 774 766 kbd_dev->output_size = 0; 775 767 kbd_dev->output_buffer = usb_hid_report_output(hid_dev->parser, 776 &kbd_dev->output_size , 0x00);777 if (kbd_dev->output_buffer == NULL ) {768 &kbd_dev->output_size); 769 if (kbd_dev->output_buffer == NULL && kbd_dev->output_size != 0) { 778 770 usb_log_warning("Error creating output report buffer.\n"); 779 771 free(kbd_dev->keys); 780 return ENOMEM; /* TODO: other error code */ 772 free(kbd_dev); 773 return ENOMEM; 781 774 } 782 775 -
uspace/drv/usbhid/lgtch-ultrax/lgtch-ultrax.c
r63517c2 rda1dd48 81 81 usb_hid_report_path_t *path = usb_hid_report_path(); 82 82 usb_hid_report_path_append_item(path, 0xc, 0); 83 usb_hid_report_path_set_report_id(path, 0);83 usb_hid_report_path_set_report_id(path, 1); 84 84 85 int rc = usb_hid_parse_report(hid_dev->parser, buffer, buffer_size); 86 87 usb_hid_report_field_t *field = usb_hid_report_get_sibling(hid_dev->parser, NULL, path, USB_HID_PATH_COMPARE_END , USB_HID_REPORT_TYPE_INPUT); 88 while(field != NULL) { 89 usb_log_debug("KEY VALUE(%X) USAGE(%X)\n", field->value, field->usage); 90 } 91 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); 92 89 93 90 usb_hid_report_path_free(path); -
uspace/drv/usbhid/usbhid.c
r63517c2 rda1dd48 341 341 } 342 342 343 hid_dev->parser = (usb_hid_report_ t *)(malloc(sizeof(344 usb_hid_report_ t)));343 hid_dev->parser = (usb_hid_report_parser_t *)(malloc(sizeof( 344 usb_hid_report_parser_t))); 345 345 if (hid_dev->parser == NULL) { 346 346 usb_log_fatal("No memory!\n"); … … 382 382 return rc; 383 383 } 384 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 385 393 /* Get the report descriptor and parse it. */ 386 394 rc = usb_hid_process_report_descriptor(hid_dev->usb_dev, … … 584 592 // destroy the parser 585 593 if ((*hid_dev)->parser != NULL) { 586 usb_hid_free_report ((*hid_dev)->parser);594 usb_hid_free_report_parser((*hid_dev)->parser); 587 595 } 588 596 -
uspace/drv/usbhid/usbhid.h
r63517c2 rda1dd48 91 91 92 92 /** HID Report parser. */ 93 usb_hid_report_ t *parser;93 usb_hid_report_parser_t *parser; 94 94 95 95 /** Arbitrary data (e.g. a special structure for handling keyboard). */ -
uspace/drv/usbkbd/kbddev.c
r63517c2 rda1dd48 128 128 0x15, 0x00, // Logical Minimum (0), 129 129 0x25, 0x01, // Logical Maximum (1), 130 //0x85, 0x00, // Report ID,131 //0xA4, // Push132 130 0x81, 0x02, // Input (Data, Variable, Absolute), ; Modifier byte 133 //0xB4, // Pop 134 0x75, 0x08, // Report Size (1), 135 0x95, 0x01, // Report Count (8), 131 0x95, 0x01, // Report Count (1), 132 0x75, 0x08, // Report Size (8), 136 133 0x81, 0x01, // Input (Constant), ; Reserved byte 137 134 0x95, 0x05, // Report Count (5), … … 271 268 return; 272 269 } 273 270 274 271 unsigned i = 0; 275 272 … … 293 290 294 291 usb_log_debug("Creating output report.\n"); 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);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); 301 298 302 299 if (rc != EOK) { … … 566 563 assert(kbd_dev != NULL); 567 564 568 usb_log_debug("Got keys from parser (report id: % d): %s\n", report_id,569 usb_debug_str_buffer(key_codes, count, 0));565 usb_log_debug("Got keys from parser (report id: %u): %s\n", 566 report_id, usb_debug_str_buffer(key_codes, count, 0)); 570 567 571 568 if (count != kbd_dev->key_count) { … … 617 614 usb_hid_report_path_t *path = usb_hid_report_path(); 618 615 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0); 619 620 int rc = usb_hid_parse_report(kbd_dev->parser, buffer, actual_size); 621 usb_hid_descriptor_print (kbd_dev->parser); 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); 622 622 623 623 usb_hid_report_path_free (path); … … 663 663 memset(kbd_dev, 0, sizeof(usb_kbd_t)); 664 664 665 kbd_dev->parser = (usb_hid_report_ t *)(malloc(sizeof(666 usb_hid_report_ t)));665 kbd_dev->parser = (usb_hid_report_parser_t *)(malloc(sizeof( 666 usb_hid_report_parser_t))); 667 667 if (kbd_dev->parser == NULL) { 668 668 usb_log_fatal("No memory!\n"); … … 732 732 733 733 /* 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 //}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 } 739 739 740 740 /* Get the report descriptor and parse it. */ … … 771 771 772 772 kbd_dev->key_count = usb_hid_report_input_length( 773 kbd_dev->parser, path, USB_HID_PATH_COMPARE_END); 773 kbd_dev->parser, path, 774 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY); 774 775 usb_hid_report_path_free (path); 775 776 … … 788 789 kbd_dev->output_size = 0; 789 790 kbd_dev->output_buffer = usb_hid_report_output(kbd_dev->parser, 790 &kbd_dev->output_size , 0x00);791 if (kbd_dev->output_buffer == NULL ) {791 &kbd_dev->output_size); 792 if (kbd_dev->output_buffer == NULL && kbd_dev->output_size != 0) { 792 793 usb_log_warning("Error creating output report buffer.\n"); 793 794 free(kbd_dev->keys); … … 800 801 usb_hid_report_path_append_item( 801 802 kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0); 802 usb_hid_report_path_set_report_id(kbd_dev->led_path, 0x00);803 803 804 804 kbd_dev->led_output_size = usb_hid_report_output_size(kbd_dev->parser, … … 849 849 * Set Idle rate 850 850 */ 851 usb_kbd_set_led(kbd_dev); 851 usb_kbd_set_led(kbd_dev); 852 852 853 853 usbhid_req_set_idle(&kbd_dev->usb_dev->ctrl_pipe, … … 934 934 // destroy the parser 935 935 if ((*kbd_dev)->parser != NULL) { 936 usb_hid_free_report ((*kbd_dev)->parser);936 usb_hid_free_report_parser((*kbd_dev)->parser); 937 937 } 938 938 -
uspace/drv/usbkbd/kbddev.h
r63517c2 rda1dd48 106 106 107 107 /** HID Report parser. */ 108 usb_hid_report_ t *parser;108 usb_hid_report_parser_t *parser; 109 109 110 110 /** State of the structure (for checking before use). -
uspace/lib/usb/include/usb/classes/hid.h
r63517c2 rda1dd48 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 = 3 57 } usb_hid_report_type_t; 52 58 53 59 typedef enum { -
uspace/lib/usb/include/usb/classes/hidparser.h
r63517c2 rda1dd48 73 73 #define USB_HID_PATH_COMPARE_END 1 74 74 #define USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY 4 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 */ 75 76 /** */ 87 77 typedef struct { 88 78 /** */ 89 uint32_t usage_page; 90 /** */ 91 uint32_t usage; 92 93 uint8_t flags; 79 int32_t usage_page; 80 /** */ 81 int32_t usage; 94 82 /** */ 95 83 link_t link; … … 103 91 104 92 /** */ 105 link_t link; /* list */ 106 107 link_t head; /* head of list of usage paths */ 93 link_t link; 108 94 109 95 } usb_hid_report_path_t; 110 96 111 97 /** 98 * Description of report items 99 */ 112 100 typedef struct { 101 /** */ 102 int32_t id; 103 /** */ 104 int32_t usage_minimum; 105 /** */ 106 int32_t usage_maximum; 107 /** */ 108 int32_t logical_minimum; 109 /** */ 110 int32_t logical_maximum; 111 /** */ 112 int32_t size; 113 /** */ 114 int32_t count; 115 /** */ 116 size_t offset; 117 /** */ 118 int32_t delimiter; 119 /** */ 120 int32_t unit_exponent; 121 /** */ 122 int32_t unit; 123 113 124 /** */ 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 122 } usb_hid_report_t; 123 124 typedef struct { 125 uint8_t report_id; 126 usb_hid_report_type_t type; 127 128 size_t bit_length; 129 size_t item_length; 130 131 link_t report_items; /** list of report items (fields) */ 132 133 link_t link; 134 } usb_hid_report_description_t; 135 136 typedef struct { 137 138 int offset; 139 size_t size; 140 141 uint16_t usage_page; 142 uint16_t usage; 143 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; 136 /** */ 137 int32_t physical_minimum; 138 /** */ 139 int32_t physical_maximum; 140 141 /** */ 144 142 uint8_t item_flags; 145 usb_hid_report_path_t *collection_path; 146 147 int32_t logical_minimum; 148 int32_t logical_maximum; 149 int32_t physical_minimum; 150 int32_t physical_maximum; 151 uint32_t usage_minimum; 152 uint32_t usage_maximum; 153 uint32_t unit; 154 uint32_t unit_exponent; 155 156 157 int32_t value; 158 159 link_t link; 160 } usb_hid_report_field_t; 161 162 163 164 /** 165 * state table 166 */ 167 typedef struct { 168 /** report id */ 169 int32_t id; 170 171 /** */ 172 uint16_t extended_usage_page; 173 uint32_t usages[USB_HID_MAX_USAGES]; 174 int usages_count; 175 176 /** */ 177 uint32_t usage_page; 178 179 /** */ 180 uint32_t usage_minimum; 181 /** */ 182 uint32_t usage_maximum; 183 /** */ 184 int32_t logical_minimum; 185 /** */ 186 int32_t logical_maximum; 187 /** */ 188 int32_t size; 189 /** */ 190 int32_t count; 191 /** */ 192 size_t offset; 193 /** */ 194 int32_t unit_exponent; 195 /** */ 196 int32_t unit; 197 198 /** */ 199 uint32_t string_index; 200 /** */ 201 uint32_t string_minimum; 202 /** */ 203 uint32_t string_maximum; 204 /** */ 205 uint32_t designator_index; 206 /** */ 207 uint32_t designator_minimum; 208 /** */ 209 uint32_t designator_maximum; 210 /** */ 211 int32_t physical_minimum; 212 /** */ 213 int32_t physical_maximum; 214 215 /** */ 216 uint8_t item_flags; 217 218 usb_hid_report_type_t type; 219 220 /** current collection path*/ 143 144 /** */ 221 145 usb_hid_report_path_t *usage_path; 222 146 /** */ 223 147 link_t link; 224 148 } 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 225 166 226 167 /** HID parser callbacks for IN items. */ … … 248 189 } usb_hid_modifiers_t; 249 190 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 = 5 198 //} usb_hid_led_t; 199 250 200 static const usb_hid_modifiers_t 251 201 usb_hid_modifiers_consts[USB_HID_MOD_COUNT] = { … … 260 210 }; 261 211 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_KANA 218 //}; 219 220 //#define USB_HID_BOOT_KEYBOARD_NUM_LOCK 0x01 221 //#define USB_HID_BOOT_KEYBOARD_CAPS_LOCK 0x02 222 //#define USB_HID_BOOT_KEYBOARD_SCROLL_LOCK 0x04 223 //#define USB_HID_BOOT_KEYBOARD_COMPOSE 0x08 224 //#define USB_HID_BOOT_KEYBOARD_KANA 0x10 225 262 226 /* 263 227 * Descriptor parser functions 264 228 */ 265 266 /** */ 267 int usb_hid_parse_report_descriptor(usb_hid_report_t *report, 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, 268 234 const uint8_t *data, size_t size); 269 235 270 236 /** */ 271 void usb_hid_free_report(usb_hid_report_t *report); 272 273 /** */ 274 void usb_hid_descriptor_print(usb_hid_report_t *report); 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); 275 251 276 252 … … 279 255 */ 280 256 /** */ 281 int usb_hid_parse_report(const usb_hid_report_t *report, const uint8_t *data, size_t size); 282 283 /** */ 284 size_t usb_hid_report_input_length(const usb_hid_report_t *report, 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, 285 264 usb_hid_report_path_t *path, int flags); 286 265 … … 317 296 usb_hid_report_path_t *usb_hid_report_path_clone(usb_hid_report_path_t *usage_path); 318 297 319 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);320 298 321 299 /* … … 323 301 */ 324 302 /** Allocates output report buffer*/ 325 uint8_t *usb_hid_report_output(usb_hid_report_ t *report, size_t *size, uint8_t report_id);303 uint8_t *usb_hid_report_output(usb_hid_report_parser_t *parser, size_t *size); 326 304 327 305 /** Frees output report buffer*/ … … 329 307 330 308 /** Returns size of output for given usage path */ 331 size_t usb_hid_report_output_size(usb_hid_report_ t *report,309 size_t usb_hid_report_output_size(usb_hid_report_parser_t *parser, 332 310 usb_hid_report_path_t *path, int flags); 333 311 334 /** Sets data in report structure */ 335 int usb_hid_report_output_set_data(usb_hid_report_t *report, 336 usb_hid_report_path_t *path, int flags, 337 int *data, size_t data_size); 338 339 /** Makes the output report buffer by translated given data */ 340 int usb_hid_report_output_translate(usb_hid_report_t *report, uint8_t report_id, uint8_t *buffer, size_t size); 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); 341 317 #endif 342 318 /** -
uspace/lib/usb/include/usb/classes/hidreport.h
r63517c2 rda1dd48 57 57 */ 58 58 int usb_hid_process_report_descriptor(usb_device_t *dev, 59 usb_hid_report_ t *report);59 usb_hid_report_parser_t *parser); 60 60 61 61 #endif /* LIBUSB_HIDREPORT_H_ */ -
uspace/lib/usb/src/hidparser.c
r63517c2 rda1dd48 39 39 #include <mem.h> 40 40 #include <usb/debug.h> 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 */ 41 42 /** */ 46 43 #define USB_HID_NEW_REPORT_ITEM 1 47 44 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*/ 45 /** */ 46 #define USB_HID_NO_ACTION 2 47 48 /** */ 56 49 #define USB_HID_UNKNOWN_TAG -99 57 50 … … 59 52 * Private descriptor parser functions 60 53 */ 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);64 54 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size, 65 55 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); … … 71 61 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); 72 62 73 void usb_hid_print_usage_path(usb_hid_report_path_t *path);74 63 void usb_hid_descriptor_print_list(link_t *head); 75 64 int usb_hid_report_reset_local_items(); … … 81 70 int32_t usb_hid_report_tag_data_int32(const uint8_t *data, size_t size); 82 71 inline size_t usb_hid_count_item_offset(usb_hid_report_item_t * report_item, size_t offset); 83 int usb_hid_translate_data(usb_hid_report_ field_t *item, const uint8_t *data, size_t j);84 uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, int32_t value);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); 85 74 int usb_pow(int a, int b); 86 75 … … 107 96 * @return Error code 108 97 */ 109 int usb_hid_ report_init(usb_hid_report_t *report)110 { 111 if( report== NULL) {98 int usb_hid_parser_init(usb_hid_report_parser_t *parser) 99 { 100 if(parser == NULL) { 112 101 return EINVAL; 113 102 } 114 103 115 memset(report, 0, sizeof(usb_hid_report_t)); 116 list_initialize(&report->reports); 117 list_initialize(&report->collection_paths); 118 119 report->use_report_ids = 0; 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; 120 111 return EOK; 121 112 } 122 113 123 int usb_hid_report_append_fields(usb_hid_report_t *report, usb_hid_report_item_t *report_item)124 {125 usb_hid_report_field_t *field;126 int i;127 128 129 /* find or append current collection path to the list */130 link_t *path_it = report->collection_paths.next;131 usb_hid_report_path_t *path = NULL;132 while(path_it != &report->collection_paths) {133 path = list_get_instance(path_it, usb_hid_report_path_t, link);134 135 if(usb_hid_report_compare_usage_path(path, report_item->usage_path, USB_HID_PATH_COMPARE_STRICT) == EOK){136 break;137 }138 path_it = path_it->next;139 }140 if(path_it == &report->collection_paths) {141 path = usb_hid_report_path_clone(report_item->usage_path);142 list_append(&path->link, &report->collection_paths);143 report->collection_paths_count++;144 }145 146 147 for(i=0; i<report_item->count; i++){148 149 field = malloc(sizeof(usb_hid_report_field_t));150 memset(field, 0, sizeof(usb_hid_report_field_t));151 list_initialize(&field->link);152 153 /* fill the attributes */154 field->collection_path = path;155 field->logical_minimum = report_item->logical_minimum;156 field->logical_maximum = report_item->logical_maximum;157 field->physical_minimum = report_item->physical_minimum;158 field->physical_maximum = report_item->physical_maximum;159 field->usage_minimum = report_item->usage_minimum;160 field->usage_maximum = report_item->usage_maximum;161 if(report_item->extended_usage_page != 0){162 field->usage_page = report_item->extended_usage_page;163 }164 else {165 field->usage_page = report_item->usage_page;166 }167 168 if(report_item->usages_count > 0 && ((report_item->usage_minimum = 0) && (report_item->usage_maximum = 0))) {169 if(i < report_item->usages_count){170 if((report_item->usages[i] & 0xFF00) > 0){171 field->usage_page = (report_item->usages[i] >> 16);172 field->usage = (report_item->usages[i] & 0xFF);173 }174 else {175 field->usage = report_item->usages[i];176 }177 }178 else {179 field->usage = report_item->usages[report_item->usages_count - 1];180 }181 }182 183 field->size = report_item->size;184 field->offset = report_item->offset + (i * report_item->size);185 if(report_item->id != 0) {186 field->offset += 8;187 report->use_report_ids = 1;188 }189 field->item_flags = report_item->item_flags;190 191 /* find the right report list*/192 usb_hid_report_description_t *report_des;193 report_des = usb_hid_report_find_description(report, report_item->id, report_item->type);194 if(report_des == NULL){195 report_des = malloc(sizeof(usb_hid_report_description_t));196 memset(report_des, 0, sizeof(usb_hid_report_description_t));197 198 report_des->type = report_item->type;199 report_des->report_id = report_item->id;200 list_initialize (&report_des->link);201 list_initialize (&report_des->report_items);202 203 list_append(&report_des->link, &report->reports);204 report->report_count++;205 }206 207 /* append this field to the end of founded report list */208 list_append (&field->link, &report_des->report_items);209 210 /* update the sizes */211 report_des->bit_length += field->size;212 report_des->item_length++;213 214 }215 216 217 return EOK;218 }219 220 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)221 {222 link_t *report_it = report->reports.next;223 usb_hid_report_description_t *report_des = NULL;224 225 while(report_it != &report->reports) {226 report_des = list_get_instance(report_it, usb_hid_report_description_t, link);227 228 if((report_des->report_id == report_id) && (report_des->type == type)){229 return report_des;230 }231 232 report_it = report_it->next;233 }234 235 return NULL;236 }237 114 238 115 /** Parse HID report descriptor. … … 242 119 * @return Error code. 243 120 */ 244 int usb_hid_parse_report_descriptor(usb_hid_report_ t *report,121 int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser, 245 122 const uint8_t *data, size_t size) 246 123 { … … 253 130 usb_hid_report_item_t *new_report_item; 254 131 usb_hid_report_path_t *usage_path; 132 usb_hid_report_path_t *tmp_usage_path; 255 133 256 134 size_t offset_input=0; 257 135 size_t offset_output=0; 258 136 size_t offset_feature=0; 259 260 link_t stack; 261 list_initialize(&stack); 137 262 138 263 139 /* parser structure initialization*/ 264 if(usb_hid_ report_init(report) != EOK) {140 if(usb_hid_parser_init(parser) != EOK) { 265 141 return EINVAL; 266 142 } 267 143 144 268 145 /*report item initialization*/ 269 146 if(!(report_item=malloc(sizeof(usb_hid_report_item_t)))){ … … 282 159 283 160 if((i+USB_HID_ITEM_SIZE(data[i]))>= size){ 284 return EINVAL; 161 return EINVAL; // TODO ERROR CODE 285 162 } 286 163 … … 288 165 item_size = USB_HID_ITEM_SIZE(data[i]); 289 166 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); 290 172 291 173 ret = usb_hid_report_parse_tag(tag,class,data+i+1, 292 174 item_size,report_item, usage_path); 175 usb_log_debug2("ret: %u\n", ret); 293 176 switch(ret){ 294 177 case USB_HID_NEW_REPORT_ITEM: 295 178 // store report item to report and create the new one 296 // store current collection path 179 usb_log_debug("\nNEW REPORT ITEM: %X",ret); 180 181 // store current usage path 297 182 report_item->usage_path = usage_path; 298 183 184 // clone path to the new one 185 tmp_usage_path = usb_hid_report_path_clone(usage_path); 186 187 // swap 188 usage_path = tmp_usage_path; 189 tmp_usage_path = NULL; 190 299 191 usb_hid_report_path_set_report_id(report_item->usage_path, report_item->id); 300 192 if(report_item->id != 0){ 301 report->use_report_ids= 1;193 parser->use_report_id = 1; 302 194 } 303 195 304 196 switch(tag) { 305 197 case USB_HID_REPORT_TAG_INPUT: 306 report_item->type = USB_HID_REPORT_TYPE_INPUT;307 198 report_item->offset = offset_input; 308 199 offset_input += report_item->count * report_item->size; 200 usb_log_debug(" - INPUT\n"); 201 list_append(&(report_item->link), &(parser->input)); 309 202 break; 310 203 case USB_HID_REPORT_TAG_OUTPUT: 311 report_item->type = USB_HID_REPORT_TYPE_OUTPUT;312 204 report_item->offset = offset_output; 313 205 offset_output += report_item->count * report_item->size; 206 usb_log_debug(" - OUTPUT\n"); 207 list_append(&(report_item->link), &(parser->output)); 314 208 315 209 break; 316 210 case USB_HID_REPORT_TAG_FEATURE: 317 report_item->type = USB_HID_REPORT_TYPE_FEATURE;318 211 report_item->offset = offset_feature; 319 212 offset_feature += report_item->count * report_item->size; 213 usb_log_debug(" - FEATURE\n"); 214 list_append(&(report_item->link), &(parser->feature)); 320 215 break; 321 216 default: … … 323 218 break; 324 219 } 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)); 325 227 326 /*327 * append new fields to the report328 * structure329 */330 usb_hid_report_append_fields(report, report_item);331 332 228 /* reset local items */ 333 while(report_item->usages_count > 0){ 334 report_item->usages[--(report_item->usages_count)] = 0; 335 } 336 337 report_item->extended_usage_page = 0; 338 report_item->usage_minimum = 0; 339 report_item->usage_maximum = 0; 340 report_item->designator_index = 0; 341 report_item->designator_minimum = 0; 342 report_item->designator_maximum = 0; 343 report_item->string_index = 0; 344 report_item->string_minimum = 0; 345 report_item->string_maximum = 0; 346 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 347 244 break; 348 349 case USB_HID_RESET_OFFSET:350 offset_input = 0;351 offset_output = 0;352 offset_feature = 0;353 break;354 355 245 case USB_HID_REPORT_TAG_PUSH: 356 246 // push current state to stack 357 247 new_report_item = usb_hid_report_item_clone(report_item); 358 usb_hid_report_path_t *tmp_path = usb_hid_report_path_clone(usage_path); 359 new_report_item->usage_path = tmp_path; 360 361 list_prepend (&new_report_item->link, &stack); 248 list_prepend (&parser->stack, &new_report_item->link); 249 362 250 break; 363 251 case USB_HID_REPORT_TAG_POP: 364 252 // restore current state from stack 365 if(list_empty (& stack)) {253 if(list_empty (&parser->stack)) { 366 254 return EINVAL; 367 255 } 368 free(report_item);369 370 report_item = list_get_instance(stack.next, usb_hid_report_item_t, link);371 256 372 usb_hid_report_usage_path_t *tmp_usage_path; 373 tmp_usage_path = list_get_instance(report_item->usage_path->link.prev, usb_hid_report_usage_path_t, link); 374 375 usb_hid_report_set_last_item(usage_path, tmp_usage_path->usage_page, tmp_usage_path->usage); 376 377 usb_hid_report_path_free(report_item->usage_path); 378 list_initialize(&report_item->usage_path->link); 379 list_remove (stack.next); 257 report_item = list_get_instance(&parser->stack, usb_hid_report_item_t, link); 258 list_remove (parser->stack.next); 380 259 381 260 break; … … 400 279 } 401 280 281 282 /** 283 * Parse input report. 284 * 285 * @param data Data for report 286 * @param size Size of report 287 * @param callbacks Callbacks for report actions 288 * @param arg Custom arguments 289 * 290 * @return Error code 291 */ 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 byte 300 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 protocol 325 * 326 * @param leds 327 * @param output Output report data buffer 328 * @param size Size of the output buffer 329 * @return Error code 330 */ 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 } 402 341 403 342 /** … … 462 401 463 402 case USB_HID_REPORT_TAG_COLLECTION: 464 // TODO usage_path->flags = *data;465 usb_hid_report_path_append_item(usage_path, report_item->usage_page, report_item->usages[report_item->usages_count-1]);403 usb_hid_report_path_append_item(usage_path, 0, 0); 404 466 405 return USB_HID_NO_ACTION; 467 406 break; 468 407 469 408 case USB_HID_REPORT_TAG_END_COLLECTION: 409 // TODO 410 // znici posledni uroven ve vsech usage paths 411 // otazka jestli nema nicit dve, respektive novou posledni vynulovat? 470 412 usb_hid_report_remove_last_item(usage_path); 471 413 return USB_HID_NO_ACTION; … … 494 436 { 495 437 case USB_HID_REPORT_TAG_USAGE_PAGE: 496 report_item->usage_page = usb_hid_report_tag_data_int32(data, item_size); 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)); 497 441 break; 498 442 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM: … … 522 466 case USB_HID_REPORT_TAG_REPORT_ID: 523 467 report_item->id = usb_hid_report_tag_data_int32(data,item_size); 524 return USB_HID_RESET_OFFSET;525 468 break; 526 469 case USB_HID_REPORT_TAG_PUSH: 527 470 case USB_HID_REPORT_TAG_POP: 528 /*529 * stack operations are done in top level parsing530 * function531 */532 471 return tag; 533 472 break; … … 555 494 { 556 495 case USB_HID_REPORT_TAG_USAGE: 557 report_item->usages[report_item->usages_count++] = usb_hid_report_tag_data_int32(data,item_size); 496 usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL, 497 usb_hid_report_tag_data_int32(data,item_size)); 558 498 break; 559 499 case USB_HID_REPORT_TAG_USAGE_MINIMUM: 560 if (item_size == 3) { 561 // usage extended usages 562 report_item->extended_usage_page = (usb_hid_report_tag_data_int32(data,item_size) & 0xFF00) >> 16; 563 report_item->usage_minimum = usb_hid_report_tag_data_int32(data,item_size) & 0xFF; 564 } 565 else { 566 report_item->usage_minimum = usb_hid_report_tag_data_int32(data,item_size); 567 } 500 report_item->usage_minimum = usb_hid_report_tag_data_int32(data,item_size); 568 501 break; 569 502 case USB_HID_REPORT_TAG_USAGE_MAXIMUM: 570 if (item_size == 3) { 571 // usage extended usages 572 report_item->extended_usage_page = (usb_hid_report_tag_data_int32(data,item_size) & 0xFF00) >> 16; 573 report_item->usage_maximum = usb_hid_report_tag_data_int32(data,item_size) & 0xFF; 574 } 575 else { 576 report_item->usage_maximum = usb_hid_report_tag_data_int32(data,item_size); 577 } 503 report_item->usage_maximum = usb_hid_report_tag_data_int32(data,item_size); 578 504 break; 579 505 case USB_HID_REPORT_TAG_DESIGNATOR_INDEX: … … 596 522 break; 597 523 case USB_HID_REPORT_TAG_DELIMITER: 598 //report_item->delimiter = usb_hid_report_tag_data_int32(data,item_size); 599 //TODO: 600 // DELIMITER STUFF 524 report_item->delimiter = usb_hid_report_tag_data_int32(data,item_size); 601 525 break; 602 526 … … 638 562 void usb_hid_descriptor_print_list(link_t *head) 639 563 { 640 usb_hid_report_field_t *report_item; 564 usb_hid_report_item_t *report_item; 565 usb_hid_report_usage_path_t *path_item; 566 link_t *path; 641 567 link_t *item; 642 643 568 644 569 if(head == NULL || list_empty(head)) { 645 570 usb_log_debug("\tempty\n"); … … 649 574 for(item = head->next; item != head; item = item->next) { 650 575 651 report_item = list_get_instance(item, usb_hid_report_field_t, link); 652 653 usb_log_debug("\t\tOFFSET: %X\n", report_item->offset); 654 usb_log_debug("\t\tSIZE: %X\n", report_item->size); 655 usb_log_debug("\t\tLOGMIN: %X\n", report_item->logical_minimum); 656 usb_log_debug("\t\tLOGMAX: %X\n", report_item->logical_maximum); 657 usb_log_debug("\t\tPHYMIN: %X\n", report_item->physical_minimum); 658 usb_log_debug("\t\tPHYMAX: %X\n", report_item->physical_maximum); 659 usb_log_debug("\t\ttUSAGEMIN: %X\n", report_item->usage_minimum); 660 usb_log_debug("\t\tUSAGEMAX: %X\n", report_item->usage_maximum); 661 662 usb_log_debug("\t\tVALUE: %X\n", report_item->value); 663 usb_log_debug("\t\ttUSAGE: %X\n", report_item->usage); 664 usb_log_debug("\t\tUSAGE PAGE: %X\n", report_item->usage_page); 665 666 // usb_log_debug("\n"); 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"); 667 600 668 601 } … … 676 609 * @return void 677 610 */ 678 void usb_hid_descriptor_print(usb_hid_report_ t *report)679 { 680 if( report== NULL) {611 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser) 612 { 613 if(parser == NULL) { 681 614 return; 682 615 } 683 684 link_t *report_it = report->reports.next; 685 usb_hid_report_description_t *report_des; 686 687 while(report_it != &report->reports) { 688 report_des = list_get_instance(report_it, usb_hid_report_description_t, link); 689 usb_log_debug("Report ID: %d\n", report_des->report_id); 690 usb_log_debug("\tType: %d\n", report_des->type); 691 usb_log_debug("\tLength: %d\n", report_des->bit_length); 692 usb_log_debug("\tItems: %d\n", report_des->item_length); 693 694 usb_hid_descriptor_print_list(&report_des->report_items); 695 696 697 link_t *path_it = report->collection_paths.next; 698 while(path_it != &report->collection_paths) { 699 usb_hid_print_usage_path (list_get_instance(path_it, usb_hid_report_path_t, link)); 700 path_it = path_it->next; 701 } 702 703 report_it = report_it->next; 704 } 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 705 626 } 706 627 … … 746 667 * @return void 747 668 */ 748 void usb_hid_free_report (usb_hid_report_t *report)749 { 750 if( report== NULL){669 void usb_hid_free_report_parser(usb_hid_report_parser_t *parser) 670 { 671 if(parser == NULL){ 751 672 return; 752 673 } 753 674 754 // free collection paths 755 usb_hid_report_path_t *path; 756 while(!list_empty(&report->collection_paths)) { 757 path = list_get_instance(report->collection_paths.next, usb_hid_report_path_t, link); 758 usb_hid_report_path_free(path); 759 } 760 761 // free report items 762 usb_hid_report_description_t *report_des; 763 usb_hid_report_field_t *field; 764 while(!list_empty(&report->reports)) { 765 report_des = list_get_instance(report->reports.next, usb_hid_report_description_t, link); 766 list_remove(&report_des->link); 767 768 while(!list_empty(&report_des->report_items)) { 769 field = list_get_instance(report_des->report_items.next, usb_hid_report_field_t, link); 770 list_remove(&field->link); 771 772 free(field); 773 } 774 775 free(report_des); 776 } 777 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 778 681 return; 779 682 } … … 785 688 * @param parser Opaque HID report parser structure. 786 689 * @param data Data for the report. 690 * @param callbacks Callbacks for report actions. 691 * @param arg Custom argument (passed through to the callbacks). 787 692 * @return Error code. 788 693 */ 789 int usb_hid_parse_report(const usb_hid_report_t *report, 790 const uint8_t *data, size_t size) 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) 791 698 { 792 699 link_t *list_item; 793 usb_hid_report_field_t *item; 794 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; 795 706 uint8_t report_id = 0; 796 usb_hid_report_description_t *report_des; 797 usb_hid_report_type_t type = USB_HID_REPORT_TYPE_INPUT; 798 799 if(report == NULL) { 707 708 if(parser == NULL) { 800 709 return EINVAL; 801 710 } 802 803 if(report->use_report_ids != 0) { 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) { 804 720 report_id = data[0]; 805 } 806 807 report_des = usb_hid_report_find_description(report, report_id, type); 721 usb_hid_report_path_set_report_id(path, report_id); 722 } 808 723 809 724 /* read data */ 810 list_item = report_des->report_items.next; 811 while(list_item != &(report_des->report_items)) { 812 813 item = list_get_instance(list_item, usb_hid_report_field_t, link); 814 815 if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags)) { 816 817 if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0) || 818 ((item->usage_minimum == 0) && (item->usage_maximum == 0))) { 819 820 // variable item 821 item->value = usb_hid_translate_data(item, data,0); 822 823 // array item ??? 824 if(!((item->usage_minimum == 0) && (item->usage_maximum == 0))) { 825 item->usage = item->value + item->usage_minimum; 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 } 826 746 } 827 747 } 828 else {829 // bitmapa830 // TODO: overit jestli vraci hodnoty podle phy min/max831 item->value = usb_hid_translate_data(item, data, 0);832 }833 748 } 834 749 list_item = list_item->next; 835 750 } 751 752 callbacks->keyboard(keys, key_count, report_id, arg); 836 753 754 free(keys); 837 755 return EOK; 838 756 … … 840 758 841 759 /** 842 * Translate data from the report as specified in report descriptor item760 * Translate data from the report as specified in report descriptor 843 761 * 844 762 * @param item Report descriptor item with definition of translation … … 847 765 * @return Translated data 848 766 */ 849 int usb_hid_translate_data(usb_hid_report_ field_t *item, const uint8_t *data, size_t j)767 int usb_hid_translate_data(usb_hid_report_item_t *item, const uint8_t *data, size_t j) 850 768 { 851 769 int resolution; … … 853 771 int part_size; 854 772 855 int32_t value =0;773 int32_t value; 856 774 int32_t mask; 857 775 const uint8_t *foo; 858 776 859 // now only shot tags are allowed777 // now only common numbers llowed 860 778 if(item->size > 32) { 861 779 return 0; … … 877 795 878 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 879 802 // FIXME 880 if((size_t)(offset/8) != (size_t)((offset+item->size-1)/8)) { 803 if((offset/8) != ((offset+item->size)/8)) { 804 usb_log_debug2("offset %d\n", offset); 881 805 882 806 part_size = ((offset+item->size)%8); 883 884 size_t i=0; 885 for(i=(size_t)(offset/8); i<=(size_t)(offset+item->size-1)/8; i++){ 886 if(i == (size_t)(offset/8)) { 887 // the higher one 888 foo = data + i; 889 mask = ((1 << (item->size-part_size))-1); 890 value = (*foo & mask) << part_size; 891 } 892 else if(i == ((offset+item->size-1)/8)){ 893 // the lower one 894 foo = data + i; 895 mask = ((1 << part_size)-1) << (8-part_size); 896 value += ((*foo & mask) >> (8-part_size)); 897 } 898 else { 899 value = value << 8; 900 value += *(data + 1); 901 } 902 } 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 903 829 } 904 830 else { … … 906 832 mask = ((1 << item->size)-1) << (8-((offset%8)+item->size)); 907 833 value = (*foo & mask) >> (8-((offset%8)+item->size)); 908 } 909 910 if(!(item->logical_minimum >= 0 && item->logical_maximum >= 0)){911 value = (int32_t)value;912 }913 else {914 value = (uint32_t)value;915 } 916 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"); 917 843 918 844 return (int)(((value - item->logical_minimum) / resolution) + item->physical_minimum); … … 921 847 922 848 /** 923 * Returns number of items in input report which are accessible by given usage path924 * 925 * @param parser Opaque report descriptor structure926 * @param path Usage path specification927 * @param flags Usage path comparison flags928 * @return Number of items in input report929 */ 930 size_t usb_hid_report_input_length(const usb_hid_report_ t *report,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, 931 857 usb_hid_report_path_t *path, int flags) 932 858 { 933 934 859 size_t ret = 0; 935 936 if(report == NULL) { 860 link_t *item; 861 usb_hid_report_item_t *report_item; 862 863 if(parser == NULL) { 937 864 return 0; 938 865 } 939 940 usb_hid_report_description_t *report_des; 941 report_des = usb_hid_report_find_description (report, path->report_id, USB_HID_REPORT_TYPE_INPUT); 942 if(report_des == NULL) { 943 return 0; 944 } 945 946 link_t *field_it = report_des->report_items.next; 947 usb_hid_report_field_t *field; 948 while(field_it != &report_des->report_items) { 949 950 field = list_get_instance(field_it, usb_hid_report_field_t, link); 951 if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) { 952 953 usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage); 954 if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK) { 955 ret++; 956 } 957 usb_hid_report_remove_last_item (field->collection_path); 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; 958 873 } 959 960 field_it = field_it->next;961 } 874 875 item = item->next; 876 } 962 877 963 878 return ret; 964 } 965 966 967 /** 968 * Appends one item (couple of usage_path and usage) into the usage path 969 * structure 970 * 971 * @param usage_path Usage path structure 972 * @param usage_page Usage page constant 973 * @param usage Usage constant 974 * @return Error code 879 } 880 881 882 /** 883 * 884 * @param usage_path 885 * @param usage_page 886 * @param usage 887 * @return 975 888 */ 976 889 int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path, … … 986 899 item->usage = usage; 987 900 item->usage_page = usage_page; 988 item->flags = 0; 989 990 list_append (&item->link, &usage_path->head); 901 902 usb_log_debug("Appending usage %d, usage page %d\n", usage, usage_page); 903 904 list_append (&usage_path->link, &item->link); 991 905 usage_path->depth++; 992 906 return EOK; … … 994 908 995 909 /** 996 * Removes last item from the usage path structure997 * @param usage_path 998 * @return void910 * 911 * @param usage_path 912 * @return 999 913 */ 1000 914 void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path) … … 1002 916 usb_hid_report_usage_path_t *item; 1003 917 1004 if(!list_empty(&usage_path-> head)){1005 item = list_get_instance(usage_path-> head.prev, usb_hid_report_usage_path_t, link);1006 list_remove(usage_path-> head.prev);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); 1007 921 usage_path->depth--; 1008 922 free(item); … … 1011 925 1012 926 /** 1013 * Nulls last item of the usage path structure.1014 927 * 1015 928 * @param usage_path 1016 * @return void929 * @return 1017 930 */ 1018 931 void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path) … … 1020 933 usb_hid_report_usage_path_t *item; 1021 934 1022 if(!list_empty(&usage_path-> head)){1023 item = list_get_instance(usage_path-> head.prev, usb_hid_report_usage_path_t, link);935 if(!list_empty(&usage_path->link)){ 936 item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link); 1024 937 memset(item, 0, sizeof(usb_hid_report_usage_path_t)); 1025 938 } … … 1027 940 1028 941 /** 1029 * Modifies last item of usage path structure by given usage page or usage 1030 * 1031 * @param usage_path Opaque usage path structure 1032 * @param tag Class of currently processed tag (Usage page tag falls into Global 1033 * class but Usage tag into the Local) 1034 * @param data Value of the processed tag 1035 * @return void 942 * 943 * @param usage_path 944 * @param tag 945 * @param data 946 * @return 1036 947 */ 1037 948 void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, int32_t tag, int32_t data) … … 1039 950 usb_hid_report_usage_path_t *item; 1040 951 1041 if(!list_empty(&usage_path-> head)){1042 item = list_get_instance(usage_path-> head.prev, usb_hid_report_usage_path_t, link);952 if(!list_empty(&usage_path->link)){ 953 item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link); 1043 954 1044 955 switch(tag) { … … 1054 965 } 1055 966 1056 1057 void usb_hid_print_usage_path(usb_hid_report_path_t *path) 1058 { 1059 usb_log_debug("USAGE_PATH FOR RId(%d):\n", path->report_id); 1060 usb_log_debug("\tLENGTH: %d\n", path->depth); 1061 1062 link_t *item = path->head.next; 1063 usb_hid_report_usage_path_t *path_item; 1064 while(item != &path->head) { 1065 1066 path_item = list_get_instance(item, usb_hid_report_usage_path_t, link); 1067 usb_log_debug("\tUSAGE_PAGE: %X\n", path_item->usage_page); 1068 usb_log_debug("\tUSAGE: %X\n", path_item->usage); 1069 usb_log_debug("\tFLAGS: %d\n", path_item->flags); 1070 1071 item = item->next; 1072 } 1073 } 1074 1075 /** 1076 * Compares two usage paths structures 1077 * 1078 * If USB_HID_PATH_COMPARE_COLLECTION_ONLY flag is given, the last item in report_path structure is forgotten 1079 * 1080 * @param report_path usage path structure to compare 1081 * @param path usage patrh structure to compare 1082 * @param flags Flags determining the mode of comparison 1083 * @return EOK if both paths are identical, non zero number otherwise 967 /** 968 * 969 * 970 * @param report_path 971 * @param path 972 * @param flags 973 * @return 1084 974 */ 1085 975 int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path, … … 1115 1005 } 1116 1006 1117 report_link = report_path-> head.next;1118 path_link = path-> head.next;1007 report_link = report_path->link.next; 1008 path_link = path->link.next; 1119 1009 1120 while((report_link != &report_path-> head) && (path_link != &path->head)) {1010 while((report_link != &report_path->link) && (path_link != &path->link)) { 1121 1011 report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link); 1122 1012 path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link); … … 1132 1022 } 1133 1023 1134 if(((report_link == &report_path->head) && (path_link == &path->head)) || 1135 (((flags & USB_HID_PATH_COMPARE_COLLECTION_ONLY) != 0) && (path_link = &path->head) && (report_link == report_path->head.prev))) { 1024 if((report_link == &report_path->link) && (path_link == &path->link)) { 1136 1025 return EOK; 1137 1026 } … … 1143 1032 /* compare with only the end of path*/ 1144 1033 case USB_HID_PATH_COMPARE_END: 1145 1146 if((flags & USB_HID_PATH_COMPARE_COLLECTION_ONLY) != 0) { 1147 report_link = report_path->head.prev->prev; 1148 } 1149 else { 1150 report_link = report_path->head.prev; 1151 } 1152 path_link = path->head.prev; 1153 1154 if(list_empty(&path->head)){ 1034 report_link = report_path->link.prev; 1035 path_link = path->link.prev; 1036 1037 if(list_empty(&path->link)){ 1155 1038 return EOK; 1156 1039 } 1157 1040 1158 while((report_link != &report_path-> head) && (path_link != &path->head)) {1041 while((report_link != &report_path->link) && (path_link != &path->link)) { 1159 1042 report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link); 1160 1043 path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link); … … 1170 1053 } 1171 1054 1172 if(path_link == &path-> head) {1055 if(path_link == &path->link) { 1173 1056 return EOK; 1174 1057 } … … 1189 1072 1190 1073 /** 1191 * Allocates and initializes new usage path structure. 1192 * 1193 * @return Initialized usage path structure 1074 * 1075 * @return 1194 1076 */ 1195 1077 usb_hid_report_path_t *usb_hid_report_path(void) … … 1197 1079 usb_hid_report_path_t *path; 1198 1080 path = malloc(sizeof(usb_hid_report_path_t)); 1199 if( path == NULL){1081 if(!path){ 1200 1082 return NULL; 1201 1083 } … … 1204 1086 path->report_id = 0; 1205 1087 list_initialize(&path->link); 1206 list_initialize(&path->head);1207 1088 return path; 1208 1089 } … … 1210 1091 1211 1092 /** 1212 * Releases given usage path structure. 1213 * 1214 * @param path usage path structure to release 1093 * 1094 * @param path 1215 1095 * @return void 1216 1096 */ 1217 1097 void usb_hid_report_path_free(usb_hid_report_path_t *path) 1218 1098 { 1219 while(!list_empty(&path-> head)){1099 while(!list_empty(&path->link)){ 1220 1100 usb_hid_report_remove_last_item(path); 1221 1101 } 1222 1223 list_remove(&path->link);1224 free(path);1225 1102 } 1226 1103 … … 1229 1106 * Clone content of given usage path to the new one 1230 1107 * 1231 * @param usage_path Usage path structure to clone1232 * @return New copy of given usage path structure1108 * @param usage_path 1109 * @return 1233 1110 */ 1234 1111 usb_hid_report_path_t *usb_hid_report_path_clone(usb_hid_report_path_t *usage_path) 1235 1112 { 1113 usb_hid_report_usage_path_t *path_item; 1236 1114 link_t *path_link; 1237 usb_hid_report_usage_path_t *path_item;1238 usb_hid_report_usage_path_t *new_path_item;1239 1115 usb_hid_report_path_t *new_usage_path = usb_hid_report_path (); 1240 1116 … … 1243 1119 } 1244 1120 1245 if(list_empty(&usage_path-> head)){1121 if(list_empty(&usage_path->link)){ 1246 1122 return new_usage_path; 1247 1123 } 1248 1124 1249 path_link = usage_path-> head.next;1250 while(path_link != &usage_path-> head) {1125 path_link = usage_path->link.next; 1126 while(path_link != &usage_path->link) { 1251 1127 path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link); 1252 new_path_item = malloc(sizeof(usb_hid_report_usage_path_t)); 1253 if(new_path_item == NULL) { 1254 return NULL; 1255 } 1256 1257 list_initialize (&new_path_item->link); 1258 new_path_item->usage_page = path_item->usage_page; 1259 new_path_item->usage = path_item->usage; 1260 new_path_item->flags = path_item->flags; 1261 1262 list_append(&new_path_item->link, &new_usage_path->head); 1263 new_usage_path->depth++; 1128 usb_hid_report_path_append_item (new_usage_path, path_item->usage_page, path_item->usage); 1264 1129 1265 1130 path_link = path_link->next; … … 1272 1137 /*** OUTPUT API **/ 1273 1138 1274 /** 1275 * Allocates output report buffer for output report 1276 * 1277 * @param parser Report parsed structure 1278 * @param size Size of returned buffer 1279 * @param report_id Report id of created output report 1280 * @return Returns allocated output buffer for specified output 1281 */ 1282 uint8_t *usb_hid_report_output(usb_hid_report_t *report, size_t *size, uint8_t report_id) 1283 { 1284 if(report == NULL) { 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) { 1285 1148 *size = 0; 1286 1149 return NULL; 1287 1150 } 1288 1289 link_t *report_it = report->reports.next; 1290 usb_hid_report_description_t *report_des = NULL; 1291 while(report_it != &report->reports) { 1292 report_des = list_get_instance(report_it, usb_hid_report_description_t, link); 1293 if((report_des->report_id == report_id) && (report_des->type == USB_HID_REPORT_TYPE_OUTPUT)){ 1294 break; 1295 } 1296 1297 report_it = report_it->next; 1298 } 1299 1300 if(report_des == NULL){ 1301 *size = 0; 1151 1152 // read the last output report item 1153 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; 1166 } 1167 else { 1168 *size = 0; 1302 1169 return NULL; 1303 1170 } 1304 else {1305 *size = (report_des->bit_length + (8 - 1))/8;1306 uint8_t *ret = malloc((*size) * sizeof(uint8_t));1307 memset(ret, 0, (*size) * sizeof(uint8_t));1308 return ret;1309 }1310 1171 } 1311 1172 … … 1314 1175 * 1315 1176 * @param output Output report buffer 1316 * @return void1177 * @return 1317 1178 */ 1318 1179 void usb_hid_report_output_free(uint8_t *output) … … 1326 1187 /** Returns size of output for given usage path 1327 1188 * 1328 * @param parser Opaque report parser structure1329 * @param path Usage path specified which items will be thought for the output1330 * @param flags Flags of usage path structure comparison1331 * @return Number of items matching the given usage path1332 */ 1333 size_t usb_hid_report_output_size(usb_hid_report_ t *report,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, 1334 1195 usb_hid_report_path_t *path, int flags) 1335 1196 { 1336 size_t ret = 0; 1337 usb_hid_report_description_t *report_des; 1338 1339 if(report == NULL) { 1197 size_t ret = 0; 1198 link_t *item; 1199 usb_hid_report_item_t *report_item; 1200 1201 if(parser == NULL) { 1340 1202 return 0; 1341 1203 } 1342 1204 1343 report_des = usb_hid_report_find_description (report, path->report_id, USB_HID_REPORT_TYPE_OUTPUT); 1344 if(report_des == NULL){ 1345 return 0; 1346 } 1347 1348 link_t *field_it = report_des->report_items.next; 1349 usb_hid_report_field_t *field; 1350 while(field_it != &report_des->report_items) { 1351 1352 field = list_get_instance(field_it, usb_hid_report_field_t, link); 1353 if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0){ 1354 usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage); 1355 if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK) { 1356 ret++; 1357 } 1358 usb_hid_report_remove_last_item (field->collection_path); 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; 1359 1211 } 1360 1361 field_it = field_it->next;1362 } 1212 1213 item = item->next; 1214 } 1363 1215 1364 1216 return ret; … … 1366 1218 } 1367 1219 1368 /** Makes the output report buffer for data given in the report structure 1369 * 1370 * @param parser Opaque report parser structure 1371 * @param path Usage path specifing which parts of output will be set 1372 * @param flags Usage path structure comparison flags 1373 * @param buffer Output buffer 1374 * @param size Size of output buffer 1375 * @return Error code 1376 */ 1377 int usb_hid_report_output_translate(usb_hid_report_t *report, uint8_t report_id, 1378 uint8_t *buffer, size_t size) 1379 { 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; 1380 1237 link_t *item; 1238 size_t idx=0; 1239 int i=0; 1381 1240 int32_t value=0; 1382 1241 int offset; 1383 1242 int length; 1384 1243 int32_t tmp_value; 1385 1386 if(report == NULL) { 1244 size_t offset_prefix = 0; 1245 1246 if(parser == NULL) { 1387 1247 return EINVAL; 1388 1248 } 1389 1249 1390 if(report->use_report_ids != 0) { 1391 buffer[0] = report_id; 1250 if(parser->use_report_id != 0) { 1251 buffer[0] = path->report_id; 1252 offset_prefix = 8; 1392 1253 } 1393 1254 1394 1255 usb_log_debug("OUTPUT BUFFER: %s\n", usb_debug_str_buffer(buffer,size, 0)); 1395 1396 usb_hid_report_description_t *report_des; 1397 report_des = usb_hid_report_find_description (report, report_id, USB_HID_REPORT_TYPE_OUTPUT);1398 if(report_des == NULL){1399 re turn EINVAL;1400 } 1401 1402 usb_hid_report_field_t *report_item; 1403 item = report_des->report_items.next;1404 while(item != &report_des->report_items) {1405 report_item = list_get_instance(item, usb_hid_report_field_t, link);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 } 1406 1267 1407 1268 if((USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) || 1408 1269 ((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0))) { 1409 1270 1410 // variable item1411 value = usb_hid_translate_data_reverse(report_item, report_item->value);1412 offset = report_item->offset ;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; 1413 1274 length = report_item->size; 1414 1275 } 1415 1276 else { 1416 1277 //bitmap 1417 value += usb_hid_translate_data_reverse(report_item, report_item->value);1418 offset = report_item->offset ;1419 length = report_item->size ;1278 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; 1420 1281 } 1421 1282 … … 1436 1297 } 1437 1298 else { 1438 int i = 0; 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 1439 1306 uint8_t mask = 0; 1440 for(i = (offset/8); i <= ((offset+length-1)/8); i++) { 1441 if(i == (offset/8)) { 1442 tmp_value = value; 1443 tmp_value = tmp_value & ((1 << (8-(offset%8)))-1); 1444 tmp_value = tmp_value << (offset%8); 1445 1446 mask = ~(((1 << (8-(offset%8)))-1) << (offset%8)); 1447 buffer[i] = (buffer[i] & mask) | tmp_value; 1448 } 1449 else if (i == ((offset + length -1)/8)) { 1450 1451 value = value >> (length - ((offset + length) % 8)); 1452 value = value & ((1 << (length - ((offset + length) % 8))) - 1); 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); 1453 1313 1454 mask = (1 << (length - ((offset + length) % 8))) - 1; 1455 buffer[i] = (buffer[i] & mask) | value; 1456 } 1457 else { 1458 buffer[i] = value & (0xFF << i); 1459 } 1460 } 1314 mask = ((1 << (length - (8 - (offset % 8)))) - 1); 1315 buffer[(offset+length-1)/8] = (buffer[(offset+length-1)/8] & mask) | value; 1461 1316 } 1462 1317 1318 } 1463 1319 1464 1320 item = item->next; … … 1471 1327 1472 1328 /** 1473 * Translate given data for putting them into the outoput report1474 * @param item Report item structure1475 * @param value Value to translate1476 * @return ranslated value1477 */ 1478 uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, int value)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) 1479 1335 { 1480 1336 int ret=0; … … 1516 1372 1517 1373 1518 return (uint32_t)ret; 1519 } 1520 1521 /** 1522 * Sets report id in usage path structure 1523 * 1524 * @param path Usage path structure 1525 * @param report_id Report id to set 1526 * @return Error code 1527 */ 1374 return ret; 1375 } 1376 1377 1528 1378 int usb_hid_report_path_set_report_id(usb_hid_report_path_t *path, uint8_t report_id) 1529 1379 { … … 1533 1383 1534 1384 path->report_id = report_id; 1535 return EOK;1536 }1537 1538 /**1539 *1540 *1541 *1542 *1543 *1544 */1545 int usb_hid_report_output_set_data(usb_hid_report_t *report,1546 usb_hid_report_path_t *path, int flags,1547 int *data, size_t data_size)1548 {1549 size_t data_idx = 0;1550 if(report == NULL){1551 return EINVAL;1552 }1553 1554 usb_hid_report_description_t *report_des;1555 report_des = usb_hid_report_find_description (report, path->report_id,1556 USB_HID_REPORT_TYPE_OUTPUT);1557 if(report_des == NULL){1558 return EINVAL;1559 }1560 1561 usb_hid_report_field_t *field;1562 link_t *field_it = report_des->report_items.next;1563 while(field_it != &report_des->report_items){1564 1565 field = list_get_instance(field_it, usb_hid_report_field_t, link);1566 if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) {1567 usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage);1568 if(usb_hid_report_compare_usage_path (field->collection_path, path,1569 flags) == EOK) {1570 1571 if(data_idx < data_size) {1572 field->value = data[data_idx++];1573 }1574 else {1575 field->value = 0;1576 }1577 }1578 usb_hid_report_remove_last_item (field->collection_path);1579 }1580 1581 field_it = field_it->next;1582 }1583 1584 1385 return EOK; 1585 1386 } … … 1599 1400 } 1600 1401 1601 1602 usb_hid_report_field_t *usb_hid_report_get_sibling(usb_hid_report_t *report,1603 usb_hid_report_field_t *field,1604 usb_hid_report_path_t *path, int flags,1605 usb_hid_report_type_t type)1606 {1607 usb_hid_report_description_t *report_des = usb_hid_report_find_description (report, path->report_id, type);1608 link_t *field_it;1609 1610 if(report_des == NULL){1611 return NULL;1612 }1613 1614 if(field == NULL){1615 // vezmu prvni co mathuje podle path!!1616 field_it = report_des->report_items.next;1617 }1618 else {1619 field_it = field->link.next;1620 }1621 1622 while(field_it != &report_des->report_items) {1623 field = list_get_instance(field_it, usb_hid_report_field_t, link);1624 1625 usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage);1626 if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK){1627 usb_hid_report_remove_last_item (field->collection_path);1628 usb_log_debug("....OK\n");1629 return field;1630 }1631 usb_hid_report_remove_last_item (field->collection_path);1632 1633 field_it = field_it->next;1634 }1635 1636 return NULL;1637 }1638 1402 /** 1639 1403 * @} -
uspace/lib/usb/src/hidreport.c
r63517c2 rda1dd48 164 164 165 165 int usb_hid_process_report_descriptor(usb_device_t *dev, 166 usb_hid_report_ t *report)166 usb_hid_report_parser_t *parser) 167 167 { 168 if (dev == NULL || report== NULL) {168 if (dev == NULL || parser == 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( report, report_desc, report_size);191 rc = usb_hid_parse_report_descriptor(parser, 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( report);199 usb_hid_descriptor_print(parser); 200 200 free(report_desc); 201 201
Note:
See TracChangeset
for help on using the changeset viewer.