Ignore:
Timestamp:
2011-05-27T12:14:02Z (14 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
2df648c2
Parents:
fb2de0a (diff), 74341ed (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Development branch changes

File:
1 edited

Legend:

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

    rfb2de0a rd208f3f  
    4141#include <assert.h>
    4242
    43 
     43/*---------------------------------------------------------------------------*/
     44/*
     45 * Constants defining current parsing mode for correct parsing of the set of
     46 * local tags (usage) enclosed in delimter tags.
     47 */
     48/**
     49 * Second delimiter tag was read. The set of local items (usage) ended.
     50 */
    4451#define OUTSIDE_DELIMITER_SET   0
     52
     53/**
     54 * First delimiter tag was read. The set of local items (usage) started.
     55 */
    4556#define START_DELIMITER_SET     1
     57
     58/**
     59 * Parser is in the set of local items.
     60 */
    4661#define INSIDE_DELIMITER_SET    2
     62
     63/*---------------------------------------------------------------------------*/
    4764       
    4865/** The new report item flag. Used to determine when the item is completly
     
    6178#define USB_HID_UNKNOWN_TAG             -99
    6279
    63 usb_hid_report_path_t *usb_hid_report_path_try_insert(usb_hid_report_t *report, usb_hid_report_path_t *cmp_path)
    64 {
    65         /* find or append current collection path to the list */
    66         //link_t *path_it = report->collection_paths.next;
     80/*---------------------------------------------------------------------------*/
     81/**
     82 * Checks if given collection path is already present in report structure and
     83 * inserts it if not.
     84 *
     85 * @param report Report structure
     86 * @param cmp_path The collection path
     87 * @return Pointer to the result collection path in report structure.
     88 * @retval NULL If some error occurs
     89 */
     90usb_hid_report_path_t *usb_hid_report_path_try_insert(
     91                usb_hid_report_t *report, usb_hid_report_path_t *cmp_path) {
     92       
    6793        link_t *path_it = report->collection_paths.prev->next;
    6894        usb_hid_report_path_t *path = NULL;
    6995       
     96        if((report == NULL) || (cmp_path == NULL)) {
     97                return NULL;
     98        }
    7099       
    71100        while(path_it != &report->collection_paths) {
    72                 path = list_get_instance(path_it, usb_hid_report_path_t, link);
    73                
    74                 if(usb_hid_report_compare_usage_path(path, cmp_path, USB_HID_PATH_COMPARE_STRICT) == EOK){
     101                path = list_get_instance(path_it, usb_hid_report_path_t,
     102                                link);
     103               
     104                if(usb_hid_report_compare_usage_path(path, cmp_path,
     105                                        USB_HID_PATH_COMPARE_STRICT) == EOK){
    75106                        break;
    76107                }                       
     
    78109        }
    79110        if(path_it == &report->collection_paths) {
    80                 path = usb_hid_report_path_clone(cmp_path);                     
     111                path = usb_hid_report_path_clone(cmp_path);
     112                if(path == NULL) {
     113                        return NULL;
     114                }
    81115                list_append(&path->link, &report->collection_paths);                                   
    82116                report->collection_paths_count++;
     
    85119        }
    86120        else {
    87                 return list_get_instance(path_it, usb_hid_report_path_t, link);
    88         }
    89 }
    90 
     121                return list_get_instance(path_it, usb_hid_report_path_t,
     122                                link);
     123        }
     124}
     125
     126/*---------------------------------------------------------------------------*/
    91127/**
    92128 * Initialize the report descriptor parser structure
     
    94130 * @param parser Report descriptor parser structure
    95131 * @return Error code
     132 * @retval EINVAL If no report structure was given
     133 * @retval EOK If report structure was successfully initialized
    96134 */
    97135int usb_hid_report_init(usb_hid_report_t *report)
     
    109147}
    110148
    111 
    112 /*
    113  *
    114  *
    115  */
    116 int usb_hid_report_append_fields(usb_hid_report_t *report, usb_hid_report_item_t *report_item)
    117 {
     149/*---------------------------------------------------------------------------*/
     150
     151/**
     152 *
     153 *
     154 * @param report Report structure in which the new report items should be
     155 *               stored
     156 * @param report_item Current report descriptor's parsing state table
     157 * @return Error code
     158 * @retval EOK If all fields were successfully append to report
     159 * @retval EINVAL If invalid parameters (NULL) was given
     160 * @retval ENOMEM If there is no memmory to store new report description
     161 *
     162 */
     163int usb_hid_report_append_fields(usb_hid_report_t *report,
     164                usb_hid_report_item_t *report_item) {
     165
    118166        usb_hid_report_field_t *field;
    119167        int i;
     
    121169        uint32_t *usages;
    122170        int usages_used=0;
     171
     172        if((report == NULL) || (report_item == NULL)) {
     173                return EINVAL;
     174        }
     175
    123176        if(report_item->usages_count > 0){
    124177                usages = malloc(sizeof(int32_t) * report_item->usages_count);
    125                 memcpy(usages, report_item->usages, sizeof(int32_t) * report_item->usages_count);
     178                memcpy(usages, report_item->usages, sizeof(int32_t) *
     179                                report_item->usages_count);
    126180        }
    127181        else {
     
    144198                if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0){
    145199                        /*
    146                                 Store usage array. The Correct Usage Page and Usage is depending
    147                                 on data in report and will be filled later
     200                        Store usage array. The Correct Usage Page and Usage is
     201                        depending on data in report and will be filled later
    148202                        */
    149203                        field->usage = 0;
     
    162216                        }
    163217                        else {
    164                                 usage = report_item->usages[report_item->usages_count - 1];
     218                                usage = report_item->usages[
     219                                        report_item->usages_count- 1];
    165220                        }
    166221
    167222                        if(USB_HID_IS_EXTENDED_USAGE(usage)){
    168223                                field->usage = USB_HID_EXTENDED_USAGE(usage);
    169                                 field->usage_page = USB_HID_EXTENDED_USAGE_PAGE(usage);
     224                                field->usage_page =
     225                                        USB_HID_EXTENDED_USAGE_PAGE(usage);
    170226                        }
    171227                        else {
     
    176232                }
    177233               
    178                 usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_GLOBAL, field->usage_page);
    179                 usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_LOCAL, field->usage);
    180 
    181                 field->collection_path = usb_hid_report_path_try_insert(report, path);
     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);
    182241
    183242                field->size = report_item->size;
    184243               
    185                 size_t offset_byte = (report_item->offset + (i * report_item->size)) / 8;
    186                 size_t offset_bit = 8 - ((report_item->offset + (i * report_item->size)) % 8) - report_item->size;
     244                size_t offset_byte = (report_item->offset + (i *
     245                        report_item->size)) / 8;
     246
     247                size_t offset_bit = 8 - ((report_item->offset + (i *
     248                        report_item->size)) % 8) - report_item->size;
    187249
    188250                field->offset = 8 * offset_byte + offset_bit;
     
    195257                /* find the right report list*/
    196258                usb_hid_report_description_t *report_des;
    197                 report_des = usb_hid_report_find_description(report, report_item->id, report_item->type);
     259                report_des = usb_hid_report_find_description(report,
     260                        report_item->id, report_item->type);
     261               
    198262                if(report_des == NULL){
    199                         report_des = malloc(sizeof(usb_hid_report_description_t));
    200                         memset(report_des, 0, sizeof(usb_hid_report_description_t));
     263                        report_des = malloc(
     264                                sizeof(usb_hid_report_description_t));
     265                        if(report_des == NULL) {
     266                                return ENOMEM;
     267                        }
     268
     269                        memset(report_des, 0,
     270                                sizeof(usb_hid_report_description_t));
    201271
    202272                        report_des->type = report_item->type;
    203273                        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
    204279                        list_initialize (&report_des->link);
    205280                        list_initialize (&report_des->report_items);
     
    225300        return EOK;
    226301}
    227 
    228 usb_hid_report_description_t * usb_hid_report_find_description(const usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type)
    229 {
     302/*---------------------------------------------------------------------------*/
     303/**
     304 * Finds description of report with given report_id and of given type in
     305 * opaque report structure.
     306 *
     307 * @param report Opaque structure containing the parsed report descriptor
     308 * @param report_id ReportId of report we are searching
     309 * @param type Type of report we are searching
     310 * @return Pointer to the particular report description
     311 * @retval NULL If no description is founded
     312 */
     313usb_hid_report_description_t * usb_hid_report_find_description(
     314                const usb_hid_report_t *report, uint8_t report_id,
     315                usb_hid_report_type_t type) {
     316
    230317        link_t *report_it = report->reports.next;
    231318        usb_hid_report_description_t *report_des = NULL;
    232319       
    233320        while(report_it != &report->reports) {
    234                 report_des = list_get_instance(report_it, usb_hid_report_description_t, link);
    235 
    236                 if((report_des->report_id == report_id) && (report_des->type == type)){
     321                report_des = list_get_instance(report_it,
     322                                usb_hid_report_description_t, link);
     323
     324                if((report_des->report_id == report_id) &&
     325                   (report_des->type == type)) {
    237326                        return report_des;
    238327                }
     
    243332        return NULL;
    244333}
     334/*---------------------------------------------------------------------------*/
    245335
    246336/** Parse HID report descriptor.
     
    249339 * @param data Data describing the report.
    250340 * @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
    251344 */
    252345int usb_hid_parse_report_descriptor(usb_hid_report_t *report,
     
    299392                       
    300393                        ret = usb_hid_report_parse_tag(tag,class,data+i+1,
    301                                                        item_size,report_item, usage_path);
     394                                item_size,report_item, usage_path);
     395
    302396                        switch(ret){
    303                                 case USB_HID_NEW_REPORT_ITEM:
    304                                         // store report item to report and create the new one
    305                                         // store current collection path
    306                                         report_item->usage_path = usage_path;
     397                        case USB_HID_NEW_REPORT_ITEM:
     398                                /* store report item to report and create the
     399                                 * new one store current collection path
     400                                 */
     401                                report_item->usage_path = usage_path;
    307402                                       
    308                                         usb_hid_report_path_set_report_id(report_item->usage_path, report_item->id);   
    309                                         if(report_item->id != 0){
    310                                                 report->use_report_ids = 1;
    311                                         }
     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                                }
    312409                                       
    313                                         switch(tag) {
    314                                                 case USB_HID_REPORT_TAG_INPUT:
    315                                                         report_item->type = USB_HID_REPORT_TYPE_INPUT;
    316                                                         report_item->offset = offset_input;
    317                                                         offset_input += report_item->count * report_item->size;
    318                                                         break;
    319                                                 case USB_HID_REPORT_TAG_OUTPUT:
    320                                                         report_item->type = USB_HID_REPORT_TYPE_OUTPUT;
    321                                                         report_item->offset = offset_output;
    322                                                         offset_output += report_item->count * report_item->size;
    323 
    324                                                         break;
    325                                                 case USB_HID_REPORT_TAG_FEATURE:
    326                                                         report_item->type = USB_HID_REPORT_TYPE_FEATURE;
    327                                                         report_item->offset = offset_feature;
    328                                                         offset_feature += report_item->count * report_item->size;
    329                                                         break;
    330                                                 default:
    331                                                     usb_log_debug("\tjump over - tag %X\n", tag);
    332                                                     break;
    333                                         }
     410                                switch(tag) {
     411                                case USB_HID_REPORT_TAG_INPUT:
     412                                        report_item->type =
     413                                            USB_HID_REPORT_TYPE_INPUT;
     414
     415                                        report_item->offset = offset_input;
     416                                        offset_input += report_item->count *
     417                                            report_item->size;
     418                                        break;
     419       
     420                                case USB_HID_REPORT_TAG_OUTPUT:
     421                                        report_item->type =
     422                                            USB_HID_REPORT_TYPE_OUTPUT;
    334423                                       
    335                                         /*
    336                                          * append new fields to the report
    337                                          * structure                                     
    338                                          */
    339                                         usb_hid_report_append_fields(report, report_item);
    340 
    341                                         /* reset local items */
    342                                         usb_hid_report_reset_local_items (report_item);
    343 
     424                                        report_item->offset = offset_output;
     425                                        offset_output += report_item->count *
     426                                            report_item->size;
    344427                                        break;
    345 
    346                                 case USB_HID_RESET_OFFSET:
    347                                         offset_input = 0;
    348                                         offset_output = 0;
    349                                         offset_feature = 0;
    350                                         usb_hid_report_path_set_report_id (usage_path, report_item->id);
     428       
     429                                case USB_HID_REPORT_TAG_FEATURE:
     430                                        report_item->type =
     431                                            USB_HID_REPORT_TYPE_FEATURE;
     432
     433                                        report_item->offset = offset_feature;
     434                                        offset_feature += report_item->count *
     435                                                report_item->size;
    351436                                        break;
    352 
    353                                 case USB_HID_REPORT_TAG_PUSH:
    354                                         // push current state to stack
    355                                         new_report_item = usb_hid_report_item_clone(report_item);
    356                                         usb_hid_report_path_t *tmp_path = usb_hid_report_path_clone(usage_path);
    357                                         new_report_item->usage_path = tmp_path;
    358 
    359                                         list_prepend (&new_report_item->link, &stack);
    360                                         break;
    361                                 case USB_HID_REPORT_TAG_POP:
    362                                         // restore current state from stack
    363                                         if(list_empty (&stack)) {
    364                                                 return EINVAL;
    365                                         }
    366                                         free(report_item);
     437       
     438                                default:
     439                                        usb_log_debug2(
     440                                            "\tjump over - tag %X\n", tag);
     441                                        break;
     442                                }
     443                                       
     444                                /*
     445                                 * append new fields to the report structure                                     
     446                                 */
     447                                usb_hid_report_append_fields(report,
     448                                    report_item);
     449
     450                                /* reset local items */
     451                                usb_hid_report_reset_local_items (report_item);
     452                                break;
     453
     454                        case USB_HID_RESET_OFFSET:
     455                                offset_input = 0;
     456                                offset_output = 0;
     457                                offset_feature = 0;
     458                                usb_hid_report_path_set_report_id (usage_path,
     459                                    report_item->id);
     460                                break;
     461
     462                        case USB_HID_REPORT_TAG_PUSH:
     463                                // push current state to stack
     464                                new_report_item = usb_hid_report_item_clone(
     465                                    report_item);
     466                               
     467                                usb_hid_report_path_t *tmp_path =
     468                                    usb_hid_report_path_clone(usage_path);
     469
     470                                new_report_item->usage_path = tmp_path;
     471
     472                                list_prepend (&new_report_item->link, &stack);
     473                                break;
     474                        case USB_HID_REPORT_TAG_POP:
     475                                // restore current state from stack
     476                                if(list_empty (&stack)) {
     477                                        return EINVAL;
     478                                }
     479                                free(report_item);
    367480                                               
    368                                         report_item = list_get_instance(stack.next, usb_hid_report_item_t, link);
     481                                report_item = list_get_instance(stack.next,
     482                                    usb_hid_report_item_t, link);
    369483                                       
    370                                         usb_hid_report_usage_path_t *tmp_usage_path;
    371                                         tmp_usage_path = list_get_instance(report_item->usage_path->link.prev, usb_hid_report_usage_path_t, link);
     484                                usb_hid_report_usage_path_t *tmp_usage_path;
     485                                tmp_usage_path = list_get_instance(
     486                                    report_item->usage_path->link.prev,
     487                                    usb_hid_report_usage_path_t, link);
    372488                                       
    373                                         usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL, tmp_usage_path->usage_page);
    374                                         usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL, tmp_usage_path->usage);
    375 
    376                                         usb_hid_report_path_free(report_item->usage_path);
    377                                         list_initialize(&report_item->usage_path->link);
    378                                         list_remove (stack.next);
     489                                usb_hid_report_set_last_item(usage_path,
     490                                    USB_HID_TAG_CLASS_GLOBAL, tmp_usage_path->usage_page);
     491                               
     492                                usb_hid_report_set_last_item(usage_path,
     493                                    USB_HID_TAG_CLASS_LOCAL, tmp_usage_path->usage);
     494
     495                                usb_hid_report_path_free(report_item->usage_path);
     496                                list_initialize(&report_item->usage_path->link);
     497                                list_remove (stack.next);
    379498                                       
    380                                         break;
     499                                break;
    381500                                       
    382                                 default:
    383                                         // nothing special to do                                       
    384                                         break;
     501                        default:
     502                                // nothing special to do                                       
     503                                break;
    385504                        }
    386505
     
    399518}
    400519
     520/*---------------------------------------------------------------------------*/
    401521
    402522/**
     
    409529 * @return Code of action to be done next
    410530 */
    411 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size,
    412                              usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
    413 {       
     531int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data,
     532        size_t item_size, usb_hid_report_item_t *report_item,
     533        usb_hid_report_path_t *usage_path) {   
     534       
    414535        int ret;
    415536       
    416537        switch(class){
    417                 case USB_HID_TAG_CLASS_MAIN:
    418 
    419                         if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item, usage_path)) == EOK) {
    420                                 return USB_HID_NEW_REPORT_ITEM;
    421                         }
    422                         else {
    423                                 /*TODO process the error */
    424                                 return ret;
    425                            }
    426                         break;
    427 
    428                 case USB_HID_TAG_CLASS_GLOBAL: 
    429                         return usb_hid_report_parse_global_tag(tag,data,item_size,report_item, usage_path);
    430                         break;
    431 
    432                 case USB_HID_TAG_CLASS_LOCAL:                   
    433                         return usb_hid_report_parse_local_tag(tag,data,item_size,report_item, usage_path);
    434                         break;
    435                 default:
    436                         return USB_HID_NO_ACTION;
     538        case USB_HID_TAG_CLASS_MAIN:
     539
     540                if((ret=usb_hid_report_parse_main_tag(tag, data, item_size,
     541                        report_item, usage_path)) == EOK) {
     542
     543                        return USB_HID_NEW_REPORT_ITEM;
     544                }
     545                else {
     546                        return ret;
     547                }
     548                break;
     549
     550        case USB_HID_TAG_CLASS_GLOBAL: 
     551                return usb_hid_report_parse_global_tag(tag, data, item_size,
     552                        report_item, usage_path);
     553                break;
     554
     555        case USB_HID_TAG_CLASS_LOCAL:                   
     556                return usb_hid_report_parse_local_tag(tag, data, item_size,
     557                        report_item, usage_path);
     558                break;
     559       
     560        default:
     561                return USB_HID_NO_ACTION;
    437562        }
    438563}
     
    448573 */
    449574
    450 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    451                              usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
     575int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data,
     576        size_t item_size, usb_hid_report_item_t *report_item,
     577        usb_hid_report_path_t *usage_path)
    452578{
    453579        usb_hid_report_usage_path_t *path_item;
     
    455581        switch(tag)
    456582        {
    457                 case USB_HID_REPORT_TAG_INPUT:
    458                 case USB_HID_REPORT_TAG_OUTPUT:
    459                 case USB_HID_REPORT_TAG_FEATURE:
    460                         report_item->item_flags = *data;                       
    461                         return EOK;                     
    462                         break;
     583        case USB_HID_REPORT_TAG_INPUT:
     584        case USB_HID_REPORT_TAG_OUTPUT:
     585        case USB_HID_REPORT_TAG_FEATURE:
     586                report_item->item_flags = *data;                       
     587                return EOK;                     
     588                break;
    463589                       
    464                 case USB_HID_REPORT_TAG_COLLECTION:
    465 
    466                         // store collection atributes
    467                         path_item = list_get_instance(usage_path->head.prev, usb_hid_report_usage_path_t, link);
    468                         path_item->flags = *data;       
     590        case USB_HID_REPORT_TAG_COLLECTION:
     591
     592                /* store collection atributes */
     593                path_item = list_get_instance(usage_path->head.prev,
     594                        usb_hid_report_usage_path_t, link);
     595                path_item->flags = *data;       
    469596                       
    470                         // set last item
    471                         usb_hid_report_set_last_item(usage_path,
    472                                                      USB_HID_TAG_CLASS_GLOBAL,
    473                                                      USB_HID_EXTENDED_USAGE_PAGE(report_item->usages[report_item->usages_count-1]));
    474                         usb_hid_report_set_last_item(usage_path,
    475                                                      USB_HID_TAG_CLASS_LOCAL,
    476                                                      USB_HID_EXTENDED_USAGE(report_item->usages[report_item->usages_count-1]));
     597                /* set last item */
     598                usb_hid_report_set_last_item(usage_path,
     599                        USB_HID_TAG_CLASS_GLOBAL,
     600                        USB_HID_EXTENDED_USAGE_PAGE(report_item->usages[
     601                                report_item->usages_count-1]));
     602
     603                usb_hid_report_set_last_item(usage_path,
     604                        USB_HID_TAG_CLASS_LOCAL,
     605                        USB_HID_EXTENDED_USAGE(report_item->usages[
     606                                report_item->usages_count-1]));
    477607                       
    478                         // append the new one which will be set by common
    479                         // usage/usage page
    480                         usb_hid_report_path_append_item(usage_path, report_item->usage_page, report_item->usages[report_item->usages_count-1]);
    481                         usb_hid_report_reset_local_items (report_item);
    482                         return USB_HID_NO_ACTION;
    483                         break;
     608                /* append the new one which will be set by common usage/usage
     609                 * page */
     610                usb_hid_report_path_append_item(usage_path,
     611                        report_item->usage_page,
     612                        report_item->usages[report_item->usages_count-1]);
     613
     614                usb_hid_report_reset_local_items (report_item);
     615                return USB_HID_NO_ACTION;
     616                break;
    484617                       
    485                 case USB_HID_REPORT_TAG_END_COLLECTION:
    486                         usb_hid_report_remove_last_item(usage_path);
    487                         return USB_HID_NO_ACTION;
    488                         break;
    489                 default:
    490                         return USB_HID_NO_ACTION;
     618        case USB_HID_REPORT_TAG_END_COLLECTION:
     619                usb_hid_report_remove_last_item(usage_path);
     620                return USB_HID_NO_ACTION;
     621                break;
     622
     623        default:
     624                return USB_HID_NO_ACTION;
    491625        }
    492626
     
    503637 * @return Error code
    504638 */
    505 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    506                              usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
    507 {
    508         // TODO take care about the bit length of data
     639int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data,
     640        size_t item_size, usb_hid_report_item_t *report_item,
     641        usb_hid_report_path_t *usage_path) {
     642       
    509643        switch(tag)
    510644        {
    511                 case USB_HID_REPORT_TAG_USAGE_PAGE:
    512                         report_item->usage_page = usb_hid_report_tag_data_uint32(data, item_size);
    513                         break;
    514                 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM:
    515                         report_item->logical_minimum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
    516                         break;
    517                 case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM:
    518                         report_item->logical_maximum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
    519                         break;
    520                 case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM:
    521                         report_item->physical_minimum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
    522                         break;                 
    523                 case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM:
    524                         report_item->physical_maximum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
    525 
    526                         break;
    527                 case USB_HID_REPORT_TAG_UNIT_EXPONENT:
    528                         report_item->unit_exponent = usb_hid_report_tag_data_uint32(data,item_size);
    529                         break;
    530                 case USB_HID_REPORT_TAG_UNIT:
    531                         report_item->unit = usb_hid_report_tag_data_uint32(data,item_size);
    532                         break;
    533                 case USB_HID_REPORT_TAG_REPORT_SIZE:
    534                         report_item->size = usb_hid_report_tag_data_uint32(data,item_size);
    535                         break;
    536                 case USB_HID_REPORT_TAG_REPORT_COUNT:
    537                         report_item->count = usb_hid_report_tag_data_uint32(data,item_size);
    538                         break;
    539                 case USB_HID_REPORT_TAG_REPORT_ID:
    540                         report_item->id = usb_hid_report_tag_data_uint32(data,item_size);
    541                         return USB_HID_RESET_OFFSET;
    542                         break;
    543                 case USB_HID_REPORT_TAG_PUSH:
    544                 case USB_HID_REPORT_TAG_POP:
    545                         /*
    546                          * stack operations are done in top level parsing
    547                          * function
    548                          */
    549                         return tag;
    550                         break;
     645        case USB_HID_REPORT_TAG_USAGE_PAGE:
     646                report_item->usage_page =
     647                        usb_hid_report_tag_data_uint32(data, item_size);
     648                break;
     649
     650        case USB_HID_REPORT_TAG_LOGICAL_MINIMUM:
     651                report_item->logical_minimum = USB_HID_UINT32_TO_INT32(
     652                        usb_hid_report_tag_data_uint32(data,item_size),
     653                        item_size * 8);
     654                break;
     655
     656        case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM:
     657                report_item->logical_maximum = USB_HID_UINT32_TO_INT32(
     658                        usb_hid_report_tag_data_uint32(data,item_size),
     659                        item_size * 8);
     660                break;
     661
     662        case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM:
     663                report_item->physical_minimum = USB_HID_UINT32_TO_INT32(
     664                        usb_hid_report_tag_data_uint32(data,item_size),
     665                        item_size * 8);
     666                break;                 
     667
     668        case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM:
     669                report_item->physical_maximum = USB_HID_UINT32_TO_INT32(
     670                        usb_hid_report_tag_data_uint32(data,item_size),
     671                        item_size * 8);
     672                break;
     673
     674        case USB_HID_REPORT_TAG_UNIT_EXPONENT:
     675                report_item->unit_exponent = usb_hid_report_tag_data_uint32(
     676                        data,item_size);
     677                break;
     678
     679        case USB_HID_REPORT_TAG_UNIT:
     680                report_item->unit = usb_hid_report_tag_data_uint32(
     681                        data,item_size);
     682                break;
     683
     684        case USB_HID_REPORT_TAG_REPORT_SIZE:
     685                report_item->size = usb_hid_report_tag_data_uint32(
     686                        data,item_size);
     687                break;
     688
     689        case USB_HID_REPORT_TAG_REPORT_COUNT:
     690                report_item->count = usb_hid_report_tag_data_uint32(
     691                        data,item_size);
     692                break;
     693
     694        case USB_HID_REPORT_TAG_REPORT_ID:
     695                report_item->id = usb_hid_report_tag_data_uint32(data,
     696                        item_size);
     697                return USB_HID_RESET_OFFSET;
     698                break;
     699       
     700        case USB_HID_REPORT_TAG_PUSH:
     701        case USB_HID_REPORT_TAG_POP:
     702                /*
     703                 * stack operations are done in top level parsing
     704                 * function
     705                 */
     706                return tag;
     707                break;
    551708                       
    552                 default:
    553                         return USB_HID_NO_ACTION;
     709        default:
     710                return USB_HID_NO_ACTION;
    554711        }
    555712
     
    566723 * @return Error code
    567724 */
    568 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    569                              usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
     725int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data,
     726        size_t item_size, usb_hid_report_item_t *report_item,
     727        usb_hid_report_path_t *usage_path)
    570728{
    571729        int32_t extended_usage;
    572730       
    573731        switch(tag) {
    574                 case USB_HID_REPORT_TAG_USAGE:
    575                         switch(report_item->in_delimiter) {
    576                                 case INSIDE_DELIMITER_SET:
    577                                         // nothing to do
    578                                         break;
    579                                 case START_DELIMITER_SET:
    580                                         report_item->in_delimiter = INSIDE_DELIMITER_SET;
    581                                 case OUTSIDE_DELIMITER_SET:
    582                                         extended_usage = ((report_item->usage_page) << 16);
    583                                         extended_usage += usb_hid_report_tag_data_uint32(data,item_size);
    584                                         report_item->usages[report_item->usages_count] = extended_usage;
    585                                         report_item->usages_count++;
    586                                         break;
     732        case USB_HID_REPORT_TAG_USAGE:
     733                switch(report_item->in_delimiter) {
     734                case INSIDE_DELIMITER_SET:
     735                        /* nothing to do
     736                         * we catch only the first one
     737                         */
     738                        break;
     739       
     740                case START_DELIMITER_SET:
     741                        report_item->in_delimiter = INSIDE_DELIMITER_SET;
     742                case OUTSIDE_DELIMITER_SET:
     743                        extended_usage = ((report_item->usage_page) << 16);
     744                        extended_usage += usb_hid_report_tag_data_uint32(
     745                                data,item_size);
     746
     747                        report_item->usages[report_item->usages_count] =
     748                                extended_usage;
     749
     750                        report_item->usages_count++;
     751                        break;
     752                }
     753                break;
     754               
     755        case USB_HID_REPORT_TAG_USAGE_MINIMUM:                 
     756                if (item_size == 3) {
     757                        // usage extended usages
     758                        report_item->extended_usage_page =
     759                            USB_HID_EXTENDED_USAGE_PAGE(
     760                            usb_hid_report_tag_data_uint32(data,item_size));
     761                           
     762
     763                        report_item->usage_minimum =
     764                            USB_HID_EXTENDED_USAGE(
     765                            usb_hid_report_tag_data_uint32(data,item_size));
     766                }
     767                else {
     768                        report_item->usage_minimum =
     769                            usb_hid_report_tag_data_uint32(data,item_size);
     770                }
     771                break;
     772       
     773        case USB_HID_REPORT_TAG_USAGE_MAXIMUM:
     774                if (item_size == 3) {
     775                        if(report_item->extended_usage_page !=
     776                            USB_HID_EXTENDED_USAGE_PAGE(       
     777                            usb_hid_report_tag_data_uint32(data,item_size))) {
     778                               
     779                                return EINVAL;
    587780                        }
    588                         break;
    589                 case USB_HID_REPORT_TAG_USAGE_MINIMUM:                 
    590                         if (item_size == 3) {
    591                                 // usage extended usages
    592                                 report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16;
    593                                 report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size) & 0xFF;
     781                               
     782                        // usage extended usages
     783                        report_item->extended_usage_page =
     784                                USB_HID_EXTENDED_USAGE_PAGE(
     785                                usb_hid_report_tag_data_uint32(data,item_size));
     786
     787                        report_item->usage_maximum =
     788                                USB_HID_EXTENDED_USAGE(
     789                                usb_hid_report_tag_data_uint32(data,item_size));
     790                }
     791                else {
     792                        report_item->usage_maximum =
     793                                usb_hid_report_tag_data_uint32(data,item_size);
     794                }
     795
     796                // vlozit zaznamy do pole usages
     797                int32_t i;
     798                for(i = report_item->usage_minimum;
     799                    i <= report_item->usage_maximum; i++) {
     800
     801                        if(report_item->extended_usage_page) {
     802                            report_item->usages[report_item->usages_count++] =
     803                                (report_item->extended_usage_page << 16) + i;
    594804                        }
    595                         else {
    596                                 report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size);
     805                        else {                 
     806                            report_item->usages[report_item->usages_count++] =
     807                                (report_item->usage_page << 16) + i;
    597808                        }
    598                         break;
    599                 case USB_HID_REPORT_TAG_USAGE_MAXIMUM:
    600                         if (item_size == 3) {
    601 
    602                                 if(report_item->extended_usage_page != ((usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16)) {
    603                                         return EINVAL;
    604                                 }
    605                                
    606                                 // usage extended usages
    607                                 report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16;
    608                                 report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size) & 0xFF;
    609                         }
    610                         else {
    611                                 report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size);
    612                         }
    613 
    614                         // vlozit zaznamy do pole usages
    615                         int32_t i;
    616                         for(i=report_item->usage_minimum; i<=report_item->usage_maximum; i++) {
    617                                 if(report_item->extended_usage_page) {
    618                                         report_item->usages[report_item->usages_count++] = (report_item->extended_usage_page << 16) + i;
    619                                 }
    620                                 else {
    621                                        
    622                                         report_item->usages[report_item->usages_count++] = (report_item->usage_page << 16) + i;
    623                                 }
    624                         }
    625                         report_item->extended_usage_page = 0;
     809                }
     810                report_item->extended_usage_page = 0;
    626811                       
    627                         break;
    628                 case USB_HID_REPORT_TAG_DESIGNATOR_INDEX:
    629                         report_item->designator_index = usb_hid_report_tag_data_uint32(data,item_size);
    630                         break;
    631                 case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM:
    632                         report_item->designator_minimum = usb_hid_report_tag_data_uint32(data,item_size);
    633                         break;
    634                 case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM:
    635                         report_item->designator_maximum = usb_hid_report_tag_data_uint32(data,item_size);
    636                         break;
    637                 case USB_HID_REPORT_TAG_STRING_INDEX:
    638                         report_item->string_index = usb_hid_report_tag_data_uint32(data,item_size);
    639                         break;
    640                 case USB_HID_REPORT_TAG_STRING_MINIMUM:
    641                         report_item->string_minimum = usb_hid_report_tag_data_uint32(data,item_size);
    642                         break;
    643                 case USB_HID_REPORT_TAG_STRING_MAXIMUM:
    644                         report_item->string_maximum = usb_hid_report_tag_data_uint32(data,item_size);
    645                         break;                 
    646                 case USB_HID_REPORT_TAG_DELIMITER:
    647                         report_item->in_delimiter = usb_hid_report_tag_data_uint32(data,item_size);
    648                         break;
    649 
    650                 default:
    651                         return USB_HID_NO_ACTION;
     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;
    652851        }
    653852
    654853        return EOK;
    655854}
     855/*---------------------------------------------------------------------------*/
    656856
    657857/**
     
    674874        return result;
    675875}
     876/*---------------------------------------------------------------------------*/
    676877
    677878/**
     
    694895        for(item = head->next; item != head; item = item->next) {
    695896               
    696                 report_item = list_get_instance(item, usb_hid_report_field_t, link);
     897                report_item = list_get_instance(item, usb_hid_report_field_t,
     898                                link);
    697899
    698900                usb_log_debug("\t\tOFFSET: %X\n", report_item->offset);
    699                 usb_log_debug("\t\tSIZE: %zu\n", report_item->size);                           
    700                 usb_log_debug("\t\tLOGMIN: %d\n", report_item->logical_minimum);
    701                 usb_log_debug("\t\tLOGMAX: %d\n", report_item->logical_maximum);               
    702                 usb_log_debug("\t\tPHYMIN: %d\n", report_item->physical_minimum);               
    703                 usb_log_debug("\t\tPHYMAX: %d\n", report_item->physical_maximum);                               
    704                 usb_log_debug("\t\ttUSAGEMIN: %X\n", report_item->usage_minimum);
    705                 usb_log_debug("\t\tUSAGEMAX: %X\n", report_item->usage_maximum);
    706                 usb_log_debug("\t\tUSAGES COUNT: %zu\n", report_item->usages_count);
     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);
    707916
    708917                usb_log_debug("\t\tVALUE: %X\n", report_item->value);
     
    716925        }
    717926
    718 
    719 }
     927}
     928/*---------------------------------------------------------------------------*/
     929
    720930/**
    721931 * Prints content of given report descriptor in human readable format.
     
    734944
    735945        while(report_it != &report->reports) {
    736                 report_des = list_get_instance(report_it, usb_hid_report_description_t, link);
     946                report_des = list_get_instance(report_it,
     947                        usb_hid_report_description_t, link);
    737948                usb_log_debug("Report ID: %d\n", report_des->report_id);
    738949                usb_log_debug("\tType: %d\n", report_des->type);
    739950                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));
    740955                usb_log_debug("\tItems: %zu\n", report_des->item_length);               
    741956
    742957                usb_hid_descriptor_print_list(&report_des->report_items);
    743958
    744 /*
    745                 link_t *path_it = report->collection_paths.next;
    746                 while(path_it != &report->collection_paths) {
    747                         usb_hid_print_usage_path (list_get_instance(path_it, usb_hid_report_path_t, link));
    748                         path_it = path_it->next;
    749                 }
    750 */             
    751959                report_it = report_it->next;
    752960        }
    753961}
     962/*---------------------------------------------------------------------------*/
    754963
    755964/**
     
    776985
    777986                while(!list_empty(&report_item->usage_path->link)) {
    778                         usb_hid_report_remove_last_item(report_item->usage_path);
     987                    usb_hid_report_remove_last_item(report_item->usage_path);
    779988                }
    780989
     
    788997       
    789998}
     999/*---------------------------------------------------------------------------*/
    7901000
    7911001/** Frees the HID report descriptor parser structure
     
    8031013        usb_hid_report_path_t *path;
    8041014        while(!list_empty(&report->collection_paths)) {
    805                 path = list_get_instance(report->collection_paths.next, usb_hid_report_path_t, link);
     1015                path = list_get_instance(report->collection_paths.next,
     1016                                usb_hid_report_path_t, link);
     1017
    8061018                usb_hid_report_path_free(path);         
    8071019        }
     
    8111023        usb_hid_report_field_t *field;
    8121024        while(!list_empty(&report->reports)) {
    813                 report_des = list_get_instance(report->reports.next, usb_hid_report_description_t, link);
     1025                report_des = list_get_instance(report->reports.next,
     1026                                usb_hid_report_description_t, link);
     1027
    8141028                list_remove(&report_des->link);
    8151029               
    8161030                while(!list_empty(&report_des->report_items)) {
    817                         field = list_get_instance(report_des->report_items.next, usb_hid_report_field_t, link);
     1031                        field = list_get_instance(
     1032                                report_des->report_items.next,
     1033                                usb_hid_report_field_t, link);
     1034
    8181035                        list_remove(&field->link);
    8191036
     
    8261043        return;
    8271044}
     1045/*---------------------------------------------------------------------------*/
    8281046
    8291047/**
Note: See TracChangeset for help on using the changeset viewer.