Ignore:
File:
1 edited

Legend:

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

    rd861c22 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;
     
    288209        }
    289210
    290         // free only when not used!!!
    291         if(usages && usages_used == 0) {
    292                 free(usages);
    293         }
    294211
    295212        return EOK;
    296213}
    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  */
    308 usb_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 
     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{
    312217        link_t *report_it = report->reports.next;
    313218        usb_hid_report_description_t *report_des = NULL;
    314219       
    315220        while(report_it != &report->reports) {
    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)) {
     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)){
    321224                        return report_des;
    322225                }
     
    327230        return NULL;
    328231}
    329 /*---------------------------------------------------------------------------*/
    330232
    331233/** Parse HID report descriptor.
     
    334236 * @param data Data describing the report.
    335237 * @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
    339238 */
    340239int usb_hid_parse_report_descriptor(usb_hid_report_t *report,
     
    387286                       
    388287                        ret = usb_hid_report_parse_tag(tag,class,data+i+1,
    389                                 item_size,report_item, usage_path);
    390 
     288                                                       item_size,report_item, usage_path);
    391289                        switch(ret){
    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;
     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;
    397294                                       
    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                                 }
     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                                        }
    404299                                       
    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;
     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
    413331                                        break;
    414        
    415                                 case USB_HID_REPORT_TAG_OUTPUT:
    416                                         report_item->type =
    417                                             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);
    418356                                       
    419                                         report_item->offset = offset_output;
    420                                         offset_output += report_item->count *
    421                                             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                                       
    422367                                        break;
    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;
     368                                       
     369                                default:
     370                                        // nothing special to do                                       
    431371                                        break;
    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);
    475                                                
    476                                 report_item = list_get_instance(stack.next,
    477                                     usb_hid_report_item_t, link);
    478                                        
    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);
    483                                        
    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);
    493                                        
    494                                 break;
    495                                        
    496                         default:
    497                                 // nothing special to do                                       
    498                                 break;
    499372                        }
    500373
     
    513386}
    514387
    515 /*---------------------------------------------------------------------------*/
    516388
    517389/**
     
    524396 * @return Code of action to be done next
    525397 */
    526 int 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        
     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{       
    530401        int ret;
    531402       
    532403        switch(class){
    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;
     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;
    557424        }
    558425}
     
    568435 */
    569436
    570 int 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)
     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)
    573439{
    574440        usb_hid_report_usage_path_t *path_item;
     
    576442        switch(tag)
    577443        {
    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;
     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;
    584450                       
    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;       
     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;       
    591455                       
    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]));
     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]);
    602459                       
    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;
     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;
    612466                       
    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;
     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;
    620473        }
    621474
     
    632485 * @return Error code
    633486 */
    634 int 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        
     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
    638491        switch(tag)
    639492        {
    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;
     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;
    703533                       
    704         default:
    705                 return USB_HID_NO_ACTION;
     534                default:
     535                        return USB_HID_NO_ACTION;
    706536        }
    707537
     
    718548 * @return Error code
    719549 */
    720 int 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)
    723 {
    724         int32_t extended_usage;
    725        
     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{
    726553        switch(tag) {
    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;
    775                         }
    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;
    799                         }
    800                         else {                 
    801                             report_item->usages[report_item->usages_count++] =
    802                                 (report_item->usage_page << 16) + i;
    803                         }
    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;
     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;
    846611        }
    847612
    848613        return EOK;
    849614}
    850 /*---------------------------------------------------------------------------*/
    851615
    852616/**
     
    869633        return result;
    870634}
    871 /*---------------------------------------------------------------------------*/
    872635
    873636/**
     
    890653        for(item = head->next; item != head; item = item->next) {
    891654               
    892                 report_item = list_get_instance(item, usb_hid_report_field_t,
    893                                 link);
     655                report_item = list_get_instance(item, usb_hid_report_field_t, link);
    894656
    895657                usb_log_debug("\t\tOFFSET: %X\n", report_item->offset);
    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);
     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);
    911665
    912666                usb_log_debug("\t\tVALUE: %X\n", report_item->value);
     
    914668                usb_log_debug("\t\tUSAGE PAGE: %X\n", report_item->usage_page);
    915669               
    916                 usb_hid_print_usage_path(report_item->collection_path);
     670                //usb_hid_print_usage_path(report_item->collection_path);
    917671
    918672                usb_log_debug("\n");           
     
    920674        }
    921675
    922 }
    923 /*---------------------------------------------------------------------------*/
    924 
     676
     677}
    925678/**
    926679 * Prints content of given report descriptor in human readable format.
     
    939692
    940693        while(report_it != &report->reports) {
    941                 report_des = list_get_instance(report_it,
    942                         usb_hid_report_description_t, link);
     694                report_des = list_get_instance(report_it, usb_hid_report_description_t, link);
    943695                usb_log_debug("Report ID: %d\n", report_des->report_id);
    944696                usb_log_debug("\tType: %d\n", report_des->type);
    945697                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));
    950698                usb_log_debug("\tItems: %zu\n", report_des->item_length);               
    951699
    952700                usb_hid_descriptor_print_list(&report_des->report_items);
    953701
     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               
    954709                report_it = report_it->next;
    955710        }
    956711}
    957 /*---------------------------------------------------------------------------*/
    958712
    959713/**
     
    980734
    981735                while(!list_empty(&report_item->usage_path->link)) {
    982                     usb_hid_report_remove_last_item(report_item->usage_path);
     736                        usb_hid_report_remove_last_item(report_item->usage_path);
    983737                }
    984738
     
    992746       
    993747}
    994 /*---------------------------------------------------------------------------*/
    995748
    996749/** Frees the HID report descriptor parser structure
     
    1008761        usb_hid_report_path_t *path;
    1009762        while(!list_empty(&report->collection_paths)) {
    1010                 path = list_get_instance(report->collection_paths.next,
    1011                                 usb_hid_report_path_t, link);
    1012 
     763                path = list_get_instance(report->collection_paths.next, usb_hid_report_path_t, link);
    1013764                usb_hid_report_path_free(path);         
    1014765        }
     
    1018769        usb_hid_report_field_t *field;
    1019770        while(!list_empty(&report->reports)) {
    1020                 report_des = list_get_instance(report->reports.next,
    1021                                 usb_hid_report_description_t, link);
    1022 
     771                report_des = list_get_instance(report->reports.next, usb_hid_report_description_t, link);
    1023772                list_remove(&report_des->link);
    1024773               
    1025774                while(!list_empty(&report_des->report_items)) {
    1026                         field = list_get_instance(
    1027                                 report_des->report_items.next,
    1028                                 usb_hid_report_field_t, link);
    1029 
     775                        field = list_get_instance(report_des->report_items.next, usb_hid_report_field_t, link);
    1030776                        list_remove(&field->link);
    1031777
     
    1038784        return;
    1039785}
    1040 /*---------------------------------------------------------------------------*/
    1041786
    1042787/**
Note: See TracChangeset for help on using the changeset viewer.