Changes in / [ac8285d:19a1800] in mainline
- Location:
- uspace/lib/usb
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/include/usb/classes/hidparser.h
rac8285d r19a1800 39 39 40 40 /** 41 * Item prefix 42 */ 43 #define USB_HID_ITEM_SIZE(data) ((uint8_t)(data & 0x3)) 44 #define USB_HID_ITEM_TAG(data) ((uint8_t)((data & 0xF0) >> 4)) 45 #define USB_HID_ITEM_TAG_CLASS(data) ((uint8_t)((data & 0xC) >> 2)) 46 #define USB_HID_ITEM_IS_LONG(data) (data == 0xFE) 47 48 49 /** 50 * Input/Output/Feature Item flags 51 */ 52 #define USB_HID_ITEM_FLAG_CONSTANT(flags) (flags & 0x1) 53 #define USB_HID_ITEM_FLAG_VARIABLE(flags) (flags & 0x2) 54 #define USB_HID_ITEM_FLAG_RELATIVE(flags) (flags & 0x4) 55 #define USB_HID_ITEM_FLAG_WRAP(flags) (flags & 0x8) 56 #define USB_HID_ITEM_FLAG_LINEAR(flags) (flags & 0x10) 57 #define USB_HID_ITEM_FLAG_PREFERRED(flags) (flags & 0x20) 58 #define USB_HID_ITEM_FLAG_POSITION(flags) (flags & 0x40) 59 #define USB_HID_ITEM_FLAG_VOLATILE(flags) (flags & 0x80) 60 #define USB_HID_ITEM_FLAG_BUFFERED(flags) (flags & 0x100) 61 62 63 /** 41 64 * Description of report items 42 65 */ 43 66 typedef struct { 67 int32_t id; 68 int32_t usage_page; 69 int32_t usage; 70 int32_t usage_minimum; 71 int32_t usage_maximum; 72 int32_t logical_minimum; 73 int32_t logical_maximum; 74 int32_t size; 75 int32_t count; 76 int32_t offset; 44 77 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; 78 int32_t unit_exponent; 79 int32_t unit; 52 80 81 /* 82 * some not yet used fields 83 */ 84 int32_t string_index; 85 int32_t string_minimum; 86 int32_t string_maximum; 87 int32_t designator_index; 88 int32_t designator_minimum; 89 int32_t designator_maximum; 90 int32_t physical_minimum; 91 int32_t physical_maximum; 92 93 uint8_t item_flags; 94 95 link_t link; 53 96 } usb_hid_report_item_t; 54 97 55 98 56 99 /** HID report parser structure. */ 57 typedef struct { 58 } usb_hid_report_parser_t; 100 typedef struct { 101 link_t input; 102 link_t output; 103 link_t feature; 104 } usb_hid_report_parser_t; 105 59 106 60 107 … … 127 174 int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size); 128 175 176 int usb_hid_parser_init(usb_hid_report_parser_t *parser); 129 177 int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser, 130 178 const uint8_t *data, size_t size); … … 135 183 136 184 137 int usb_hid_free_report_parser(usb_hid_report_parser_t *parser); 185 void usb_hid_free_report_parser(usb_hid_report_parser_t *parser); 186 187 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser); 138 188 139 189 #endif -
uspace/lib/usb/src/hidparser.c
rac8285d r19a1800 36 36 #include <errno.h> 37 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 38 71 39 72 /** Parse HID report descriptor. … … 46 79 const uint8_t *data, size_t size) 47 80 { 48 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; 49 164 } 50 165 … … 81 196 } 82 197 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 198 95 199 /** … … 116 220 item.size = 8; 117 221 item.count = 6; 118 item.usage_min = 0;119 item.usage_max = 255;120 item.logical_min = 0;121 item.logical_max = 255;222 item.usage_minimum = 0; 223 item.usage_maximum = 255; 224 item.logical_minimum = 0; 225 item.logical_maximum = 255; 122 226 123 227 if (size != 8) { … … 144 248 int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size) 145 249 { 146 if (size <1){250 if(size != 1){ 147 251 return -1; 148 252 } 149 253 150 data[0] = leds; 254 /* used only first five bits, others are only padding*/ 255 *data = leds; 151 256 return EOK; 152 257 } 153 258 154 259 /** 260 * 261 * @param Tag to parse 262 * @param Report descriptor buffer 263 * @param Size of data belongs to this tag 264 * @param Current report item structe 265 * @return Code of action to be done next 266 */ 267 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, uint8_t *data, size_t item_size, 268 usb_hid_report_item_t *report_item) 269 { 270 switch(class){ 271 case USB_HID_TAG_CLASS_MAIN: 272 273 if(usb_hid_report_parse_main_tag(tag,data,item_size,report_item) == EOK) { 274 return USB_HID_NEW_REPORT_ITEM; 275 } 276 else { 277 /*TODO process the error */ 278 return -1; 279 } 280 break; 281 282 case USB_HID_TAG_CLASS_GLOBAL: 283 return usb_hid_report_parse_global_tag(tag,data,item_size,report_item); 284 break; 285 286 case USB_HID_TAG_CLASS_LOCAL: 287 return usb_hid_report_parse_local_tag(tag,data,item_size,report_item); 288 break; 289 default: 290 return -1; /* TODO ERROR CODE - UNKNOWN TAG CODE */ 291 } 292 } 293 294 /** 295 * Parse main tags of report descriptor 296 * 297 * @param Tag identifier 298 * @param Data buffer 299 * @param Length of data buffer 300 * @param Current state table 301 * @return Error code 302 */ 303 304 int usb_hid_report_parse_main_tag(uint8_t tag, uint8_t *data, size_t item_size, 305 usb_hid_report_item_t *report_item) 306 { 307 switch(tag) 308 { 309 case USB_HID_REPORT_TAG_INPUT: 310 case USB_HID_REPORT_TAG_OUTPUT: 311 case USB_HID_REPORT_TAG_FEATURE: 312 report_item->item_flags = *data; 313 return USB_HID_NEW_REPORT_ITEM; 314 break; 315 316 case USB_HID_REPORT_TAG_COLLECTION: 317 // TODO 318 break; 319 320 case USB_HID_REPORT_TAG_END_COLLECTION: 321 /* should be ignored */ 322 break; 323 default: 324 return -1; //TODO ERROR CODE 325 } 326 327 return EOK; 328 } 329 330 /** 331 * Parse global tags of report descriptor 332 * 333 * @param Tag identifier 334 * @param Data buffer 335 * @param Length of data buffer 336 * @param Current state table 337 * @return Error code 338 */ 339 340 int usb_hid_report_parse_global_tag(uint8_t tag, uint8_t *data, size_t item_size, 341 usb_hid_report_item_t *report_item) 342 { 343 // TODO take care about the bit length of data 344 switch(tag) 345 { 346 case USB_HID_REPORT_TAG_USAGE_PAGE: 347 report_item->usage_page = usb_hid_report_tag_data_int32(data,item_size); 348 break; 349 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM: 350 report_item->logical_minimum = usb_hid_report_tag_data_int32(data,item_size); 351 break; 352 case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM: 353 report_item->logical_maximum = usb_hid_report_tag_data_int32(data,item_size); 354 break; 355 case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM: 356 report_item->physical_minimum = usb_hid_report_tag_data_int32(data,item_size); 357 break; 358 case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM: 359 report_item->physical_maximum = usb_hid_report_tag_data_int32(data,item_size); 360 break; 361 case USB_HID_REPORT_TAG_UNIT_EXPONENT: 362 report_item->unit_exponent = usb_hid_report_tag_data_int32(data,item_size); 363 break; 364 case USB_HID_REPORT_TAG_UNIT: 365 report_item->unit = usb_hid_report_tag_data_int32(data,item_size); 366 break; 367 case USB_HID_REPORT_TAG_REPORT_SIZE: 368 report_item->size = usb_hid_report_tag_data_int32(data,item_size); 369 break; 370 case USB_HID_REPORT_TAG_REPORT_COUNT: 371 report_item->count = usb_hid_report_tag_data_int32(data,item_size); 372 break; 373 case USB_HID_REPORT_TAG_REPORT_ID: 374 report_item->id = usb_hid_report_tag_data_int32(data,item_size); 375 break; 376 case USB_HID_REPORT_TAG_PUSH: 377 case USB_HID_REPORT_TAG_POP: 378 return tag; 379 break; 380 381 default: 382 return -1; //TODO ERROR CODE INVALID GLOBAL TAG 383 } 384 } 385 386 /** 387 * Parse local tags of report descriptor 388 * 389 * @param Tag identifier 390 * @param Data buffer 391 * @param Length of data buffer 392 * @param Current state table 393 * @return Error code 394 */ 395 int usb_hid_report_parse_local_tag(uint8_t tag, uint8_t *data, size_t item_size, 396 usb_hid_report_item_t *report_item) 397 { 398 switch(tag) 399 { 400 case USB_HID_REPORT_TAG_USAGE: 401 report_item->usage = usb_hid_report_tag_data_int32(data,item_size); 402 break; 403 case USB_HID_REPORT_TAG_USAGE_MINIMUM: 404 report_item->usage_minimum = usb_hid_report_tag_data_int32(data,item_size); 405 break; 406 case USB_HID_REPORT_TAG_USAGE_MAXIMUM: 407 report_item->usage_maximum = usb_hid_report_tag_data_int32(data,item_size); 408 break; 409 case USB_HID_REPORT_TAG_DESIGNATOR_INDEX: 410 report_item->designator_index = usb_hid_report_tag_data_int32(data,item_size); 411 break; 412 case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM: 413 report_item->designator_minimum = usb_hid_report_tag_data_int32(data,item_size); 414 break; 415 case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM: 416 report_item->designator_maximum = usb_hid_report_tag_data_int32(data,item_size); 417 break; 418 case USB_HID_REPORT_TAG_STRING_INDEX: 419 report_item->string_index = usb_hid_report_tag_data_int32(data,item_size); 420 break; 421 case USB_HID_REPORT_TAG_STRING_MINIMUM: 422 report_item->string_minimum = usb_hid_report_tag_data_int32(data,item_size); 423 break; 424 case USB_HID_REPORT_TAG_STRING_MAXIMUM: 425 report_item->string_maximum = usb_hid_report_tag_data_int32(data,item_size); 426 break; 427 case USB_HID_REPORT_TAG_DELIMITER: 428 report_item->delimiter = usb_hid_report_tag_data_int32(data,item_size); 429 break; 430 431 default: 432 return -1; //TODO ERROR CODE INVALID LOCAL TAG NOW IS ONLY UNSUPPORTED 433 } 434 } 435 436 /** 437 * Converts raw data to int32 (thats the maximum length of short item data) 438 * 439 * @param Data buffer 440 * @param Size of buffer 441 * @return Converted int32 number 442 */ 443 int32_t usb_hid_report_tag_data_int32(uint8_t *data, size_t size) 444 { 445 int i; 446 int32_t result; 447 448 result = 0; 449 for(i=0; i<size; i++) { 450 result = (result | (data[i]) << (i*8)); 451 } 452 453 return result; 454 } 455 456 457 458 /** 459 * Prints content of given list of report items. 460 * 461 * @param List of report items 462 * @return void 463 */ 464 void usb_hid_descriptor_print_list(link_t *head) 465 { 466 usb_hid_report_item_t *report_item; 467 link_t *item; 468 469 if(head == NULL || list_empty(head)) { 470 printf("\tempty\n"); 471 return; 472 } 473 474 475 printf("\tHEAD %p\n",head); 476 for(item = head->next; item != head; item = item->next) { 477 478 report_item = list_get_instance(item, usb_hid_report_item_t, link); 479 480 printf("\tOFFSET: %X\n", report_item->offset); 481 printf("\tCOUNT: %X\n", report_item->count); 482 printf("\tSIZE: %X\n", report_item->size); 483 printf("\tCONSTANT: %X\n", USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags)); 484 printf("\tUSAGE: %X\n", report_item->usage); 485 printf("\tUSAGE PAGE: %X\n", report_item->usage_page); 486 printf("\n"); 487 488 } 489 490 491 } 492 /** 493 * Prints content of given descriptor in human readable format. 494 * 495 * @param Parsed descriptor to print 496 * @return void 497 */ 498 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser) 499 { 500 printf("INPUT:\n"); 501 usb_hid_descriptor_print_list(&parser->input); 502 503 printf("OUTPUT: \n"); 504 usb_hid_descriptor_print_list(&parser->output); 505 506 printf("FEATURE:\n"); 507 usb_hid_descriptor_print_list(&parser->feature); 508 509 } 510 511 /** 512 * Releases whole linked list of report items 513 * 514 * 515 */ 516 void usb_hid_free_report_list(link_t *list) 517 { 518 usb_hid_report_item_t *report_item; 519 link_t *item; 520 521 if(head == NULL || list_empty(head)) { 522 return EOK; 523 } 524 525 for(item = head->next; item != head; item = item->next) { 526 list_remove(item); 527 free(list_get_instance(item,usb_hid_report_item_t, link)); 528 } 529 } 530 531 /** Free the HID report parser structure 532 * 533 * @param parser Opaque HID report parser structure 534 * @return Error code 535 */ 536 void usb_hid_free_report_parser(usb_hid_report_parser_t *parser) 537 { 538 if(parser == NULL){ 539 return; 540 } 541 542 usb_hid_free_report_list(&parser->input); 543 usb_hid_free_report_list(&parser->output); 544 usb_hid_free_report_list(&parser->feature); 545 546 return; 547 } 548 /** 155 549 * @} 156 550 */
Note:
See TracChangeset
for help on using the changeset viewer.