Changes in / [e69f10b:45dd8bf] in mainline


Ignore:
Location:
uspace
Files:
1 deleted
6 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/usbhid/hiddev.c

    re69f10b r45dd8bf  
    158158        }
    159159       
    160         hid_dev->report_desc_size = length;
    161        
    162160        usb_log_debug("Done.\n");
    163161       
     
    264262       
    265263        if (rc != EOK) {
    266                 usb_log_warning("Problem with getting Report descriptor: %s.\n",
     264                usb_log_warning("Problem with parsing Report descriptor: %s.\n",
    267265                    str_error(rc));
    268266                return rc;
    269267        }
    270        
    271         rc = usb_hid_parse_report_descriptor(hid_dev->parser,
    272             hid_dev->report_desc, hid_dev->report_desc_size);
    273         if (rc != EOK) {
    274                 usb_log_warning("Problem parsing Report descriptor: %s.\n",
    275                     str_error(rc));
    276                 return rc;
    277         }
    278        
    279         usb_hid_descriptor_print(hid_dev->parser);
    280268       
    281269        return EOK;
     
    301289       
    302290        memset(dev, 0, sizeof(usbhid_dev_t));
    303        
    304         dev->parser = (usb_hid_report_parser_t *)(malloc(sizeof(
    305             usb_hid_report_parser_t)));
    306         if (dev->parser == NULL) {
    307                 usb_log_fatal("No memory!\n");
    308                 free(dev);
    309                 return NULL;
    310         }
    311291       
    312292        dev->initialized = 0;
     
    411391                return rc;
    412392        }
    413        
    414         /*
    415          * Initialize the report parser.
    416          */
    417         rc = usb_hid_parser_init(hid_dev->parser);
    418         if (rc != EOK) {
    419                 usb_log_error("Failed to initialize report parser.\n");
    420                 return rc;
    421         }
    422393
    423394        /*
  • uspace/drv/usbhid/hiddev.h

    re69f10b r45dd8bf  
    7575        /** Report descriptor. */
    7676        uint8_t *report_desc;
    77 
    78         size_t report_desc_size;
    79 
    8077        /** HID Report parser. */
    8178        usb_hid_report_parser_t *parser;
  • uspace/drv/usbhid/kbddev.c

    re69f10b r45dd8bf  
    541541        callbacks->keyboard = usbhid_kbd_process_keycodes;
    542542
    543         usb_log_debug("Calling usb_hid_parse_report() with "
     543        usb_log_debug("Calling usb_hid_boot_keyboard_input_report() with "
    544544            "buffer %s\n", usb_debug_str_buffer(buffer, actual_size, 0));
    545545       
    546 //      int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size,
    547 //          callbacks, kbd_dev);
    548         int rc = usb_hid_parse_report(kbd_dev->hid_dev->parser, buffer,
    549             actual_size, callbacks, kbd_dev);
     546        int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size,
     547            callbacks, kbd_dev);
    550548       
    551549        if (rc != EOK) {
     
    616614                free((*kbd_dev)->repeat_mtx);
    617615        }
    618 
    619         usb_hid_free_report_parser((*kbd_dev)->parser);
    620616       
    621617        free(*kbd_dev);
     
    713709        assert(kbd_dev->hid_dev != NULL);
    714710        assert(kbd_dev->hid_dev->initialized);
    715         //usbhid_req_set_protocol(kbd_dev->hid_dev, USB_HID_PROTOCOL_BOOT);
     711        usbhid_req_set_protocol(kbd_dev->hid_dev, USB_HID_PROTOCOL_BOOT);
    716712       
    717713        usbhid_kbd_set_led(kbd_dev);
  • uspace/drv/usbhid/kbddev.h

    re69f10b r45dd8bf  
    4242
    4343#include <usb/classes/hid.h>
    44 #include <usb/classes/hidparser.h>
    4544#include <ddf/driver.h>
    4645#include <usb/pipes.h>
     
    10099        /** Mutex for accessing the information about auto-repeat. */
    101100        fibril_mutex_t *repeat_mtx;
    102 
    103         usb_hid_report_parser_t *parser;
    104101       
    105102        /** State of the structure (for checking before use). */
  • uspace/lib/usb/include/usb/classes/hidparser.h

    re69f10b r45dd8bf  
    3737
    3838#include <stdint.h>
    39 #include <adt/list.h>
    40 #include <usb/classes/hid_report_items.h>
    41 
    42 /**
    43  * Item prefix
    44  */
    45 #define USB_HID_ITEM_SIZE(data)         ((uint8_t)(data & 0x3))
    46 #define USB_HID_ITEM_TAG(data)          ((uint8_t)((data & 0xF0) >> 4))
    47 #define USB_HID_ITEM_TAG_CLASS(data)    ((uint8_t)((data & 0xC) >> 2))
    48 #define USB_HID_ITEM_IS_LONG(data)      (data == 0xFE)
    49 
    50 
    51 /**
    52  * Input/Output/Feature Item flags
    53  */
    54 #define USB_HID_ITEM_FLAG_CONSTANT(flags)       (flags & 0x1)
    55 #define USB_HID_ITEM_FLAG_VARIABLE(flags)       (flags & 0x2)
    56 #define USB_HID_ITEM_FLAG_RELATIVE(flags)       (flags & 0x4)
    57 #define USB_HID_ITEM_FLAG_WRAP(flags)           (flags & 0x8)
    58 #define USB_HID_ITEM_FLAG_LINEAR(flags)         (flags & 0x10)
    59 #define USB_HID_ITEM_FLAG_PREFERRED(flags)      (flags & 0x20)
    60 #define USB_HID_ITEM_FLAG_POSITION(flags)       (flags & 0x40)
    61 #define USB_HID_ITEM_FLAG_VOLATILE(flags)       (flags & 0x80)
    62 #define USB_HID_ITEM_FLAG_BUFFERED(flags)       (flags & 0x100)
    63 
    6439
    6540/**
     
    6742 */
    6843typedef struct {
    69         int32_t id;
    70         int32_t usage_page;
    71         int32_t usage; 
    72         int32_t usage_minimum;
    73         int32_t usage_maximum;
    74         int32_t logical_minimum;
    75         int32_t logical_maximum;
    76         int32_t size;
    77         int32_t count;
    78         size_t offset;
    79         int32_t delimiter;
    8044
    81         int32_t unit_exponent;
    82         int32_t unit;
     45        uint8_t usage_min;
     46        uint8_t usage_max;
     47        uint8_t logical_min;
     48        uint8_t logical_max;
     49        uint8_t size;
     50        uint8_t count;
     51        uint8_t offset;
    8352
    84         /*
    85          * some not yet used fields
    86          */
    87         int32_t string_index;
    88         int32_t string_minimum;
    89         int32_t string_maximum;
    90         int32_t designator_index;
    91         int32_t designator_minimum;
    92         int32_t designator_maximum;
    93         int32_t physical_minimum;
    94         int32_t physical_maximum;
    95 
    96         uint8_t item_flags;
    97 
    98         link_t link;
    9953} usb_hid_report_item_t;
    10054
    10155
    10256/** HID report parser structure. */
    103 typedef struct {       
    104         link_t input;
    105         link_t output;
    106         link_t feature;
    107 } usb_hid_report_parser_t;     
    108 
     57typedef struct {
     58} usb_hid_report_parser_t;
    10959
    11060
     
    177127int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size);
    178128
    179 int usb_hid_parser_init(usb_hid_report_parser_t *parser);
    180129int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser,
    181130    const uint8_t *data, size_t size);
     
    186135
    187136
    188 void usb_hid_free_report_parser(usb_hid_report_parser_t *parser);
    189 
    190 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser);
     137int usb_hid_free_report_parser(usb_hid_report_parser_t *parser);
    191138
    192139#endif
  • uspace/lib/usb/src/hidparser.c

    re69f10b r45dd8bf  
    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                                         link_initialize(&(new_report_item->link));
    181                                         report_item = new_report_item;
    182                                        
    183                                         break;
    184                                 case USB_HID_REPORT_TAG_PUSH:
    185                                         // push current state to stack
    186                                         // not yet implemented
    187                                         break;
    188                                 case USB_HID_REPORT_TAG_POP:
    189                                         // restore current state from stack
    190                                         // not yet implemented                                             
    191                                         break;
    192                                        
    193                                 default:
    194                                         // nothing special to do                                       
    195                                         break;
    196                         }
    197 
    198                         /* jump over the processed block */
    199                         i += 1 + USB_HID_ITEM_SIZE(data[i]);
    200                 }
    201                 else{
    202                         // TBD
    203                         i += 3 + USB_HID_ITEM_SIZE(data[i+1]);
    204                 }
    205                
    206 
     67        /* main parsing loop */
     68        while(0){
    20769        }
    20870       
     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
    20991        return EOK;
    21092}
     
    234116        item.size = 8;
    235117        item.count = 6;
    236         item.usage_minimum = 0;
    237         item.usage_maximum = 255;
    238         item.logical_minimum = 0;
    239         item.logical_maximum = 255;
     118        item.usage_min = 0;
     119        item.usage_max = 255;
     120        item.logical_min = 0;
     121        item.logical_max = 255;
    240122
    241123        if (size != 8) {
    242                 return -1; //ERANGE;
     124                return ERANGE;
    243125        }
    244126
     
    262144int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size)
    263145{
    264         if(size != 1){
     146        if (size < 1){
    265147                return -1;
    266148        }
    267149
    268         /* used only first five bits, others are only padding*/
    269         *data = leds;
     150        data[0] = leds;
    270151        return EOK;
    271152}
    272153
    273154/**
    274  *
    275  * @param Tag to parse
    276  * @param Report descriptor buffer
    277  * @param Size of data belongs to this tag
    278  * @param Current report item structe
    279  * @return Code of action to be done next
    280  */
    281 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size,
    282                              usb_hid_report_item_t *report_item)
    283 {       
    284         int ret;
    285        
    286         switch(class){
    287                 case USB_HID_TAG_CLASS_MAIN:
    288 
    289                         if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item)) == EOK) {
    290                                 return USB_HID_NEW_REPORT_ITEM;
    291                         }
    292                         else {
    293                                 /*TODO process the error */
    294                                 return ret;
    295                            }
    296                         break;
    297 
    298                 case USB_HID_TAG_CLASS_GLOBAL: 
    299                         return usb_hid_report_parse_global_tag(tag,data,item_size,report_item);
    300                         break;
    301 
    302                 case USB_HID_TAG_CLASS_LOCAL:                   
    303                         return usb_hid_report_parse_local_tag(tag,data,item_size,report_item);
    304                         break;
    305                 default:
    306                         return USB_HID_NO_ACTION;
    307         }
    308 }
    309 
    310 /**
    311  * Parse main tags of report descriptor
    312  *
    313  * @param Tag identifier
    314  * @param Data buffer
    315  * @param Length of data buffer
    316  * @param Current state table
    317  * @return Error code
    318  */
    319 
    320 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    321                              usb_hid_report_item_t *report_item)
    322 {
    323         switch(tag)
    324         {
    325                 case USB_HID_REPORT_TAG_INPUT:
    326                 case USB_HID_REPORT_TAG_OUTPUT:
    327                 case USB_HID_REPORT_TAG_FEATURE:
    328                         report_item->item_flags = *data;                       
    329                         return EOK;                     
    330                         break;
    331                        
    332                 case USB_HID_REPORT_TAG_COLLECTION:
    333                         // TODO
    334                         return USB_HID_NO_ACTION;
    335                         break;
    336                        
    337                 case USB_HID_REPORT_TAG_END_COLLECTION:
    338                         /* should be ignored */
    339                         return USB_HID_NO_ACTION;
    340                         break;
    341                 default:
    342                         return USB_HID_NO_ACTION;
    343         }
    344 
    345         return EOK;
    346 }
    347 
    348 /**
    349  * Parse global tags of report descriptor
    350  *
    351  * @param Tag identifier
    352  * @param Data buffer
    353  * @param Length of data buffer
    354  * @param Current state table
    355  * @return Error code
    356  */
    357 
    358 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    359                              usb_hid_report_item_t *report_item)
    360 {
    361         // TODO take care about the bit length of data
    362         switch(tag)
    363         {
    364                 case USB_HID_REPORT_TAG_USAGE_PAGE:
    365                         report_item->usage_page = usb_hid_report_tag_data_int32(data,item_size);
    366                         break;
    367                 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM:
    368                         report_item->logical_minimum = usb_hid_report_tag_data_int32(data,item_size);
    369                         break;
    370                 case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM:
    371                         report_item->logical_maximum = usb_hid_report_tag_data_int32(data,item_size);
    372                         break;
    373                 case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM:
    374                         report_item->physical_minimum = usb_hid_report_tag_data_int32(data,item_size);
    375                         break;                 
    376                 case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM:
    377                         report_item->physical_maximum = usb_hid_report_tag_data_int32(data,item_size);
    378                         break;
    379                 case USB_HID_REPORT_TAG_UNIT_EXPONENT:
    380                         report_item->unit_exponent = usb_hid_report_tag_data_int32(data,item_size);
    381                         break;
    382                 case USB_HID_REPORT_TAG_UNIT:
    383                         report_item->unit = usb_hid_report_tag_data_int32(data,item_size);
    384                         break;
    385                 case USB_HID_REPORT_TAG_REPORT_SIZE:
    386                         report_item->size = usb_hid_report_tag_data_int32(data,item_size);
    387                         break;
    388                 case USB_HID_REPORT_TAG_REPORT_COUNT:
    389                         report_item->count = usb_hid_report_tag_data_int32(data,item_size);
    390                         break;
    391                 case USB_HID_REPORT_TAG_REPORT_ID:
    392                         report_item->id = usb_hid_report_tag_data_int32(data,item_size);
    393                         break;
    394                 case USB_HID_REPORT_TAG_PUSH:
    395                 case USB_HID_REPORT_TAG_POP:
    396                         return tag;
    397                         break;
    398                        
    399                 default:
    400                         return USB_HID_NO_ACTION;
    401         }
    402        
    403         return EOK;
    404 }
    405 
    406 /**
    407  * Parse local tags of report descriptor
    408  *
    409  * @param Tag identifier
    410  * @param Data buffer
    411  * @param Length of data buffer
    412  * @param Current state table
    413  * @return Error code
    414  */
    415 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    416                              usb_hid_report_item_t *report_item)
    417 {
    418         switch(tag)
    419         {
    420                 case USB_HID_REPORT_TAG_USAGE:
    421                         report_item->usage = usb_hid_report_tag_data_int32(data,item_size);
    422                         break;
    423                 case USB_HID_REPORT_TAG_USAGE_MINIMUM:
    424                         report_item->usage_minimum = usb_hid_report_tag_data_int32(data,item_size);
    425                         break;
    426                 case USB_HID_REPORT_TAG_USAGE_MAXIMUM:
    427                         report_item->usage_maximum = usb_hid_report_tag_data_int32(data,item_size);
    428                         break;
    429                 case USB_HID_REPORT_TAG_DESIGNATOR_INDEX:
    430                         report_item->designator_index = usb_hid_report_tag_data_int32(data,item_size);
    431                         break;
    432                 case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM:
    433                         report_item->designator_minimum = usb_hid_report_tag_data_int32(data,item_size);
    434                         break;
    435                 case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM:
    436                         report_item->designator_maximum = usb_hid_report_tag_data_int32(data,item_size);
    437                         break;
    438                 case USB_HID_REPORT_TAG_STRING_INDEX:
    439                         report_item->string_index = usb_hid_report_tag_data_int32(data,item_size);
    440                         break;
    441                 case USB_HID_REPORT_TAG_STRING_MINIMUM:
    442                         report_item->string_minimum = usb_hid_report_tag_data_int32(data,item_size);
    443                         break;
    444                 case USB_HID_REPORT_TAG_STRING_MAXIMUM:
    445                         report_item->string_maximum = usb_hid_report_tag_data_int32(data,item_size);
    446                         break;                 
    447                 case USB_HID_REPORT_TAG_DELIMITER:
    448                         report_item->delimiter = usb_hid_report_tag_data_int32(data,item_size);
    449                         break;
    450                
    451                 default:
    452                         return USB_HID_NO_ACTION;
    453         }
    454        
    455         return EOK;
    456 }
    457 
    458 /**
    459  * Converts raw data to int32 (thats the maximum length of short item data)
    460  *
    461  * @param Data buffer
    462  * @param Size of buffer
    463  * @return Converted int32 number
    464  */
    465 int32_t usb_hid_report_tag_data_int32(const uint8_t *data, size_t size)
    466 {
    467         unsigned int i;
    468         int32_t result;
    469 
    470         result = 0;
    471         for(i=0; i<size; i++) {
    472                 result = (result | (data[i]) << (i*8));
    473         }
    474 
    475         return result;
    476 }
    477 
    478 
    479 
    480 /**
    481  * Prints content of given list of report items.
    482  *
    483  * @param List of report items
    484  * @return void
    485  */
    486 void usb_hid_descriptor_print_list(link_t *head)
    487 {
    488         usb_hid_report_item_t *report_item;
    489         link_t *item;
    490        
    491         if(head == NULL || list_empty(head)) {
    492             usb_log_debug("\tempty\n");
    493             return;
    494         }
    495        
    496         for(item = head->next; item != head; item = item->next) {
    497                
    498                 report_item = list_get_instance(item, usb_hid_report_item_t, link);
    499 
    500                 usb_log_debug("\tOFFSET: %X\n", report_item->offset);
    501                 usb_log_debug("\tCOUNT: %X\n", report_item->count);
    502                 usb_log_debug("\tSIZE: %X\n", report_item->size);
    503                 usb_log_debug("\tCONSTANT: %X\n", USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags));
    504                 usb_log_debug("\tUSAGE: %X\n", report_item->usage);
    505                 usb_log_debug("\tUSAGE PAGE: %X\n", report_item->usage_page);
    506                 usb_log_debug("\tLOGMIN: %X\n", report_item->logical_minimum);
    507                 usb_log_debug("\tLOGMAX: %X\n", report_item->logical_maximum);         
    508                 usb_log_debug("\tPHYMIN: %X\n", report_item->physical_minimum);         
    509                 usb_log_debug("\tPHYMAX: %X\n", report_item->physical_maximum);                         
    510                 usb_log_debug("\n");           
    511 
    512         }
    513 
    514 
    515 }
    516 /**
    517  * Prints content of given descriptor in human readable format.
    518  *
    519  * @param Parsed descriptor to print
    520  * @return void
    521  */
    522 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser)
    523 {
    524         usb_log_debug("INPUT:\n");
    525         usb_hid_descriptor_print_list(&parser->input);
    526        
    527         usb_log_debug("OUTPUT: \n");
    528         usb_hid_descriptor_print_list(&parser->output);
    529        
    530         usb_log_debug("FEATURE:\n");   
    531         usb_hid_descriptor_print_list(&parser->feature);
    532 
    533 }
    534 
    535 /**
    536  * Releases whole linked list of report items
    537  *
    538  *
    539  */
    540 void usb_hid_free_report_list(link_t *head)
    541 {
    542         return;
    543        
    544         usb_hid_report_item_t *report_item;
    545         link_t *next;
    546        
    547         if(head == NULL || list_empty(head)) {         
    548             return;
    549         }
    550        
    551         next = head->next;
    552         while(next != head) {
    553        
    554             report_item = list_get_instance(next, usb_hid_report_item_t, link);
    555             next = next->next;
    556            
    557             free(report_item);
    558         }
    559        
    560         return;
    561        
    562 }
    563 
    564 /** Free the HID report parser structure
    565  *
    566  * @param parser Opaque HID report parser structure
    567  * @return Error code
    568  */
    569 void usb_hid_free_report_parser(usb_hid_report_parser_t *parser)
    570 {
    571         if(parser == NULL){
    572                 return;
    573         }
    574 
    575         usb_hid_free_report_list(&parser->input);
    576         usb_hid_free_report_list(&parser->output);
    577         usb_hid_free_report_list(&parser->feature);
    578 
    579         return;
    580 }
    581 
    582 /** Parse and act upon a HID report.
    583  *
    584  * @see usb_hid_parse_report_descriptor
    585  *
    586  * @param parser Opaque HID report parser structure.
    587  * @param data Data for the report.
    588  * @param callbacks Callbacks for report actions.
    589  * @param arg Custom argument (passed through to the callbacks).
    590  * @return Error code.
    591  */
    592 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 
    593     const uint8_t *data, size_t size,
    594     const usb_hid_report_in_callbacks_t *callbacks, void *arg)
    595 {
    596         /*
    597          *
    598          * only key codes (usage page 0x07) will be processed
    599          * other usages will be ignored
    600          */
    601         link_t *list_item;
    602         usb_hid_report_item_t *item;
    603         uint8_t *keys;
    604         size_t key_count=0;
    605         size_t i=0;
    606         size_t j=0;
    607 
    608         // get the size of result keycodes array
    609         list_item = parser->input.next;   
    610         while(list_item != &(parser->input)) {
    611 
    612                 item = list_get_instance(list_item, usb_hid_report_item_t, link);
    613                 if(item->usage_page == BAD_HACK_USAGE_PAGE) {
    614                         key_count += item->count;
    615                 }
    616 
    617                 list_item = list_item->next;
    618         }
    619 
    620        
    621         if(!(keys = malloc(sizeof(uint8_t) * key_count))){
    622                 return ENOMEM;
    623         }
    624 
    625         // read data           
    626         list_item = parser->input.next;   
    627         while(list_item != &(parser->input)) {
    628 
    629                 item = list_get_instance(list_item, usb_hid_report_item_t, link);
    630                 if(item->usage_page == BAD_HACK_USAGE_PAGE) {
    631                         for(j=0; j<(size_t)(item->count); j++) {
    632                                 keys[i++] = usb_hid_translate_data(item, data,j);
    633                         }
    634                 }
    635                 list_item = list_item->next;
    636         }
    637 
    638         callbacks->keyboard(keys, key_count, 0, arg);
    639            
    640         free(keys);     
    641         return EOK;
    642        
    643 }
    644 
    645 
    646 int usb_hid_translate_data(usb_hid_report_item_t *item, const uint8_t *data, size_t j)
    647 {
    648         int resolution;
    649         int offset;
    650         int part_size;
    651        
    652         int32_t value;
    653         int32_t mask;
    654         const uint8_t *foo;
    655        
    656         // now only common numbers llowed
    657         if(item->size > 32) {
    658                 return 0;
    659         }
    660 
    661         if((item->physical_minimum == 0) && (item->physical_maximum == 0)) {
    662                 item->physical_minimum = item->logical_minimum;
    663                 item->physical_maximum = item->logical_maximum;         
    664         }
    665 
    666         if(item->physical_maximum == item->physical_minimum){
    667             resolution = 1;
    668         }
    669         else {
    670             resolution = (item->logical_maximum - item->logical_minimum) /
    671                 ((item->physical_maximum - item->physical_minimum) *
    672                 (usb_pow(10,(item->unit_exponent))));
    673         }
    674         offset = item->offset + (j * item->size);
    675        
    676         // FIXME
    677         if((offset/8) != ((offset+item->size)/8)) {
    678                 usb_log_debug2("offset %d\n", offset);
    679                
    680                 part_size = ((offset+item->size)%8);
    681                 usb_log_debug2("part size %d\n",part_size);
    682 
    683                 // the higher one
    684                 foo = data+(offset/8);
    685                 mask =  ((1 << (item->size-part_size))-1);
    686                 value = (*foo & mask) << part_size;
    687 
    688                 usb_log_debug2("hfoo %x\n", *foo);
    689                 usb_log_debug2("hmaska %x\n",  mask);
    690                 usb_log_debug2("hval %d\n", value);             
    691 
    692                 // the lower one
    693                 foo = data+((offset+item->size)/8);
    694                 mask =  ((1 << part_size)-1) << (8-part_size);
    695                 value += ((*foo & mask) >> (8-part_size));
    696 
    697                 usb_log_debug2("lfoo %x\n", *foo);
    698                 usb_log_debug2("lmaska %x\n",  mask);
    699                 usb_log_debug2("lval %d\n", ((*foo & mask) >> (8-(item->size-part_size))));             
    700                 usb_log_debug2("val %d\n", value);
    701                
    702                
    703         }
    704         else {         
    705                 foo = data+(offset/8);
    706                 mask =  ((1 << item->size)-1) << (8-((offset%8)+item->size));
    707                 value = (*foo & mask) >> (8-((offset%8)+item->size));
    708 
    709                 usb_log_debug2("offset %d\n", offset);
    710        
    711                 usb_log_debug2("foo %x\n", *foo);
    712                 usb_log_debug2("maska %x\n",  mask);
    713                 usb_log_debug2("val %d\n", value);                             
    714         }
    715 
    716         usb_log_debug2("---\n\n");
    717 
    718         return (int)(((value - item->logical_minimum) / resolution) + item->physical_minimum);
    719        
    720 }
    721 /**
    722155 * @}
    723156 */
Note: See TracChangeset for help on using the changeset viewer.