Ignore:
File:
1 edited

Legend:

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

    rf90c0d6 r0a494fe  
    4141#include <assert.h>
    4242
    43 
    44 #define OUTSIDE_DELIMITER_SET   0
    45 #define START_DELIMITER_SET     1
    46 #define INSIDE_DELIMITER_SET    2
    47        
    4843/** The new report item flag. Used to determine when the item is completly
    4944 * configured and should be added to the report structure
     
    6156#define USB_HID_UNKNOWN_TAG             -99
    6257
    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 {
     58
     59/**
     60 * Initialize the report descriptor parser structure
     61 *
     62 * @param parser Report descriptor parser structure
     63 * @return Error code
     64 */
     65int usb_hid_report_init(usb_hid_report_t *report)
     66{
     67        if(report == NULL) {
     68                return EINVAL;
     69        }
     70
     71        memset(report, 0, sizeof(usb_hid_report_t));
     72        list_initialize(&report->reports);
     73        list_initialize(&report->collection_paths);
     74
     75        report->use_report_ids = 0;
     76    return EOK;   
     77}
     78
     79int usb_hid_report_append_fields(usb_hid_report_t *report, usb_hid_report_item_t *report_item)
     80{
     81        usb_hid_report_field_t *field;
     82        int i;
     83
     84
    6585        /* find or append current collection path to the list */
    6686        link_t *path_it = report->collection_paths.next;
     
    6989                path = list_get_instance(path_it, usb_hid_report_path_t, link);
    7090               
    71                 if(usb_hid_report_compare_usage_path(path, cmp_path, USB_HID_PATH_COMPARE_STRICT) == EOK){
     91                if(usb_hid_report_compare_usage_path(path, report_item->usage_path, USB_HID_PATH_COMPARE_STRICT) == EOK){
    7292                        break;
    7393                }                       
     
    7595        }
    7696        if(path_it == &report->collection_paths) {
    77                 path = usb_hid_report_path_clone(cmp_path);                     
     97                path = usb_hid_report_path_clone(report_item->usage_path);                     
    7898                list_append(&path->link, &report->collection_paths);                                   
    7999                report->collection_paths_count++;
    80 
    81                 return path;
    82         }
    83         else {
    84                 return list_get_instance(path_it, usb_hid_report_path_t, link);
    85         }
    86 }
    87 
    88 /**
    89  * Initialize the report descriptor parser structure
    90  *
    91  * @param parser Report descriptor parser structure
    92  * @return Error code
    93  */
    94 int usb_hid_report_init(usb_hid_report_t *report)
    95 {
    96         if(report == NULL) {
    97                 return EINVAL;
    98         }
    99 
    100         memset(report, 0, sizeof(usb_hid_report_t));
    101         list_initialize(&report->reports);
    102         list_initialize(&report->collection_paths);
    103 
    104         report->use_report_ids = 0;
    105     return EOK;   
    106 }
    107 
    108 
    109 /*
    110  *
    111  *
    112  */
    113 int usb_hid_report_append_fields(usb_hid_report_t *report, usb_hid_report_item_t *report_item)
    114 {
    115         usb_hid_report_field_t *field;
    116         int i;
     100        }
    117101
    118102        for(i=0; i<report_item->usages_count; i++){
     
    120104        }
    121105
    122         usb_hid_report_path_t *path = report_item->usage_path; 
     106       
    123107        for(i=0; i<report_item->count; i++){
    124108
     
    128112
    129113                /* fill the attributes */               
     114                field->collection_path = path;
    130115                field->logical_minimum = report_item->logical_minimum;
    131116                field->logical_maximum = report_item->logical_maximum;
     
    144129                if(report_item->usages_count > 0 && ((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0))) {
    145130                        uint32_t usage;
    146                         if(i < report_item->usages_count){
    147                                 usage = report_item->usages[i];
     131                        if(report_item->type != USB_HID_REPORT_TYPE_OUTPUT) {
     132                                if(i < report_item->usages_count){
     133                                        usage = report_item->usages[i];
     134                                }
     135                                else {
     136                                        usage = report_item->usages[report_item->usages_count - 1];
     137                                }
    148138                        }
    149139                        else {
    150                                 usage = report_item->usages[report_item->usages_count - 1];
     140                                if((report_item->count - i - 1) < report_item->usages_count){
     141                                        usage = report_item->usages[(report_item->count - i - 1)];
     142                                }
     143                                else {
     144                                        usage = report_item->usages[report_item->usages_count - 1];
     145                                }
    151146                        }
    152147
     
    164159
    165160                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);
    173 
     161                        if(report_item->type == USB_HID_REPORT_TYPE_INPUT) {
     162                                field->usage = report_item->usage_maximum - i;
     163                        }
     164                        else {
     165                                field->usage = report_item->usage_minimum + i;                                 
     166                        }
     167
     168                }
     169               
    174170                field->size = report_item->size;
    175                
    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;
    178 
    179                 field->offset = 8 * offset_byte + offset_bit;
     171                field->offset = report_item->offset + (i * report_item->size);
    180172                if(report_item->id != 0) {
    181173                        field->offset += 8;
     
    272264                return ENOMEM;
    273265        }
    274         usb_hid_report_path_append_item(usage_path, 0, 0);     
    275266       
    276267        while(i<size){ 
     
    358349                                        tmp_usage_path = list_get_instance(report_item->usage_path->link.prev, usb_hid_report_usage_path_t, link);
    359350                                       
    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);
     351                                        usb_hid_report_set_last_item(usage_path, tmp_usage_path->usage_page, tmp_usage_path->usage);
    362352
    363353                                        usb_hid_report_path_free(report_item->usage_path);
     
    437427int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    438428                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
    439 {
    440         usb_hid_report_usage_path_t *path_item;
    441        
     429{               
    442430        switch(tag)
    443431        {
     
    450438                       
    451439                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;       
    455                        
    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]);
    459                        
    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]);
     440                        // TODO usage_path->flags = *data;
     441                        usb_hid_report_path_append_item(usage_path, report_item->usage_page, report_item->usages[report_item->usages_count-1]);                                         
    463442                        usb_hid_report_reset_local_items (report_item);
    464443                        return USB_HID_NO_ACTION;
     
    551530                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
    552531{
    553         switch(tag) {
     532        switch(tag)
     533        {
    554534                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                         }
     535                        report_item->usages[report_item->usages_count] = usb_hid_report_tag_data_uint32(data,item_size);
     536                        report_item->usages_count++;
    566537                        break;
    567538                case USB_HID_REPORT_TAG_USAGE_MINIMUM:
     
    604575                        break;                 
    605576                case USB_HID_REPORT_TAG_DELIMITER:
    606                         report_item->in_delimiter = usb_hid_report_tag_data_uint32(data,item_size);
    607                         break;
    608 
     577                        //report_item->delimiter = usb_hid_report_tag_data_uint32(data,item_size);
     578                        //TODO:
     579                        //      DELIMITER STUFF
     580                        break;
     581               
    609582                default:
    610583                        return USB_HID_NO_ACTION;
    611584        }
    612 
     585       
    613586        return EOK;
    614587}
     
    656629
    657630                usb_log_debug("\t\tOFFSET: %X\n", report_item->offset);
    658                 usb_log_debug("\t\tSIZE: %zu\n", report_item->size);                           
     631                usb_log_debug("\t\tSIZE: %zu\n", report_item->size);
    659632                usb_log_debug("\t\tLOGMIN: %d\n", report_item->logical_minimum);
    660633                usb_log_debug("\t\tLOGMAX: %d\n", report_item->logical_maximum);               
     
    667640                usb_log_debug("\t\ttUSAGE: %X\n", report_item->usage);
    668641                usb_log_debug("\t\tUSAGE PAGE: %X\n", report_item->usage_page);
    669                
    670                 //usb_hid_print_usage_path(report_item->collection_path);
    671 
    672                 usb_log_debug("\n");           
     642                                               
     643//              usb_log_debug("\n");           
    673644
    674645        }
     
    695666                usb_log_debug("Report ID: %d\n", report_des->report_id);
    696667                usb_log_debug("\tType: %d\n", report_des->type);
    697                 usb_log_debug("\tLength: %zu\n", report_des->bit_length);               
    698                 usb_log_debug("\tItems: %zu\n", report_des->item_length);               
     668                usb_log_debug("\tLength: %zu\n", report_des->bit_length);
     669                usb_log_debug("\tItems: %zu\n", report_des->item_length);
    699670
    700671                usb_hid_descriptor_print_list(&report_des->report_items);
Note: See TracChangeset for help on using the changeset viewer.