Ignore:
File:
1 edited

Legend:

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

    r1432fcf3 r160b75e  
    4141#include <assert.h>
    4242
    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  */
     43
    5144#define OUTSIDE_DELIMITER_SET   0
    52 
    53 /**
    54  * First delimiter tag was read. The set of local items (usage) started.
    55  */
    5645#define START_DELIMITER_SET     1
    57 
    58 /**
    59  * Parser is in the set of local items.
    60  */
    6146#define INSIDE_DELIMITER_SET    2
    62 
    63 /*---------------------------------------------------------------------------*/
    6447       
    6548/** The new report item flag. Used to determine when the item is completly
     
    7861#define USB_HID_UNKNOWN_TAG             -99
    7962
    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  */
    90 usb_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;
     63usb_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;
    9467        usb_hid_report_path_t *path = NULL;
    95        
    96         if((report == NULL) || (cmp_path == NULL)) {
    97                 return NULL;
    98         }
    99        
    10068        while(path_it != &report->collection_paths) {
    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){
     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){
    10672                        break;
    10773                }                       
     
    10975        }
    11076        if(path_it == &report->collection_paths) {
    111                 path = usb_hid_report_path_clone(cmp_path);
    112                 if(path == NULL) {
    113                         return NULL;
    114                 }
     77                path = usb_hid_report_path_clone(cmp_path);                     
    11578                list_append(&path->link, &report->collection_paths);                                   
    11679                report->collection_paths_count++;
     
    11982        }
    12083        else {
    121                 return list_get_instance(path_it, usb_hid_report_path_t,
    122                                 link);
    123         }
    124 }
    125 
    126 /*---------------------------------------------------------------------------*/
     84                return list_get_instance(path_it, usb_hid_report_path_t, link);
     85        }
     86}
     87
    12788/**
    12889 * Initialize the report descriptor parser structure
     
    13091 * @param parser Report descriptor parser structure
    13192 * @return Error code
    132  * @retval EINVAL If no report structure was given
    133  * @retval EOK If report structure was successfully initialized
    13493 */
    13594int usb_hid_report_init(usb_hid_report_t *report)
     
    147106}
    148107
    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  */
    163 int usb_hid_report_append_fields(usb_hid_report_t *report,
    164                 usb_hid_report_item_t *report_item) {
    165 
     108
     109/*
     110 *
     111 *
     112 */
     113int usb_hid_report_append_fields(usb_hid_report_t *report, usb_hid_report_item_t *report_item)
     114{
    166115        usb_hid_report_field_t *field;
    167116        int i;
    168117
    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        
     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
    185122        usb_hid_report_path_t *path = report_item->usage_path; 
    186123        for(i=0; i<report_item->count; i++){
     
    196133                field->physical_maximum = report_item->physical_maximum;
    197134
    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;
     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;
    209139                }
    210140                else {
    211 
    212                         /* Fill the correct Usage and Usage Page */
    213                         int32_t usage;
    214                         if(i < report_item->usages_count) {
     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){
    215147                                usage = report_item->usages[i];
    216148                        }
    217149                        else {
    218                                 usage = report_item->usages[
    219                                         report_item->usages_count- 1];
    220                         }
    221 
    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);
     150                                usage = report_item->usages[report_item->usages_count - 1];
     151                        }
     152
     153                                               
     154                        if((usage & 0xFFFF0000) != 0){
     155                                field->usage_page = (usage >> 16);                                     
     156                                field->usage = (usage & 0xFFFF);
    226157                        }
    227158                        else {
    228                                 // should not occur
    229159                                field->usage = usage;
    230                                 field->usage_page = report_item->usage_page;
    231                         }
    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);
     160                        }
     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);
    241173
    242174                field->size = report_item->size;
    243175               
    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;
     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;
    249178
    250179                field->offset = 8 * offset_byte + offset_bit;
     
    257186                /* find the right report list*/
    258187                usb_hid_report_description_t *report_des;
    259                 report_des = usb_hid_report_find_description(report,
    260                         report_item->id, report_item->type);
    261                
     188                report_des = usb_hid_report_find_description(report, report_item->id, report_item->type);
    262189                if(report_des == NULL){
    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));
     190                        report_des = malloc(sizeof(usb_hid_report_description_t));
     191                        memset(report_des, 0, sizeof(usb_hid_report_description_t));
    271192
    272193                        report_des->type = report_item->type;
    273194                        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 
    279195                        list_initialize (&report_des->link);
    280196                        list_initialize (&report_des->report_items);
     
    293209        }
    294210
    295         // free only when not used!!!
    296         if(usages && usages_used == 0) {
    297                 free(usages);
    298         }
    299211
    300212        return EOK;
    301213}
    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  */
    313 usb_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 
     214
     215usb_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{
    317217        link_t *report_it = report->reports.next;
    318218        usb_hid_report_description_t *report_des = NULL;
    319219       
    320220        while(report_it != &report->reports) {
    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)) {
     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)){
    326224                        return report_des;
    327225                }
     
    332230        return NULL;
    333231}
    334 /*---------------------------------------------------------------------------*/
    335232
    336233/** Parse HID report descriptor.
     
    339236 * @param data Data describing the report.
    340237 * @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
    344238 */
    345239int usb_hid_parse_report_descriptor(usb_hid_report_t *report,
     
    392286                       
    393287                        ret = usb_hid_report_parse_tag(tag,class,data+i+1,
    394                                 item_size,report_item, usage_path);
    395 
     288                                                       item_size,report_item, usage_path);
    396289                        switch(ret){
    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;
     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;
    402294                                       
    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                                 }
     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                                        }
    409299                                       
    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;
     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                                        }
     321                                       
     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
    418331                                        break;
    419        
    420                                 case USB_HID_REPORT_TAG_OUTPUT:
    421                                         report_item->type =
    422                                             USB_HID_REPORT_TYPE_OUTPUT;
     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);
     338                                        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);
     354                                               
     355                                        report_item = list_get_instance(stack.next, usb_hid_report_item_t, link);
    423356                                       
    424                                         report_item->offset = offset_output;
    425                                         offset_output += report_item->count *
    426                                             report_item->size;
     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);
     359                                       
     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);
     366                                       
    427367                                        break;
    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;
     368                                       
     369                                default:
     370                                        // nothing special to do                                       
    436371                                        break;
    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);
    480                                                
    481                                 report_item = list_get_instance(stack.next,
    482                                     usb_hid_report_item_t, link);
    483                                        
    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);
    488                                        
    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);
    498                                        
    499                                 break;
    500                                        
    501                         default:
    502                                 // nothing special to do                                       
    503                                 break;
    504372                        }
    505373
     
    518386}
    519387
    520 /*---------------------------------------------------------------------------*/
    521388
    522389/**
     
    529396 * @return Code of action to be done next
    530397 */
    531 int 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        
     398int 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{       
    535401        int ret;
    536402       
    537403        switch(class){
    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;
     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;
    562424        }
    563425}
     
    573435 */
    574436
    575 int 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)
     437int 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)
    578439{
    579440        usb_hid_report_usage_path_t *path_item;
     
    581442        switch(tag)
    582443        {
    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;
     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;
    589450                       
    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;       
     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;       
    596455                       
    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]));
     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]);
    607459                       
    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;
     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;
    617466                       
    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;
     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;
    625473        }
    626474
     
    637485 * @return Error code
    638486 */
    639 int 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        
     487int 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
    643491        switch(tag)
    644492        {
    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;
     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;
    708533                       
    709         default:
    710                 return USB_HID_NO_ACTION;
     534                default:
     535                        return USB_HID_NO_ACTION;
    711536        }
    712537
     
    723548 * @return Error code
    724549 */
    725 int 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)
    728 {
    729         int32_t extended_usage;
    730        
     550int 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)
     552{
    731553        switch(tag) {
    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;
    780                         }
    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;
    804                         }
    805                         else {                 
    806                             report_item->usages[report_item->usages_count++] =
    807                                 (report_item->usage_page << 16) + i;
    808                         }
    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;
     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;
     565                        }
     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;
     572                        }
     573                        else {
     574                                report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size);
     575                        }
     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;
    851611        }
    852612
    853613        return EOK;
    854614}
    855 /*---------------------------------------------------------------------------*/
    856615
    857616/**
     
    874633        return result;
    875634}
    876 /*---------------------------------------------------------------------------*/
    877635
    878636/**
     
    895653        for(item = head->next; item != head; item = item->next) {
    896654               
    897                 report_item = list_get_instance(item, usb_hid_report_field_t,
    898                                 link);
     655                report_item = list_get_instance(item, usb_hid_report_field_t, link);
    899656
    900657                usb_log_debug("\t\tOFFSET: %X\n", report_item->offset);
    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);
     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);
    916665
    917666                usb_log_debug("\t\tVALUE: %X\n", report_item->value);
     
    919668                usb_log_debug("\t\tUSAGE PAGE: %X\n", report_item->usage_page);
    920669               
    921                 usb_hid_print_usage_path(report_item->collection_path);
     670                //usb_hid_print_usage_path(report_item->collection_path);
    922671
    923672                usb_log_debug("\n");           
     
    925674        }
    926675
    927 }
    928 /*---------------------------------------------------------------------------*/
    929 
     676
     677}
    930678/**
    931679 * Prints content of given report descriptor in human readable format.
     
    944692
    945693        while(report_it != &report->reports) {
    946                 report_des = list_get_instance(report_it,
    947                         usb_hid_report_description_t, link);
     694                report_des = list_get_instance(report_it, usb_hid_report_description_t, link);
    948695                usb_log_debug("Report ID: %d\n", report_des->report_id);
    949696                usb_log_debug("\tType: %d\n", report_des->type);
    950697                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));
    955698                usb_log_debug("\tItems: %zu\n", report_des->item_length);               
    956699
    957700                usb_hid_descriptor_print_list(&report_des->report_items);
    958701
     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               
    959709                report_it = report_it->next;
    960710        }
    961711}
    962 /*---------------------------------------------------------------------------*/
    963712
    964713/**
     
    985734
    986735                while(!list_empty(&report_item->usage_path->link)) {
    987                     usb_hid_report_remove_last_item(report_item->usage_path);
     736                        usb_hid_report_remove_last_item(report_item->usage_path);
    988737                }
    989738
     
    997746       
    998747}
    999 /*---------------------------------------------------------------------------*/
    1000748
    1001749/** Frees the HID report descriptor parser structure
     
    1013761        usb_hid_report_path_t *path;
    1014762        while(!list_empty(&report->collection_paths)) {
    1015                 path = list_get_instance(report->collection_paths.next,
    1016                                 usb_hid_report_path_t, link);
    1017 
     763                path = list_get_instance(report->collection_paths.next, usb_hid_report_path_t, link);
    1018764                usb_hid_report_path_free(path);         
    1019765        }
     
    1023769        usb_hid_report_field_t *field;
    1024770        while(!list_empty(&report->reports)) {
    1025                 report_des = list_get_instance(report->reports.next,
    1026                                 usb_hid_report_description_t, link);
    1027 
     771                report_des = list_get_instance(report->reports.next, usb_hid_report_description_t, link);
    1028772                list_remove(&report_des->link);
    1029773               
    1030774                while(!list_empty(&report_des->report_items)) {
    1031                         field = list_get_instance(
    1032                                 report_des->report_items.next,
    1033                                 usb_hid_report_field_t, link);
    1034 
     775                        field = list_get_instance(report_des->report_items.next, usb_hid_report_field_t, link);
    1035776                        list_remove(&field->link);
    1036777
     
    1043784        return;
    1044785}
    1045 /*---------------------------------------------------------------------------*/
    1046786
    1047787/**
Note: See TracChangeset for help on using the changeset viewer.