Changes in / [0588062e:d3594362] in mainline


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

Legend:

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

    r0588062e rd3594362  
    3737
    3838#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 
    6439
    6540/**
     
    6742 */
    6843typedef 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;
    7944
    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;
    8252
    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;
    9853} usb_hid_report_item_t;
    9954
    10055
    10156/** 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 
     57typedef struct {
     58} usb_hid_report_parser_t;
    10859
    10960
     
    176127int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size);
    177128
    178 int usb_hid_parser_init(usb_hid_report_parser_t *parser);
    179129int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser,
    180130    const uint8_t *data, size_t size);
     
    185135
    186136
    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);
     137int usb_hid_free_report_parser(usb_hid_report_parser_t *parser);
    190138
    191139#endif
  • uspace/lib/usb/src/hidparser.c

    r0588062e rd3594362  
    3636#include <errno.h>
    3737#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 
    7438
    7539/** Parse HID report descriptor.
     
    8246    const uint8_t *data, size_t size)
    8347{
    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;
    16749}
    16850
     
    19981}
    20082
     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
    20194
    20295/**
     
    223116        item.size = 8;
    224117        item.count = 6;
    225         item.usage_minimum = 0;
    226         item.usage_maximum = 255;
    227         item.logical_minimum = 0;
    228         item.logical_maximum = 255;
     118        item.usage_min = 0;
     119        item.usage_max = 255;
     120        item.logical_min = 0;
     121        item.logical_max = 255;
    229122
    230123        if (size != 8) {
    231                 return -1; //ERANGE;
     124                return ERANGE;
    232125        }
    233126
     
    251144int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size)
    252145{
    253         if(size != 1){
     146        if (size < 1){
    254147                return -1;
    255148        }
    256149
    257         /* used only first five bits, others are only padding*/
    258         *data = leds;
     150        data[0] = leds;
    259151        return EOK;
    260152}
    261153
    262154/**
    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 }
    565 /**
    566155 * @}
    567156 */
Note: See TracChangeset for help on using the changeset viewer.