Ignore:
File:
1 edited

Legend:

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

    r0a494fe r1be39e9  
    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       
    4348/** The new report item flag. Used to determine when the item is completly
    4449 * configured and should be added to the report structure
     
    5661#define USB_HID_UNKNOWN_TAG             -99
    5762
    58 
    59 /**
    60  * Initialize the report descriptor parser structure
    61  *
    62  * @param parser Report descriptor parser structure
    63  * @return Error code
    64  */
    65 int 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 
    79 int 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 
     63usb_hid_report_path_t *usb_hid_report_path_try_insert(usb_hid_report_t *report, usb_hid_report_path_t *cmp_path)
     64{
    8565        /* find or append current collection path to the list */
    8666        link_t *path_it = report->collection_paths.next;
     
    8969                path = list_get_instance(path_it, usb_hid_report_path_t, link);
    9070               
    91                 if(usb_hid_report_compare_usage_path(path, report_item->usage_path, USB_HID_PATH_COMPARE_STRICT) == EOK){
     71                if(usb_hid_report_compare_usage_path(path, cmp_path, USB_HID_PATH_COMPARE_STRICT) == EOK){
    9272                        break;
    9373                }                       
     
    9575        }
    9676        if(path_it == &report->collection_paths) {
    97                 path = usb_hid_report_path_clone(report_item->usage_path);                     
     77                path = usb_hid_report_path_clone(cmp_path);                     
    9878                list_append(&path->link, &report->collection_paths);                                   
    9979                report->collection_paths_count++;
    100         }
     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 */
     94int 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 */
     113int 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;
    101117
    102118        for(i=0; i<report_item->usages_count; i++){
     
    104120        }
    105121
    106        
     122        usb_hid_report_path_t *path = report_item->usage_path; 
    107123        for(i=0; i<report_item->count; i++){
    108124
     
    112128
    113129                /* fill the attributes */               
    114                 field->collection_path = path;
    115130                field->logical_minimum = report_item->logical_minimum;
    116131                field->logical_maximum = report_item->logical_maximum;
     
    129144                if(report_item->usages_count > 0 && ((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0))) {
    130145                        uint32_t usage;
    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                                 }
     146                        if(i < report_item->usages_count){
     147                                usage = report_item->usages[i];
    138148                        }
    139149                        else {
    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                                 }
     150                                usage = report_item->usages[report_item->usages_count - 1];
    146151                        }
    147152
     
    159164
    160165                if((USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) != 0) && (!((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0)))) {
    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                
     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
    170174                field->size = report_item->size;
    171                 field->offset = report_item->offset + (i * 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;
    172180                if(report_item->id != 0) {
    173181                        field->offset += 8;
     
    264272                return ENOMEM;
    265273        }
     274        usb_hid_report_path_append_item(usage_path, 0, 0);     
    266275       
    267276        while(i<size){ 
     
    349358                                        tmp_usage_path = list_get_instance(report_item->usage_path->link.prev, usb_hid_report_usage_path_t, link);
    350359                                       
    351                                         usb_hid_report_set_last_item(usage_path, tmp_usage_path->usage_page, tmp_usage_path->usage);
     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);
    352362
    353363                                        usb_hid_report_path_free(report_item->usage_path);
     
    427437int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    428438                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
    429 {               
     439{
     440        usb_hid_report_usage_path_t *path_item;
     441       
    430442        switch(tag)
    431443        {
     
    438450                       
    439451                case USB_HID_REPORT_TAG_COLLECTION:
    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]);                                         
     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]);
    442463                        usb_hid_report_reset_local_items (report_item);
    443464                        return USB_HID_NO_ACTION;
     
    530551                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
    531552{
    532         switch(tag)
    533         {
     553        switch(tag) {
    534554                case USB_HID_REPORT_TAG_USAGE:
    535                         report_item->usages[report_item->usages_count] = usb_hid_report_tag_data_uint32(data,item_size);
    536                         report_item->usages_count++;
     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                        }
    537566                        break;
    538567                case USB_HID_REPORT_TAG_USAGE_MINIMUM:
     
    575604                        break;                 
    576605                case USB_HID_REPORT_TAG_DELIMITER:
    577                         //report_item->delimiter = usb_hid_report_tag_data_uint32(data,item_size);
    578                         //TODO:
    579                         //      DELIMITER STUFF
    580                         break;
    581                
     606                        report_item->in_delimiter = usb_hid_report_tag_data_uint32(data,item_size);
     607                        break;
     608
    582609                default:
    583610                        return USB_HID_NO_ACTION;
    584611        }
    585        
     612
    586613        return EOK;
    587614}
     
    629656
    630657                usb_log_debug("\t\tOFFSET: %X\n", report_item->offset);
    631                 usb_log_debug("\t\tSIZE: %zu\n", report_item->size);
     658                usb_log_debug("\t\tSIZE: %X\n", report_item->size);                             
    632659                usb_log_debug("\t\tLOGMIN: %d\n", report_item->logical_minimum);
    633660                usb_log_debug("\t\tLOGMAX: %d\n", report_item->logical_maximum);               
     
    640667                usb_log_debug("\t\ttUSAGE: %X\n", report_item->usage);
    641668                usb_log_debug("\t\tUSAGE PAGE: %X\n", report_item->usage_page);
    642                                                
    643 //              usb_log_debug("\n");           
     669               
     670                //usb_hid_print_usage_path(report_item->collection_path);
     671
     672                usb_log_debug("\n");           
    644673
    645674        }
     
    666695                usb_log_debug("Report ID: %d\n", report_des->report_id);
    667696                usb_log_debug("\tType: %d\n", report_des->type);
    668                 usb_log_debug("\tLength: %zu\n", report_des->bit_length);
    669                 usb_log_debug("\tItems: %zu\n", report_des->item_length);
     697                usb_log_debug("\tLength: %d\n", report_des->bit_length);               
     698                usb_log_debug("\tItems: %d\n", report_des->item_length);               
    670699
    671700                usb_hid_descriptor_print_list(&report_des->report_items);
Note: See TracChangeset for help on using the changeset viewer.