Changeset 0588062e in mainline
- Timestamp:
- 2011-03-03T18:56:11Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 8e9becf6
- Parents:
- d3594362 (diff), e259d95 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace/lib/usb
- Files:
-
- 1 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/include/usb/classes/hidparser.h
rd3594362 r0588062e 37 37 38 38 #include <stdint.h> 39 #include <adt/list.h> 40 #include <usb/classes/hid_report_items.h> 41 42 /** 43 * Item prefix 44 */ 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 flags 53 */ 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 39 64 40 65 /** … … 42 67 */ 43 68 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 int32_t offset; 44 79 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; 80 int32_t unit_exponent; 81 int32_t unit; 52 82 83 /* 84 * some not yet used fields 85 */ 86 int32_t string_index; 87 int32_t string_minimum; 88 int32_t string_maximum; 89 int32_t designator_index; 90 int32_t designator_minimum; 91 int32_t designator_maximum; 92 int32_t physical_minimum; 93 int32_t physical_maximum; 94 95 uint8_t item_flags; 96 97 link_t link; 53 98 } usb_hid_report_item_t; 54 99 55 100 56 101 /** HID report parser structure. */ 57 typedef struct { 58 } usb_hid_report_parser_t; 102 typedef struct { 103 link_t input; 104 link_t output; 105 link_t feature; 106 } usb_hid_report_parser_t; 107 59 108 60 109 … … 127 176 int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size); 128 177 178 int usb_hid_parser_init(usb_hid_report_parser_t *parser); 129 179 int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser, 130 180 const uint8_t *data, size_t size); … … 135 185 136 186 137 int usb_hid_free_report_parser(usb_hid_report_parser_t *parser); 187 void usb_hid_free_report_parser(usb_hid_report_parser_t *parser); 188 189 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser); 138 190 139 191 #endif -
uspace/lib/usb/src/hidparser.c
rd3594362 r0588062e 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 0 43 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 38 74 39 75 /** Parse HID report descriptor. … … 46 82 const uint8_t *data, size_t size) 47 83 { 48 return ENOTSUP; 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; 49 167 } 50 168 … … 81 199 } 82 200 83 /** Free the HID report parser structure84 *85 * @param parser Opaque HID report parser structure86 * @return Error code87 */88 int usb_hid_free_report_parser(usb_hid_report_parser_t *parser)89 {90 91 return EOK;92 }93 94 201 95 202 /** … … 116 223 item.size = 8; 117 224 item.count = 6; 118 item.usage_min = 0;119 item.usage_max = 255;120 item.logical_min = 0;121 item.logical_max = 255;225 item.usage_minimum = 0; 226 item.usage_maximum = 255; 227 item.logical_minimum = 0; 228 item.logical_maximum = 255; 122 229 123 230 if (size != 8) { 124 return ERANGE;231 return -1; //ERANGE; 125 232 } 126 233 … … 144 251 int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size) 145 252 { 146 if (size <1){253 if(size != 1){ 147 254 return -1; 148 255 } 149 256 150 data[0] = leds; 151 return EOK; 152 } 153 257 /* used only first five bits, others are only padding*/ 258 *data = leds; 259 return EOK; 260 } 261 262 /** 263 * 264 * @param Tag to parse 265 * @param Report descriptor buffer 266 * @param Size of data belongs to this tag 267 * @param Current report item structe 268 * @return Code of action to be done next 269 */ 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 descriptor 299 * 300 * @param Tag identifier 301 * @param Data buffer 302 * @param Length of data buffer 303 * @param Current state table 304 * @return Error code 305 */ 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 // TODO 321 break; 322 323 case USB_HID_REPORT_TAG_END_COLLECTION: 324 /* should be ignored */ 325 break; 326 default: 327 return -1; //TODO ERROR CODE 328 } 329 330 return EOK; 331 } 332 333 /** 334 * Parse global tags of report descriptor 335 * 336 * @param Tag identifier 337 * @param Data buffer 338 * @param Length of data buffer 339 * @param Current state table 340 * @return Error code 341 */ 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 data 347 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 TAG 386 } 387 388 return EOK; 389 } 390 391 /** 392 * Parse local tags of report descriptor 393 * 394 * @param Tag identifier 395 * @param Data buffer 396 * @param Length of data buffer 397 * @param Current state table 398 * @return Error code 399 */ 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 UNSUPPORTED 439 } 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 buffer 448 * @param Size of buffer 449 * @return Converted int32 number 450 */ 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 items 470 * @return void 471 */ 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 print 504 * @return void 505 */ 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 items 521 * 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 structure 549 * 550 * @param parser Opaque HID report parser structure 551 * @return Error code 552 */ 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 } 154 565 /** 155 566 * @}
Note:
See TracChangeset
for help on using the changeset viewer.