Changes in / [19a1800:ac8285d] in mainline


Ignore:
Location:
uspace/lib/usb
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usb/include/usb/classes/hidparser.h

    r19a1800 rac8285d  
    3939
    4040/**
    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 /**
    6441 * Description of report items
    6542 */
    6643typedef 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;
    7744
    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;
    8052
    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;
    9653} usb_hid_report_item_t;
    9754
    9855
    9956/** 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 
     57typedef struct {
     58} usb_hid_report_parser_t;
    10659
    10760
     
    174127int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size);
    175128
    176 int usb_hid_parser_init(usb_hid_report_parser_t *parser);
    177129int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser,
    178130    const uint8_t *data, size_t size);
     
    183135
    184136
    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);
     137int usb_hid_free_report_parser(usb_hid_report_parser_t *parser);
    188138
    189139#endif
  • uspace/lib/usb/src/hidparser.c

    r19a1800 rac8285d  
    3636#include <errno.h>
    3737#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 
    7138
    7239/** Parse HID report descriptor.
     
    7946    const uint8_t *data, size_t size)
    8047{
    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;
    16449}
    16550
     
    19681}
    19782
     83/** Free the HID report parser structure
     84 *
     85 * @param parser Opaque HID report parser structure
     86 * @return Error code
     87 */
     88int usb_hid_free_report_parser(usb_hid_report_parser_t *parser)
     89{
     90
     91        return EOK;
     92}
     93
    19894
    19995/**
     
    220116        item.size = 8;
    221117        item.count = 6;
    222         item.usage_minimum = 0;
    223         item.usage_maximum = 255;
    224         item.logical_minimum = 0;
    225         item.logical_maximum = 255;
     118        item.usage_min = 0;
     119        item.usage_max = 255;
     120        item.logical_min = 0;
     121        item.logical_max = 255;
    226122
    227123        if (size != 8) {
     
    248144int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size)
    249145{
    250         if(size != 1){
     146        if (size < 1){
    251147                return -1;
    252148        }
    253149
    254         /* used only first five bits, others are only padding*/
    255         *data = leds;
     150        data[0] = leds;
    256151        return EOK;
    257152}
    258153
    259154/**
    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 /**
    549155 * @}
    550156 */
Note: See TracChangeset for help on using the changeset viewer.