Changes in uspace/lib/usb/src/hidparser.c [e259d95:ad4562c2] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/src/hidparser.c
re259d95 rad4562c2 36 36 #include <errno.h> 37 37 #include <stdio.h> 38 #include <adt/list.h>39 #include <malloc.h>40 #include <mem.h>41 42 #define USB_HID_NEW_REPORT_ITEM 043 44 45 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, uint8_t *data, size_t item_size,46 usb_hid_report_item_t *report_item);47 int usb_hid_report_parse_main_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_global_tag(uint8_t tag, uint8_t *data, size_t item_size,50 usb_hid_report_item_t *report_item);51 int usb_hid_report_parse_local_tag(uint8_t tag, uint8_t *data, size_t item_size,52 usb_hid_report_item_t *report_item);53 54 void usb_hid_descriptor_print_list(link_t *head);55 int usb_hid_report_reset_local_items();56 void usb_hid_free_report_list(link_t *head);57 int32_t usb_hid_report_tag_data_int32(uint8_t *data, size_t size);58 /**59 *60 */61 int usb_hid_parser_init(usb_hid_report_parser_t *parser)62 {63 if(parser == NULL) {64 return -1;65 }66 67 list_initialize(&(parser->input));68 list_initialize(&(parser->output));69 list_initialize(&(parser->feature));70 71 return EOK;72 }73 74 38 75 39 /** Parse HID report descriptor. … … 82 46 const uint8_t *data, size_t size) 83 47 { 84 size_t i=0; 85 uint8_t tag=0; 86 uint8_t item_size=0; 87 int class=0; 88 int ret; 89 usb_hid_report_item_t *report_item=0; 90 usb_hid_report_item_t *new_report_item; 91 92 93 if(!(report_item=malloc(sizeof(usb_hid_report_item_t)))){ 94 return ENOMEM; 95 } 96 link_initialize(&(report_item->link)); 97 98 while(i<size){ 99 100 if(!USB_HID_ITEM_IS_LONG(data[i])){ 101 tag = USB_HID_ITEM_TAG(data[i]); 102 item_size = USB_HID_ITEM_SIZE(data[i]); 103 class = USB_HID_ITEM_TAG_CLASS(data[i]); 104 105 ret = usb_hid_report_parse_tag(tag,class, 106 (uint8_t *)(data + sizeof(uint8_t)*(i+1)), 107 item_size,report_item); 108 switch(ret){ 109 case USB_HID_NEW_REPORT_ITEM: 110 // store report item to report and create the new one 111 printf("\nNEW REPORT ITEM: %X",tag); 112 switch(tag) { 113 case USB_HID_REPORT_TAG_INPUT: 114 printf(" - INPUT\n"); 115 list_append(&(report_item->link), &(parser->input)); 116 break; 117 case USB_HID_REPORT_TAG_OUTPUT: 118 printf(" - OUTPUT\n"); 119 list_append(&(report_item->link), &(parser->output)); 120 121 break; 122 case USB_HID_REPORT_TAG_FEATURE: 123 printf(" - FEATURE\n"); 124 list_append(&(report_item->link), &(parser->feature)); 125 break; 126 default: 127 printf("\tjump over\n"); 128 break; 129 } 130 131 /* clone current state table to the new item */ 132 if(!(new_report_item = malloc(sizeof(usb_hid_report_item_t)))) { 133 return ENOMEM; 134 } 135 memcpy(new_report_item,report_item, sizeof(usb_hid_report_item_t)); 136 link_initialize(&(new_report_item->link)); 137 report_item = new_report_item; 138 139 break; 140 case USB_HID_REPORT_TAG_PUSH: 141 // push current state to stack 142 // not yet implemented 143 break; 144 case USB_HID_REPORT_TAG_POP: 145 // restore current state from stack 146 // not yet implemented 147 break; 148 149 default: 150 // nothing special to do 151 break; 152 } 153 154 /* jump over the processed block */ 155 i += 1 + USB_HID_ITEM_SIZE(data[i]); 156 } 157 else{ 158 // TBD 159 i += 3 + USB_HID_ITEM_SIZE(data[i+1]); 160 } 161 162 163 } 164 165 166 return EOK; 48 return ENOTSUP; 167 49 } 168 50 … … 199 81 } 200 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 91 return EOK; 92 } 93 201 94 202 95 /** … … 223 116 item.size = 8; 224 117 item.count = 6; 225 item.usage_min imum= 0;226 item.usage_max imum= 255;227 item.logical_min imum= 0;228 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; 229 122 230 123 if (size != 8) { 231 return -1; //ERANGE;124 return ERANGE; 232 125 } 233 126 … … 251 144 int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size) 252 145 { 253 if (size !=1){146 if (size < 1){ 254 147 return -1; 255 148 } 256 149 257 /* used only first five bits, others are only padding*/ 258 *data = leds; 150 data[0] = leds; 259 151 return EOK; 260 152 } 261 153 262 154 /** 263 *264 * @param Tag to parse265 * @param Report descriptor buffer266 * @param Size of data belongs to this tag267 * @param Current report item structe268 * @return Code of action to be done next269 */270 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, uint8_t *data, size_t item_size,271 usb_hid_report_item_t *report_item)272 {273 switch(class){274 case USB_HID_TAG_CLASS_MAIN:275 276 if(usb_hid_report_parse_main_tag(tag,data,item_size,report_item) == EOK) {277 return USB_HID_NEW_REPORT_ITEM;278 }279 else {280 /*TODO process the error */281 return -1;282 }283 break;284 285 case USB_HID_TAG_CLASS_GLOBAL:286 return usb_hid_report_parse_global_tag(tag,data,item_size,report_item);287 break;288 289 case USB_HID_TAG_CLASS_LOCAL:290 return usb_hid_report_parse_local_tag(tag,data,item_size,report_item);291 break;292 default:293 return -1; /* TODO ERROR CODE - UNKNOWN TAG CODE */294 }295 }296 297 /**298 * Parse main tags of report descriptor299 *300 * @param Tag identifier301 * @param Data buffer302 * @param Length of data buffer303 * @param Current state table304 * @return Error code305 */306 307 int usb_hid_report_parse_main_tag(uint8_t tag, uint8_t *data, size_t item_size,308 usb_hid_report_item_t *report_item)309 {310 switch(tag)311 {312 case USB_HID_REPORT_TAG_INPUT:313 case USB_HID_REPORT_TAG_OUTPUT:314 case USB_HID_REPORT_TAG_FEATURE:315 report_item->item_flags = *data;316 return USB_HID_NEW_REPORT_ITEM;317 break;318 319 case USB_HID_REPORT_TAG_COLLECTION:320 // TODO321 break;322 323 case USB_HID_REPORT_TAG_END_COLLECTION:324 /* should be ignored */325 break;326 default:327 return -1; //TODO ERROR CODE328 }329 330 return EOK;331 }332 333 /**334 * Parse global tags of report descriptor335 *336 * @param Tag identifier337 * @param Data buffer338 * @param Length of data buffer339 * @param Current state table340 * @return Error code341 */342 343 int usb_hid_report_parse_global_tag(uint8_t tag, uint8_t *data, size_t item_size,344 usb_hid_report_item_t *report_item)345 {346 // TODO take care about the bit length of data347 switch(tag)348 {349 case USB_HID_REPORT_TAG_USAGE_PAGE:350 report_item->usage_page = usb_hid_report_tag_data_int32(data,item_size);351 break;352 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM:353 report_item->logical_minimum = usb_hid_report_tag_data_int32(data,item_size);354 break;355 case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM:356 report_item->logical_maximum = usb_hid_report_tag_data_int32(data,item_size);357 break;358 case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM:359 report_item->physical_minimum = usb_hid_report_tag_data_int32(data,item_size);360 break;361 case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM:362 report_item->physical_maximum = usb_hid_report_tag_data_int32(data,item_size);363 break;364 case USB_HID_REPORT_TAG_UNIT_EXPONENT:365 report_item->unit_exponent = usb_hid_report_tag_data_int32(data,item_size);366 break;367 case USB_HID_REPORT_TAG_UNIT:368 report_item->unit = usb_hid_report_tag_data_int32(data,item_size);369 break;370 case USB_HID_REPORT_TAG_REPORT_SIZE:371 report_item->size = usb_hid_report_tag_data_int32(data,item_size);372 break;373 case USB_HID_REPORT_TAG_REPORT_COUNT:374 report_item->count = usb_hid_report_tag_data_int32(data,item_size);375 break;376 case USB_HID_REPORT_TAG_REPORT_ID:377 report_item->id = usb_hid_report_tag_data_int32(data,item_size);378 break;379 case USB_HID_REPORT_TAG_PUSH:380 case USB_HID_REPORT_TAG_POP:381 return tag;382 break;383 384 default:385 return -1; //TODO ERROR CODE INVALID GLOBAL TAG386 }387 388 return EOK;389 }390 391 /**392 * Parse local tags of report descriptor393 *394 * @param Tag identifier395 * @param Data buffer396 * @param Length of data buffer397 * @param Current state table398 * @return Error code399 */400 int usb_hid_report_parse_local_tag(uint8_t tag, uint8_t *data, size_t item_size,401 usb_hid_report_item_t *report_item)402 {403 switch(tag)404 {405 case USB_HID_REPORT_TAG_USAGE:406 report_item->usage = usb_hid_report_tag_data_int32(data,item_size);407 break;408 case USB_HID_REPORT_TAG_USAGE_MINIMUM:409 report_item->usage_minimum = usb_hid_report_tag_data_int32(data,item_size);410 break;411 case USB_HID_REPORT_TAG_USAGE_MAXIMUM:412 report_item->usage_maximum = usb_hid_report_tag_data_int32(data,item_size);413 break;414 case USB_HID_REPORT_TAG_DESIGNATOR_INDEX:415 report_item->designator_index = usb_hid_report_tag_data_int32(data,item_size);416 break;417 case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM:418 report_item->designator_minimum = usb_hid_report_tag_data_int32(data,item_size);419 break;420 case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM:421 report_item->designator_maximum = usb_hid_report_tag_data_int32(data,item_size);422 break;423 case USB_HID_REPORT_TAG_STRING_INDEX:424 report_item->string_index = usb_hid_report_tag_data_int32(data,item_size);425 break;426 case USB_HID_REPORT_TAG_STRING_MINIMUM:427 report_item->string_minimum = usb_hid_report_tag_data_int32(data,item_size);428 break;429 case USB_HID_REPORT_TAG_STRING_MAXIMUM:430 report_item->string_maximum = usb_hid_report_tag_data_int32(data,item_size);431 break;432 /*433 case USB_HID_REPORT_TAG_DELIMITER:434 report_item->delimiter = usb_hid_report_tag_data_int32(data,item_size);435 break;436 */437 default:438 return -1; //TODO ERROR CODE INVALID LOCAL TAG NOW IS ONLY UNSUPPORTED439 }440 441 return EOK;442 }443 444 /**445 * Converts raw data to int32 (thats the maximum length of short item data)446 *447 * @param Data buffer448 * @param Size of buffer449 * @return Converted int32 number450 */451 int32_t usb_hid_report_tag_data_int32(uint8_t *data, size_t size)452 {453 unsigned int i;454 int32_t result;455 456 result = 0;457 for(i=0; i<size; i++) {458 result = (result | (data[i]) << (i*8));459 }460 461 return result;462 }463 464 465 466 /**467 * Prints content of given list of report items.468 *469 * @param List of report items470 * @return void471 */472 void usb_hid_descriptor_print_list(link_t *head)473 {474 usb_hid_report_item_t *report_item;475 link_t *item;476 477 if(head == NULL || list_empty(head)) {478 printf("\tempty\n");479 return;480 }481 482 483 printf("\tHEAD %p\n",head);484 for(item = head->next; item != head; item = item->next) {485 486 report_item = list_get_instance(item, usb_hid_report_item_t, link);487 488 printf("\tOFFSET: %X\n", report_item->offset);489 printf("\tCOUNT: %X\n", report_item->count);490 printf("\tSIZE: %X\n", report_item->size);491 printf("\tCONSTANT: %X\n", USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags));492 printf("\tUSAGE: %X\n", report_item->usage);493 printf("\tUSAGE PAGE: %X\n", report_item->usage_page);494 printf("\n");495 496 }497 498 499 }500 /**501 * Prints content of given descriptor in human readable format.502 *503 * @param Parsed descriptor to print504 * @return void505 */506 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser)507 {508 printf("INPUT:\n");509 usb_hid_descriptor_print_list(&parser->input);510 511 printf("OUTPUT: \n");512 usb_hid_descriptor_print_list(&parser->output);513 514 printf("FEATURE:\n");515 usb_hid_descriptor_print_list(&parser->feature);516 517 }518 519 /**520 * Releases whole linked list of report items521 *522 *523 */524 void usb_hid_free_report_list(link_t *head)525 {526 return;527 528 usb_hid_report_item_t *report_item;529 link_t *next;530 531 if(head == NULL || list_empty(head)) {532 return;533 }534 535 next = head->next;536 while(next != head) {537 538 report_item = list_get_instance(next, usb_hid_report_item_t, link);539 next = next->next;540 541 free(report_item);542 }543 544 return;545 546 }547 548 /** Free the HID report parser structure549 *550 * @param parser Opaque HID report parser structure551 * @return Error code552 */553 void usb_hid_free_report_parser(usb_hid_report_parser_t *parser)554 {555 if(parser == NULL){556 return;557 }558 559 usb_hid_free_report_list(&parser->input);560 usb_hid_free_report_list(&parser->output);561 usb_hid_free_report_list(&parser->feature);562 563 return;564 }565 /**566 155 * @} 567 156 */
Note:
See TracChangeset
for help on using the changeset viewer.