Changes in / [e69f10b:45dd8bf] in mainline
- Location:
- uspace
- Files:
-
- 1 deleted
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbhid/hiddev.c
re69f10b r45dd8bf 158 158 } 159 159 160 hid_dev->report_desc_size = length;161 162 160 usb_log_debug("Done.\n"); 163 161 … … 264 262 265 263 if (rc != EOK) { 266 usb_log_warning("Problem with getting Report descriptor: %s.\n",264 usb_log_warning("Problem with parsing Report descriptor: %s.\n", 267 265 str_error(rc)); 268 266 return rc; 269 267 } 270 271 rc = usb_hid_parse_report_descriptor(hid_dev->parser,272 hid_dev->report_desc, hid_dev->report_desc_size);273 if (rc != EOK) {274 usb_log_warning("Problem parsing Report descriptor: %s.\n",275 str_error(rc));276 return rc;277 }278 279 usb_hid_descriptor_print(hid_dev->parser);280 268 281 269 return EOK; … … 301 289 302 290 memset(dev, 0, sizeof(usbhid_dev_t)); 303 304 dev->parser = (usb_hid_report_parser_t *)(malloc(sizeof(305 usb_hid_report_parser_t)));306 if (dev->parser == NULL) {307 usb_log_fatal("No memory!\n");308 free(dev);309 return NULL;310 }311 291 312 292 dev->initialized = 0; … … 411 391 return rc; 412 392 } 413 414 /*415 * Initialize the report parser.416 */417 rc = usb_hid_parser_init(hid_dev->parser);418 if (rc != EOK) {419 usb_log_error("Failed to initialize report parser.\n");420 return rc;421 }422 393 423 394 /* -
uspace/drv/usbhid/hiddev.h
re69f10b r45dd8bf 75 75 /** Report descriptor. */ 76 76 uint8_t *report_desc; 77 78 size_t report_desc_size;79 80 77 /** HID Report parser. */ 81 78 usb_hid_report_parser_t *parser; -
uspace/drv/usbhid/kbddev.c
re69f10b r45dd8bf 541 541 callbacks->keyboard = usbhid_kbd_process_keycodes; 542 542 543 usb_log_debug("Calling usb_hid_ parse_report() with "543 usb_log_debug("Calling usb_hid_boot_keyboard_input_report() with " 544 544 "buffer %s\n", usb_debug_str_buffer(buffer, actual_size, 0)); 545 545 546 // int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size, 547 // callbacks, kbd_dev); 548 int rc = usb_hid_parse_report(kbd_dev->hid_dev->parser, buffer, 549 actual_size, callbacks, kbd_dev); 546 int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size, 547 callbacks, kbd_dev); 550 548 551 549 if (rc != EOK) { … … 616 614 free((*kbd_dev)->repeat_mtx); 617 615 } 618 619 usb_hid_free_report_parser((*kbd_dev)->parser);620 616 621 617 free(*kbd_dev); … … 713 709 assert(kbd_dev->hid_dev != NULL); 714 710 assert(kbd_dev->hid_dev->initialized); 715 //usbhid_req_set_protocol(kbd_dev->hid_dev, USB_HID_PROTOCOL_BOOT);711 usbhid_req_set_protocol(kbd_dev->hid_dev, USB_HID_PROTOCOL_BOOT); 716 712 717 713 usbhid_kbd_set_led(kbd_dev); -
uspace/drv/usbhid/kbddev.h
re69f10b r45dd8bf 42 42 43 43 #include <usb/classes/hid.h> 44 #include <usb/classes/hidparser.h>45 44 #include <ddf/driver.h> 46 45 #include <usb/pipes.h> … … 100 99 /** Mutex for accessing the information about auto-repeat. */ 101 100 fibril_mutex_t *repeat_mtx; 102 103 usb_hid_report_parser_t *parser;104 101 105 102 /** State of the structure (for checking before use). */ -
uspace/lib/usb/include/usb/classes/hidparser.h
re69f10b r45dd8bf 37 37 38 38 #include <stdint.h> 39 #include <adt/list.h>40 #include <usb/classes/hid_report_items.h>41 42 /**43 * Item prefix44 */45 #define USB_HID_ITEM_SIZE(data) ((uint8_t)(data & 0x3))46 #define USB_HID_ITEM_TAG(data) ((uint8_t)((data & 0xF0) >> 4))47 #define USB_HID_ITEM_TAG_CLASS(data) ((uint8_t)((data & 0xC) >> 2))48 #define USB_HID_ITEM_IS_LONG(data) (data == 0xFE)49 50 51 /**52 * Input/Output/Feature Item flags53 */54 #define USB_HID_ITEM_FLAG_CONSTANT(flags) (flags & 0x1)55 #define USB_HID_ITEM_FLAG_VARIABLE(flags) (flags & 0x2)56 #define USB_HID_ITEM_FLAG_RELATIVE(flags) (flags & 0x4)57 #define USB_HID_ITEM_FLAG_WRAP(flags) (flags & 0x8)58 #define USB_HID_ITEM_FLAG_LINEAR(flags) (flags & 0x10)59 #define USB_HID_ITEM_FLAG_PREFERRED(flags) (flags & 0x20)60 #define USB_HID_ITEM_FLAG_POSITION(flags) (flags & 0x40)61 #define USB_HID_ITEM_FLAG_VOLATILE(flags) (flags & 0x80)62 #define USB_HID_ITEM_FLAG_BUFFERED(flags) (flags & 0x100)63 64 39 65 40 /** … … 67 42 */ 68 43 typedef struct { 69 int32_t id;70 int32_t usage_page;71 int32_t usage;72 int32_t usage_minimum;73 int32_t usage_maximum;74 int32_t logical_minimum;75 int32_t logical_maximum;76 int32_t size;77 int32_t count;78 size_t offset;79 int32_t delimiter;80 44 81 int32_t unit_exponent; 82 int32_t unit; 45 uint8_t usage_min; 46 uint8_t usage_max; 47 uint8_t logical_min; 48 uint8_t logical_max; 49 uint8_t size; 50 uint8_t count; 51 uint8_t offset; 83 52 84 /*85 * some not yet used fields86 */87 int32_t string_index;88 int32_t string_minimum;89 int32_t string_maximum;90 int32_t designator_index;91 int32_t designator_minimum;92 int32_t designator_maximum;93 int32_t physical_minimum;94 int32_t physical_maximum;95 96 uint8_t item_flags;97 98 link_t link;99 53 } usb_hid_report_item_t; 100 54 101 55 102 56 /** HID report parser structure. */ 103 typedef struct { 104 link_t input; 105 link_t output; 106 link_t feature; 107 } usb_hid_report_parser_t; 108 57 typedef struct { 58 } usb_hid_report_parser_t; 109 59 110 60 … … 177 127 int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size); 178 128 179 int usb_hid_parser_init(usb_hid_report_parser_t *parser);180 129 int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser, 181 130 const uint8_t *data, size_t size); … … 186 135 187 136 188 void usb_hid_free_report_parser(usb_hid_report_parser_t *parser); 189 190 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser); 137 int usb_hid_free_report_parser(usb_hid_report_parser_t *parser); 191 138 192 139 #endif -
uspace/lib/usb/src/hidparser.c
re69f10b r45dd8bf 36 36 #include <errno.h> 37 37 #include <stdio.h> 38 #include <malloc.h>39 #include <mem.h>40 #include <usb/debug.h>41 42 #define USB_HID_NEW_REPORT_ITEM 143 #define USB_HID_NO_ACTION 244 #define USB_HID_UNKNOWN_TAG -9945 46 #define BAD_HACK_USAGE_PAGE 0x0747 48 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size,49 usb_hid_report_item_t *report_item);50 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size,51 usb_hid_report_item_t *report_item);52 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size,53 usb_hid_report_item_t *report_item);54 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size,55 usb_hid_report_item_t *report_item);56 57 void usb_hid_descriptor_print_list(link_t *head);58 int usb_hid_report_reset_local_items();59 void usb_hid_free_report_list(link_t *head);60 int32_t usb_hid_report_tag_data_int32(const uint8_t *data, size_t size);61 inline size_t usb_hid_count_item_offset(usb_hid_report_item_t * report_item, size_t offset);62 int usb_hid_translate_data(usb_hid_report_item_t *item, const uint8_t *data, size_t j);63 int usb_pow(int a, int b);64 65 int usb_pow(int a, int b)66 {67 switch(b) {68 case 0:69 return 1;70 break;71 case 1:72 return a;73 break;74 default:75 return a * usb_pow(a, b-1);76 break;77 }78 }79 80 /**81 *82 */83 int usb_hid_parser_init(usb_hid_report_parser_t *parser)84 {85 if(parser == NULL) {86 return -1;87 }88 89 list_initialize(&(parser->input));90 list_initialize(&(parser->output));91 list_initialize(&(parser->feature));92 93 return EOK;94 }95 96 38 97 39 /** Parse HID report descriptor. … … 104 46 const uint8_t *data, size_t size) 105 47 { 106 size_t i=0; 107 uint8_t tag=0; 108 uint8_t item_size=0; 109 int class=0; 110 int ret; 111 usb_hid_report_item_t *report_item=0; 112 usb_hid_report_item_t *new_report_item; 48 return ENOTSUP; 49 } 113 50 114 size_t offset_input=0; 115 size_t offset_output=0; 116 size_t offset_feature=0; 51 /** Parse and act upon a HID report. 52 * 53 * @see usb_hid_parse_report_descriptor 54 * 55 * @param parser Opaque HID report parser structure. 56 * @param data Data for the report. 57 * @param callbacks Callbacks for report actions. 58 * @param arg Custom argument (passed through to the callbacks). 59 * @return Error code. 60 */ 61 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 62 const uint8_t *data, size_t size, 63 const usb_hid_report_in_callbacks_t *callbacks, void *arg) 64 { 65 int i; 117 66 118 119 if(!(report_item=malloc(sizeof(usb_hid_report_item_t)))){ 120 return ENOMEM; 121 } 122 memset(report_item, 0, sizeof(usb_hid_report_item_t)); 123 124 link_initialize(&(report_item->link)); 125 126 while(i<size){ 127 if(!USB_HID_ITEM_IS_LONG(data[i])){ 128 129 if((i+USB_HID_ITEM_SIZE(data[i]))>= size){ 130 return -1; // TODO ERROR CODE 131 } 132 133 tag = USB_HID_ITEM_TAG(data[i]); 134 item_size = USB_HID_ITEM_SIZE(data[i]); 135 class = USB_HID_ITEM_TAG_CLASS(data[i]); 136 137 usb_log_debug2( 138 "i(%u) data(%X) value(%X): TAG %u, class %u, size %u - ", i, 139 data[i], usb_hid_report_tag_data_int32(data+i+1,item_size), 140 tag, class, item_size); 141 142 ret = usb_hid_report_parse_tag(tag,class,data+i+1, 143 item_size,report_item); 144 usb_log_debug2("ret: %u\n", ret); 145 switch(ret){ 146 case USB_HID_NEW_REPORT_ITEM: 147 // store report item to report and create the new one 148 usb_log_debug("\nNEW REPORT ITEM: %X",tag); 149 150 switch(tag) { 151 case USB_HID_REPORT_TAG_INPUT: 152 report_item->offset = offset_input; 153 offset_input += report_item->count * report_item->size; 154 usb_log_debug(" - INPUT\n"); 155 list_append(&(report_item->link), &(parser->input)); 156 break; 157 case USB_HID_REPORT_TAG_OUTPUT: 158 report_item->offset = offset_output; 159 offset_output += report_item->count * report_item->size; 160 usb_log_debug(" - OUTPUT\n"); 161 list_append(&(report_item->link), &(parser->output)); 162 163 break; 164 case USB_HID_REPORT_TAG_FEATURE: 165 report_item->offset = offset_feature; 166 offset_feature += report_item->count * report_item->size; 167 usb_log_debug(" - FEATURE\n"); 168 list_append(&(report_item->link), &(parser->feature)); 169 break; 170 default: 171 usb_log_debug("\tjump over - tag %X\n", tag); 172 break; 173 } 174 175 /* clone current state table to the new item */ 176 if(!(new_report_item = malloc(sizeof(usb_hid_report_item_t)))) { 177 return ENOMEM; 178 } 179 memcpy(new_report_item,report_item, sizeof(usb_hid_report_item_t)); 180 link_initialize(&(new_report_item->link)); 181 report_item = new_report_item; 182 183 break; 184 case USB_HID_REPORT_TAG_PUSH: 185 // push current state to stack 186 // not yet implemented 187 break; 188 case USB_HID_REPORT_TAG_POP: 189 // restore current state from stack 190 // not yet implemented 191 break; 192 193 default: 194 // nothing special to do 195 break; 196 } 197 198 /* jump over the processed block */ 199 i += 1 + USB_HID_ITEM_SIZE(data[i]); 200 } 201 else{ 202 // TBD 203 i += 3 + USB_HID_ITEM_SIZE(data[i+1]); 204 } 205 206 67 /* main parsing loop */ 68 while(0){ 207 69 } 208 70 71 72 uint8_t keys[6]; 73 74 for (i = 0; i < 6; ++i) { 75 keys[i] = data[i]; 76 } 77 78 callbacks->keyboard(keys, 6, 0, arg); 79 80 return EOK; 81 } 82 83 /** Free the HID report parser structure 84 * 85 * @param parser Opaque HID report parser structure 86 * @return Error code 87 */ 88 int usb_hid_free_report_parser(usb_hid_report_parser_t *parser) 89 { 90 209 91 return EOK; 210 92 } … … 234 116 item.size = 8; 235 117 item.count = 6; 236 item.usage_min imum= 0;237 item.usage_max imum= 255;238 item.logical_min imum= 0;239 item.logical_max imum= 255;118 item.usage_min = 0; 119 item.usage_max = 255; 120 item.logical_min = 0; 121 item.logical_max = 255; 240 122 241 123 if (size != 8) { 242 return -1; //ERANGE;124 return ERANGE; 243 125 } 244 126 … … 262 144 int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size) 263 145 { 264 if (size !=1){146 if (size < 1){ 265 147 return -1; 266 148 } 267 149 268 /* used only first five bits, others are only padding*/ 269 *data = leds; 150 data[0] = leds; 270 151 return EOK; 271 152 } 272 153 273 154 /** 274 *275 * @param Tag to parse276 * @param Report descriptor buffer277 * @param Size of data belongs to this tag278 * @param Current report item structe279 * @return Code of action to be done next280 */281 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size,282 usb_hid_report_item_t *report_item)283 {284 int ret;285 286 switch(class){287 case USB_HID_TAG_CLASS_MAIN:288 289 if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item)) == EOK) {290 return USB_HID_NEW_REPORT_ITEM;291 }292 else {293 /*TODO process the error */294 return ret;295 }296 break;297 298 case USB_HID_TAG_CLASS_GLOBAL:299 return usb_hid_report_parse_global_tag(tag,data,item_size,report_item);300 break;301 302 case USB_HID_TAG_CLASS_LOCAL:303 return usb_hid_report_parse_local_tag(tag,data,item_size,report_item);304 break;305 default:306 return USB_HID_NO_ACTION;307 }308 }309 310 /**311 * Parse main tags of report descriptor312 *313 * @param Tag identifier314 * @param Data buffer315 * @param Length of data buffer316 * @param Current state table317 * @return Error code318 */319 320 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size,321 usb_hid_report_item_t *report_item)322 {323 switch(tag)324 {325 case USB_HID_REPORT_TAG_INPUT:326 case USB_HID_REPORT_TAG_OUTPUT:327 case USB_HID_REPORT_TAG_FEATURE:328 report_item->item_flags = *data;329 return EOK;330 break;331 332 case USB_HID_REPORT_TAG_COLLECTION:333 // TODO334 return USB_HID_NO_ACTION;335 break;336 337 case USB_HID_REPORT_TAG_END_COLLECTION:338 /* should be ignored */339 return USB_HID_NO_ACTION;340 break;341 default:342 return USB_HID_NO_ACTION;343 }344 345 return EOK;346 }347 348 /**349 * Parse global tags of report descriptor350 *351 * @param Tag identifier352 * @param Data buffer353 * @param Length of data buffer354 * @param Current state table355 * @return Error code356 */357 358 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size,359 usb_hid_report_item_t *report_item)360 {361 // TODO take care about the bit length of data362 switch(tag)363 {364 case USB_HID_REPORT_TAG_USAGE_PAGE:365 report_item->usage_page = usb_hid_report_tag_data_int32(data,item_size);366 break;367 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM:368 report_item->logical_minimum = usb_hid_report_tag_data_int32(data,item_size);369 break;370 case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM:371 report_item->logical_maximum = usb_hid_report_tag_data_int32(data,item_size);372 break;373 case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM:374 report_item->physical_minimum = usb_hid_report_tag_data_int32(data,item_size);375 break;376 case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM:377 report_item->physical_maximum = usb_hid_report_tag_data_int32(data,item_size);378 break;379 case USB_HID_REPORT_TAG_UNIT_EXPONENT:380 report_item->unit_exponent = usb_hid_report_tag_data_int32(data,item_size);381 break;382 case USB_HID_REPORT_TAG_UNIT:383 report_item->unit = usb_hid_report_tag_data_int32(data,item_size);384 break;385 case USB_HID_REPORT_TAG_REPORT_SIZE:386 report_item->size = usb_hid_report_tag_data_int32(data,item_size);387 break;388 case USB_HID_REPORT_TAG_REPORT_COUNT:389 report_item->count = usb_hid_report_tag_data_int32(data,item_size);390 break;391 case USB_HID_REPORT_TAG_REPORT_ID:392 report_item->id = usb_hid_report_tag_data_int32(data,item_size);393 break;394 case USB_HID_REPORT_TAG_PUSH:395 case USB_HID_REPORT_TAG_POP:396 return tag;397 break;398 399 default:400 return USB_HID_NO_ACTION;401 }402 403 return EOK;404 }405 406 /**407 * Parse local tags of report descriptor408 *409 * @param Tag identifier410 * @param Data buffer411 * @param Length of data buffer412 * @param Current state table413 * @return Error code414 */415 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size,416 usb_hid_report_item_t *report_item)417 {418 switch(tag)419 {420 case USB_HID_REPORT_TAG_USAGE:421 report_item->usage = usb_hid_report_tag_data_int32(data,item_size);422 break;423 case USB_HID_REPORT_TAG_USAGE_MINIMUM:424 report_item->usage_minimum = usb_hid_report_tag_data_int32(data,item_size);425 break;426 case USB_HID_REPORT_TAG_USAGE_MAXIMUM:427 report_item->usage_maximum = usb_hid_report_tag_data_int32(data,item_size);428 break;429 case USB_HID_REPORT_TAG_DESIGNATOR_INDEX:430 report_item->designator_index = usb_hid_report_tag_data_int32(data,item_size);431 break;432 case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM:433 report_item->designator_minimum = usb_hid_report_tag_data_int32(data,item_size);434 break;435 case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM:436 report_item->designator_maximum = usb_hid_report_tag_data_int32(data,item_size);437 break;438 case USB_HID_REPORT_TAG_STRING_INDEX:439 report_item->string_index = usb_hid_report_tag_data_int32(data,item_size);440 break;441 case USB_HID_REPORT_TAG_STRING_MINIMUM:442 report_item->string_minimum = usb_hid_report_tag_data_int32(data,item_size);443 break;444 case USB_HID_REPORT_TAG_STRING_MAXIMUM:445 report_item->string_maximum = usb_hid_report_tag_data_int32(data,item_size);446 break;447 case USB_HID_REPORT_TAG_DELIMITER:448 report_item->delimiter = usb_hid_report_tag_data_int32(data,item_size);449 break;450 451 default:452 return USB_HID_NO_ACTION;453 }454 455 return EOK;456 }457 458 /**459 * Converts raw data to int32 (thats the maximum length of short item data)460 *461 * @param Data buffer462 * @param Size of buffer463 * @return Converted int32 number464 */465 int32_t usb_hid_report_tag_data_int32(const uint8_t *data, size_t size)466 {467 unsigned int i;468 int32_t result;469 470 result = 0;471 for(i=0; i<size; i++) {472 result = (result | (data[i]) << (i*8));473 }474 475 return result;476 }477 478 479 480 /**481 * Prints content of given list of report items.482 *483 * @param List of report items484 * @return void485 */486 void usb_hid_descriptor_print_list(link_t *head)487 {488 usb_hid_report_item_t *report_item;489 link_t *item;490 491 if(head == NULL || list_empty(head)) {492 usb_log_debug("\tempty\n");493 return;494 }495 496 for(item = head->next; item != head; item = item->next) {497 498 report_item = list_get_instance(item, usb_hid_report_item_t, link);499 500 usb_log_debug("\tOFFSET: %X\n", report_item->offset);501 usb_log_debug("\tCOUNT: %X\n", report_item->count);502 usb_log_debug("\tSIZE: %X\n", report_item->size);503 usb_log_debug("\tCONSTANT: %X\n", USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags));504 usb_log_debug("\tUSAGE: %X\n", report_item->usage);505 usb_log_debug("\tUSAGE PAGE: %X\n", report_item->usage_page);506 usb_log_debug("\tLOGMIN: %X\n", report_item->logical_minimum);507 usb_log_debug("\tLOGMAX: %X\n", report_item->logical_maximum);508 usb_log_debug("\tPHYMIN: %X\n", report_item->physical_minimum);509 usb_log_debug("\tPHYMAX: %X\n", report_item->physical_maximum);510 usb_log_debug("\n");511 512 }513 514 515 }516 /**517 * Prints content of given descriptor in human readable format.518 *519 * @param Parsed descriptor to print520 * @return void521 */522 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser)523 {524 usb_log_debug("INPUT:\n");525 usb_hid_descriptor_print_list(&parser->input);526 527 usb_log_debug("OUTPUT: \n");528 usb_hid_descriptor_print_list(&parser->output);529 530 usb_log_debug("FEATURE:\n");531 usb_hid_descriptor_print_list(&parser->feature);532 533 }534 535 /**536 * Releases whole linked list of report items537 *538 *539 */540 void usb_hid_free_report_list(link_t *head)541 {542 return;543 544 usb_hid_report_item_t *report_item;545 link_t *next;546 547 if(head == NULL || list_empty(head)) {548 return;549 }550 551 next = head->next;552 while(next != head) {553 554 report_item = list_get_instance(next, usb_hid_report_item_t, link);555 next = next->next;556 557 free(report_item);558 }559 560 return;561 562 }563 564 /** Free the HID report parser structure565 *566 * @param parser Opaque HID report parser structure567 * @return Error code568 */569 void usb_hid_free_report_parser(usb_hid_report_parser_t *parser)570 {571 if(parser == NULL){572 return;573 }574 575 usb_hid_free_report_list(&parser->input);576 usb_hid_free_report_list(&parser->output);577 usb_hid_free_report_list(&parser->feature);578 579 return;580 }581 582 /** Parse and act upon a HID report.583 *584 * @see usb_hid_parse_report_descriptor585 *586 * @param parser Opaque HID report parser structure.587 * @param data Data for the report.588 * @param callbacks Callbacks for report actions.589 * @param arg Custom argument (passed through to the callbacks).590 * @return Error code.591 */592 int usb_hid_parse_report(const usb_hid_report_parser_t *parser,593 const uint8_t *data, size_t size,594 const usb_hid_report_in_callbacks_t *callbacks, void *arg)595 {596 /*597 *598 * only key codes (usage page 0x07) will be processed599 * other usages will be ignored600 */601 link_t *list_item;602 usb_hid_report_item_t *item;603 uint8_t *keys;604 size_t key_count=0;605 size_t i=0;606 size_t j=0;607 608 // get the size of result keycodes array609 list_item = parser->input.next;610 while(list_item != &(parser->input)) {611 612 item = list_get_instance(list_item, usb_hid_report_item_t, link);613 if(item->usage_page == BAD_HACK_USAGE_PAGE) {614 key_count += item->count;615 }616 617 list_item = list_item->next;618 }619 620 621 if(!(keys = malloc(sizeof(uint8_t) * key_count))){622 return ENOMEM;623 }624 625 // read data626 list_item = parser->input.next;627 while(list_item != &(parser->input)) {628 629 item = list_get_instance(list_item, usb_hid_report_item_t, link);630 if(item->usage_page == BAD_HACK_USAGE_PAGE) {631 for(j=0; j<(size_t)(item->count); j++) {632 keys[i++] = usb_hid_translate_data(item, data,j);633 }634 }635 list_item = list_item->next;636 }637 638 callbacks->keyboard(keys, key_count, 0, arg);639 640 free(keys);641 return EOK;642 643 }644 645 646 int usb_hid_translate_data(usb_hid_report_item_t *item, const uint8_t *data, size_t j)647 {648 int resolution;649 int offset;650 int part_size;651 652 int32_t value;653 int32_t mask;654 const uint8_t *foo;655 656 // now only common numbers llowed657 if(item->size > 32) {658 return 0;659 }660 661 if((item->physical_minimum == 0) && (item->physical_maximum == 0)) {662 item->physical_minimum = item->logical_minimum;663 item->physical_maximum = item->logical_maximum;664 }665 666 if(item->physical_maximum == item->physical_minimum){667 resolution = 1;668 }669 else {670 resolution = (item->logical_maximum - item->logical_minimum) /671 ((item->physical_maximum - item->physical_minimum) *672 (usb_pow(10,(item->unit_exponent))));673 }674 offset = item->offset + (j * item->size);675 676 // FIXME677 if((offset/8) != ((offset+item->size)/8)) {678 usb_log_debug2("offset %d\n", offset);679 680 part_size = ((offset+item->size)%8);681 usb_log_debug2("part size %d\n",part_size);682 683 // the higher one684 foo = data+(offset/8);685 mask = ((1 << (item->size-part_size))-1);686 value = (*foo & mask) << part_size;687 688 usb_log_debug2("hfoo %x\n", *foo);689 usb_log_debug2("hmaska %x\n", mask);690 usb_log_debug2("hval %d\n", value);691 692 // the lower one693 foo = data+((offset+item->size)/8);694 mask = ((1 << part_size)-1) << (8-part_size);695 value += ((*foo & mask) >> (8-part_size));696 697 usb_log_debug2("lfoo %x\n", *foo);698 usb_log_debug2("lmaska %x\n", mask);699 usb_log_debug2("lval %d\n", ((*foo & mask) >> (8-(item->size-part_size))));700 usb_log_debug2("val %d\n", value);701 702 703 }704 else {705 foo = data+(offset/8);706 mask = ((1 << item->size)-1) << (8-((offset%8)+item->size));707 value = (*foo & mask) >> (8-((offset%8)+item->size));708 709 usb_log_debug2("offset %d\n", offset);710 711 usb_log_debug2("foo %x\n", *foo);712 usb_log_debug2("maska %x\n", mask);713 usb_log_debug2("val %d\n", value);714 }715 716 usb_log_debug2("---\n\n");717 718 return (int)(((value - item->logical_minimum) / resolution) + item->physical_minimum);719 720 }721 /**722 155 * @} 723 156 */
Note:
See TracChangeset
for help on using the changeset viewer.