Changes in / [0588062e:d3594362] in mainline
- Location:
- uspace/lib/usb
- Files:
-
- 1 deleted
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/include/usb/classes/hidparser.h
r0588062e rd3594362 37 37 38 38 #include <stdint.h> 39 #include <adt/list.h>40 #include <usb/classes/hid_report_items.h>41 42 /**43 * Item prefix44 */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 flags53 */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 64 39 65 40 /** … … 67 42 */ 68 43 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;79 44 80 int32_t unit_exponent; 81 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; 82 52 83 /*84 * some not yet used fields85 */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;98 53 } usb_hid_report_item_t; 99 54 100 55 101 56 /** HID report parser structure. */ 102 typedef struct { 103 link_t input; 104 link_t output; 105 link_t feature; 106 } usb_hid_report_parser_t; 107 57 typedef struct { 58 } usb_hid_report_parser_t; 108 59 109 60 … … 176 127 int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size); 177 128 178 int usb_hid_parser_init(usb_hid_report_parser_t *parser);179 129 int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser, 180 130 const uint8_t *data, size_t size); … … 185 135 186 136 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); 137 int usb_hid_free_report_parser(usb_hid_report_parser_t *parser); 190 138 191 139 #endif -
uspace/lib/usb/src/hidparser.c
r0588062e rd3594362 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.