Ignore:
File:
1 edited

Legend:

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

    r160b75e rd861c22  
    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;
     
    209288        }
    210289
     290        // free only when not used!!!
     291        if(usages && usages_used == 0) {
     292                free(usages);
     293        }
    211294
    212295        return EOK;
    213296}
    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 {
     297/*---------------------------------------------------------------------------*/
     298/**
     299 * Finds description of report with given report_id and of given type in
     300 * opaque report structure.
     301 *
     302 * @param report Opaque structure containing the parsed report descriptor
     303 * @param report_id ReportId of report we are searching
     304 * @param type Type of report we are searching
     305 * @return Pointer to the particular report description
     306 * @retval NULL If no description is founded
     307 */
     308usb_hid_report_description_t * usb_hid_report_find_description(
     309                const usb_hid_report_t *report, uint8_t report_id,
     310                usb_hid_report_type_t type) {
     311
    217312        link_t *report_it = report->reports.next;
    218313        usb_hid_report_description_t *report_des = NULL;
    219314       
    220315        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)){
     316                report_des = list_get_instance(report_it,
     317                                usb_hid_report_description_t, link);
     318
     319                if((report_des->report_id == report_id) &&
     320                   (report_des->type == type)) {
    224321                        return report_des;
    225322                }
     
    230327        return NULL;
    231328}
     329/*---------------------------------------------------------------------------*/
    232330
    233331/** Parse HID report descriptor.
     
    236334 * @param data Data describing the report.
    237335 * @return Error code.
     336 * @retval ENOMEM If no more memmory is available
     337 * @retval EINVAL If invalid data are founded
     338 * @retval EOK If report descriptor is successfully parsed
    238339 */
    239340int usb_hid_parse_report_descriptor(usb_hid_report_t *report,
     
    286387                       
    287388                        ret = usb_hid_report_parse_tag(tag,class,data+i+1,
    288                                                        item_size,report_item, usage_path);
     389                                item_size,report_item, usage_path);
     390
    289391                        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;
     392                        case USB_HID_NEW_REPORT_ITEM:
     393                                /* store report item to report and create the
     394                                 * new one store current collection path
     395                                 */
     396                                report_item->usage_path = usage_path;
    294397                                       
    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                                         }
     398                                usb_hid_report_path_set_report_id(
     399                                     report_item->usage_path, report_item->id);
     400                               
     401                                if(report_item->id != 0){
     402                                        report->use_report_ids = 1;
     403                                }
    299404                                       
    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                                         }
     405                                switch(tag) {
     406                                case USB_HID_REPORT_TAG_INPUT:
     407                                        report_item->type =
     408                                            USB_HID_REPORT_TYPE_INPUT;
     409
     410                                        report_item->offset = offset_input;
     411                                        offset_input += report_item->count *
     412                                            report_item->size;
     413                                        break;
     414       
     415                                case USB_HID_REPORT_TAG_OUTPUT:
     416                                        report_item->type =
     417                                            USB_HID_REPORT_TYPE_OUTPUT;
    321418                                       
    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 
     419                                        report_item->offset = offset_output;
     420                                        offset_output += report_item->count *
     421                                            report_item->size;
    331422                                        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);
     423       
     424                                case USB_HID_REPORT_TAG_FEATURE:
     425                                        report_item->type =
     426                                            USB_HID_REPORT_TYPE_FEATURE;
     427
     428                                        report_item->offset = offset_feature;
     429                                        offset_feature += report_item->count *
     430                                                report_item->size;
    338431                                        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);
     432       
     433                                default:
     434                                        usb_log_debug2(
     435                                            "\tjump over - tag %X\n", tag);
     436                                        break;
     437                                }
     438                                       
     439                                /*
     440                                 * append new fields to the report structure                                     
     441                                 */
     442                                usb_hid_report_append_fields(report,
     443                                    report_item);
     444
     445                                /* reset local items */
     446                                usb_hid_report_reset_local_items (report_item);
     447                                break;
     448
     449                        case USB_HID_RESET_OFFSET:
     450                                offset_input = 0;
     451                                offset_output = 0;
     452                                offset_feature = 0;
     453                                usb_hid_report_path_set_report_id (usage_path,
     454                                    report_item->id);
     455                                break;
     456
     457                        case USB_HID_REPORT_TAG_PUSH:
     458                                // push current state to stack
     459                                new_report_item = usb_hid_report_item_clone(
     460                                    report_item);
     461                               
     462                                usb_hid_report_path_t *tmp_path =
     463                                    usb_hid_report_path_clone(usage_path);
     464
     465                                new_report_item->usage_path = tmp_path;
     466
     467                                list_prepend (&new_report_item->link, &stack);
     468                                break;
     469                        case USB_HID_REPORT_TAG_POP:
     470                                // restore current state from stack
     471                                if(list_empty (&stack)) {
     472                                        return EINVAL;
     473                                }
     474                                free(report_item);
    354475                                               
    355                                         report_item = list_get_instance(stack.next, usb_hid_report_item_t, link);
     476                                report_item = list_get_instance(stack.next,
     477                                    usb_hid_report_item_t, link);
    356478                                       
    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);
     479                                usb_hid_report_usage_path_t *tmp_usage_path;
     480                                tmp_usage_path = list_get_instance(
     481                                    report_item->usage_path->link.prev,
     482                                    usb_hid_report_usage_path_t, link);
    359483                                       
    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);
     484                                usb_hid_report_set_last_item(usage_path,
     485                                    USB_HID_TAG_CLASS_GLOBAL, tmp_usage_path->usage_page);
     486                               
     487                                usb_hid_report_set_last_item(usage_path,
     488                                    USB_HID_TAG_CLASS_LOCAL, tmp_usage_path->usage);
     489
     490                                usb_hid_report_path_free(report_item->usage_path);
     491                                list_initialize(&report_item->usage_path->link);
     492                                list_remove (stack.next);
    366493                                       
    367                                         break;
     494                                break;
    368495                                       
    369                                 default:
    370                                         // nothing special to do                                       
    371                                         break;
     496                        default:
     497                                // nothing special to do                                       
     498                                break;
    372499                        }
    373500
     
    386513}
    387514
     515/*---------------------------------------------------------------------------*/
    388516
    389517/**
     
    396524 * @return Code of action to be done next
    397525 */
    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 {       
     526int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data,
     527        size_t item_size, usb_hid_report_item_t *report_item,
     528        usb_hid_report_path_t *usage_path) {   
     529       
    401530        int ret;
    402531       
    403532        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;
     533        case USB_HID_TAG_CLASS_MAIN:
     534
     535                if((ret=usb_hid_report_parse_main_tag(tag, data, item_size,
     536                        report_item, usage_path)) == EOK) {
     537
     538                        return USB_HID_NEW_REPORT_ITEM;
     539                }
     540                else {
     541                        return ret;
     542                }
     543                break;
     544
     545        case USB_HID_TAG_CLASS_GLOBAL: 
     546                return usb_hid_report_parse_global_tag(tag, data, item_size,
     547                        report_item, usage_path);
     548                break;
     549
     550        case USB_HID_TAG_CLASS_LOCAL:                   
     551                return usb_hid_report_parse_local_tag(tag, data, item_size,
     552                        report_item, usage_path);
     553                break;
     554       
     555        default:
     556                return USB_HID_NO_ACTION;
    424557        }
    425558}
     
    435568 */
    436569
    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)
     570int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data,
     571        size_t item_size, usb_hid_report_item_t *report_item,
     572        usb_hid_report_path_t *usage_path)
    439573{
    440574        usb_hid_report_usage_path_t *path_item;
     
    442576        switch(tag)
    443577        {
    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;
     578        case USB_HID_REPORT_TAG_INPUT:
     579        case USB_HID_REPORT_TAG_OUTPUT:
     580        case USB_HID_REPORT_TAG_FEATURE:
     581                report_item->item_flags = *data;                       
     582                return EOK;                     
     583                break;
    450584                       
    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;       
     585        case USB_HID_REPORT_TAG_COLLECTION:
     586
     587                /* store collection atributes */
     588                path_item = list_get_instance(usage_path->head.prev,
     589                        usb_hid_report_usage_path_t, link);
     590                path_item->flags = *data;       
    455591                       
    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]);
     592                /* set last item */
     593                usb_hid_report_set_last_item(usage_path,
     594                        USB_HID_TAG_CLASS_GLOBAL,
     595                        USB_HID_EXTENDED_USAGE_PAGE(report_item->usages[
     596                                report_item->usages_count-1]));
     597
     598                usb_hid_report_set_last_item(usage_path,
     599                        USB_HID_TAG_CLASS_LOCAL,
     600                        USB_HID_EXTENDED_USAGE(report_item->usages[
     601                                report_item->usages_count-1]));
    459602                       
    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;
     603                /* append the new one which will be set by common usage/usage
     604                 * page */
     605                usb_hid_report_path_append_item(usage_path,
     606                        report_item->usage_page,
     607                        report_item->usages[report_item->usages_count-1]);
     608
     609                usb_hid_report_reset_local_items (report_item);
     610                return USB_HID_NO_ACTION;
     611                break;
    466612                       
    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;
     613        case USB_HID_REPORT_TAG_END_COLLECTION:
     614                usb_hid_report_remove_last_item(usage_path);
     615                return USB_HID_NO_ACTION;
     616                break;
     617
     618        default:
     619                return USB_HID_NO_ACTION;
    473620        }
    474621
     
    485632 * @return Error code
    486633 */
    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
     634int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data,
     635        size_t item_size, usb_hid_report_item_t *report_item,
     636        usb_hid_report_path_t *usage_path) {
     637       
    491638        switch(tag)
    492639        {
    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;
     640        case USB_HID_REPORT_TAG_USAGE_PAGE:
     641                report_item->usage_page =
     642                        usb_hid_report_tag_data_uint32(data, item_size);
     643                break;
     644
     645        case USB_HID_REPORT_TAG_LOGICAL_MINIMUM:
     646                report_item->logical_minimum = USB_HID_UINT32_TO_INT32(
     647                        usb_hid_report_tag_data_uint32(data,item_size),
     648                        item_size * 8);
     649                break;
     650
     651        case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM:
     652                report_item->logical_maximum = USB_HID_UINT32_TO_INT32(
     653                        usb_hid_report_tag_data_uint32(data,item_size),
     654                        item_size * 8);
     655                break;
     656
     657        case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM:
     658                report_item->physical_minimum = USB_HID_UINT32_TO_INT32(
     659                        usb_hid_report_tag_data_uint32(data,item_size),
     660                        item_size * 8);
     661                break;                 
     662
     663        case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM:
     664                report_item->physical_maximum = USB_HID_UINT32_TO_INT32(
     665                        usb_hid_report_tag_data_uint32(data,item_size),
     666                        item_size * 8);
     667                break;
     668
     669        case USB_HID_REPORT_TAG_UNIT_EXPONENT:
     670                report_item->unit_exponent = usb_hid_report_tag_data_uint32(
     671                        data,item_size);
     672                break;
     673
     674        case USB_HID_REPORT_TAG_UNIT:
     675                report_item->unit = usb_hid_report_tag_data_uint32(
     676                        data,item_size);
     677                break;
     678
     679        case USB_HID_REPORT_TAG_REPORT_SIZE:
     680                report_item->size = usb_hid_report_tag_data_uint32(
     681                        data,item_size);
     682                break;
     683
     684        case USB_HID_REPORT_TAG_REPORT_COUNT:
     685                report_item->count = usb_hid_report_tag_data_uint32(
     686                        data,item_size);
     687                break;
     688
     689        case USB_HID_REPORT_TAG_REPORT_ID:
     690                report_item->id = usb_hid_report_tag_data_uint32(data,
     691                        item_size);
     692                return USB_HID_RESET_OFFSET;
     693                break;
     694       
     695        case USB_HID_REPORT_TAG_PUSH:
     696        case USB_HID_REPORT_TAG_POP:
     697                /*
     698                 * stack operations are done in top level parsing
     699                 * function
     700                 */
     701                return tag;
     702                break;
    533703                       
    534                 default:
    535                         return USB_HID_NO_ACTION;
     704        default:
     705                return USB_HID_NO_ACTION;
    536706        }
    537707
     
    548718 * @return Error code
    549719 */
    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)
     720int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data,
     721        size_t item_size, usb_hid_report_item_t *report_item,
     722        usb_hid_report_path_t *usage_path)
    552723{
     724        int32_t extended_usage;
     725       
    553726        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;
     727        case USB_HID_REPORT_TAG_USAGE:
     728                switch(report_item->in_delimiter) {
     729                case INSIDE_DELIMITER_SET:
     730                        /* nothing to do
     731                         * we catch only the first one
     732                         */
     733                        break;
     734       
     735                case START_DELIMITER_SET:
     736                        report_item->in_delimiter = INSIDE_DELIMITER_SET;
     737                case OUTSIDE_DELIMITER_SET:
     738                        extended_usage = ((report_item->usage_page) << 16);
     739                        extended_usage += usb_hid_report_tag_data_uint32(
     740                                data,item_size);
     741
     742                        report_item->usages[report_item->usages_count] =
     743                                extended_usage;
     744
     745                        report_item->usages_count++;
     746                        break;
     747                }
     748                break;
     749               
     750        case USB_HID_REPORT_TAG_USAGE_MINIMUM:                 
     751                if (item_size == 3) {
     752                        // usage extended usages
     753                        report_item->extended_usage_page =
     754                            USB_HID_EXTENDED_USAGE_PAGE(
     755                            usb_hid_report_tag_data_uint32(data,item_size));
     756                           
     757
     758                        report_item->usage_minimum =
     759                            USB_HID_EXTENDED_USAGE(
     760                            usb_hid_report_tag_data_uint32(data,item_size));
     761                }
     762                else {
     763                        report_item->usage_minimum =
     764                            usb_hid_report_tag_data_uint32(data,item_size);
     765                }
     766                break;
     767       
     768        case USB_HID_REPORT_TAG_USAGE_MAXIMUM:
     769                if (item_size == 3) {
     770                        if(report_item->extended_usage_page !=
     771                            USB_HID_EXTENDED_USAGE_PAGE(       
     772                            usb_hid_report_tag_data_uint32(data,item_size))) {
     773                               
     774                                return EINVAL;
    565775                        }
    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;
     776                               
     777                        // usage extended usages
     778                        report_item->extended_usage_page =
     779                                USB_HID_EXTENDED_USAGE_PAGE(
     780                                usb_hid_report_tag_data_uint32(data,item_size));
     781
     782                        report_item->usage_maximum =
     783                                USB_HID_EXTENDED_USAGE(
     784                                usb_hid_report_tag_data_uint32(data,item_size));
     785                }
     786                else {
     787                        report_item->usage_maximum =
     788                                usb_hid_report_tag_data_uint32(data,item_size);
     789                }
     790
     791                // vlozit zaznamy do pole usages
     792                int32_t i;
     793                for(i = report_item->usage_minimum;
     794                    i <= report_item->usage_maximum; i++) {
     795
     796                        if(report_item->extended_usage_page) {
     797                            report_item->usages[report_item->usages_count++] =
     798                                (report_item->extended_usage_page << 16) + i;
    572799                        }
    573                         else {
    574                                 report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size);
     800                        else {                 
     801                            report_item->usages[report_item->usages_count++] =
     802                                (report_item->usage_page << 16) + i;
    575803                        }
    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;
     804                }
     805                report_item->extended_usage_page = 0;
     806                       
     807                break;
     808               
     809        case USB_HID_REPORT_TAG_DESIGNATOR_INDEX:
     810                report_item->designator_index =
     811                        usb_hid_report_tag_data_uint32(data,item_size);
     812                break;
     813       
     814        case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM:
     815                report_item->designator_minimum =
     816                        usb_hid_report_tag_data_uint32(data,item_size);
     817                break;
     818
     819        case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM:
     820                report_item->designator_maximum =
     821                        usb_hid_report_tag_data_uint32(data,item_size);
     822                break;
     823
     824        case USB_HID_REPORT_TAG_STRING_INDEX:
     825                report_item->string_index =
     826                        usb_hid_report_tag_data_uint32(data,item_size);
     827                break;
     828
     829        case USB_HID_REPORT_TAG_STRING_MINIMUM:
     830                report_item->string_minimum =
     831                        usb_hid_report_tag_data_uint32(data,item_size);
     832                break;
     833
     834        case USB_HID_REPORT_TAG_STRING_MAXIMUM:
     835                report_item->string_maximum =
     836                        usb_hid_report_tag_data_uint32(data,item_size);
     837                break;                 
     838
     839        case USB_HID_REPORT_TAG_DELIMITER:
     840                report_item->in_delimiter =
     841                        usb_hid_report_tag_data_uint32(data,item_size);
     842                break;
     843
     844        default:
     845                return USB_HID_NO_ACTION;
    611846        }
    612847
    613848        return EOK;
    614849}
     850/*---------------------------------------------------------------------------*/
    615851
    616852/**
     
    633869        return result;
    634870}
     871/*---------------------------------------------------------------------------*/
    635872
    636873/**
     
    653890        for(item = head->next; item != head; item = item->next) {
    654891               
    655                 report_item = list_get_instance(item, usb_hid_report_field_t, link);
     892                report_item = list_get_instance(item, usb_hid_report_field_t,
     893                                link);
    656894
    657895                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);
     896                usb_log_debug("\t\tSIZE: %zu\n", report_item->size);
     897                usb_log_debug("\t\tLOGMIN: %d\n",
     898                        report_item->logical_minimum);
     899                usb_log_debug("\t\tLOGMAX: %d\n",
     900                        report_item->logical_maximum);         
     901                usb_log_debug("\t\tPHYMIN: %d\n",
     902                        report_item->physical_minimum);         
     903                usb_log_debug("\t\tPHYMAX: %d\n",
     904                        report_item->physical_maximum);                         
     905                usb_log_debug("\t\ttUSAGEMIN: %X\n",
     906                        report_item->usage_minimum);
     907                usb_log_debug("\t\tUSAGEMAX: %X\n",
     908                               report_item->usage_maximum);
     909                usb_log_debug("\t\tUSAGES COUNT: %zu\n",
     910                        report_item->usages_count);
    665911
    666912                usb_log_debug("\t\tVALUE: %X\n", report_item->value);
     
    668914                usb_log_debug("\t\tUSAGE PAGE: %X\n", report_item->usage_page);
    669915               
    670                 //usb_hid_print_usage_path(report_item->collection_path);
     916                usb_hid_print_usage_path(report_item->collection_path);
    671917
    672918                usb_log_debug("\n");           
     
    674920        }
    675921
    676 
    677 }
     922}
     923/*---------------------------------------------------------------------------*/
     924
    678925/**
    679926 * Prints content of given report descriptor in human readable format.
     
    692939
    693940        while(report_it != &report->reports) {
    694                 report_des = list_get_instance(report_it, usb_hid_report_description_t, link);
     941                report_des = list_get_instance(report_it,
     942                        usb_hid_report_description_t, link);
    695943                usb_log_debug("Report ID: %d\n", report_des->report_id);
    696944                usb_log_debug("\tType: %d\n", report_des->type);
    697945                usb_log_debug("\tLength: %zu\n", report_des->bit_length);               
     946                usb_log_debug("\tB Size: %zu\n",
     947                        usb_hid_report_byte_size(report,
     948                                report_des->report_id,
     949                                report_des->type));
    698950                usb_log_debug("\tItems: %zu\n", report_des->item_length);               
    699951
    700952                usb_hid_descriptor_print_list(&report_des->report_items);
    701953
    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                
    709954                report_it = report_it->next;
    710955        }
    711956}
     957/*---------------------------------------------------------------------------*/
    712958
    713959/**
     
    734980
    735981                while(!list_empty(&report_item->usage_path->link)) {
    736                         usb_hid_report_remove_last_item(report_item->usage_path);
     982                    usb_hid_report_remove_last_item(report_item->usage_path);
    737983                }
    738984
     
    746992       
    747993}
     994/*---------------------------------------------------------------------------*/
    748995
    749996/** Frees the HID report descriptor parser structure
     
    7611008        usb_hid_report_path_t *path;
    7621009        while(!list_empty(&report->collection_paths)) {
    763                 path = list_get_instance(report->collection_paths.next, usb_hid_report_path_t, link);
     1010                path = list_get_instance(report->collection_paths.next,
     1011                                usb_hid_report_path_t, link);
     1012
    7641013                usb_hid_report_path_free(path);         
    7651014        }
     
    7691018        usb_hid_report_field_t *field;
    7701019        while(!list_empty(&report->reports)) {
    771                 report_des = list_get_instance(report->reports.next, usb_hid_report_description_t, link);
     1020                report_des = list_get_instance(report->reports.next,
     1021                                usb_hid_report_description_t, link);
     1022
    7721023                list_remove(&report_des->link);
    7731024               
    7741025                while(!list_empty(&report_des->report_items)) {
    775                         field = list_get_instance(report_des->report_items.next, usb_hid_report_field_t, link);
     1026                        field = list_get_instance(
     1027                                report_des->report_items.next,
     1028                                usb_hid_report_field_t, link);
     1029
    7761030                        list_remove(&field->link);
    7771031
     
    7841038        return;
    7851039}
     1040/*---------------------------------------------------------------------------*/
    7861041
    7871042/**
Note: See TracChangeset for help on using the changeset viewer.