Changes in / [98637224:e93e319] in mainline


Ignore:
Location:
uspace
Files:
1 deleted
6 edited

Legend:

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

    r98637224 re93e319  
    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;
     
    419399
    420400        /*
    421          * Initialize the report parser.
    422          */
    423         rc = usb_hid_parser_init(hid_dev->parser);
    424         if (rc != EOK) {
    425                 usb_log_error("Failed to initialize report parser.\n");
    426                 return rc;
    427         }
    428 
    429         /*
    430401         * Get descriptors, parse descriptors and save endpoints.
    431402         */
  • uspace/drv/usbhid/hiddev.h

    r98637224 re93e319  
    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

    r98637224 re93e319  
    5151#include <usb/classes/hidparser.h>
    5252#include <usb/classes/classes.h>
    53 #include <usb/classes/hidut.h>
    5453
    5554#include "kbddev.h"
     
    123122        KC_RALT,          /* USB_HID_MOD_RALT */
    124123        0,                /* USB_HID_MOD_RGUI */
    125 };
    126 
    127 typedef enum usbhid_lock_code {
    128         USBHID_LOCK_NUM = 0x53,
    129         USBHID_LOCK_CAPS = 0x39,
    130         USBHID_LOCK_SCROLL = 0x47,
    131         USBHID_LOCK_COUNT = 3
    132 } usbhid_lock_code;
    133 
    134 static const usbhid_lock_code usbhid_lock_codes[USBHID_LOCK_COUNT] = {
    135         USBHID_LOCK_NUM,
    136         USBHID_LOCK_CAPS,
    137         USBHID_LOCK_SCROLL
    138124};
    139125
     
    360346 * @sa usbhid_kbd_push_ev()
    361347 */
    362 //static void usbhid_kbd_check_modifier_changes(usbhid_kbd_t *kbd_dev,
    363 //    const uint8_t *key_codes, size_t count)
    364 //{
    365 //      /*
    366 //       * TODO: why the USB keyboard has NUM_, SCROLL_ and CAPS_LOCK
    367 //       *       both as modifiers and as keyUSB_HID_LOCK_COUNTs with their own scancodes???
    368 //       *
    369 //       * modifiers should be sent as normal keys to usbhid_parse_scancode()!!
    370 //       * so maybe it would be better if I received it from report parser in
    371 //       * that way
    372 //       */
    373        
    374 //      int i;
    375 //      for (i = 0; i < count; ++i) {
    376 //              if ((modifiers & usb_hid_modifiers_consts[i]) &&
    377 //                  !(kbd_dev->modifiers & usb_hid_modifiers_consts[i])) {
    378 //                      // modifier pressed
    379 //                      if (usbhid_modifiers_keycodes[i] != 0) {
    380 //                              usbhid_kbd_push_ev(kbd_dev, KEY_PRESS,
    381 //                                  usbhid_modifiers_keycodes[i]);
    382 //                      }
    383 //              } else if (!(modifiers & usb_hid_modifiers_consts[i]) &&
    384 //                  (kbd_dev->modifiers & usb_hid_modifiers_consts[i])) {
    385 //                      // modifier released
    386 //                      if (usbhid_modifiers_keycodes[i] != 0) {
    387 //                              usbhid_kbd_push_ev(kbd_dev, KEY_RELEASE,
    388 //                                  usbhid_modifiers_keycodes[i]);
    389 //                      }
    390 //              }       // no change
    391 //      }
    392        
    393 //      kbd_dev->modifiers = modifiers;
    394 //}
    395 
    396 /*----------------------------------------------------------------------------*/
    397 
    398 static inline int usbhid_kbd_is_lock(unsigned int key_code)
    399 {
    400         return (key_code == KC_NUM_LOCK
    401             || key_code == KC_SCROLL_LOCK
    402             || key_code == KC_CAPS_LOCK);
     348static void usbhid_kbd_check_modifier_changes(usbhid_kbd_t *kbd_dev,
     349    uint8_t modifiers)
     350{
     351        /*
     352         * TODO: why the USB keyboard has NUM_, SCROLL_ and CAPS_LOCK
     353         *       both as modifiers and as keys with their own scancodes???
     354         *
     355         * modifiers should be sent as normal keys to usbhid_parse_scancode()!!
     356         * so maybe it would be better if I received it from report parser in
     357         * that way
     358         */
     359       
     360        int i;
     361        for (i = 0; i < USB_HID_MOD_COUNT; ++i) {
     362                if ((modifiers & usb_hid_modifiers_consts[i]) &&
     363                    !(kbd_dev->modifiers & usb_hid_modifiers_consts[i])) {
     364                        // modifier pressed
     365                        if (usbhid_modifiers_keycodes[i] != 0) {
     366                                usbhid_kbd_push_ev(kbd_dev, KEY_PRESS,
     367                                    usbhid_modifiers_keycodes[i]);
     368                        }
     369                } else if (!(modifiers & usb_hid_modifiers_consts[i]) &&
     370                    (kbd_dev->modifiers & usb_hid_modifiers_consts[i])) {
     371                        // modifier released
     372                        if (usbhid_modifiers_keycodes[i] != 0) {
     373                                usbhid_kbd_push_ev(kbd_dev, KEY_RELEASE,
     374                                    usbhid_modifiers_keycodes[i]);
     375                        }
     376                }       // no change
     377        }
     378       
     379        kbd_dev->modifiers = modifiers;
    403380}
    404381
     
    427404        /*
    428405         * First of all, check if the kbd have reported phantom state.
    429          *
    430          * TODO: this must be changed as we don't know which keys are modifiers
    431          *       and which are regular keys.
    432406         */
    433407        i = 0;
     
    460434                        // not found, i.e. the key was released
    461435                        key = usbhid_parse_scancode(kbd_dev->keys[j]);
    462                         if (!usbhid_kbd_is_lock(key)) {
    463                                 usbhid_kbd_repeat_stop(kbd_dev, key);
    464                         }
     436                        usbhid_kbd_repeat_stop(kbd_dev, key);
    465437                        usbhid_kbd_push_ev(kbd_dev, KEY_RELEASE, key);
    466438                        usb_log_debug2("Key released: %d\n", key);
     
    486458                            key_codes[i]);
    487459                        usbhid_kbd_push_ev(kbd_dev, KEY_PRESS, key);
    488                         if (!usbhid_kbd_is_lock(key)) {
    489                                 usbhid_kbd_repeat_start(kbd_dev, key);
    490                         }
     460                        usbhid_kbd_repeat_start(kbd_dev, key);
    491461                } else {
    492462                        // found, nothing happens
     
    532502
    533503        usb_log_debug("Got keys from parser: %s\n",
    534             usb_debug_str_buffer(key_codes, count, 0));
     504            usb_debug_str_buffer(key_codes, kbd_dev->key_count, 0));
    535505       
    536506        if (count != kbd_dev->key_count) {
     
    540510        }
    541511       
    542         ///usbhid_kbd_check_modifier_changes(kbd_dev, key_codes, count);
     512        usbhid_kbd_check_modifier_changes(kbd_dev, modifiers);
    543513        usbhid_kbd_check_key_changes(kbd_dev, key_codes, count);
    544514}
     
    565535                                    uint8_t *buffer, size_t actual_size)
    566536{
    567         assert(kbd_dev->initialized);
    568         assert(kbd_dev->hid_dev->parser != NULL);
    569        
    570537        usb_hid_report_in_callbacks_t *callbacks =
    571538            (usb_hid_report_in_callbacks_t *)malloc(
     
    574541        callbacks->keyboard = usbhid_kbd_process_keycodes;
    575542
    576         usb_log_debug("Calling usb_hid_parse_report() with "
     543        usb_log_debug("Calling usb_hid_boot_keyboard_input_report() with "
    577544            "buffer %s\n", usb_debug_str_buffer(buffer, actual_size, 0));
    578545       
    579 //      int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size,
    580 //          callbacks, kbd_dev);
    581         int rc = usb_hid_parse_report(kbd_dev->hid_dev->parser, buffer,
    582             actual_size, callbacks, kbd_dev);
     546        int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size,
     547            callbacks, kbd_dev);
    583548       
    584549        if (rc != EOK) {
     
    649614                free((*kbd_dev)->repeat_mtx);
    650615        }
    651 
     616       
    652617        free(*kbd_dev);
    653618        *kbd_dev = NULL;
     
    709674       
    710675        // save the size of the report (boot protocol report by default)
    711 //      kbd_dev->key_count = BOOTP_REPORT_SIZE;
    712        
    713         usb_hid_report_path_t path;
    714         path.usage_page = USB_HIDUT_PAGE_KEYBOARD;
    715         kbd_dev->key_count = usb_hid_report_input_length(
    716             kbd_dev->hid_dev->parser, &path);
    717        
    718         usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count);
    719        
     676        kbd_dev->key_count = BOOTP_REPORT_SIZE;
    720677        kbd_dev->keys = (uint8_t *)calloc(
    721678            kbd_dev->key_count, sizeof(uint8_t));
     
    752709        assert(kbd_dev->hid_dev != NULL);
    753710        assert(kbd_dev->hid_dev->initialized);
    754         //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);
    755712       
    756713        usbhid_kbd_set_led(kbd_dev);
  • uspace/drv/usbhid/kbddev.h

    r98637224 re93e319  
    4242
    4343#include <usb/classes/hid.h>
    44 #include <usb/classes/hidparser.h>
    4544#include <ddf/driver.h>
    4645#include <usb/pipes.h>
  • uspace/lib/usb/include/usb/classes/hidparser.h

    r98637224 re93e319  
    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 /** Constant (1) / Variable (0) */
    55 #define USB_HID_ITEM_FLAG_CONSTANT(flags)       ((flags & 0x1) == 0x1)
    56 /** Variable (1) / Array (0) */
    57 #define USB_HID_ITEM_FLAG_VARIABLE(flags)       ((flags & 0x2) == 0x2)
    58 /** Absolute / Relative*/
    59 #define USB_HID_ITEM_FLAG_RELATIVE(flags)       ((flags & 0x4) == 0x4)
    60 /** Wrap / No Wrap */
    61 #define USB_HID_ITEM_FLAG_WRAP(flags)           ((flags & 0x8) == 0x8)
    62 #define USB_HID_ITEM_FLAG_LINEAR(flags)         ((flags & 0x10) == 0x10)
    63 #define USB_HID_ITEM_FLAG_PREFERRED(flags)      ((flags & 0x20) == 0x20)
    64 #define USB_HID_ITEM_FLAG_POSITION(flags)       ((flags & 0x40) == 0x40)
    65 #define USB_HID_ITEM_FLAG_VOLATILE(flags)       ((flags & 0x80) == 0x80)
    66 #define USB_HID_ITEM_FLAG_BUFFERED(flags)       ((flags & 0x100) == 0x100)
    67 
    68 
    69 /**
    70  * Description of path of usage pages and usages in report descriptor
    71  */
    72 typedef struct {
    73         int32_t usage_page;
    74 } usb_hid_report_path_t;
    7539
    7640/**
     
    7842 */
    7943typedef struct {
    80         int32_t id;
    81         int32_t usage_page;
    82         int32_t usage; 
    83         int32_t usage_minimum;
    84         int32_t usage_maximum;
    85         int32_t logical_minimum;
    86         int32_t logical_maximum;
    87         int32_t size;
    88         int32_t count;
    89         size_t offset;
    90         int32_t delimiter;
    9144
    92         int32_t unit_exponent;
    93         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;
    9452
    95         /*
    96          * some not yet used fields
    97          */
    98         int32_t string_index;
    99         int32_t string_minimum;
    100         int32_t string_maximum;
    101         int32_t designator_index;
    102         int32_t designator_minimum;
    103         int32_t designator_maximum;
    104         int32_t physical_minimum;
    105         int32_t physical_maximum;
    106 
    107         uint8_t item_flags;
    108 
    109         link_t link;
    11053} usb_hid_report_item_t;
    11154
    11255
    11356/** HID report parser structure. */
    114 typedef struct {       
    115         link_t input;
    116         link_t output;
    117         link_t feature;
    118 } usb_hid_report_parser_t;     
    119 
     57typedef struct {
     58} usb_hid_report_parser_t;
    12059
    12160
     
    188127int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size);
    189128
    190 int usb_hid_parser_init(usb_hid_report_parser_t *parser);
    191129int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser,
    192130    const uint8_t *data, size_t size);
     
    196134    const usb_hid_report_in_callbacks_t *callbacks, void *arg);
    197135
    198 int usb_hid_report_input_length(const usb_hid_report_parser_t *parser,
    199         const usb_hid_report_path_t *path);
    200136
    201 
    202 void usb_hid_free_report_parser(usb_hid_report_parser_t *parser);
    203 
    204 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser);
     137int usb_hid_free_report_parser(usb_hid_report_parser_t *parser);
    205138
    206139#endif
  • uspace/lib/usb/src/hidparser.c

    r98637224 re93e319  
    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.