Changes in / [19a1800:ac8285d] in mainline
- Location:
- uspace/lib/usb
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/include/usb/classes/hidparser.h
r19a1800 rac8285d 39 39 40 40 /** 41 * Item prefix42 */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 flags51 */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 /**64 41 * Description of report items 65 42 */ 66 43 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;77 44 78 int32_t unit_exponent; 79 int32_t unit; 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 52 81 /*82 * some not yet used fields83 */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;96 53 } usb_hid_report_item_t; 97 54 98 55 99 56 /** HID report parser structure. */ 100 typedef struct { 101 link_t input; 102 link_t output; 103 link_t feature; 104 } usb_hid_report_parser_t; 105 57 typedef struct { 58 } usb_hid_report_parser_t; 106 59 107 60 … … 174 127 int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size); 175 128 176 int usb_hid_parser_init(usb_hid_report_parser_t *parser);177 129 int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser, 178 130 const uint8_t *data, size_t size); … … 183 135 184 136 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); 137 int usb_hid_free_report_parser(usb_hid_report_parser_t *parser); 188 138 189 139 #endif -
uspace/lib/usb/src/hidparser.c
r19a1800 rac8285d 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 … … 196 81 } 197 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 198 94 199 95 /** … … 220 116 item.size = 8; 221 117 item.count = 6; 222 item.usage_min imum= 0;223 item.usage_max imum= 255;224 item.logical_min imum= 0;225 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; 226 122 227 123 if (size != 8) { … … 248 144 int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size) 249 145 { 250 if (size !=1){146 if (size < 1){ 251 147 return -1; 252 148 } 253 149 254 /* used only first five bits, others are only padding*/ 255 *data = leds; 150 data[0] = leds; 256 151 return EOK; 257 152 } 258 153 259 154 /** 260 *261 * @param Tag to parse262 * @param Report descriptor buffer263 * @param Size of data belongs to this tag264 * @param Current report item structe265 * @return Code of action to be done next266 */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 descriptor296 *297 * @param Tag identifier298 * @param Data buffer299 * @param Length of data buffer300 * @param Current state table301 * @return Error code302 */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 // TODO318 break;319 320 case USB_HID_REPORT_TAG_END_COLLECTION:321 /* should be ignored */322 break;323 default:324 return -1; //TODO ERROR CODE325 }326 327 return EOK;328 }329 330 /**331 * Parse global tags of report descriptor332 *333 * @param Tag identifier334 * @param Data buffer335 * @param Length of data buffer336 * @param Current state table337 * @return Error code338 */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 data344 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 TAG383 }384 }385 386 /**387 * Parse local tags of report descriptor388 *389 * @param Tag identifier390 * @param Data buffer391 * @param Length of data buffer392 * @param Current state table393 * @return Error code394 */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 UNSUPPORTED433 }434 }435 436 /**437 * Converts raw data to int32 (thats the maximum length of short item data)438 *439 * @param Data buffer440 * @param Size of buffer441 * @return Converted int32 number442 */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 items462 * @return void463 */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 print496 * @return void497 */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 items513 *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 structure532 *533 * @param parser Opaque HID report parser structure534 * @return Error code535 */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 /**549 155 * @} 550 156 */
Note:
See TracChangeset
for help on using the changeset viewer.