Ignore:
File:
1 edited

Legend:

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

    rc32688d rad4562c2  
    3636#include <errno.h>
    3737#include <stdio.h>
    38 #include <malloc.h>
    39 #include <mem.h>
    40 #include <usb/debug.h>
    41 
    42 #define USB_HID_NEW_REPORT_ITEM 1
    43 #define USB_HID_NO_ACTION               2
    44 #define USB_HID_UNKNOWN_TAG             -99
    45 
    46 #define BAD_HACK_USAGE_PAGE             0x07
    47 
    48 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size,
    49                              usb_hid_report_item_t *report_item);
    50 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    51                              usb_hid_report_item_t *report_item);
    52 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    53                              usb_hid_report_item_t *report_item);
    54 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    55                              usb_hid_report_item_t *report_item);
    56 
    57 void usb_hid_descriptor_print_list(link_t *head);
    58 int usb_hid_report_reset_local_items();
    59 void usb_hid_free_report_list(link_t *head);
    60 int32_t usb_hid_report_tag_data_int32(const uint8_t *data, size_t size);
    61 inline size_t usb_hid_count_item_offset(usb_hid_report_item_t * report_item, size_t offset);
    62 int usb_hid_translate_data(usb_hid_report_item_t *item, const uint8_t *data, size_t j);
    63 int usb_pow(int a, int b);
    64 
    65 int usb_pow(int a, int b)
    66 {
    67         switch(b) {
    68                 case 0:
    69                         return 1;
    70                         break;
    71                 case 1:
    72                         return a;
    73                         break;
    74                 default:
    75                         return a * usb_pow(a, b-1);
    76                         break;
    77         }
    78 }
    79 
    80 /**
    81  *
    82  */
    83 int usb_hid_parser_init(usb_hid_report_parser_t *parser)
    84 {
    85    if(parser == NULL) {
    86         return -1;
    87    }
    88 
    89     list_initialize(&(parser->input));
    90     list_initialize(&(parser->output));
    91     list_initialize(&(parser->feature));
    92 
    93     return EOK;   
    94 }
    95 
    9638
    9739/** Parse HID report descriptor.
     
    10446    const uint8_t *data, size_t size)
    10547{
    106         size_t i=0;
    107         uint8_t tag=0;
    108         uint8_t item_size=0;
    109         int class=0;
    110         int ret;
    111         usb_hid_report_item_t *report_item=0;
    112         usb_hid_report_item_t *new_report_item;
     48        return ENOTSUP;
     49}
    11350
    114         size_t offset_input=0;
    115         size_t offset_output=0;
    116         size_t offset_feature=0;
     51/** Parse and act upon a HID report.
     52 *
     53 * @see usb_hid_parse_report_descriptor
     54 *
     55 * @param parser Opaque HID report parser structure.
     56 * @param data Data for the report.
     57 * @param callbacks Callbacks for report actions.
     58 * @param arg Custom argument (passed through to the callbacks).
     59 * @return Error code.
     60 */
     61int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 
     62    const uint8_t *data, size_t size,
     63    const usb_hid_report_in_callbacks_t *callbacks, void *arg)
     64{
     65        int i;
    11766       
    118 
    119         if(!(report_item=malloc(sizeof(usb_hid_report_item_t)))){
    120                 return ENOMEM;
    121         }
    122         memset(report_item, 0, sizeof(usb_hid_report_item_t));
    123        
    124         link_initialize(&(report_item->link)); 
    125 
    126         while(i<size){ 
    127                 if(!USB_HID_ITEM_IS_LONG(data[i])){
    128 
    129                         if((i+USB_HID_ITEM_SIZE(data[i]))>= size){
    130                                 return -1; // TODO ERROR CODE
    131                         }
    132                        
    133                         tag = USB_HID_ITEM_TAG(data[i]);
    134                         item_size = USB_HID_ITEM_SIZE(data[i]);
    135                         class = USB_HID_ITEM_TAG_CLASS(data[i]);
    136 
    137                         usb_log_debug2(
    138                                 "i(%u) data(%X) value(%X): TAG %u, class %u, size %u - ", i,
    139                             data[i], usb_hid_report_tag_data_int32(data+i+1,item_size),
    140                             tag, class, item_size);
    141                        
    142                         ret = usb_hid_report_parse_tag(tag,class,data+i+1,
    143                                                  item_size,report_item);
    144                         usb_log_debug2("ret: %u\n", ret);
    145                         switch(ret){
    146                                 case USB_HID_NEW_REPORT_ITEM:
    147                                         // store report item to report and create the new one
    148                                         usb_log_debug("\nNEW REPORT ITEM: %X",tag);
    149                                        
    150                                         switch(tag) {
    151                                                 case USB_HID_REPORT_TAG_INPUT:
    152                                                         report_item->offset = offset_input;
    153                                                         offset_input += report_item->count * report_item->size;
    154                                                         usb_log_debug(" - INPUT\n");
    155                                                         list_append(&(report_item->link), &(parser->input));
    156                                                         break;
    157                                                 case USB_HID_REPORT_TAG_OUTPUT:
    158                                                         report_item->offset = offset_output;
    159                                                         offset_output += report_item->count * report_item->size;
    160                                                         usb_log_debug(" - OUTPUT\n");
    161                                                                 list_append(&(report_item->link), &(parser->output));
    162 
    163                                                         break;
    164                                                 case USB_HID_REPORT_TAG_FEATURE:
    165                                                         report_item->offset = offset_feature;
    166                                                         offset_feature += report_item->count * report_item->size;
    167                                                         usb_log_debug(" - FEATURE\n");
    168                                                                 list_append(&(report_item->link), &(parser->feature));
    169                                                         break;
    170                                                 default:
    171                                                     usb_log_debug("\tjump over - tag %X\n", tag);
    172                                                     break;
    173                                         }
    174 
    175                                         /* clone current state table to the new item */
    176                                         if(!(new_report_item = malloc(sizeof(usb_hid_report_item_t)))) {
    177                                                 return ENOMEM;
    178                                         }
    179                                         memcpy(new_report_item,report_item, sizeof(usb_hid_report_item_t));
    180                                         /* reset local items */
    181                                         new_report_item->usage_minimum = 0;
    182                                         new_report_item->usage_maximum = 0;
    183                                        
    184                                         link_initialize(&(new_report_item->link));
    185                                         report_item = new_report_item;
    186                                        
    187                                         break;
    188                                 case USB_HID_REPORT_TAG_PUSH:
    189                                         // push current state to stack
    190                                         // not yet implemented
    191                                         break;
    192                                 case USB_HID_REPORT_TAG_POP:
    193                                         // restore current state from stack
    194                                         // not yet implemented                                             
    195                                         break;
    196                                        
    197                                 default:
    198                                         // nothing special to do                                       
    199                                         break;
    200                         }
    201 
    202                         /* jump over the processed block */
    203                         i += 1 + USB_HID_ITEM_SIZE(data[i]);
    204                 }
    205                 else{
    206                         // TBD
    207                         i += 3 + USB_HID_ITEM_SIZE(data[i+1]);
    208                 }
    209                
    210 
     67        /* main parsing loop */
     68        while(0){
    21169        }
    21270       
     71       
     72        uint8_t keys[6];
     73       
     74        for (i = 0; i < 6; ++i) {
     75                keys[i] = data[i];
     76        }
     77       
     78        callbacks->keyboard(keys, 6, 0, arg);
     79
     80        return EOK;
     81}
     82
     83/** Free the HID report parser structure
     84 *
     85 * @param parser Opaque HID report parser structure
     86 * @return Error code
     87 */
     88int usb_hid_free_report_parser(usb_hid_report_parser_t *parser)
     89{
     90
    21391        return EOK;
    21492}
     
    238116        item.size = 8;
    239117        item.count = 6;
    240         item.usage_minimum = 0;
    241         item.usage_maximum = 255;
    242         item.logical_minimum = 0;
    243         item.logical_maximum = 255;
     118        item.usage_min = 0;
     119        item.usage_max = 255;
     120        item.logical_min = 0;
     121        item.logical_max = 255;
    244122
    245123        if (size != 8) {
    246                 return -1; //ERANGE;
     124                return ERANGE;
    247125        }
    248126
     
    266144int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size)
    267145{
    268         if(size != 1){
     146        if (size < 1){
    269147                return -1;
    270148        }
    271149
    272         /* used only first five bits, others are only padding*/
    273         *data = leds;
     150        data[0] = leds;
    274151        return EOK;
    275152}
    276153
    277154/**
    278  *
    279  * @param Tag to parse
    280  * @param Report descriptor buffer
    281  * @param Size of data belongs to this tag
    282  * @param Current report item structe
    283  * @return Code of action to be done next
    284  */
    285 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size,
    286                              usb_hid_report_item_t *report_item)
    287 {       
    288         int ret;
    289        
    290         switch(class){
    291                 case USB_HID_TAG_CLASS_MAIN:
    292 
    293                         if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item)) == EOK) {
    294                                 return USB_HID_NEW_REPORT_ITEM;
    295                         }
    296                         else {
    297                                 /*TODO process the error */
    298                                 return ret;
    299                            }
    300                         break;
    301 
    302                 case USB_HID_TAG_CLASS_GLOBAL: 
    303                         return usb_hid_report_parse_global_tag(tag,data,item_size,report_item);
    304                         break;
    305 
    306                 case USB_HID_TAG_CLASS_LOCAL:                   
    307                         return usb_hid_report_parse_local_tag(tag,data,item_size,report_item);
    308                         break;
    309                 default:
    310                         return USB_HID_NO_ACTION;
    311         }
    312 }
    313 
    314 /**
    315  * Parse main tags of report descriptor
    316  *
    317  * @param Tag identifier
    318  * @param Data buffer
    319  * @param Length of data buffer
    320  * @param Current state table
    321  * @return Error code
    322  */
    323 
    324 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    325                              usb_hid_report_item_t *report_item)
    326 {
    327         switch(tag)
    328         {
    329                 case USB_HID_REPORT_TAG_INPUT:
    330                 case USB_HID_REPORT_TAG_OUTPUT:
    331                 case USB_HID_REPORT_TAG_FEATURE:
    332                         report_item->item_flags = *data;                       
    333                         return EOK;                     
    334                         break;
    335                        
    336                 case USB_HID_REPORT_TAG_COLLECTION:
    337                         // TODO
    338                         return USB_HID_NO_ACTION;
    339                         break;
    340                        
    341                 case USB_HID_REPORT_TAG_END_COLLECTION:
    342                         /* should be ignored */
    343                         return USB_HID_NO_ACTION;
    344                         break;
    345                 default:
    346                         return USB_HID_NO_ACTION;
    347         }
    348 
    349         return EOK;
    350 }
    351 
    352 /**
    353  * Parse global tags of report descriptor
    354  *
    355  * @param Tag identifier
    356  * @param Data buffer
    357  * @param Length of data buffer
    358  * @param Current state table
    359  * @return Error code
    360  */
    361 
    362 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    363                              usb_hid_report_item_t *report_item)
    364 {
    365         // TODO take care about the bit length of data
    366         switch(tag)
    367         {
    368                 case USB_HID_REPORT_TAG_USAGE_PAGE:
    369                         report_item->usage_page = usb_hid_report_tag_data_int32(data,item_size);
    370                         break;
    371                 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM:
    372                         report_item->logical_minimum = usb_hid_report_tag_data_int32(data,item_size);
    373                         break;
    374                 case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM:
    375                         report_item->logical_maximum = usb_hid_report_tag_data_int32(data,item_size);
    376                         break;
    377                 case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM:
    378                         report_item->physical_minimum = usb_hid_report_tag_data_int32(data,item_size);
    379                         break;                 
    380                 case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM:
    381                         report_item->physical_maximum = usb_hid_report_tag_data_int32(data,item_size);
    382                         break;
    383                 case USB_HID_REPORT_TAG_UNIT_EXPONENT:
    384                         report_item->unit_exponent = usb_hid_report_tag_data_int32(data,item_size);
    385                         break;
    386                 case USB_HID_REPORT_TAG_UNIT:
    387                         report_item->unit = usb_hid_report_tag_data_int32(data,item_size);
    388                         break;
    389                 case USB_HID_REPORT_TAG_REPORT_SIZE:
    390                         report_item->size = usb_hid_report_tag_data_int32(data,item_size);
    391                         break;
    392                 case USB_HID_REPORT_TAG_REPORT_COUNT:
    393                         report_item->count = usb_hid_report_tag_data_int32(data,item_size);
    394                         break;
    395                 case USB_HID_REPORT_TAG_REPORT_ID:
    396                         report_item->id = usb_hid_report_tag_data_int32(data,item_size);
    397                         break;
    398                 case USB_HID_REPORT_TAG_PUSH:
    399                 case USB_HID_REPORT_TAG_POP:
    400                         return tag;
    401                         break;
    402                        
    403                 default:
    404                         return USB_HID_NO_ACTION;
    405         }
    406        
    407         return EOK;
    408 }
    409 
    410 /**
    411  * Parse local tags of report descriptor
    412  *
    413  * @param Tag identifier
    414  * @param Data buffer
    415  * @param Length of data buffer
    416  * @param Current state table
    417  * @return Error code
    418  */
    419 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    420                              usb_hid_report_item_t *report_item)
    421 {
    422         switch(tag)
    423         {
    424                 case USB_HID_REPORT_TAG_USAGE:
    425                         report_item->usage = usb_hid_report_tag_data_int32(data,item_size);
    426                         break;
    427                 case USB_HID_REPORT_TAG_USAGE_MINIMUM:
    428                         report_item->usage_minimum = usb_hid_report_tag_data_int32(data,item_size);
    429                         break;
    430                 case USB_HID_REPORT_TAG_USAGE_MAXIMUM:
    431                         report_item->usage_maximum = usb_hid_report_tag_data_int32(data,item_size);
    432                         break;
    433                 case USB_HID_REPORT_TAG_DESIGNATOR_INDEX:
    434                         report_item->designator_index = usb_hid_report_tag_data_int32(data,item_size);
    435                         break;
    436                 case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM:
    437                         report_item->designator_minimum = usb_hid_report_tag_data_int32(data,item_size);
    438                         break;
    439                 case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM:
    440                         report_item->designator_maximum = usb_hid_report_tag_data_int32(data,item_size);
    441                         break;
    442                 case USB_HID_REPORT_TAG_STRING_INDEX:
    443                         report_item->string_index = usb_hid_report_tag_data_int32(data,item_size);
    444                         break;
    445                 case USB_HID_REPORT_TAG_STRING_MINIMUM:
    446                         report_item->string_minimum = usb_hid_report_tag_data_int32(data,item_size);
    447                         break;
    448                 case USB_HID_REPORT_TAG_STRING_MAXIMUM:
    449                         report_item->string_maximum = usb_hid_report_tag_data_int32(data,item_size);
    450                         break;                 
    451                 case USB_HID_REPORT_TAG_DELIMITER:
    452                         report_item->delimiter = usb_hid_report_tag_data_int32(data,item_size);
    453                         break;
    454                
    455                 default:
    456                         return USB_HID_NO_ACTION;
    457         }
    458        
    459         return EOK;
    460 }
    461 
    462 /**
    463  * Converts raw data to int32 (thats the maximum length of short item data)
    464  *
    465  * @param Data buffer
    466  * @param Size of buffer
    467  * @return Converted int32 number
    468  */
    469 int32_t usb_hid_report_tag_data_int32(const uint8_t *data, size_t size)
    470 {
    471         unsigned int i;
    472         int32_t result;
    473 
    474         result = 0;
    475         for(i=0; i<size; i++) {
    476                 result = (result | (data[i]) << (i*8));
    477         }
    478 
    479         return result;
    480 }
    481 
    482 
    483 
    484 /**
    485  * Prints content of given list of report items.
    486  *
    487  * @param List of report items
    488  * @return void
    489  */
    490 void usb_hid_descriptor_print_list(link_t *head)
    491 {
    492         usb_hid_report_item_t *report_item;
    493         link_t *item;
    494        
    495         if(head == NULL || list_empty(head)) {
    496             usb_log_debug("\tempty\n");
    497             return;
    498         }
    499        
    500         for(item = head->next; item != head; item = item->next) {
    501                
    502                 report_item = list_get_instance(item, usb_hid_report_item_t, link);
    503 
    504                 usb_log_debug("\tOFFSET: %X\n", report_item->offset);
    505                 usb_log_debug("\tCOUNT: %X\n", report_item->count);
    506                 usb_log_debug("\tSIZE: %X\n", report_item->size);
    507                 usb_log_debug("\tCONSTANT/VAR: %X\n", USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags));
    508                 usb_log_debug("\tVARIABLE/ARRAY: %X\n", USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags));
    509                 usb_log_debug("\tUSAGE: %X\n", report_item->usage);
    510                 usb_log_debug("\tUSAGE PAGE: %X\n", report_item->usage_page);
    511                 usb_log_debug("\tLOGMIN: %X\n", report_item->logical_minimum);
    512                 usb_log_debug("\tLOGMAX: %X\n", report_item->logical_maximum);         
    513                 usb_log_debug("\tPHYMIN: %X\n", report_item->physical_minimum);         
    514                 usb_log_debug("\tPHYMAX: %X\n", report_item->physical_maximum);                         
    515                 usb_log_debug("\tUSAGEMIN: %X\n", report_item->usage_minimum);
    516                 usb_log_debug("\tUSAGEMAX: %X\n", report_item->usage_maximum);
    517                
    518                 usb_log_debug("\n");           
    519 
    520         }
    521 
    522 
    523 }
    524 /**
    525  * Prints content of given descriptor in human readable format.
    526  *
    527  * @param Parsed descriptor to print
    528  * @return void
    529  */
    530 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser)
    531 {
    532         usb_log_debug("INPUT:\n");
    533         usb_hid_descriptor_print_list(&parser->input);
    534        
    535         usb_log_debug("OUTPUT: \n");
    536         usb_hid_descriptor_print_list(&parser->output);
    537        
    538         usb_log_debug("FEATURE:\n");   
    539         usb_hid_descriptor_print_list(&parser->feature);
    540 
    541 }
    542 
    543 /**
    544  * Releases whole linked list of report items
    545  *
    546  *
    547  */
    548 void usb_hid_free_report_list(link_t *head)
    549 {
    550         return;
    551        
    552         usb_hid_report_item_t *report_item;
    553         link_t *next;
    554        
    555         if(head == NULL || list_empty(head)) {         
    556             return;
    557         }
    558        
    559         next = head->next;
    560         while(next != head) {
    561        
    562             report_item = list_get_instance(next, usb_hid_report_item_t, link);
    563             next = next->next;
    564            
    565             free(report_item);
    566         }
    567        
    568         return;
    569        
    570 }
    571 
    572 /** Free the HID report parser structure
    573  *
    574  * @param parser Opaque HID report parser structure
    575  * @return Error code
    576  */
    577 void usb_hid_free_report_parser(usb_hid_report_parser_t *parser)
    578 {
    579         if(parser == NULL){
    580                 return;
    581         }
    582 
    583         usb_hid_free_report_list(&parser->input);
    584         usb_hid_free_report_list(&parser->output);
    585         usb_hid_free_report_list(&parser->feature);
    586 
    587         return;
    588 }
    589 
    590 /** Parse and act upon a HID report.
    591  *
    592  * @see usb_hid_parse_report_descriptor
    593  *
    594  * @param parser Opaque HID report parser structure.
    595  * @param data Data for the report.
    596  * @param callbacks Callbacks for report actions.
    597  * @param arg Custom argument (passed through to the callbacks).
    598  * @return Error code.
    599  */
    600 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 
    601     const uint8_t *data, size_t size,
    602     const usb_hid_report_in_callbacks_t *callbacks, void *arg)
    603 {
    604         /*
    605          *
    606          * only key codes (usage page 0x07) will be processed
    607          * other usages will be ignored
    608          */
    609         link_t *list_item;
    610         usb_hid_report_item_t *item;
    611         uint8_t *keys;
    612         uint8_t item_value;
    613         size_t key_count=0;
    614         size_t i=0;
    615         size_t j=0;
    616 
    617         // get the size of result keycodes array
    618         usb_hid_report_path_t path;
    619         path.usage_page = BAD_HACK_USAGE_PAGE;
    620         key_count = usb_hid_report_input_length(parser, &path);
    621 
    622         if(!(keys = malloc(sizeof(uint8_t) * key_count))){
    623                 return ENOMEM;
    624         }
    625 
    626         // read data           
    627         list_item = parser->input.next;   
    628         while(list_item != &(parser->input)) {
    629 
    630                 item = list_get_instance(list_item, usb_hid_report_item_t, link);
    631                 if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) &&
    632                    (item->usage_page == path.usage_page)) {
    633                         for(j=0; j<(size_t)(item->count); j++) {
    634                                 if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0) ||
    635                                    ((item->usage_minimum == 0) && (item->usage_maximum == 0))) {
    636                                         // variable item
    637                                         keys[i++] = usb_hid_translate_data(item, data,j);
    638                                 }
    639                                 else {
    640                                         // bitmapa
    641                                         if((item_value = usb_hid_translate_data(item, data, j)) != 0) {
    642                                                 keys[i++] = j + item->usage_minimum;
    643                                         }
    644                                         else {
    645                                                 keys[i++] = 0;
    646                                         }
    647                                 }
    648                         }
    649                 }
    650                 list_item = list_item->next;
    651         }
    652 
    653         callbacks->keyboard(keys, key_count, 0, arg);
    654            
    655         free(keys);     
    656         return EOK;
    657        
    658 }
    659 
    660 
    661 int usb_hid_translate_data(usb_hid_report_item_t *item, const uint8_t *data, size_t j)
    662 {
    663         int resolution;
    664         int offset;
    665         int part_size;
    666        
    667         int32_t value;
    668         int32_t mask;
    669         const uint8_t *foo;
    670        
    671         // now only common numbers llowed
    672         if(item->size > 32) {
    673                 return 0;
    674         }
    675 
    676         if((item->physical_minimum == 0) && (item->physical_maximum == 0)) {
    677                 item->physical_minimum = item->logical_minimum;
    678                 item->physical_maximum = item->logical_maximum;         
    679         }
    680 
    681         if(item->physical_maximum == item->physical_minimum){
    682             resolution = 1;
    683         }
    684         else {
    685             resolution = (item->logical_maximum - item->logical_minimum) /
    686                 ((item->physical_maximum - item->physical_minimum) *
    687                 (usb_pow(10,(item->unit_exponent))));
    688         }
    689         offset = item->offset + (j * item->size);
    690        
    691         // FIXME
    692         if((offset/8) != ((offset+item->size)/8)) {
    693                 usb_log_debug2("offset %d\n", offset);
    694                
    695                 part_size = ((offset+item->size)%8);
    696                 usb_log_debug2("part size %d\n",part_size);
    697 
    698                 // the higher one
    699                 foo = data+(offset/8);
    700                 mask =  ((1 << (item->size-part_size))-1);
    701                 value = (*foo & mask) << part_size;
    702 
    703                 usb_log_debug2("hfoo %x\n", *foo);
    704                 usb_log_debug2("hmaska %x\n",  mask);
    705                 usb_log_debug2("hval %d\n", value);             
    706 
    707                 // the lower one
    708                 foo = data+((offset+item->size)/8);
    709                 mask =  ((1 << part_size)-1) << (8-part_size);
    710                 value += ((*foo & mask) >> (8-part_size));
    711 
    712                 usb_log_debug2("lfoo %x\n", *foo);
    713                 usb_log_debug2("lmaska %x\n",  mask);
    714                 usb_log_debug2("lval %d\n", ((*foo & mask) >> (8-(item->size-part_size))));             
    715                 usb_log_debug2("val %d\n", value);
    716                
    717                
    718         }
    719         else {         
    720                 foo = data+(offset/8);
    721                 mask =  ((1 << item->size)-1) << (8-((offset%8)+item->size));
    722                 value = (*foo & mask) >> (8-((offset%8)+item->size));
    723 
    724                 usb_log_debug2("offset %d\n", offset);
    725        
    726                 usb_log_debug2("foo %x\n", *foo);
    727                 usb_log_debug2("maska %x\n",  mask);
    728                 usb_log_debug2("val %d\n", value);                             
    729         }
    730 
    731         usb_log_debug2("---\n\n");
    732 
    733         return (int)(((value - item->logical_minimum) / resolution) + item->physical_minimum);
    734        
    735 }
    736 
    737 int usb_hid_report_input_length(const usb_hid_report_parser_t *parser,
    738         const usb_hid_report_path_t *path)
    739 {
    740         int ret = 0;
    741         link_t *item;
    742         usb_hid_report_item_t *report_item;
    743 
    744         item = (&parser->input)->next;
    745         while(&parser->input != item) {
    746                 report_item = list_get_instance(item, usb_hid_report_item_t, link);
    747                 if(!USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags) &&
    748                    (report_item->usage_page == path->usage_page)) {
    749                         ret += report_item->count;
    750                 }
    751 
    752                 item = item->next;
    753         }
    754 
    755         return ret;
    756 }
    757 
    758 
    759 
    760 /**
    761155 * @}
    762156 */
Note: See TracChangeset for help on using the changeset viewer.