Changeset 976f546 in mainline for uspace/lib/usb/src/hidparser.c
- Timestamp:
- 2011-03-01T22:03:37Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 19a1800
- Parents:
- 2f60e57d
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/src/hidparser.c
r2f60e57d r976f546 27 27 */ 28 28 29 /** @addtogroup libusb usb29 /** @addtogroup libusb 30 30 * @{ 31 31 */ … … 35 35 #include <usb/classes/hidparser.h> 36 36 #include <errno.h> 37 #include <stdio.h> 38 #include <adt/list.h> 39 40 #define USB_HID_NEW_REPORT_ITEM 0 41 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 37 71 38 72 /** Parse HID report descriptor. … … 45 79 const uint8_t *data, size_t size) 46 80 { 47 return ENOTSUP; 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 164 } 49 165 … … 115 231 item.size = 8; 116 232 item.count = 6; 117 item.usage_min = 0;118 item.usage_max = 255;119 item.logical_min = 0;120 item.logical_max = 255;121 122 if (size != 8){123 return -1; 233 item.usage_minimum = 0; 234 item.usage_maximum = 255; 235 item.logical_minimum = 0; 236 item.logical_maximum = 255; 237 238 if (size != 8) { 239 return -1;//ERANGE; 124 240 } 125 241 126 242 uint8_t keys[6]; 127 for (i=item.offset; i<item.count; i++) {128 keys[i -2] = data[i];243 for (i = 0; i < item.count; i++) { 244 keys[i] = data[i + item.offset]; 129 245 } 130 246 … … 153 269 154 270 /** 271 * 272 * @param Tag to parse 273 * @param Report descriptor buffer 274 * @param Size of data belongs to this tag 275 * @param Current report item structe 276 * @return Code of action to be done next 277 */ 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 descriptor 307 * 308 * @param Tag identifier 309 * @param Data buffer 310 * @param Length of data buffer 311 * @param Current state table 312 * @return Error code 313 */ 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 // TODO 329 break; 330 331 case USB_HID_REPORT_TAG_END_COLLECTION: 332 /* should be ignored */ 333 break; 334 default: 335 return -1; //TODO ERROR CODE 336 } 337 338 return EOK; 339 } 340 341 /** 342 * Parse global tags of report descriptor 343 * 344 * @param Tag identifier 345 * @param Data buffer 346 * @param Length of data buffer 347 * @param Current state table 348 * @return Error code 349 */ 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 data 355 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 TAG 394 } 395 } 396 397 /** 398 * Parse local tags of report descriptor 399 * 400 * @param Tag identifier 401 * @param Data buffer 402 * @param Length of data buffer 403 * @param Current state table 404 * @return Error code 405 */ 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 UNSUPPORTED 444 } 445 } 446 447 /** 448 * Converts raw data to int32 (thats the maximum length of short item data) 449 * 450 * @param Data buffer 451 * @param Size of buffer 452 * @return Converted int32 number 453 */ 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 items 473 * @return void 474 */ 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 print 507 * @return void 508 */ 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 items 524 * 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 parser 544 * 545 * @param Parser to free 546 * @return Error code 547 */ 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 /** 155 561 * @} 156 562 */ 563 564 565 /** 566 * @} 567 */
Note:
See TracChangeset
for help on using the changeset viewer.