Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usbhid/src/hiddescriptor.c

    r160b75e r1432fcf3  
    4141#include <assert.h>
    4242
    43 
     43/*---------------------------------------------------------------------------*/
     44/*
     45 * Constants defining current parsing mode for correct parsing of the set of
     46 * local tags (usage) enclosed in delimter tags.
     47 */
     48/**
     49 * Second delimiter tag was read. The set of local items (usage) ended.
     50 */
    4451#define OUTSIDE_DELIMITER_SET   0
     52
     53/**
     54 * First delimiter tag was read. The set of local items (usage) started.
     55 */
    4556#define START_DELIMITER_SET     1
     57
     58/**
     59 * Parser is in the set of local items.
     60 */
    4661#define INSIDE_DELIMITER_SET    2
     62
     63/*---------------------------------------------------------------------------*/
    4764       
    4865/** The new report item flag. Used to determine when the item is completly
     
    6178#define USB_HID_UNKNOWN_TAG             -99
    6279
    63 usb_hid_report_path_t *usb_hid_report_path_try_insert(usb_hid_report_t *report, usb_hid_report_path_t *cmp_path)
    64 {
    65         /* find or append current collection path to the list */
    66         link_t *path_it = report->collection_paths.next;
     80/*---------------------------------------------------------------------------*/
     81/**
     82 * Checks if given collection path is already present in report structure and
     83 * inserts it if not.
     84 *
     85 * @param report Report structure
     86 * @param cmp_path The collection path
     87 * @return Pointer to the result collection path in report structure.
     88 * @retval NULL If some error occurs
     89 */
     90usb_hid_report_path_t *usb_hid_report_path_try_insert(
     91                usb_hid_report_t *report, usb_hid_report_path_t *cmp_path) {
     92       
     93        link_t *path_it = report->collection_paths.prev->next;
    6794        usb_hid_report_path_t *path = NULL;
     95       
     96        if((report == NULL) || (cmp_path == NULL)) {
     97                return NULL;
     98        }
     99       
    68100        while(path_it != &report->collection_paths) {
    69                 path = list_get_instance(path_it, usb_hid_report_path_t, link);
    70                
    71                 if(usb_hid_report_compare_usage_path(path, cmp_path, USB_HID_PATH_COMPARE_STRICT) == EOK){
     101                path = list_get_instance(path_it, usb_hid_report_path_t,
     102                                link);
     103               
     104                if(usb_hid_report_compare_usage_path(path, cmp_path,
     105                                        USB_HID_PATH_COMPARE_STRICT) == EOK){
    72106                        break;
    73107                }                       
     
    75109        }
    76110        if(path_it == &report->collection_paths) {
    77                 path = usb_hid_report_path_clone(cmp_path);                     
     111                path = usb_hid_report_path_clone(cmp_path);
     112                if(path == NULL) {
     113                        return NULL;
     114                }
    78115                list_append(&path->link, &report->collection_paths);                                   
    79116                report->collection_paths_count++;
     
    82119        }
    83120        else {
    84                 return list_get_instance(path_it, usb_hid_report_path_t, link);
    85         }
    86 }
    87 
     121                return list_get_instance(path_it, usb_hid_report_path_t,
     122                                link);
     123        }
     124}
     125
     126/*---------------------------------------------------------------------------*/
    88127/**
    89128 * Initialize the report descriptor parser structure
     
    91130 * @param parser Report descriptor parser structure
    92131 * @return Error code
     132 * @retval EINVAL If no report structure was given
     133 * @retval EOK If report structure was successfully initialized
    93134 */
    94135int usb_hid_report_init(usb_hid_report_t *report)
     
    106147}
    107148
    108 
    109 /*
    110  *
    111  *
    112  */
    113 int usb_hid_report_append_fields(usb_hid_report_t *report, usb_hid_report_item_t *report_item)
    114 {
     149/*---------------------------------------------------------------------------*/
     150
     151/**
     152 *
     153 *
     154 * @param report Report structure in which the new report items should be
     155 *               stored
     156 * @param report_item Current report descriptor's parsing state table
     157 * @return Error code
     158 * @retval EOK If all fields were successfully append to report
     159 * @retval EINVAL If invalid parameters (NULL) was given
     160 * @retval ENOMEM If there is no memmory to store new report description
     161 *
     162 */
     163int usb_hid_report_append_fields(usb_hid_report_t *report,
     164                usb_hid_report_item_t *report_item) {
     165
    115166        usb_hid_report_field_t *field;
    116167        int i;
    117168
    118         for(i=0; i<report_item->usages_count; i++){
    119                 usb_log_debug("usages (%d) - %x\n", i, report_item->usages[i]);
    120         }
    121 
     169        uint32_t *usages;
     170        int usages_used=0;
     171
     172        if((report == NULL) || (report_item == NULL)) {
     173                return EINVAL;
     174        }
     175
     176        if(report_item->usages_count > 0){
     177                usages = malloc(sizeof(int32_t) * report_item->usages_count);
     178                memcpy(usages, report_item->usages, sizeof(int32_t) *
     179                                report_item->usages_count);
     180        }
     181        else {
     182                usages = NULL;
     183        }
     184       
    122185        usb_hid_report_path_t *path = report_item->usage_path; 
    123186        for(i=0; i<report_item->count; i++){
     
    133196                field->physical_maximum = report_item->physical_maximum;
    134197
    135                 field->usage_minimum = report_item->usage_minimum;
    136                 field->usage_maximum = report_item->usage_maximum;
    137                 if(report_item->extended_usage_page != 0){
    138                         field->usage_page = report_item->extended_usage_page;
     198                if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0){
     199                        /*
     200                        Store usage array. The Correct Usage Page and Usage is
     201                        depending on data in report and will be filled later
     202                        */
     203                        field->usage = 0;
     204                        field->usage_page = 0; //report_item->usage_page;
     205
     206                        field->usages_count = report_item->usages_count;
     207                        field->usages = usages;
     208                        usages_used = 1;
    139209                }
    140210                else {
    141                         field->usage_page = report_item->usage_page;
    142                 }
    143 
    144                 if(report_item->usages_count > 0 && ((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0))) {
    145                         uint32_t usage;
    146                         if(i < report_item->usages_count){
     211
     212                        /* Fill the correct Usage and Usage Page */
     213                        int32_t usage;
     214                        if(i < report_item->usages_count) {
    147215                                usage = report_item->usages[i];
    148216                        }
    149217                        else {
    150                                 usage = report_item->usages[report_item->usages_count - 1];
     218                                usage = report_item->usages[
     219                                        report_item->usages_count- 1];
    151220                        }
    152221
    153                                                
    154                         if((usage & 0xFFFF0000) != 0){
    155                                 field->usage_page = (usage >> 16);                                     
    156                                 field->usage = (usage & 0xFFFF);
     222                        if(USB_HID_IS_EXTENDED_USAGE(usage)){
     223                                field->usage = USB_HID_EXTENDED_USAGE(usage);
     224                                field->usage_page =
     225                                        USB_HID_EXTENDED_USAGE_PAGE(usage);
    157226                        }
    158227                        else {
     228                                // should not occur
    159229                                field->usage = usage;
     230                                field->usage_page = report_item->usage_page;
    160231                        }
    161 
    162                        
    163                 }       
    164 
    165                 if((USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) != 0) && (!((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0)))) {
    166                         field->usage = report_item->usage_minimum + i;                                 
    167                 }
    168                
    169                 usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_GLOBAL, field->usage_page);
    170                 usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_LOCAL, field->usage);
    171 
    172                 field->collection_path = usb_hid_report_path_try_insert(report, path);
     232                }
     233               
     234                usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_GLOBAL,
     235                                field->usage_page);
     236                usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_LOCAL,
     237                                field->usage);
     238
     239                field->collection_path =
     240                        usb_hid_report_path_try_insert(report, path);
    173241
    174242                field->size = report_item->size;
    175243               
    176                 size_t offset_byte = (report_item->offset + (i * report_item->size)) / 8;
    177                 size_t offset_bit = 8 - ((report_item->offset + (i * report_item->size)) % 8) - report_item->size;
     244                size_t offset_byte = (report_item->offset + (i *
     245                        report_item->size)) / 8;
     246
     247                size_t offset_bit = 8 - ((report_item->offset + (i *
     248                        report_item->size)) % 8) - report_item->size;
    178249
    179250                field->offset = 8 * offset_byte + offset_bit;
     
    186257                /* find the right report list*/
    187258                usb_hid_report_description_t *report_des;
    188                 report_des = usb_hid_report_find_description(report, report_item->id, report_item->type);
     259                report_des = usb_hid_report_find_description(report,
     260                        report_item->id, report_item->type);
     261               
    189262                if(report_des == NULL){
    190                         report_des = malloc(sizeof(usb_hid_report_description_t));
    191                         memset(report_des, 0, sizeof(usb_hid_report_description_t));
     263                        report_des = malloc(
     264                                sizeof(usb_hid_report_description_t));
     265                        if(report_des == NULL) {
     266                                return ENOMEM;
     267                        }
     268
     269                        memset(report_des, 0,
     270                                sizeof(usb_hid_report_description_t));
    192271
    193272                        report_des->type = report_item->type;
    194273                        report_des->report_id = report_item->id;
     274                        if(report_des->report_id != 0) {
     275                                /* set up the bit length by report_id field */
     276                                report_des->bit_length = 8;
     277                        }
     278
    195279                        list_initialize (&report_des->link);
    196280                        list_initialize (&report_des->report_items);
     
    209293        }
    210294
     295        // free only when not used!!!
     296        if(usages && usages_used == 0) {
     297                free(usages);
     298        }
    211299
    212300        return EOK;
    213301}
    214 
    215 usb_hid_report_description_t * usb_hid_report_find_description(const usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type)
    216 {
     302/*---------------------------------------------------------------------------*/
     303/**
     304 * Finds description of report with given report_id and of given type in
     305 * opaque report structure.
     306 *
     307 * @param report Opaque structure containing the parsed report descriptor
     308 * @param report_id ReportId of report we are searching
     309 * @param type Type of report we are searching
     310 * @return Pointer to the particular report description
     311 * @retval NULL If no description is founded
     312 */
     313usb_hid_report_description_t * usb_hid_report_find_description(
     314                const usb_hid_report_t *report, uint8_t report_id,
     315                usb_hid_report_type_t type) {
     316
    217317        link_t *report_it = report->reports.next;
    218318        usb_hid_report_description_t *report_des = NULL;
    219319       
    220320        while(report_it != &report->reports) {
    221                 report_des = list_get_instance(report_it, usb_hid_report_description_t, link);
    222 
    223                 if((report_des->report_id == report_id) && (report_des->type == type)){
     321                report_des = list_get_instance(report_it,
     322                                usb_hid_report_description_t, link);
     323
     324                if((report_des->report_id == report_id) &&
     325                   (report_des->type == type)) {
    224326                        return report_des;
    225327                }
     
    230332        return NULL;
    231333}
     334/*---------------------------------------------------------------------------*/
    232335
    233336/** Parse HID report descriptor.
     
    236339 * @param data Data describing the report.
    237340 * @return Error code.
     341 * @retval ENOMEM If no more memmory is available
     342 * @retval EINVAL If invalid data are founded
     343 * @retval EOK If report descriptor is successfully parsed
    238344 */
    239345int usb_hid_parse_report_descriptor(usb_hid_report_t *report,
     
    286392                       
    287393                        ret = usb_hid_report_parse_tag(tag,class,data+i+1,
    288                                                        item_size,report_item, usage_path);
     394                                item_size,report_item, usage_path);
     395
    289396                        switch(ret){
    290                                 case USB_HID_NEW_REPORT_ITEM:
    291                                         // store report item to report and create the new one
    292                                         // store current collection path
    293                                         report_item->usage_path = usage_path;
     397                        case USB_HID_NEW_REPORT_ITEM:
     398                                /* store report item to report and create the
     399                                 * new one store current collection path
     400                                 */
     401                                report_item->usage_path = usage_path;
    294402                                       
    295                                         usb_hid_report_path_set_report_id(report_item->usage_path, report_item->id);   
    296                                         if(report_item->id != 0){
    297                                                 report->use_report_ids = 1;
    298                                         }
     403                                usb_hid_report_path_set_report_id(
     404                                     report_item->usage_path, report_item->id);
     405                               
     406                                if(report_item->id != 0){
     407                                        report->use_report_ids = 1;
     408                                }
    299409                                       
    300                                         switch(tag) {
    301                                                 case USB_HID_REPORT_TAG_INPUT:
    302                                                         report_item->type = USB_HID_REPORT_TYPE_INPUT;
    303                                                         report_item->offset = offset_input;
    304                                                         offset_input += report_item->count * report_item->size;
    305                                                         break;
    306                                                 case USB_HID_REPORT_TAG_OUTPUT:
    307                                                         report_item->type = USB_HID_REPORT_TYPE_OUTPUT;
    308                                                         report_item->offset = offset_output;
    309                                                         offset_output += report_item->count * report_item->size;
    310 
    311                                                         break;
    312                                                 case USB_HID_REPORT_TAG_FEATURE:
    313                                                         report_item->type = USB_HID_REPORT_TYPE_FEATURE;
    314                                                         report_item->offset = offset_feature;
    315                                                         offset_feature += report_item->count * report_item->size;
    316                                                         break;
    317                                                 default:
    318                                                     usb_log_debug("\tjump over - tag %X\n", tag);
    319                                                     break;
    320                                         }
     410                                switch(tag) {
     411                                case USB_HID_REPORT_TAG_INPUT:
     412                                        report_item->type =
     413                                            USB_HID_REPORT_TYPE_INPUT;
     414
     415                                        report_item->offset = offset_input;
     416                                        offset_input += report_item->count *
     417                                            report_item->size;
     418                                        break;
     419       
     420                                case USB_HID_REPORT_TAG_OUTPUT:
     421                                        report_item->type =
     422                                            USB_HID_REPORT_TYPE_OUTPUT;
    321423                                       
    322                                         /*
    323                                          * append new fields to the report
    324                                          * structure                                     
    325                                          */
    326                                         usb_hid_report_append_fields(report, report_item);
    327 
    328                                         /* reset local items */
    329                                         usb_hid_report_reset_local_items (report_item);
    330 
     424                                        report_item->offset = offset_output;
     425                                        offset_output += report_item->count *
     426                                            report_item->size;
    331427                                        break;
    332 
    333                                 case USB_HID_RESET_OFFSET:
    334                                         offset_input = 0;
    335                                         offset_output = 0;
    336                                         offset_feature = 0;
    337                                         usb_hid_report_path_set_report_id (usage_path, report_item->id);
     428       
     429                                case USB_HID_REPORT_TAG_FEATURE:
     430                                        report_item->type =
     431                                            USB_HID_REPORT_TYPE_FEATURE;
     432
     433                                        report_item->offset = offset_feature;
     434                                        offset_feature += report_item->count *
     435                                                report_item->size;
    338436                                        break;
    339 
    340                                 case USB_HID_REPORT_TAG_PUSH:
    341                                         // push current state to stack
    342                                         new_report_item = usb_hid_report_item_clone(report_item);
    343                                         usb_hid_report_path_t *tmp_path = usb_hid_report_path_clone(usage_path);
    344                                         new_report_item->usage_path = tmp_path;
    345 
    346                                         list_prepend (&new_report_item->link, &stack);
    347                                         break;
    348                                 case USB_HID_REPORT_TAG_POP:
    349                                         // restore current state from stack
    350                                         if(list_empty (&stack)) {
    351                                                 return EINVAL;
    352                                         }
    353                                         free(report_item);
     437       
     438                                default:
     439                                        usb_log_debug2(
     440                                            "\tjump over - tag %X\n", tag);
     441                                        break;
     442                                }
     443                                       
     444                                /*
     445                                 * append new fields to the report structure                                     
     446                                 */
     447                                usb_hid_report_append_fields(report,
     448                                    report_item);
     449
     450                                /* reset local items */
     451                                usb_hid_report_reset_local_items (report_item);
     452                                break;
     453
     454                        case USB_HID_RESET_OFFSET:
     455                                offset_input = 0;
     456                                offset_output = 0;
     457                                offset_feature = 0;
     458                                usb_hid_report_path_set_report_id (usage_path,
     459                                    report_item->id);
     460                                break;
     461
     462                        case USB_HID_REPORT_TAG_PUSH:
     463                                // push current state to stack
     464                                new_report_item = usb_hid_report_item_clone(
     465                                    report_item);
     466                               
     467                                usb_hid_report_path_t *tmp_path =
     468                                    usb_hid_report_path_clone(usage_path);
     469
     470                                new_report_item->usage_path = tmp_path;
     471
     472                                list_prepend (&new_report_item->link, &stack);
     473                                break;
     474                        case USB_HID_REPORT_TAG_POP:
     475                                // restore current state from stack
     476                                if(list_empty (&stack)) {
     477                                        return EINVAL;
     478                                }
     479                                free(report_item);
    354480                                               
    355                                         report_item = list_get_instance(stack.next, usb_hid_report_item_t, link);
     481                                report_item = list_get_instance(stack.next,
     482                                    usb_hid_report_item_t, link);
    356483                                       
    357                                         usb_hid_report_usage_path_t *tmp_usage_path;
    358                                         tmp_usage_path = list_get_instance(report_item->usage_path->link.prev, usb_hid_report_usage_path_t, link);
     484                                usb_hid_report_usage_path_t *tmp_usage_path;
     485                                tmp_usage_path = list_get_instance(
     486                                    report_item->usage_path->link.prev,
     487                                    usb_hid_report_usage_path_t, link);
    359488                                       
    360                                         usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL, tmp_usage_path->usage_page);
    361                                         usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL, tmp_usage_path->usage);
    362 
    363                                         usb_hid_report_path_free(report_item->usage_path);
    364                                         list_initialize(&report_item->usage_path->link);
    365                                         list_remove (stack.next);
     489                                usb_hid_report_set_last_item(usage_path,
     490                                    USB_HID_TAG_CLASS_GLOBAL, tmp_usage_path->usage_page);
     491                               
     492                                usb_hid_report_set_last_item(usage_path,
     493                                    USB_HID_TAG_CLASS_LOCAL, tmp_usage_path->usage);
     494
     495                                usb_hid_report_path_free(report_item->usage_path);
     496                                list_initialize(&report_item->usage_path->link);
     497                                list_remove (stack.next);
    366498                                       
    367                                         break;
     499                                break;
    368500                                       
    369                                 default:
    370                                         // nothing special to do                                       
    371                                         break;
     501                        default:
     502                                // nothing special to do                                       
     503                                break;
    372504                        }
    373505
     
    386518}
    387519
     520/*---------------------------------------------------------------------------*/
    388521
    389522/**
     
    396529 * @return Code of action to be done next
    397530 */
    398 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size,
    399                              usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
    400 {       
     531int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data,
     532        size_t item_size, usb_hid_report_item_t *report_item,
     533        usb_hid_report_path_t *usage_path) {   
     534       
    401535        int ret;
    402536       
    403537        switch(class){
    404                 case USB_HID_TAG_CLASS_MAIN:
    405 
    406                         if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item, usage_path)) == EOK) {
    407                                 return USB_HID_NEW_REPORT_ITEM;
    408                         }
    409                         else {
    410                                 /*TODO process the error */
    411                                 return ret;
    412                            }
    413                         break;
    414 
    415                 case USB_HID_TAG_CLASS_GLOBAL: 
    416                         return usb_hid_report_parse_global_tag(tag,data,item_size,report_item, usage_path);
    417                         break;
    418 
    419                 case USB_HID_TAG_CLASS_LOCAL:                   
    420                         return usb_hid_report_parse_local_tag(tag,data,item_size,report_item, usage_path);
    421                         break;
    422                 default:
    423                         return USB_HID_NO_ACTION;
     538        case USB_HID_TAG_CLASS_MAIN:
     539
     540                if((ret=usb_hid_report_parse_main_tag(tag, data, item_size,
     541                        report_item, usage_path)) == EOK) {
     542
     543                        return USB_HID_NEW_REPORT_ITEM;
     544                }
     545                else {
     546                        return ret;
     547                }
     548                break;
     549
     550        case USB_HID_TAG_CLASS_GLOBAL: 
     551                return usb_hid_report_parse_global_tag(tag, data, item_size,
     552                        report_item, usage_path);
     553                break;
     554
     555        case USB_HID_TAG_CLASS_LOCAL:                   
     556                return usb_hid_report_parse_local_tag(tag, data, item_size,
     557                        report_item, usage_path);
     558                break;
     559       
     560        default:
     561                return USB_HID_NO_ACTION;
    424562        }
    425563}
     
    435573 */
    436574
    437 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    438                              usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
     575int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data,
     576        size_t item_size, usb_hid_report_item_t *report_item,
     577        usb_hid_report_path_t *usage_path)
    439578{
    440579        usb_hid_report_usage_path_t *path_item;
     
    442581        switch(tag)
    443582        {
    444                 case USB_HID_REPORT_TAG_INPUT:
    445                 case USB_HID_REPORT_TAG_OUTPUT:
    446                 case USB_HID_REPORT_TAG_FEATURE:
    447                         report_item->item_flags = *data;                       
    448                         return EOK;                     
    449                         break;
     583        case USB_HID_REPORT_TAG_INPUT:
     584        case USB_HID_REPORT_TAG_OUTPUT:
     585        case USB_HID_REPORT_TAG_FEATURE:
     586                report_item->item_flags = *data;                       
     587                return EOK;                     
     588                break;
    450589                       
    451                 case USB_HID_REPORT_TAG_COLLECTION:
    452                         // store collection atributes
    453                         path_item = list_get_instance(usage_path->head.prev, usb_hid_report_usage_path_t, link);
    454                         path_item->flags = *data;       
     590        case USB_HID_REPORT_TAG_COLLECTION:
     591
     592                /* store collection atributes */
     593                path_item = list_get_instance(usage_path->head.prev,
     594                        usb_hid_report_usage_path_t, link);
     595                path_item->flags = *data;       
    455596                       
    456                         // set last item
    457                         usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL, report_item->usage_page);
    458                         usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL, report_item->usages[report_item->usages_count-1]);
     597                /* set last item */
     598                usb_hid_report_set_last_item(usage_path,
     599                        USB_HID_TAG_CLASS_GLOBAL,
     600                        USB_HID_EXTENDED_USAGE_PAGE(report_item->usages[
     601                                report_item->usages_count-1]));
     602
     603                usb_hid_report_set_last_item(usage_path,
     604                        USB_HID_TAG_CLASS_LOCAL,
     605                        USB_HID_EXTENDED_USAGE(report_item->usages[
     606                                report_item->usages_count-1]));
    459607                       
    460                         // append the new one which will be set by common
    461                         // usage/usage page
    462                         usb_hid_report_path_append_item(usage_path, report_item->usage_page, report_item->usages[report_item->usages_count-1]);
    463                         usb_hid_report_reset_local_items (report_item);
    464                         return USB_HID_NO_ACTION;
    465                         break;
     608                /* append the new one which will be set by common usage/usage
     609                 * page */
     610                usb_hid_report_path_append_item(usage_path,
     611                        report_item->usage_page,
     612                        report_item->usages[report_item->usages_count-1]);
     613
     614                usb_hid_report_reset_local_items (report_item);
     615                return USB_HID_NO_ACTION;
     616                break;
    466617                       
    467                 case USB_HID_REPORT_TAG_END_COLLECTION:
    468                         usb_hid_report_remove_last_item(usage_path);
    469                         return USB_HID_NO_ACTION;
    470                         break;
    471                 default:
    472                         return USB_HID_NO_ACTION;
     618        case USB_HID_REPORT_TAG_END_COLLECTION:
     619                usb_hid_report_remove_last_item(usage_path);
     620                return USB_HID_NO_ACTION;
     621                break;
     622
     623        default:
     624                return USB_HID_NO_ACTION;
    473625        }
    474626
     
    485637 * @return Error code
    486638 */
    487 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    488                              usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
    489 {
    490         // TODO take care about the bit length of data
     639int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data,
     640        size_t item_size, usb_hid_report_item_t *report_item,
     641        usb_hid_report_path_t *usage_path) {
     642       
    491643        switch(tag)
    492644        {
    493                 case USB_HID_REPORT_TAG_USAGE_PAGE:
    494                         report_item->usage_page = usb_hid_report_tag_data_uint32(data, item_size);
    495                         break;
    496                 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM:
    497                         report_item->logical_minimum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
    498                         break;
    499                 case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM:
    500                         report_item->logical_maximum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
    501                         break;
    502                 case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM:
    503                         report_item->physical_minimum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
    504                         break;                 
    505                 case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM:
    506                         report_item->physical_maximum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
    507 
    508                         break;
    509                 case USB_HID_REPORT_TAG_UNIT_EXPONENT:
    510                         report_item->unit_exponent = usb_hid_report_tag_data_uint32(data,item_size);
    511                         break;
    512                 case USB_HID_REPORT_TAG_UNIT:
    513                         report_item->unit = usb_hid_report_tag_data_uint32(data,item_size);
    514                         break;
    515                 case USB_HID_REPORT_TAG_REPORT_SIZE:
    516                         report_item->size = usb_hid_report_tag_data_uint32(data,item_size);
    517                         break;
    518                 case USB_HID_REPORT_TAG_REPORT_COUNT:
    519                         report_item->count = usb_hid_report_tag_data_uint32(data,item_size);
    520                         break;
    521                 case USB_HID_REPORT_TAG_REPORT_ID:
    522                         report_item->id = usb_hid_report_tag_data_uint32(data,item_size);
    523                         return USB_HID_RESET_OFFSET;
    524                         break;
    525                 case USB_HID_REPORT_TAG_PUSH:
    526                 case USB_HID_REPORT_TAG_POP:
    527                         /*
    528                          * stack operations are done in top level parsing
    529                          * function
    530                          */
    531                         return tag;
    532                         break;
     645        case USB_HID_REPORT_TAG_USAGE_PAGE:
     646                report_item->usage_page =
     647                        usb_hid_report_tag_data_uint32(data, item_size);
     648                break;
     649
     650        case USB_HID_REPORT_TAG_LOGICAL_MINIMUM:
     651                report_item->logical_minimum = USB_HID_UINT32_TO_INT32(
     652                        usb_hid_report_tag_data_uint32(data,item_size),
     653                        item_size * 8);
     654                break;
     655
     656        case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM:
     657                report_item->logical_maximum = USB_HID_UINT32_TO_INT32(
     658                        usb_hid_report_tag_data_uint32(data,item_size),
     659                        item_size * 8);
     660                break;
     661
     662        case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM:
     663                report_item->physical_minimum = USB_HID_UINT32_TO_INT32(
     664                        usb_hid_report_tag_data_uint32(data,item_size),
     665                        item_size * 8);
     666                break;                 
     667
     668        case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM:
     669                report_item->physical_maximum = USB_HID_UINT32_TO_INT32(
     670                        usb_hid_report_tag_data_uint32(data,item_size),
     671                        item_size * 8);
     672                break;
     673
     674        case USB_HID_REPORT_TAG_UNIT_EXPONENT:
     675                report_item->unit_exponent = usb_hid_report_tag_data_uint32(
     676                        data,item_size);
     677                break;
     678
     679        case USB_HID_REPORT_TAG_UNIT:
     680                report_item->unit = usb_hid_report_tag_data_uint32(
     681                        data,item_size);
     682                break;
     683
     684        case USB_HID_REPORT_TAG_REPORT_SIZE:
     685                report_item->size = usb_hid_report_tag_data_uint32(
     686                        data,item_size);
     687                break;
     688
     689        case USB_HID_REPORT_TAG_REPORT_COUNT:
     690                report_item->count = usb_hid_report_tag_data_uint32(
     691                        data,item_size);
     692                break;
     693
     694        case USB_HID_REPORT_TAG_REPORT_ID:
     695                report_item->id = usb_hid_report_tag_data_uint32(data,
     696                        item_size);
     697                return USB_HID_RESET_OFFSET;
     698                break;
     699       
     700        case USB_HID_REPORT_TAG_PUSH:
     701        case USB_HID_REPORT_TAG_POP:
     702                /*
     703                 * stack operations are done in top level parsing
     704                 * function
     705                 */
     706                return tag;
     707                break;
    533708                       
    534                 default:
    535                         return USB_HID_NO_ACTION;
     709        default:
     710                return USB_HID_NO_ACTION;
    536711        }
    537712
     
    548723 * @return Error code
    549724 */
    550 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    551                              usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
     725int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data,
     726        size_t item_size, usb_hid_report_item_t *report_item,
     727        usb_hid_report_path_t *usage_path)
    552728{
     729        int32_t extended_usage;
     730       
    553731        switch(tag) {
    554                 case USB_HID_REPORT_TAG_USAGE:
    555                         switch(report_item->in_delimiter) {
    556                                 case INSIDE_DELIMITER_SET:
    557                                         // nothing to do
    558                                         break;
    559                                 case START_DELIMITER_SET:
    560                                         report_item->in_delimiter = INSIDE_DELIMITER_SET;
    561                                 case OUTSIDE_DELIMITER_SET:
    562                                         report_item->usages[report_item->usages_count] = usb_hid_report_tag_data_uint32(data,item_size);
    563                                         report_item->usages_count++;
    564                                         break;
     732        case USB_HID_REPORT_TAG_USAGE:
     733                switch(report_item->in_delimiter) {
     734                case INSIDE_DELIMITER_SET:
     735                        /* nothing to do
     736                         * we catch only the first one
     737                         */
     738                        break;
     739       
     740                case START_DELIMITER_SET:
     741                        report_item->in_delimiter = INSIDE_DELIMITER_SET;
     742                case OUTSIDE_DELIMITER_SET:
     743                        extended_usage = ((report_item->usage_page) << 16);
     744                        extended_usage += usb_hid_report_tag_data_uint32(
     745                                data,item_size);
     746
     747                        report_item->usages[report_item->usages_count] =
     748                                extended_usage;
     749
     750                        report_item->usages_count++;
     751                        break;
     752                }
     753                break;
     754               
     755        case USB_HID_REPORT_TAG_USAGE_MINIMUM:                 
     756                if (item_size == 3) {
     757                        // usage extended usages
     758                        report_item->extended_usage_page =
     759                            USB_HID_EXTENDED_USAGE_PAGE(
     760                            usb_hid_report_tag_data_uint32(data,item_size));
     761                           
     762
     763                        report_item->usage_minimum =
     764                            USB_HID_EXTENDED_USAGE(
     765                            usb_hid_report_tag_data_uint32(data,item_size));
     766                }
     767                else {
     768                        report_item->usage_minimum =
     769                            usb_hid_report_tag_data_uint32(data,item_size);
     770                }
     771                break;
     772       
     773        case USB_HID_REPORT_TAG_USAGE_MAXIMUM:
     774                if (item_size == 3) {
     775                        if(report_item->extended_usage_page !=
     776                            USB_HID_EXTENDED_USAGE_PAGE(       
     777                            usb_hid_report_tag_data_uint32(data,item_size))) {
     778                               
     779                                return EINVAL;
    565780                        }
    566                         break;
    567                 case USB_HID_REPORT_TAG_USAGE_MINIMUM:
    568                         if (item_size == 3) {
    569                                 // usage extended usages
    570                                 report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16;
    571                                 report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size) & 0xFF;
     781                               
     782                        // usage extended usages
     783                        report_item->extended_usage_page =
     784                                USB_HID_EXTENDED_USAGE_PAGE(
     785                                usb_hid_report_tag_data_uint32(data,item_size));
     786
     787                        report_item->usage_maximum =
     788                                USB_HID_EXTENDED_USAGE(
     789                                usb_hid_report_tag_data_uint32(data,item_size));
     790                }
     791                else {
     792                        report_item->usage_maximum =
     793                                usb_hid_report_tag_data_uint32(data,item_size);
     794                }
     795
     796                // vlozit zaznamy do pole usages
     797                int32_t i;
     798                for(i = report_item->usage_minimum;
     799                    i <= report_item->usage_maximum; i++) {
     800
     801                        if(report_item->extended_usage_page) {
     802                            report_item->usages[report_item->usages_count++] =
     803                                (report_item->extended_usage_page << 16) + i;
    572804                        }
    573                         else {
    574                                 report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size);
     805                        else {                 
     806                            report_item->usages[report_item->usages_count++] =
     807                                (report_item->usage_page << 16) + i;
    575808                        }
    576                         break;
    577                 case USB_HID_REPORT_TAG_USAGE_MAXIMUM:
    578                         if (item_size == 3) {
    579                                 // usage extended usages
    580                                 report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16;
    581                                 report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size) & 0xFF;
    582                         }
    583                         else {
    584                                 report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size);
    585                         }
    586                         break;
    587                 case USB_HID_REPORT_TAG_DESIGNATOR_INDEX:
    588                         report_item->designator_index = usb_hid_report_tag_data_uint32(data,item_size);
    589                         break;
    590                 case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM:
    591                         report_item->designator_minimum = usb_hid_report_tag_data_uint32(data,item_size);
    592                         break;
    593                 case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM:
    594                         report_item->designator_maximum = usb_hid_report_tag_data_uint32(data,item_size);
    595                         break;
    596                 case USB_HID_REPORT_TAG_STRING_INDEX:
    597                         report_item->string_index = usb_hid_report_tag_data_uint32(data,item_size);
    598                         break;
    599                 case USB_HID_REPORT_TAG_STRING_MINIMUM:
    600                         report_item->string_minimum = usb_hid_report_tag_data_uint32(data,item_size);
    601                         break;
    602                 case USB_HID_REPORT_TAG_STRING_MAXIMUM:
    603                         report_item->string_maximum = usb_hid_report_tag_data_uint32(data,item_size);
    604                         break;                 
    605                 case USB_HID_REPORT_TAG_DELIMITER:
    606                         report_item->in_delimiter = usb_hid_report_tag_data_uint32(data,item_size);
    607                         break;
    608 
    609                 default:
    610                         return USB_HID_NO_ACTION;
     809                }
     810                report_item->extended_usage_page = 0;
     811                       
     812                break;
     813               
     814        case USB_HID_REPORT_TAG_DESIGNATOR_INDEX:
     815                report_item->designator_index =
     816                        usb_hid_report_tag_data_uint32(data,item_size);
     817                break;
     818       
     819        case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM:
     820                report_item->designator_minimum =
     821                        usb_hid_report_tag_data_uint32(data,item_size);
     822                break;
     823
     824        case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM:
     825                report_item->designator_maximum =
     826                        usb_hid_report_tag_data_uint32(data,item_size);
     827                break;
     828
     829        case USB_HID_REPORT_TAG_STRING_INDEX:
     830                report_item->string_index =
     831                        usb_hid_report_tag_data_uint32(data,item_size);
     832                break;
     833
     834        case USB_HID_REPORT_TAG_STRING_MINIMUM:
     835                report_item->string_minimum =
     836                        usb_hid_report_tag_data_uint32(data,item_size);
     837                break;
     838
     839        case USB_HID_REPORT_TAG_STRING_MAXIMUM:
     840                report_item->string_maximum =
     841                        usb_hid_report_tag_data_uint32(data,item_size);
     842                break;                 
     843
     844        case USB_HID_REPORT_TAG_DELIMITER:
     845                report_item->in_delimiter =
     846                        usb_hid_report_tag_data_uint32(data,item_size);
     847                break;
     848
     849        default:
     850                return USB_HID_NO_ACTION;
    611851        }
    612852
    613853        return EOK;
    614854}
     855/*---------------------------------------------------------------------------*/
    615856
    616857/**
     
    633874        return result;
    634875}
     876/*---------------------------------------------------------------------------*/
    635877
    636878/**
     
    653895        for(item = head->next; item != head; item = item->next) {
    654896               
    655                 report_item = list_get_instance(item, usb_hid_report_field_t, link);
     897                report_item = list_get_instance(item, usb_hid_report_field_t,
     898                                link);
    656899
    657900                usb_log_debug("\t\tOFFSET: %X\n", report_item->offset);
    658                 usb_log_debug("\t\tSIZE: %zu\n", report_item->size);                           
    659                 usb_log_debug("\t\tLOGMIN: %d\n", report_item->logical_minimum);
    660                 usb_log_debug("\t\tLOGMAX: %d\n", report_item->logical_maximum);               
    661                 usb_log_debug("\t\tPHYMIN: %d\n", report_item->physical_minimum);               
    662                 usb_log_debug("\t\tPHYMAX: %d\n", report_item->physical_maximum);                               
    663                 usb_log_debug("\t\ttUSAGEMIN: %X\n", report_item->usage_minimum);
    664                 usb_log_debug("\t\tUSAGEMAX: %X\n", report_item->usage_maximum);
     901                usb_log_debug("\t\tSIZE: %zu\n", report_item->size);
     902                usb_log_debug("\t\tLOGMIN: %d\n",
     903                        report_item->logical_minimum);
     904                usb_log_debug("\t\tLOGMAX: %d\n",
     905                        report_item->logical_maximum);         
     906                usb_log_debug("\t\tPHYMIN: %d\n",
     907                        report_item->physical_minimum);         
     908                usb_log_debug("\t\tPHYMAX: %d\n",
     909                        report_item->physical_maximum);                         
     910                usb_log_debug("\t\ttUSAGEMIN: %X\n",
     911                        report_item->usage_minimum);
     912                usb_log_debug("\t\tUSAGEMAX: %X\n",
     913                               report_item->usage_maximum);
     914                usb_log_debug("\t\tUSAGES COUNT: %zu\n",
     915                        report_item->usages_count);
    665916
    666917                usb_log_debug("\t\tVALUE: %X\n", report_item->value);
     
    668919                usb_log_debug("\t\tUSAGE PAGE: %X\n", report_item->usage_page);
    669920               
    670                 //usb_hid_print_usage_path(report_item->collection_path);
     921                usb_hid_print_usage_path(report_item->collection_path);
    671922
    672923                usb_log_debug("\n");           
     
    674925        }
    675926
    676 
    677 }
     927}
     928/*---------------------------------------------------------------------------*/
     929
    678930/**
    679931 * Prints content of given report descriptor in human readable format.
     
    692944
    693945        while(report_it != &report->reports) {
    694                 report_des = list_get_instance(report_it, usb_hid_report_description_t, link);
     946                report_des = list_get_instance(report_it,
     947                        usb_hid_report_description_t, link);
    695948                usb_log_debug("Report ID: %d\n", report_des->report_id);
    696949                usb_log_debug("\tType: %d\n", report_des->type);
    697950                usb_log_debug("\tLength: %zu\n", report_des->bit_length);               
     951                usb_log_debug("\tB Size: %zu\n",
     952                        usb_hid_report_byte_size(report,
     953                                report_des->report_id,
     954                                report_des->type));
    698955                usb_log_debug("\tItems: %zu\n", report_des->item_length);               
    699956
    700957                usb_hid_descriptor_print_list(&report_des->report_items);
    701958
    702 
    703                 link_t *path_it = report->collection_paths.next;
    704                 while(path_it != &report->collection_paths) {
    705                         usb_hid_print_usage_path (list_get_instance(path_it, usb_hid_report_path_t, link));
    706                         path_it = path_it->next;
    707                 }
    708                
    709959                report_it = report_it->next;
    710960        }
    711961}
     962/*---------------------------------------------------------------------------*/
    712963
    713964/**
     
    734985
    735986                while(!list_empty(&report_item->usage_path->link)) {
    736                         usb_hid_report_remove_last_item(report_item->usage_path);
     987                    usb_hid_report_remove_last_item(report_item->usage_path);
    737988                }
    738989
     
    746997       
    747998}
     999/*---------------------------------------------------------------------------*/
    7481000
    7491001/** Frees the HID report descriptor parser structure
     
    7611013        usb_hid_report_path_t *path;
    7621014        while(!list_empty(&report->collection_paths)) {
    763                 path = list_get_instance(report->collection_paths.next, usb_hid_report_path_t, link);
     1015                path = list_get_instance(report->collection_paths.next,
     1016                                usb_hid_report_path_t, link);
     1017
    7641018                usb_hid_report_path_free(path);         
    7651019        }
     
    7691023        usb_hid_report_field_t *field;
    7701024        while(!list_empty(&report->reports)) {
    771                 report_des = list_get_instance(report->reports.next, usb_hid_report_description_t, link);
     1025                report_des = list_get_instance(report->reports.next,
     1026                                usb_hid_report_description_t, link);
     1027
    7721028                list_remove(&report_des->link);
    7731029               
    7741030                while(!list_empty(&report_des->report_items)) {
    775                         field = list_get_instance(report_des->report_items.next, usb_hid_report_field_t, link);
     1031                        field = list_get_instance(
     1032                                report_des->report_items.next,
     1033                                usb_hid_report_field_t, link);
     1034
    7761035                        list_remove(&field->link);
    7771036
     
    7841043        return;
    7851044}
     1045/*---------------------------------------------------------------------------*/
    7861046
    7871047/**
Note: See TracChangeset for help on using the changeset viewer.