Changes in uspace/lib/usb/src/hidparser.c [976f546:ad4562c2] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/src/hidparser.c
r976f546 rad4562c2 36 36 #include <errno.h> 37 37 #include <stdio.h> 38 #include <adt/list.h>39 40 #define USB_HID_NEW_REPORT_ITEM 041 42 43 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, uint8_t *data, size_t item_size,44 usb_hid_report_item_t *report_item);45 int usb_hid_report_parse_main_tag(uint8_t tag, uint8_t *data, size_t item_size,46 usb_hid_report_item_t *report_item);47 int usb_hid_report_parse_global_tag(uint8_t tag, uint8_t *data, size_t item_size,48 usb_hid_report_item_t *report_item);49 int usb_hid_report_parse_local_tag(uint8_t tag, uint8_t *data, size_t item_size,50 usb_hid_report_item_t *report_item);51 52 void usb_hid_descriptor_print_list(link_t *head)53 int usb_hid_report_reset_local_items();54 void usb_hid_free_report_list(link_t *list);55 56 /**57 *58 */59 int usb_hid_parser_init(usb_hid_report_parser_t *parser)60 {61 if(parser == NULL) {62 return -1;63 }64 65 list_initialize(&(parser->input));66 list_initialize(&(parser->output));67 list_initialize(&(parser->feature));68 69 }70 71 38 72 39 /** Parse HID report descriptor. … … 79 46 const uint8_t *data, size_t size) 80 47 { 81 size_t i=0; 82 uint8_t tag=0; 83 uint8_t item_size=0; 84 int class=0; 85 int ret; 86 usb_hid_report_item_t *report_item=0; 87 usb_hid_report_item_t *new_report_item; 88 89 90 if(!(report_item=malloc(sizeof(usb_hid_report_item_t)))){ 91 return ENOMEM; 92 } 93 link_initialize(&(report_item->link)); 94 95 while(i<size){ 96 97 if(!USB_HID_ITEM_IS_LONG(data[i])){ 98 tag = USB_HID_ITEM_TAG(data[i]); 99 item_size = USB_HID_ITEM_SIZE(data[i]); 100 class = USB_HID_ITEM_TAG_CLASS(data[i]); 101 102 ret = usb_hid_report_parse_tag(tag,class, 103 (uint8_t *)(data + sizeof(uint8_t)*(i+1)), 104 item_size,report_item); 105 switch(ret){ 106 case USB_HID_NEW_REPORT_ITEM: 107 // store report item to report and create the new one 108 printf("\nNEW REPORT ITEM: %X",tag); 109 switch(tag) { 110 case USB_HID_REPORT_TAG_INPUT: 111 printf(" - INPUT\n"); 112 list_append(&(report_item->link), &(parser->input)); 113 break; 114 case USB_HID_REPORT_TAG_OUTPUT: 115 printf(" - OUTPUT\n"); 116 list_append(&(report_item->link), &(parser->output)); 117 118 break; 119 case USB_HID_REPORT_TAG_FEATURE: 120 printf(" - FEATURE\n"); 121 list_append(&(report_item->link), &(parser->feature)); 122 break; 123 default: 124 printf("\tjump over\n"); 125 break; 126 } 127 128 /* clone current state table to the new item */ 129 if(!(new_report_item = malloc(sizeof(usb_hid_report_item_t)))) { 130 return ENOMEM; 131 } 132 memcpy(new_report_item,report_item, sizeof(usb_hid_report_item_t)); 133 link_initialize(&(new_report_item->link)); 134 report_item = new_report_item; 135 136 break; 137 case USB_HID_REPORT_TAG_PUSH: 138 // push current state to stack 139 // not yet implemented 140 break; 141 case USB_HID_REPORT_TAG_POP: 142 // restore current state from stack 143 // not yet implemented 144 break; 145 146 default: 147 // nothing special to do 148 break; 149 } 150 151 /* jump over the processed block */ 152 i += 1 + USB_HID_ITEM_SIZE(data[i]); 153 } 154 else{ 155 // TBD 156 i += 3 + USB_HID_ITEM_SIZE(data[i+1]); 157 } 158 159 160 } 161 162 163 return EOK; 48 return ENOTSUP; 164 49 } 165 50 … … 231 116 item.size = 8; 232 117 item.count = 6; 233 item.usage_min imum= 0;234 item.usage_max imum= 255;235 item.logical_min imum= 0;236 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; 237 122 238 123 if (size != 8) { 239 return -1;//ERANGE;124 return ERANGE; 240 125 } 241 126 … … 259 144 int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size) 260 145 { 261 if (size !=1){146 if (size < 1){ 262 147 return -1; 263 148 } 264 149 265 /* used only first five bits, others are only padding*/ 266 *data = leds; 150 data[0] = leds; 267 151 return EOK; 268 152 } 269 153 270 154 /** 271 *272 * @param Tag to parse273 * @param Report descriptor buffer274 * @param Size of data belongs to this tag275 * @param Current report item structe276 * @return Code of action to be done next277 */278 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, uint8_t *data, size_t item_size,279 usb_hid_report_item_t *report_item)280 {281 switch(class){282 case USB_HID_TAG_CLASS_MAIN:283 284 if(usb_hid_report_parse_main_tag(tag,data,item_size,report_item) == EOK) {285 return USB_HID_NEW_REPORT_ITEM;286 }287 else {288 /*TODO process the error */289 return -1;290 }291 break;292 293 case USB_HID_TAG_CLASS_GLOBAL:294 return usb_hid_report_parse_global_tag(tag,data,item_size,report_item);295 break;296 297 case USB_HID_TAG_CLASS_LOCAL:298 return usb_hid_report_parse_local_tag(tag,data,item_size,report_item);299 break;300 default:301 return -1; /* TODO ERROR CODE - UNKNOWN TAG CODE */302 }303 }304 305 /**306 * Parse main tags of report descriptor307 *308 * @param Tag identifier309 * @param Data buffer310 * @param Length of data buffer311 * @param Current state table312 * @return Error code313 */314 315 int usb_hid_report_parse_main_tag(uint8_t tag, uint8_t *data, size_t item_size,316 usb_hid_report_item_t *report_item)317 {318 switch(tag)319 {320 case USB_HID_REPORT_TAG_INPUT:321 case USB_HID_REPORT_TAG_OUTPUT:322 case USB_HID_REPORT_TAG_FEATURE:323 report_item->item_flags = *data;324 return USB_HID_NEW_REPORT_ITEM;325 break;326 327 case USB_HID_REPORT_TAG_COLLECTION:328 // TODO329 break;330 331 case USB_HID_REPORT_TAG_END_COLLECTION:332 /* should be ignored */333 break;334 default:335 return -1; //TODO ERROR CODE336 }337 338 return EOK;339 }340 341 /**342 * Parse global tags of report descriptor343 *344 * @param Tag identifier345 * @param Data buffer346 * @param Length of data buffer347 * @param Current state table348 * @return Error code349 */350 351 int usb_hid_report_parse_global_tag(uint8_t tag, uint8_t *data, size_t item_size,352 usb_hid_report_item_t *report_item)353 {354 // TODO take care about the bit length of data355 switch(tag)356 {357 case USB_HID_REPORT_TAG_USAGE_PAGE:358 report_item->usage_page = usb_hid_report_tag_data_int32(data,item_size);359 break;360 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM:361 report_item->logical_minimum = usb_hid_report_tag_data_int32(data,item_size);362 break;363 case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM:364 report_item->logical_maximum = usb_hid_report_tag_data_int32(data,item_size);365 break;366 case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM:367 report_item->physical_minimum = usb_hid_report_tag_data_int32(data,item_size);368 break;369 case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM:370 report_item->physical_maximum = usb_hid_report_tag_data_int32(data,item_size);371 break;372 case USB_HID_REPORT_TAG_UNIT_EXPONENT:373 report_item->unit_exponent = usb_hid_report_tag_data_int32(data,item_size);374 break;375 case USB_HID_REPORT_TAG_UNIT:376 report_item->unit = usb_hid_report_tag_data_int32(data,item_size);377 break;378 case USB_HID_REPORT_TAG_REPORT_SIZE:379 report_item->size = usb_hid_report_tag_data_int32(data,item_size);380 break;381 case USB_HID_REPORT_TAG_REPORT_COUNT:382 report_item->count = usb_hid_report_tag_data_int32(data,item_size);383 break;384 case USB_HID_REPORT_TAG_REPORT_ID:385 report_item->id = usb_hid_report_tag_data_int32(data,item_size);386 break;387 case USB_HID_REPORT_TAG_PUSH:388 case USB_HID_REPORT_TAG_POP:389 return tag;390 break;391 392 default:393 return -1; //TODO ERROR CODE INVALID GLOBAL TAG394 }395 }396 397 /**398 * Parse local tags of report descriptor399 *400 * @param Tag identifier401 * @param Data buffer402 * @param Length of data buffer403 * @param Current state table404 * @return Error code405 */406 int usb_hid_report_parse_local_tag(uint8_t tag, uint8_t *data, size_t item_size,407 usb_hid_report_item_t *report_item)408 {409 switch(tag)410 {411 case USB_HID_REPORT_TAG_USAGE:412 report_item->usage = usb_hid_report_tag_data_int32(data,item_size);413 break;414 case USB_HID_REPORT_TAG_USAGE_MINIMUM:415 report_item->usage_minimum = usb_hid_report_tag_data_int32(data,item_size);416 break;417 case USB_HID_REPORT_TAG_USAGE_MAXIMUM:418 report_item->usage_maximum = usb_hid_report_tag_data_int32(data,item_size);419 break;420 case USB_HID_REPORT_TAG_DESIGNATOR_INDEX:421 report_item->designator_index = usb_hid_report_tag_data_int32(data,item_size);422 break;423 case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM:424 report_item->designator_minimum = usb_hid_report_tag_data_int32(data,item_size);425 break;426 case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM:427 report_item->designator_maximum = usb_hid_report_tag_data_int32(data,item_size);428 break;429 case USB_HID_REPORT_TAG_STRING_INDEX:430 report_item->string_index = usb_hid_report_tag_data_int32(data,item_size);431 break;432 case USB_HID_REPORT_TAG_STRING_MINIMUM:433 report_item->string_minimum = usb_hid_report_tag_data_int32(data,item_size);434 break;435 case USB_HID_REPORT_TAG_STRING_MAXIMUM:436 report_item->string_maximum = usb_hid_report_tag_data_int32(data,item_size);437 break;438 case USB_HID_REPORT_TAG_DELIMITER:439 report_item->delimiter = usb_hid_report_tag_data_int32(data,item_size);440 break;441 442 default:443 return -1; //TODO ERROR CODE INVALID LOCAL TAG NOW IS ONLY UNSUPPORTED444 }445 }446 447 /**448 * Converts raw data to int32 (thats the maximum length of short item data)449 *450 * @param Data buffer451 * @param Size of buffer452 * @return Converted int32 number453 */454 int32_t usb_hid_report_tag_data_int32(uint8_t *data, size_t size)455 {456 int i;457 int32_t result;458 459 result = 0;460 for(i=0; i<size; i++) {461 result = (result | (data[i]) << (i*8));462 }463 464 return result;465 }466 467 468 469 /**470 * Prints content of given list of report items.471 *472 * @param List of report items473 * @return void474 */475 void usb_hid_descriptor_print_list(link_t *head)476 {477 usb_hid_report_item_t *report_item;478 link_t *item;479 480 if(head == NULL || list_empty(head)) {481 printf("\tempty\n");482 return;483 }484 485 486 printf("\tHEAD %p\n",head);487 for(item = head->next; item != head; item = item->next) {488 489 report_item = list_get_instance(item, usb_hid_report_item_t, link);490 491 printf("\tOFFSET: %X\n", report_item->offset);492 printf("\tCOUNT: %X\n", report_item->count);493 printf("\tSIZE: %X\n", report_item->size);494 printf("\tCONSTANT: %X\n", USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags));495 printf("\tUSAGE: %X\n", report_item->usage);496 printf("\tUSAGE PAGE: %X\n", report_item->usage_page);497 printf("\n");498 499 }500 501 502 }503 /**504 * Prints content of given descriptor in human readable format.505 *506 * @param Parsed descriptor to print507 * @return void508 */509 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser)510 {511 printf("INPUT:\n");512 usb_hid_descriptor_print_list(&parser->input);513 514 printf("OUTPUT: \n");515 usb_hid_descriptor_print_list(&parser->output);516 517 printf("FEATURE:\n");518 usb_hid_descriptor_print_list(&parser->feature);519 520 }521 522 /**523 * Releases whole linked list of report items524 *525 *526 */527 void usb_hid_free_report_list(link_t *list)528 {529 usb_hid_report_item_t *report_item;530 link_t *item;531 532 if(head == NULL || list_empty(head)) {533 return EOK;534 }535 536 for(item = head->next; item != head; item = item->next) {537 list_remove(item);538 free(list_get_instance(item,usb_hid_report_item_t, link));539 }540 }541 542 /**543 * Frees complete structure of report parser544 *545 * @param Parser to free546 * @return Error code547 */548 void usb_hid_free_report_parser(usb_hid_report_parser_t *parser)549 {550 if(parser == NULL){551 return;552 }553 554 usb_hid_free_report_list(&parser->input);555 usb_hid_free_report_list(&parser->output);556 usb_hid_free_report_list(&parser->feature);557 558 return;559 }560 /**561 155 * @} 562 156 */ 563 564 565 /**566 * @}567 */
Note:
See TracChangeset
for help on using the changeset viewer.