Changes in / [59e01689:e93e319] in mainline


Ignore:
Location:
uspace
Files:
1 deleted
10 edited

Legend:

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

    r59e01689 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         */
     
    440411        if (rc != EOK) {
    441412                /* TODO: end session?? */
    442                 usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe);
    443413                usb_log_error("Failed to process descriptors: %s.\n",
    444414                    str_error(rc));
  • uspace/drv/usbhid/hiddev.h

    r59e01689 re93e319  
    3232/** @file
    3333 * Generic USB HID device structure and API.
    34  *
    35  * @todo Add function for parsing report - this is generic HID function, not
    36  *       keyboard-specific, as the report parser is also generic.
    37  * @todo Add function for polling as that is also a generic HID process.
    38  * @todo Add interrupt in pipe to the structure.
    3934 */
    4035
     
    8075        /** Report descriptor. */
    8176        uint8_t *report_desc;
    82 
    83         size_t report_desc_size;
    84 
    8577        /** HID Report parser. */
    8678        usb_hid_report_parser_t *parser;
  • uspace/drv/usbhid/kbddev.c

    r59e01689 re93e319  
    5151#include <usb/classes/hidparser.h>
    5252#include <usb/classes/classes.h>
    53 #include <usb/classes/hidut.h>
    5453
    5554#include "kbddev.h"
     
    9493        .flags = 0
    9594};
    96 
    97 typedef enum usbhid_kbd_flags {
    98         USBHID_KBD_STATUS_UNINITIALIZED = 0,
    99         USBHID_KBD_STATUS_INITIALIZED = 1,
    100         USBHID_KBD_STATUS_TO_DESTROY = -1
    101 } usbhid_kbd_flags;
    10295
    10396/*----------------------------------------------------------------------------*/
     
    131124};
    132125
    133 typedef enum usbhid_lock_code {
    134         USBHID_LOCK_NUM = 0x53,
    135         USBHID_LOCK_CAPS = 0x39,
    136         USBHID_LOCK_SCROLL = 0x47,
    137         USBHID_LOCK_COUNT = 3
    138 } usbhid_lock_code;
    139 
    140 static const usbhid_lock_code usbhid_lock_codes[USBHID_LOCK_COUNT] = {
    141         USBHID_LOCK_NUM,
    142         USBHID_LOCK_CAPS,
    143         USBHID_LOCK_SCROLL
    144 };
    145 
    146126/*----------------------------------------------------------------------------*/
    147127/* IPC method handler                                                         */
     
    238218       
    239219        assert(kbd_dev->hid_dev != NULL);
    240         assert(kbd_dev->hid_dev->initialized == USBHID_KBD_STATUS_INITIALIZED);
     220        assert(kbd_dev->hid_dev->initialized);
    241221        usbhid_req_set_report(kbd_dev->hid_dev, USB_HID_REPORT_TYPE_OUTPUT,
    242222            buffer, BOOTP_BUFFER_OUT_SIZE);
     
    366346 * @sa usbhid_kbd_push_ev()
    367347 */
    368 //static void usbhid_kbd_check_modifier_changes(usbhid_kbd_t *kbd_dev,
    369 //    const uint8_t *key_codes, size_t count)
    370 //{
    371 //      /*
    372 //       * TODO: why the USB keyboard has NUM_, SCROLL_ and CAPS_LOCK
    373 //       *       both as modifiers and as keyUSB_HID_LOCK_COUNTs with their own scancodes???
    374 //       *
    375 //       * modifiers should be sent as normal keys to usbhid_parse_scancode()!!
    376 //       * so maybe it would be better if I received it from report parser in
    377 //       * that way
    378 //       */
    379        
    380 //      int i;
    381 //      for (i = 0; i < count; ++i) {
    382 //              if ((modifiers & usb_hid_modifiers_consts[i]) &&
    383 //                  !(kbd_dev->modifiers & usb_hid_modifiers_consts[i])) {
    384 //                      // modifier pressed
    385 //                      if (usbhid_modifiers_keycodes[i] != 0) {
    386 //                              usbhid_kbd_push_ev(kbd_dev, KEY_PRESS,
    387 //                                  usbhid_modifiers_keycodes[i]);
    388 //                      }
    389 //              } else if (!(modifiers & usb_hid_modifiers_consts[i]) &&
    390 //                  (kbd_dev->modifiers & usb_hid_modifiers_consts[i])) {
    391 //                      // modifier released
    392 //                      if (usbhid_modifiers_keycodes[i] != 0) {
    393 //                              usbhid_kbd_push_ev(kbd_dev, KEY_RELEASE,
    394 //                                  usbhid_modifiers_keycodes[i]);
    395 //                      }
    396 //              }       // no change
    397 //      }
    398        
    399 //      kbd_dev->modifiers = modifiers;
    400 //}
    401 
    402 /*----------------------------------------------------------------------------*/
    403 
    404 static inline int usbhid_kbd_is_lock(unsigned int key_code)
    405 {
    406         return (key_code == KC_NUM_LOCK
    407             || key_code == KC_SCROLL_LOCK
    408             || 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;
    409380}
    410381
     
    433404        /*
    434405         * First of all, check if the kbd have reported phantom state.
    435          *
    436          * TODO: this must be changed as we don't know which keys are modifiers
    437          *       and which are regular keys.
    438406         */
    439407        i = 0;
     
    466434                        // not found, i.e. the key was released
    467435                        key = usbhid_parse_scancode(kbd_dev->keys[j]);
    468                         if (!usbhid_kbd_is_lock(key)) {
    469                                 usbhid_kbd_repeat_stop(kbd_dev, key);
    470                         }
     436                        usbhid_kbd_repeat_stop(kbd_dev, key);
    471437                        usbhid_kbd_push_ev(kbd_dev, KEY_RELEASE, key);
    472438                        usb_log_debug2("Key released: %d\n", key);
     
    492458                            key_codes[i]);
    493459                        usbhid_kbd_push_ev(kbd_dev, KEY_PRESS, key);
    494                         if (!usbhid_kbd_is_lock(key)) {
    495                                 usbhid_kbd_repeat_start(kbd_dev, key);
    496                         }
     460                        usbhid_kbd_repeat_start(kbd_dev, key);
    497461                } else {
    498462                        // found, nothing happens
     
    538502
    539503        usb_log_debug("Got keys from parser: %s\n",
    540             usb_debug_str_buffer(key_codes, count, 0));
     504            usb_debug_str_buffer(key_codes, kbd_dev->key_count, 0));
    541505       
    542506        if (count != kbd_dev->key_count) {
     
    546510        }
    547511       
    548         ///usbhid_kbd_check_modifier_changes(kbd_dev, key_codes, count);
     512        usbhid_kbd_check_modifier_changes(kbd_dev, modifiers);
    549513        usbhid_kbd_check_key_changes(kbd_dev, key_codes, count);
    550514}
     
    571535                                    uint8_t *buffer, size_t actual_size)
    572536{
    573         assert(kbd_dev->initialized == USBHID_KBD_STATUS_INITIALIZED);
    574         assert(kbd_dev->hid_dev->parser != NULL);
    575        
    576537        usb_hid_report_in_callbacks_t *callbacks =
    577538            (usb_hid_report_in_callbacks_t *)malloc(
     
    580541        callbacks->keyboard = usbhid_kbd_process_keycodes;
    581542
    582         usb_log_debug("Calling usb_hid_parse_report() with "
     543        usb_log_debug("Calling usb_hid_boot_keyboard_input_report() with "
    583544            "buffer %s\n", usb_debug_str_buffer(buffer, actual_size, 0));
    584545       
    585 //      int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size,
    586 //          callbacks, kbd_dev);
    587         int rc = usb_hid_parse_report(kbd_dev->hid_dev->parser, buffer,
    588             actual_size, callbacks, kbd_dev);
     546        int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size,
     547            callbacks, kbd_dev);
    589548       
    590549        if (rc != EOK) {
     
    625584       
    626585        kbd_dev->console_phone = -1;
    627         kbd_dev->initialized = USBHID_KBD_STATUS_UNINITIALIZED;
     586        kbd_dev->initialized = 0;
    628587       
    629588        return kbd_dev;
     
    631590
    632591/*----------------------------------------------------------------------------*/
    633 
    634 static void usbhid_kbd_mark_unusable(usbhid_kbd_t *kbd_dev)
    635 {
    636         kbd_dev->initialized = USBHID_KBD_STATUS_TO_DESTROY;
     592/**
     593 * Properly destroys the USB/HID keyboard structure.
     594 *
     595 * @param kbd_dev Pointer to the structure to be destroyed.
     596 */
     597static void usbhid_kbd_free(usbhid_kbd_t **kbd_dev)
     598{
     599        if (kbd_dev == NULL || *kbd_dev == NULL) {
     600                return;
     601        }
     602       
     603        // hangup phone to the console
     604        async_hangup((*kbd_dev)->console_phone);
     605       
     606        if ((*kbd_dev)->hid_dev != NULL) {
     607                usbhid_dev_free(&(*kbd_dev)->hid_dev);
     608                assert((*kbd_dev)->hid_dev == NULL);
     609        }
     610       
     611        if ((*kbd_dev)->repeat_mtx != NULL) {
     612                /* TODO: replace by some check and wait */
     613                assert(!fibril_mutex_is_locked((*kbd_dev)->repeat_mtx));
     614                free((*kbd_dev)->repeat_mtx);
     615        }
     616       
     617        free(*kbd_dev);
     618        *kbd_dev = NULL;
    637619}
    638620
     
    676658        }
    677659       
    678         if (kbd_dev->initialized == USBHID_KBD_STATUS_INITIALIZED) {
     660        if (kbd_dev->initialized) {
    679661                usb_log_warning("Keyboard structure already initialized.\n");
    680662                return EINVAL;
     
    689671        }
    690672       
    691         assert(kbd_dev->hid_dev->initialized == USBHID_KBD_STATUS_INITIALIZED);
     673        assert(kbd_dev->hid_dev->initialized);
    692674       
    693675        // save the size of the report (boot protocol report by default)
    694 //      kbd_dev->key_count = BOOTP_REPORT_SIZE;
    695        
    696         usb_hid_report_path_t path;
    697         path.usage_page = USB_HIDUT_PAGE_KEYBOARD;
    698         kbd_dev->key_count = usb_hid_report_input_length(
    699             kbd_dev->hid_dev->parser, &path);
    700        
    701         usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count);
    702        
     676        kbd_dev->key_count = BOOTP_REPORT_SIZE;
    703677        kbd_dev->keys = (uint8_t *)calloc(
    704678            kbd_dev->key_count, sizeof(uint8_t));
     
    735709        assert(kbd_dev->hid_dev != NULL);
    736710        assert(kbd_dev->hid_dev->initialized);
    737         //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);
    738712       
    739713        usbhid_kbd_set_led(kbd_dev);
     
    741715        usbhid_req_set_idle(kbd_dev->hid_dev, IDLE_RATE);
    742716       
    743         kbd_dev->initialized = USBHID_KBD_STATUS_INITIALIZED;
     717        kbd_dev->initialized = 1;
    744718        usb_log_info("HID/KBD device structure initialized.\n");
    745719       
     
    855829        usbhid_kbd_poll(kbd_dev);
    856830       
    857         // as there is another fibril using this device, so we must leave the
    858         // structure to it, but mark it for destroying.
    859         usbhid_kbd_mark_unusable(kbd_dev);
    860831        // at the end, properly destroy the KBD structure
    861 //      usbhid_kbd_free(&kbd_dev);
    862 //      assert(kbd_dev == NULL);
     832        usbhid_kbd_free(&kbd_dev);
     833        assert(kbd_dev == NULL);
    863834
    864835        return EOK;
     
    982953}
    983954
    984 /*----------------------------------------------------------------------------*/
    985 
    986 int usbhid_kbd_is_usable(const usbhid_kbd_t *kbd_dev)
    987 {
    988         return (kbd_dev->initialized == USBHID_KBD_STATUS_INITIALIZED);
    989 }
    990 
    991 /*----------------------------------------------------------------------------*/
    992 /**
    993  * Properly destroys the USB/HID keyboard structure.
    994  *
    995  * @param kbd_dev Pointer to the structure to be destroyed.
    996  */
    997 void usbhid_kbd_free(usbhid_kbd_t **kbd_dev)
    998 {
    999         if (kbd_dev == NULL || *kbd_dev == NULL) {
    1000                 return;
    1001         }
    1002        
    1003         // hangup phone to the console
    1004         async_hangup((*kbd_dev)->console_phone);
    1005        
    1006         if ((*kbd_dev)->hid_dev != NULL) {
    1007                 usbhid_dev_free(&(*kbd_dev)->hid_dev);
    1008                 assert((*kbd_dev)->hid_dev == NULL);
    1009         }
    1010        
    1011         if ((*kbd_dev)->repeat_mtx != NULL) {
    1012                 /* TODO: replace by some check and wait */
    1013                 assert(!fibril_mutex_is_locked((*kbd_dev)->repeat_mtx));
    1014                 free((*kbd_dev)->repeat_mtx);
    1015         }
    1016 
    1017         free(*kbd_dev);
    1018         *kbd_dev = NULL;
    1019 }
    1020 
    1021955/**
    1022956 * @}
  • uspace/drv/usbhid/kbddev.h

    r59e01689 re93e319  
    4242
    4343#include <usb/classes/hid.h>
    44 #include <usb/classes/hidparser.h>
    4544#include <ddf/driver.h>
    4645#include <usb/pipes.h>
     
    101100        fibril_mutex_t *repeat_mtx;
    102101       
    103         /** State of the structure (for checking before use).
    104          *
    105          * 0 - not initialized
    106          * 1 - initialized
    107          * -1 - ready for destroying
    108          */
     102        /** State of the structure (for checking before use). */
    109103        int initialized;
    110104} usbhid_kbd_t;
     
    113107
    114108int usbhid_kbd_try_add_device(ddf_dev_t *dev);
    115 
    116 int usbhid_kbd_is_usable(const usbhid_kbd_t *kbd_dev);
    117 
    118 void usbhid_kbd_free(usbhid_kbd_t **kbd_dev);
    119109
    120110void usbhid_kbd_push_ev(usbhid_kbd_t *kbd_dev, int type, unsigned int key);
  • uspace/drv/usbhid/kbdrepeat.c

    r59e01689 re93e319  
    7777
    7878        while (true) {
    79                 // check if the kbd structure is usable
    80                 if (!usbhid_kbd_is_usable(kbd)) {
    81                         usbhid_kbd_free(&kbd);
    82                         assert(kbd == NULL);
    83                         return;
    84                 }
    85                
    8679                fibril_mutex_lock(kbd->repeat_mtx);
    8780
  • uspace/drv/usbmouse/init.c

    r59e01689 re93e319  
    124124                goto leave;
    125125        }
    126        
    127         /* Open the control pipe. */
    128         rc = usb_endpoint_pipe_start_session(&dev->ctrl_pipe);
    129         if (rc != EOK) {
    130                 goto leave;
    131         }
    132        
    133         /* Set the boot protocol. */
    134         rc = usb_control_request_set(&dev->ctrl_pipe,
    135             USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
    136             USB_HIDREQ_SET_PROTOCOL, USB_HID_PROTOCOL_BOOT, dev->interface_no,
    137             NULL, 0);
    138         if (rc != EOK) {
    139                 goto leave;
    140         }
    141        
    142         /* Close the control pipe (ignore errors). */
    143         usb_endpoint_pipe_end_session(&dev->ctrl_pipe);
    144 
    145126
    146127        /* Everything allright. */
  • uspace/lib/usb/include/usb/classes/hidparser.h

    r59e01689 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/include/usb/devdrv.h

    r59e01689 re93e319  
    4747         */
    4848        usb_endpoint_mapping_t *pipes;
    49         /** Current interface.
    50          * Usually, drivers operate on single interface only.
    51          * This item contains the value of the interface or -1 for any.
    52          */
    53         int interface_no;
    5449        /** Generic DDF device backing this one. */
    5550        ddf_dev_t *ddf_dev;
  • uspace/lib/usb/src/devdrv.c

    r59e01689 re93e319  
    109109{
    110110        int rc;
    111         dev->interface_no = usb_device_get_assigned_interface(dev->ddf_dev);
     111        int my_interface = usb_device_get_assigned_interface(dev->ddf_dev);
    112112
    113113        size_t pipe_count = count_other_pipes(drv);
     
    134134
    135135                dev->pipes[i].description = drv->endpoints[i];
    136                 dev->pipes[i].interface_no = dev->interface_no;
     136                dev->pipes[i].interface_no = my_interface;
    137137        }
    138138
  • uspace/lib/usb/src/hidparser.c

    r59e01689 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.