Changes in / [9e929a0:152ec79] in mainline


Ignore:
Location:
uspace
Files:
2 deleted
20 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/usbhid/Makefile

    r9e929a0 r152ec79  
    4747        mouse/mousedev.c \
    4848        lgtch-ultrax/lgtch-ultrax.c \
    49         lgtch-ultrax/keymap.c \
    5049        $(STOLEN_LAYOUT_SOURCES)
    5150
  • uspace/drv/usbhid/kbd/conv.c

    r9e929a0 r152ec79  
    9999        [0x30] = KC_RBRACKET,
    100100        [0x31] = KC_BACKSLASH,
    101         //[0x32] = KC_, // TODO: HASH??? maybe same as 0x31 - backslash
    102         [0x32] = KC_BACKSLASH,
     101        //[0x32] = KC_, // TODO: HASH??? maybe some as 0x31 - backslash
    103102        [0x33] = KC_SEMICOLON,
    104103        [0x34] = KC_QUOTE,  // same as APOSTROPHE? (')
  • uspace/drv/usbhid/kbd/kbddev.c

    r9e929a0 r152ec79  
    177177/*----------------------------------------------------------------------------*/
    178178
    179 //static void usb_kbd_process_keycodes(const uint8_t *key_codes, size_t count,
    180 //    uint8_t report_id, void *arg);
    181 
    182 //static const usb_hid_report_in_callbacks_t usb_kbd_parser_callbacks = {
    183 //      .keyboard = usb_kbd_process_keycodes
    184 //};
     179static void usb_kbd_process_keycodes(const uint8_t *key_codes, size_t count,
     180    uint8_t report_id, void *arg);
     181
     182static const usb_hid_report_in_callbacks_t usb_kbd_parser_callbacks = {
     183        .keyboard = usb_kbd_process_keycodes
     184};
    185185
    186186/*----------------------------------------------------------------------------*/
     
    203203/*----------------------------------------------------------------------------*/
    204204/** Mapping of USB modifier key codes to generic modifier key codes. */
    205 //static const keycode_t usbhid_modifiers_keycodes[USB_HID_MOD_COUNT] = {
    206 //      KC_LCTRL,         /* USB_HID_MOD_LCTRL */
    207 //      KC_LSHIFT,        /* USB_HID_MOD_LSHIFT */
    208 //      KC_LALT,          /* USB_HID_MOD_LALT */
    209 //      0,                /* USB_HID_MOD_LGUI */
    210 //      KC_RCTRL,         /* USB_HID_MOD_RCTRL */
    211 //      KC_RSHIFT,        /* USB_HID_MOD_RSHIFT */
    212 //      KC_RALT,          /* USB_HID_MOD_RALT */
    213 //      0,                /* USB_HID_MOD_RGUI */
    214 //};
    215 
    216 //typedef enum usbhid_lock_code {
    217 //      USB_KBD_LOCK_NUM = 0x53,
    218 //      USB_KBD_LOCK_CAPS = 0x39,
    219 //      USB_KBD_LOCK_SCROLL = 0x47,
    220 //      USB_KBD_LOCK_COUNT = 3
    221 //} usbhid_lock_code;
    222 
    223 //static const usbhid_lock_code usbhid_lock_codes[USB_KBD_LOCK_COUNT] = {
    224 //      USB_KBD_LOCK_NUM,
    225 //      USB_KBD_LOCK_CAPS,
    226 //      USB_KBD_LOCK_SCROLL
    227 //};
     205static const keycode_t usbhid_modifiers_keycodes[USB_HID_MOD_COUNT] = {
     206        KC_LCTRL,         /* USB_HID_MOD_LCTRL */
     207        KC_LSHIFT,        /* USB_HID_MOD_LSHIFT */
     208        KC_LALT,          /* USB_HID_MOD_LALT */
     209        0,                /* USB_HID_MOD_LGUI */
     210        KC_RCTRL,         /* USB_HID_MOD_RCTRL */
     211        KC_RSHIFT,        /* USB_HID_MOD_RSHIFT */
     212        KC_RALT,          /* USB_HID_MOD_RALT */
     213        0,                /* USB_HID_MOD_RGUI */
     214};
     215
     216typedef enum usbhid_lock_code {
     217        USB_KBD_LOCK_NUM = 0x53,
     218        USB_KBD_LOCK_CAPS = 0x39,
     219        USB_KBD_LOCK_SCROLL = 0x47,
     220        USB_KBD_LOCK_COUNT = 3
     221} usbhid_lock_code;
     222
     223static const usbhid_lock_code usbhid_lock_codes[USB_KBD_LOCK_COUNT] = {
     224        USB_KBD_LOCK_NUM,
     225        USB_KBD_LOCK_CAPS,
     226        USB_KBD_LOCK_SCROLL
     227};
    228228
    229229/*----------------------------------------------------------------------------*/
     
    299299                return;
    300300        }
    301                
     301       
     302        unsigned i = 0;
     303       
    302304        /* Reset the LED data. */
    303305        memset(kbd_dev->led_data, 0, kbd_dev->led_output_size * sizeof(int32_t));
    304         usb_log_debug("Creating output report:\n");
    305 
    306         usb_hid_report_field_t *field = usb_hid_report_get_sibling(
    307             hid_dev->report, NULL, kbd_dev->led_path,
    308             USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY | USB_HID_PATH_COMPARE_END,
    309             USB_HID_REPORT_TYPE_OUTPUT);
    310        
    311         while (field != NULL) {
    312 
    313                 if ((field->usage == USB_HID_LED_NUM_LOCK)
    314                     && (kbd_dev->mods & KM_NUM_LOCK)){
    315                         field->value = 1;
    316                 }
    317 
    318                 if ((field->usage == USB_HID_LED_CAPS_LOCK)
    319                     && (kbd_dev->mods & KM_CAPS_LOCK)){
    320                         field->value = 1;
    321                 }
    322 
    323                 if ((field->usage == USB_HID_LED_SCROLL_LOCK)
    324                     && (kbd_dev->mods & KM_SCROLL_LOCK)){
    325                         field->value = 1;
    326                 }
    327                
    328                 field = usb_hid_report_get_sibling(hid_dev->report, field,
    329                     kbd_dev->led_path, USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY
    330                     | USB_HID_PATH_COMPARE_END, USB_HID_REPORT_TYPE_OUTPUT);
    331         }
    332        
    333         // TODO: what about the Report ID?
    334         int rc = usb_hid_report_output_translate(hid_dev->report, 0,
    335             kbd_dev->output_buffer, kbd_dev->output_size);
     306       
     307        if ((kbd_dev->mods & KM_NUM_LOCK) && (i < kbd_dev->led_output_size)) {
     308                kbd_dev->led_data[i++] = USB_HID_LED_NUM_LOCK;
     309        }
     310       
     311        if ((kbd_dev->mods & KM_CAPS_LOCK) && (i < kbd_dev->led_output_size)) {
     312                kbd_dev->led_data[i++] = USB_HID_LED_CAPS_LOCK;
     313        }
     314       
     315        if ((kbd_dev->mods & KM_SCROLL_LOCK)
     316            && (i < kbd_dev->led_output_size)) {
     317                kbd_dev->led_data[i++] = USB_HID_LED_SCROLL_LOCK;
     318        }
     319
     320        // TODO: COMPOSE and KANA
     321       
     322        usb_log_debug("Creating output report.\n");
     323       
     324        int rc = usb_hid_report_output_translate(hid_dev->parser,
     325            kbd_dev->led_path,
     326            USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
     327            kbd_dev->output_buffer,
     328            kbd_dev->output_size, kbd_dev->led_data, kbd_dev->led_output_size);
    336329       
    337330        if (rc != EOK) {
     
    492485 */
    493486static void usb_kbd_check_key_changes(usb_hid_dev_t *hid_dev,
    494     usb_kbd_t *kbd_dev/*, const uint8_t *key_codes, size_t count*/)
     487    usb_kbd_t *kbd_dev, const uint8_t *key_codes, size_t count)
    495488{
    496489        unsigned int key;
     
    506499         */
    507500        i = 0;
    508         while (i < kbd_dev->key_count && kbd_dev->keys[i] != ERROR_ROLLOVER) {
     501        while (i < count && key_codes[i] != ERROR_ROLLOVER) {
    509502                ++i;
    510503        }
    511         if (i != kbd_dev->key_count) {
     504        if (i != count) {
    512505                usb_log_debug("Phantom state occured.\n");
    513506                // phantom state, do nothing
    514507                return;
    515508        }
     509       
     510        /* TODO: quite dummy right now, think of better implementation */
     511        assert(count == kbd_dev->key_count);
    516512       
    517513        /*
    518514         * 1) Key releases
    519515         */
    520         for (j = 0; j < kbd_dev->key_count; ++j) {
     516        for (j = 0; j < count; ++j) {
    521517                // try to find the old key in the new key list
    522518                i = 0;
    523519                while (i < kbd_dev->key_count
    524                     && kbd_dev->keys[i] != kbd_dev->keys_old[j]) {
     520                    && key_codes[i] != kbd_dev->keys[j]) {
    525521                        ++i;
    526522                }
    527523               
    528                 if (i == kbd_dev->key_count) {
     524                if (i == count) {
    529525                        // not found, i.e. the key was released
    530                         key = usbhid_parse_scancode(kbd_dev->keys_old[j]);
     526                        key = usbhid_parse_scancode(kbd_dev->keys[j]);
    531527                        if (!usb_kbd_is_lock(key)) {
    532528                                usb_kbd_repeat_stop(kbd_dev, key);
     
    545541                // try to find the new key in the old key list
    546542                j = 0;
    547                 while (j < kbd_dev->key_count
    548                     && kbd_dev->keys_old[j] != kbd_dev->keys[i]) {
     543                while (j < count && kbd_dev->keys[j] != key_codes[i]) {
    549544                        ++j;
    550545                }
    551546               
    552                 if (j == kbd_dev->key_count) {
     547                if (j == count) {
    553548                        // not found, i.e. new key pressed
    554                         key = usbhid_parse_scancode(kbd_dev->keys[i]);
     549                        key = usbhid_parse_scancode(key_codes[i]);
    555550                        usb_log_debug2("Key pressed: %d (keycode: %d)\n", key,
    556                             kbd_dev->keys[i]);
    557                         usb_kbd_push_ev(hid_dev, kbd_dev, KEY_PRESS, key);
     551                            key_codes[i]);
     552                        usb_kbd_push_ev(hid_dev, kbd_dev, KEY_PRESS,
     553                            key);
    558554                        if (!usb_kbd_is_lock(key)) {
    559555                                usb_kbd_repeat_start(kbd_dev, key);
     
    564560        }
    565561       
    566 //      usb_log_debug("Old keys: ");
    567 //      for (i = 0; i < kbd_dev->key_count; ++i) {
    568 //              usb_log_debug("%d ", kbd_dev->keys_old[i]);
    569 //      }
    570 //      usb_log_debug("\n");
    571        
    572        
    573 //      usb_log_debug("New keys: ");
    574 //      for (i = 0; i < kbd_dev->key_count; ++i) {
    575 //              usb_log_debug("%d ", kbd_dev->keys[i]);
    576 //      }
    577 //      usb_log_debug("\n");
    578        
    579         memcpy(kbd_dev->keys_old, kbd_dev->keys, kbd_dev->key_count * 4);
    580        
    581         usb_log_debug2("New stored keys: ");
    582         for (i = 0; i < kbd_dev->key_count; ++i) {
    583                 usb_log_debug2("%d ", kbd_dev->keys_old[i]);
    584         }
    585         usb_log_debug2("\n");
     562        memcpy(kbd_dev->keys, key_codes, count);
     563
     564        usb_log_debug("New stored keycodes: %s\n",
     565            usb_debug_str_buffer(kbd_dev->keys, kbd_dev->key_count, 0));
    586566}
    587567
     
    605585 * @sa usb_kbd_check_key_changes(), usb_kbd_check_modifier_changes()
    606586 */
    607 //static void usb_kbd_process_keycodes(const uint8_t *key_codes, size_t count,
    608 //    uint8_t report_id, void *arg)
    609 //{
    610 //      if (arg == NULL) {
    611 //              usb_log_warning("Missing argument in callback "
    612 //                  "usbhid_process_keycodes().\n");
    613 //              return;
    614 //      }
    615        
    616 //      usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;
    617        
    618 //      if (hid_dev->data == NULL) {
    619 //              usb_log_warning("Missing KBD device structure in callback.\n");
    620 //              return;
    621 //      }
    622        
    623 //      usb_kbd_t *kbd_dev = (usb_kbd_t *)hid_dev->data;
    624 
    625 //      usb_log_debug("Got keys from parser (report id: %u): %s\n",
    626 //          report_id, usb_debug_str_buffer(key_codes, count, 0));
    627        
    628 //      if (count != kbd_dev->key_count) {
    629 //              usb_log_warning("Number of received keycodes (%zu) differs from"
    630 //                  " expected (%zu).\n", count, kbd_dev->key_count);
    631 //              return;
    632 //      }
    633        
    634 //      ///usb_kbd_check_modifier_changes(kbd_dev, key_codes, count);
    635 //      usb_kbd_check_key_changes(hid_dev, kbd_dev, key_codes, count);
    636 //}
     587static void usb_kbd_process_keycodes(const uint8_t *key_codes, size_t count,
     588    uint8_t report_id, void *arg)
     589{
     590        if (arg == NULL) {
     591                usb_log_warning("Missing argument in callback "
     592                    "usbhid_process_keycodes().\n");
     593                return;
     594        }
     595       
     596        usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;
     597       
     598        if (hid_dev->data == NULL) {
     599                usb_log_warning("Missing KBD device structure in callback.\n");
     600                return;
     601        }
     602       
     603        usb_kbd_t *kbd_dev = (usb_kbd_t *)hid_dev->data;
     604
     605        usb_log_debug("Got keys from parser (report id: %u): %s\n",
     606            report_id, usb_debug_str_buffer(key_codes, count, 0));
     607       
     608        if (count != kbd_dev->key_count) {
     609                usb_log_warning("Number of received keycodes (%zu) differs from"
     610                    " expected (%zu).\n", count, kbd_dev->key_count);
     611                return;
     612        }
     613       
     614        ///usb_kbd_check_modifier_changes(kbd_dev, key_codes, count);
     615        usb_kbd_check_key_changes(hid_dev, kbd_dev, key_codes, count);
     616}
    637617
    638618/*----------------------------------------------------------------------------*/
     
    658638                                 uint8_t *buffer, size_t actual_size)
    659639{
    660         assert(hid_dev->report != NULL);
    661         assert(hid_dev != NULL);
    662         assert(hid_dev->data != NULL);
    663        
    664         usb_kbd_t *kbd_dev = (usb_kbd_t *)hid_dev->data;
     640        assert(hid_dev->parser != NULL);
    665641
    666642        usb_log_debug("Calling usb_hid_parse_report() with "
     
    672648        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
    673649        //usb_hid_report_path_set_report_id(path, 0);
    674 
    675         uint8_t report_id;
    676         int rc = usb_hid_parse_report(hid_dev->report, buffer, actual_size,
    677             &report_id);
     650       
     651        int rc = usb_hid_parse_report(hid_dev->parser, buffer,
     652            actual_size, path,
     653            USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
     654            &usb_kbd_parser_callbacks, hid_dev);
     655
     656        usb_hid_report_path_free(path);
    678657       
    679658        if (rc != EOK) {
    680                 usb_log_warning("Error in usb_hid_parse_report():"
     659                usb_log_warning("Error in usb_hid_boot_keyboard_input_report():"
    681660                    "%s\n", str_error(rc));
    682661        }
    683        
    684         usb_hid_report_path_set_report_id (path, report_id);
    685        
    686         // fill in the currently pressed keys
    687        
    688         usb_hid_report_field_t *field = usb_hid_report_get_sibling(
    689             hid_dev->report, NULL, path,
    690             USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
    691             USB_HID_REPORT_TYPE_INPUT);
    692         unsigned i = 0;
    693        
    694         while (field != NULL) {
    695                 usb_log_debug2("FIELD (%p) - VALUE(%d) USAGE(%u)\n",
    696                     field, field->value, field->usage);
    697                
    698                 assert(i < kbd_dev->key_count);
    699 //              if (i == kbd_dev->key_count) {
    700 //                      break;
    701 //              }
    702                
    703                 // save the key usage
    704                 /* TODO: maybe it's not good to save value, nor usage
    705                  *       as the value may be e.g. 1 for LEDs and usage may be
    706                  *       value of the LED. On the other hand, in case of normal
    707                  *       keys, the usage is more important and we must check
    708                  *       that. One possible solution: distinguish between those
    709                  *       two parts of the Report somehow.
    710                  */
    711                 if (field->value != 0) {
    712                         kbd_dev->keys[i] = field->usage;
    713                 }
    714                 else {
    715                         kbd_dev->keys[i] = 0;
    716                 }
    717                 usb_log_debug2("Saved %u. key usage %d\n", i, kbd_dev->keys[i]);
    718                
    719                 ++i;
    720                 field = usb_hid_report_get_sibling(hid_dev->report, field, path,
    721                     USB_HID_PATH_COMPARE_END
    722                     | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
    723                     USB_HID_REPORT_TYPE_INPUT);
    724         }
    725        
    726         usb_hid_report_path_free(path);
    727        
    728         usb_kbd_check_key_changes(hid_dev, kbd_dev);
    729662}
    730663
     
    814747       
    815748        kbd_dev->key_count = usb_hid_report_input_length(
    816             hid_dev->report, path,
     749            hid_dev->parser, path,
    817750            USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY);
    818751        usb_hid_report_path_free(path);
     
    820753        usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count);
    821754       
    822         kbd_dev->keys = (int32_t *)calloc(kbd_dev->key_count, sizeof(int32_t));
     755        kbd_dev->keys = (uint8_t *)calloc(kbd_dev->key_count, sizeof(uint8_t));
    823756       
    824757        if (kbd_dev->keys == NULL) {
     
    828761        }
    829762       
    830         kbd_dev->keys_old =
    831                 (int32_t *)calloc(kbd_dev->key_count, sizeof(int32_t));
    832        
    833         if (kbd_dev->keys_old == NULL) {
    834                 usb_log_fatal("No memory!\n");
    835                 free(kbd_dev->keys);
    836                 free(kbd_dev);
    837                 return ENOMEM;
    838         }
    839        
    840763        /*
    841764         * Output report
    842765         */
    843766        kbd_dev->output_size = 0;
    844         kbd_dev->output_buffer = usb_hid_report_output(hid_dev->report,
    845             &kbd_dev->output_size, 0);
    846         if (kbd_dev->output_buffer == NULL) {
     767        kbd_dev->output_buffer = usb_hid_report_output(hid_dev->parser,
     768            &kbd_dev->output_size);
     769        if (kbd_dev->output_buffer == NULL && kbd_dev->output_size != 0) {
    847770                usb_log_warning("Error creating output report buffer.\n");
    848771                free(kbd_dev->keys);
    849                 return ENOMEM;  /* TODO: other error code */
     772                free(kbd_dev);
     773                return ENOMEM;
    850774        }
    851775       
     
    856780            kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0);
    857781       
    858         kbd_dev->led_output_size = usb_hid_report_output_size(hid_dev->report,
     782        kbd_dev->led_output_size = usb_hid_report_output_size(hid_dev->parser,
    859783            kbd_dev->led_path,
    860784            USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY);
     
    984908        }
    985909       
    986         // free all buffers
    987         if ((*kbd_dev)->keys != NULL) {
    988                 free((*kbd_dev)->keys);
    989         }
    990         if ((*kbd_dev)->keys_old != NULL) {
    991                 free((*kbd_dev)->keys_old);
    992         }
    993         if ((*kbd_dev)->led_data != NULL) {
    994                 free((*kbd_dev)->led_data);
    995         }
    996         if ((*kbd_dev)->output_buffer != NULL) {
    997                 free((*kbd_dev)->output_buffer);
    998         }
    999         if ((*kbd_dev)->led_path != NULL) {
    1000                 usb_hid_report_path_free((*kbd_dev)->led_path);
    1001         }
    1002         if ((*kbd_dev)->output_buffer != NULL) {
    1003                 usb_hid_report_output_free((*kbd_dev)->output_buffer);
    1004         }
     910        // free the output buffer
     911        usb_hid_report_output_free((*kbd_dev)->output_buffer);
    1005912
    1006913        free(*kbd_dev);
     
    1022929                } else {
    1023930                        usb_kbd_free(&kbd_dev);
    1024                         hid_dev->data = NULL;
    1025931                }
    1026932        }
     
    1031937int usb_kbd_set_boot_protocol(usb_hid_dev_t *hid_dev)
    1032938{
    1033         int rc = usb_hid_parse_report_descriptor(hid_dev->report,
     939        int rc = usb_hid_parse_report_descriptor(hid_dev->parser,
    1034940            USB_KBD_BOOT_REPORT_DESCRIPTOR,
    1035941            USB_KBD_BOOT_REPORT_DESCRIPTOR_SIZE);
  • uspace/drv/usbhid/kbd/kbddev.h

    r9e929a0 r152ec79  
    6565 */
    6666typedef struct usb_kbd_t {
    67         /** Previously pressed keys (not translated to key codes). */
    68         int32_t *keys_old;
    6967        /** Currently pressed keys (not translated to key codes). */
    70         int32_t *keys;
     68        uint8_t *keys;
    7169        /** Count of stored keys (i.e. number of keys in the report). */
    7270        size_t key_count;
  • uspace/drv/usbhid/lgtch-ultrax/lgtch-ultrax.c

    r9e929a0 r152ec79  
    3838#include "lgtch-ultrax.h"
    3939#include "../usbhid.h"
    40 #include "keymap.h"
    4140
    4241#include <usb/classes/hidparser.h>
    4342#include <usb/debug.h>
    44 #include <usb/classes/hidut.h>
    45 
    4643#include <errno.h>
    4744#include <str_error.h>
    4845
    49 #include <ipc/kbd.h>
    50 #include <io/console.h>
    51 
    5246#define NAME "lgtch-ultrax"
    53 
    54 typedef enum usb_lgtch_flags {
    55         USB_LGTCH_STATUS_UNINITIALIZED = 0,
    56         USB_LGTCH_STATUS_INITIALIZED = 1,
    57         USB_LGTCH_STATUS_TO_DESTROY = -1
    58 } usb_lgtch_flags;
    59 
    60 
    61 /*----------------------------------------------------------------------------*/
    62 /**
    63  * Default handler for IPC methods not handled by DDF.
    64  *
    65  * Currently recognizes only one method (IPC_M_CONNECT_TO_ME), in which case it
    66  * assumes the caller is the console and thus it stores IPC phone to it for
    67  * later use by the driver to notify about key events.
    68  *
    69  * @param fun Device function handling the call.
    70  * @param icallid Call id.
    71  * @param icall Call data.
    72  */
    73 static void default_connection_handler(ddf_fun_t *fun,
    74     ipc_callid_t icallid, ipc_call_t *icall)
    75 {
    76         usb_log_debug(NAME " default_connection_handler()\n");
    77        
    78         sysarg_t method = IPC_GET_IMETHOD(*icall);
    79        
    80         usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
    81        
    82         if (hid_dev == NULL || hid_dev->data == NULL) {
    83                 async_answer_0(icallid, EINVAL);
    84                 return;
    85         }
    86        
    87         assert(hid_dev != NULL);
    88         assert(hid_dev->data != NULL);
    89         usb_lgtch_ultrax_t *lgtch_dev = (usb_lgtch_ultrax_t *)hid_dev->data;
    90 
    91         if (method == IPC_M_CONNECT_TO_ME) {
    92                 int callback = IPC_GET_ARG5(*icall);
    93 
    94                 if (lgtch_dev->console_phone != -1) {
    95                         async_answer_0(icallid, ELIMIT);
    96                         return;
    97                 }
    98 
    99                 lgtch_dev->console_phone = callback;
    100                 usb_log_debug(NAME " Saved phone to console: %d\n", callback);
    101                 async_answer_0(icallid, EOK);
    102                 return;
    103         }
    104        
    105         async_answer_0(icallid, EINVAL);
    106 }
    10747
    10848/*----------------------------------------------------------------------------*/
    10949
    110 static ddf_dev_ops_t lgtch_ultrax_ops = {
    111         .default_handler = default_connection_handler
     50static void usb_lgtch_process_keycodes(const uint8_t *key_codes, size_t count,
     51    uint8_t report_id, void *arg);
     52
     53static const usb_hid_report_in_callbacks_t usb_lgtch_parser_callbacks = {
     54        .keyboard = usb_lgtch_process_keycodes
    11255};
    11356
    11457/*----------------------------------------------------------------------------*/
    11558
    116 //static void usb_lgtch_process_keycodes(const uint8_t *key_codes, size_t count,
    117 //    uint8_t report_id, void *arg);
    118 
    119 //static const usb_hid_report_in_callbacks_t usb_lgtch_parser_callbacks = {
    120 //      .keyboard = usb_lgtch_process_keycodes
    121 //};
    122 
    123 ///*----------------------------------------------------------------------------*/
    124 
    125 //static void usb_lgtch_process_keycodes(const uint8_t *key_codes, size_t count,
    126 //    uint8_t report_id, void *arg)
    127 //{
    128 //      // TODO: checks
     59static void usb_lgtch_process_keycodes(const uint8_t *key_codes, size_t count,
     60    uint8_t report_id, void *arg)
     61{
     62        // TODO: checks
    12963       
    130 //      usb_log_debug(NAME " Got keys from parser (report id: %u): %s\n",
    131 //          report_id, usb_debug_str_buffer(key_codes, count, 0));
    132 //}
    133 
    134 /*----------------------------------------------------------------------------*/
    135 /**
    136  * Processes key events.
    137  *
    138  * @note This function was copied from AT keyboard driver and modified to suit
    139  *       USB keyboard.
    140  *
    141  * @note Lock keys are not sent to the console, as they are completely handled
    142  *       in the driver. It may, however, be required later that the driver
    143  *       sends also these keys to application (otherwise it cannot use those
    144  *       keys at all).
    145  *
    146  * @param hid_dev
    147  * @param lgtch_dev
    148  * @param type Type of the event (press / release). Recognized values:
    149  *             KEY_PRESS, KEY_RELEASE
    150  * @param key Key code of the key according to HID Usage Tables.
    151  */
    152 static void usb_lgtch_push_ev(usb_hid_dev_t *hid_dev, int type,
    153     unsigned int key)
    154 {
    155         assert(hid_dev != NULL);
    156         assert(hid_dev->data != NULL);
    157        
    158         usb_lgtch_ultrax_t *lgtch_dev = (usb_lgtch_ultrax_t *)hid_dev->data;
    159        
    160         console_event_t ev;
    161        
    162         ev.type = type;
    163         ev.key = key;
    164         ev.mods = 0;
    165 
    166         ev.c = 0;
    167 
    168         usb_log_debug2(NAME " Sending key %d to the console\n", ev.key);
    169         if (lgtch_dev->console_phone < 0) {
    170                 usb_log_warning(
    171                     "Connection to console not ready, key discarded.\n");
    172                 return;
    173         }
    174        
    175         async_msg_4(lgtch_dev->console_phone, KBD_EVENT, ev.type, ev.key,
    176             ev.mods, ev.c);
    177 }
    178 
    179 /*----------------------------------------------------------------------------*/
    180 
    181 static void usb_lgtch_free(usb_lgtch_ultrax_t **lgtch_dev)
    182 {
    183         if (lgtch_dev == NULL || *lgtch_dev == NULL) {
    184                 return;
    185         }
    186        
    187         // hangup phone to the console
    188         async_hangup((*lgtch_dev)->console_phone);
    189        
    190 //      if ((*lgtch_dev)->repeat_mtx != NULL) {
    191 //              /* TODO: replace by some check and wait */
    192 //              assert(!fibril_mutex_is_locked((*lgtch_dev)->repeat_mtx));
    193 //              free((*lgtch_dev)->repeat_mtx);
    194 //      }
    195        
    196         // free all buffers
    197         if ((*lgtch_dev)->keys != NULL) {
    198                 free((*lgtch_dev)->keys);
    199         }
    200         if ((*lgtch_dev)->keys_old != NULL) {
    201                 free((*lgtch_dev)->keys_old);
    202         }
    203 
    204         free(*lgtch_dev);
    205         *lgtch_dev = NULL;
    206 }
    207 
    208 /*----------------------------------------------------------------------------*/
    209 
    210 int usb_lgtch_init(struct usb_hid_dev *hid_dev)
    211 {
    212         if (hid_dev == NULL || hid_dev->usb_dev == NULL) {
    213                 return EINVAL; /*! @todo Other return code? */
    214         }
    215        
    216         usb_log_debug(NAME " Initializing HID/lgtch_ultrax structure...\n");
    217        
    218         usb_lgtch_ultrax_t *lgtch_dev = (usb_lgtch_ultrax_t *)malloc(
    219             sizeof(usb_lgtch_ultrax_t));
    220         if (lgtch_dev == NULL) {
    221                 return ENOMEM;
    222         }
    223        
    224         lgtch_dev->console_phone = -1;
    225        
    226         usb_hid_report_path_t *path = usb_hid_report_path();
    227         usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0);
    228        
    229         usb_hid_report_path_set_report_id(path, 1);
    230        
    231         lgtch_dev->key_count = usb_hid_report_input_length(
    232             hid_dev->report, path,
    233             USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY);
    234         usb_hid_report_path_free(path);
    235        
    236         usb_log_debug(NAME " Size of the input report: %zu\n",
    237             lgtch_dev->key_count);
    238        
    239         lgtch_dev->keys = (int32_t *)calloc(lgtch_dev->key_count,
    240             sizeof(int32_t));
    241        
    242         if (lgtch_dev->keys == NULL) {
    243                 usb_log_fatal("No memory!\n");
    244                 free(lgtch_dev);
    245                 return ENOMEM;
    246         }
    247        
    248         lgtch_dev->keys_old =
    249                 (int32_t *)calloc(lgtch_dev->key_count, sizeof(int32_t));
    250        
    251         if (lgtch_dev->keys_old == NULL) {
    252                 usb_log_fatal("No memory!\n");
    253                 free(lgtch_dev->keys);
    254                 free(lgtch_dev);
    255                 return ENOMEM;
    256         }
    257        
    258         /*! @todo Autorepeat */
    259        
    260         // save the KBD device structure into the HID device structure
    261         hid_dev->data = lgtch_dev;
    262        
    263         /* Create the function exposed under /dev/devices. */
    264         ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
    265             NAME);
    266         if (fun == NULL) {
    267                 usb_log_error("Could not create DDF function node.\n");
    268                 return ENOMEM;
    269         }
    270        
    271         lgtch_dev->initialized = USB_LGTCH_STATUS_INITIALIZED;
    272         usb_log_debug(NAME " HID/lgtch_ultrax device structure initialized.\n");
    273        
    274         /*
    275          * Store the initialized HID device and HID ops
    276          * to the DDF function.
    277          */
    278         fun->ops = &lgtch_ultrax_ops;
    279         fun->driver_data = hid_dev;   // TODO: maybe change to hid_dev->data
    280        
    281         /*
    282          * 1) subdriver vytvori vlastnu ddf_fun, vlastne ddf_dev_ops, ktore da
    283          *    do nej.
    284          * 2) do tych ops do .interfaces[DEV_IFACE_USBHID (asi)] priradi
    285          *    vyplnenu strukturu usbhid_iface_t.
    286          * 3) klientska aplikacia - musi si rucne vytvorit telefon
    287          *    (devman_device_connect() - cesta k zariadeniu (/hw/pci0/...) az
    288          *    k tej fcii.
    289          *    pouzit usb/classes/hid/iface.h - prvy int je telefon
    290          */
    291 
    292         int rc = ddf_fun_bind(fun);
    293         if (rc != EOK) {
    294                 usb_log_error("Could not bind DDF function: %s.\n",
    295                     str_error(rc));
    296                 // TODO: Can / should I destroy the DDF function?
    297                 ddf_fun_destroy(fun);
    298                 usb_lgtch_free(&lgtch_dev);
    299                 return rc;
    300         }
    301        
    302         rc = ddf_fun_add_to_class(fun, "keyboard");
    303         if (rc != EOK) {
    304                 usb_log_error(
    305                     "Could not add DDF function to class 'keyboard': %s.\n",
    306                     str_error(rc));
    307                 // TODO: Can / should I destroy the DDF function?
    308                 ddf_fun_destroy(fun);
    309                 usb_lgtch_free(&lgtch_dev);
    310                 return rc;
    311         }
    312        
    313         usb_log_debug(NAME " HID/lgtch_ultrax structure initialized.\n");
    314        
    315         return EOK;
    316 }
    317 
    318 /*----------------------------------------------------------------------------*/
    319 
    320 void usb_lgtch_deinit(struct usb_hid_dev *hid_dev)
    321 {
    322         if (hid_dev == NULL) {
    323                 return;
    324         }
    325        
    326         if (hid_dev->data != NULL) {
    327                 usb_lgtch_ultrax_t *lgtch_dev =
    328                     (usb_lgtch_ultrax_t *)hid_dev->data;
    329 //              if (usb_kbd_is_initialized(kbd_dev)) {
    330 //                      usb_kbd_mark_unusable(kbd_dev);
    331 //              } else {
    332                         usb_lgtch_free(&lgtch_dev);
    333                         hid_dev->data = NULL;
    334 //              }
    335         }
     64        usb_log_debug(NAME " Got keys from parser (report id: %u): %s\n",
     65            report_id, usb_debug_str_buffer(key_codes, count, 0));
    33666}
    33767
     
    35181        usb_hid_report_path_t *path = usb_hid_report_path();
    35282        usb_hid_report_path_append_item(path, 0xc, 0);
    353 
    354         uint8_t report_id;
     83        usb_hid_report_path_set_report_id(path, 1);
    35584       
    356         int rc = usb_hid_parse_report(hid_dev->report, buffer, buffer_size,
    357             &report_id);
    358         usb_hid_report_path_set_report_id(path, report_id);
    359 
    360         usb_hid_report_field_t *field = usb_hid_report_get_sibling(
    361             hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END
    362             | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
    363             USB_HID_REPORT_TYPE_INPUT);
    364        
    365         unsigned int key;
    366        
    367         /*! @todo Is this iterating OK if done multiple times?
    368          *  @todo The parsing is not OK
    369          */
    370         while (field != NULL) {
    371                 usb_log_debug(NAME " KEY VALUE(%X) USAGE(%X)\n", field->value,
    372                     field->usage);
    373                
    374                 key = usb_lgtch_map_usage(field->usage);
    375                 usb_lgtch_push_ev(hid_dev, KEY_PRESS, key);
    376                
    377                 field = usb_hid_report_get_sibling(
    378                     hid_dev->report, field, path, USB_HID_PATH_COMPARE_END
    379                     | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
    380                     USB_HID_REPORT_TYPE_INPUT);
    381         }       
     85        int rc = usb_hid_parse_report(hid_dev->parser, buffer,
     86            buffer_size, path,
     87            USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
     88            &usb_lgtch_parser_callbacks, hid_dev);
    38289
    38390        usb_hid_report_path_free(path);
    38491       
    38592        if (rc != EOK) {
    386                 usb_log_warning(NAME "Error in usb_hid_boot_keyboard_input_report():"
     93                usb_log_warning("Error in usb_hid_boot_keyboard_input_report():"
    38794                    "%s\n", str_error(rc));
    38895        }
  • uspace/drv/usbhid/lgtch-ultrax/lgtch-ultrax.h

    r9e929a0 r152ec79  
    4040
    4141struct usb_hid_dev;
    42 
    43 /*----------------------------------------------------------------------------*/
    44 /**
    45  * USB/HID keyboard device type.
    46  *
    47  * Holds a reference to generic USB/HID device structure and keyboard-specific
    48  * data, such as currently pressed keys, modifiers and lock keys.
    49  *
    50  * Also holds a IPC phone to the console (since there is now no other way to
    51  * communicate with it).
    52  *
    53  * @note Storing active lock keys in this structure results in their setting
    54  *       being device-specific.
    55  */
    56 typedef struct usb_lgtch_ultrax_t {
    57         /** Previously pressed keys (not translated to key codes). */
    58         int32_t *keys_old;
    59         /** Currently pressed keys (not translated to key codes). */
    60         int32_t *keys;
    61         /** Count of stored keys (i.e. number of keys in the report). */
    62         size_t key_count;
    63        
    64         /** IPC phone to the console device (for sending key events). */
    65         int console_phone;
    66 
    67         /** Information for auto-repeat of keys. */
    68 //      usb_kbd_repeat_t repeat;
    69        
    70         /** Mutex for accessing the information about auto-repeat. */
    71 //      fibril_mutex_t *repeat_mtx;
    72 
    73         /** State of the structure (for checking before use).
    74          *
    75          * 0 - not initialized
    76          * 1 - initialized
    77          * -1 - ready for destroying
    78          */
    79         int initialized;
    80 } usb_lgtch_ultrax_t;
     42//struct usb_hid_subdriver_mapping;
    8143
    8244/*----------------------------------------------------------------------------*/
    8345
    84 int usb_lgtch_init(struct usb_hid_dev *hid_dev);
     46//extern struct usb_hid_subdriver_mapping usb_lgtch_mapping;
    8547
    86 void usb_lgtch_deinit(struct usb_hid_dev *hid_dev);
     48/*----------------------------------------------------------------------------*/
     49
     50//int usb_lgtch_init(struct usb_hid_dev *hid_dev);
    8751
    8852bool usb_lgtch_polling_callback(struct usb_hid_dev *hid_dev, uint8_t *buffer,
  • uspace/drv/usbhid/main.c

    r9e929a0 r152ec79  
    114114        hid_fun->ops = &hid_dev->ops;
    115115        hid_fun->driver_data = hid_dev;   // TODO: maybe change to hid_dev->data
    116        
    117         /*
    118          * 1) subdriver vytvori vlastnu ddf_fun, vlastne ddf_dev_ops, ktore da
    119          *    do nej.
    120          * 2) do tych ops do .interfaces[DEV_IFACE_USBHID (asi)] priradi
    121          *    vyplnenu strukturu usbhid_iface_t.
    122          * 3) klientska aplikacia - musi si rucne vytvorit telefon
    123          *    (devman_device_connect() - cesta k zariadeniu (/hw/pci0/...) az
    124          *    k tej fcii.
    125          *    pouzit usb/classes/hid/iface.h - prvy int je telefon
    126          */
    127116
    128117        rc = ddf_fun_bind(hid_fun);
  • uspace/drv/usbhid/mouse/mousedev.c

    r9e929a0 r152ec79  
    296296int usb_mouse_set_boot_protocol(usb_hid_dev_t *hid_dev)
    297297{
    298         int rc = usb_hid_parse_report_descriptor(hid_dev->report,
     298        int rc = usb_hid_parse_report_descriptor(hid_dev->parser,
    299299            USB_MOUSE_BOOT_REPORT_DESCRIPTOR,
    300300            USB_MOUSE_BOOT_REPORT_DESCRIPTOR_SIZE);
  • uspace/drv/usbhid/subdrivers.c

    r9e929a0 r152ec79  
    5555                USB_HID_PATH_COMPARE_END
    5656                | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
    57                 -1,
    58                 -1,
     57                0,
     58                0,
    5959                {
    6060                        .init = usb_kbd_init,
     
    7373                0xc30e,
    7474                {
    75                         .init = usb_lgtch_init,
    76                         .deinit = usb_lgtch_deinit,
     75                        .init = NULL,
     76                        .deinit = NULL,
    7777                        .poll = usb_lgtch_polling_callback,
    7878                        .poll_end = NULL
    7979                }
    8080        },
    81         {NULL, -1, 0, -1, -1, {NULL, NULL, NULL, NULL}}
     81        {NULL, -1, 0, 0, 0, {NULL, NULL, NULL, NULL}}
    8282};
    8383
  • uspace/drv/usbhid/subdrivers.h

    r9e929a0 r152ec79  
    5656        int report_id;
    5757        int compare;
    58         int vendor_id;
    59         int product_id;
     58        uint16_t vendor_id;
     59        uint16_t product_id;
    6060        usb_hid_subdriver_t subdriver;
    6161} usb_hid_subdriver_mapping_t;
  • uspace/drv/usbhid/usbhid.c

    r9e929a0 r152ec79  
    158158    const usb_hid_subdriver_mapping_t *mapping)
    159159{
    160         assert(hid_dev != NULL);
    161         assert(hid_dev->usb_dev != NULL);
    162        
    163         return (hid_dev->usb_dev->descriptors.device.vendor_id
    164             == mapping->vendor_id
    165             && hid_dev->usb_dev->descriptors.device.product_id
    166             == mapping->product_id);
     160        return false;
    167161}
    168162
     
    198192        }
    199193       
    200         assert(hid_dev->report != NULL);
     194        assert(hid_dev->parser != NULL);
    201195       
    202196        usb_log_debug("Compare flags: %d\n", mapping->compare);
    203         size_t size = usb_hid_report_input_length(hid_dev->report, usage_path,
     197        size_t size = usb_hid_report_input_length(hid_dev->parser, usage_path,
    204198            mapping->compare);
    205199        usb_log_debug("Size of the input report: %zuB\n", size);
     
    257251        while (count < USB_HID_MAX_SUBDRIVERS &&
    258252            (mapping->usage_path != NULL
    259             || mapping->vendor_id >= 0 || mapping->product_id >= 0)) {
     253            || mapping->vendor_id != 0 || mapping->product_id != 0)) {
    260254                // check the vendor & product ID
    261                 if (mapping->vendor_id >= 0 && mapping->product_id < 0) {
    262                         usb_log_warning("Missing Product ID for Vendor ID %d\n",
     255                if (mapping->vendor_id != 0 && mapping->product_id == 0) {
     256                        usb_log_warning("Missing Product ID for Vendor ID %u\n",
    263257                            mapping->vendor_id);
    264258                        return EINVAL;
    265259                }
    266                 if (mapping->product_id >= 0 && mapping->vendor_id < 0) {
    267                         usb_log_warning("Missing Vendor ID for Product ID %d\n",
     260                if (mapping->product_id != 0 && mapping->vendor_id == 0) {
     261                        usb_log_warning("Missing Vendor ID for Product ID %u\n",
    268262                            mapping->product_id);
    269263                        return EINVAL;
     
    273267                matched = false;
    274268               
    275                 if (mapping->vendor_id >= 0) {
    276                         assert(mapping->product_id >= 0);
     269                if (mapping->vendor_id != 0) {
     270                        assert(mapping->product_id != 0);
    277271                        usb_log_debug("Comparing device against vendor ID %u"
    278272                            " and product ID %u.\n", mapping->vendor_id,
     
    347341        }
    348342       
    349         hid_dev->report = (usb_hid_report_t *)(malloc(sizeof(
    350             usb_hid_report_t)));
    351         if (hid_dev->report == NULL) {
     343        hid_dev->parser = (usb_hid_report_parser_t *)(malloc(sizeof(
     344            usb_hid_report_parser_t)));
     345        if (hid_dev->parser == NULL) {
    352346                usb_log_fatal("No memory!\n");
    353347                free(hid_dev);
     
    388382                return rc;
    389383        }
    390                
     384       
     385        /* Initialize the report parser. */
     386        rc = usb_hid_parser_init(hid_dev->parser);
     387        if (rc != EOK) {
     388                usb_log_error("Failed to initialize report parser.\n");
     389                //usb_hid_free(&hid_dev);
     390                return rc;
     391        }
     392       
    391393        /* Get the report descriptor and parse it. */
    392394        rc = usb_hid_process_report_descriptor(hid_dev->usb_dev,
    393             hid_dev->report);
     395            hid_dev->parser);
    394396       
    395397        bool fallback = false;
     
    589591
    590592        // destroy the parser
    591         if ((*hid_dev)->report != NULL) {
    592                 usb_hid_free_report((*hid_dev)->report);
     593        if ((*hid_dev)->parser != NULL) {
     594                usb_hid_free_report_parser((*hid_dev)->parser);
    593595        }
    594596
  • uspace/drv/usbhid/usbhid.h

    r9e929a0 r152ec79  
    9191       
    9292        /** HID Report parser. */
    93         usb_hid_report_t *report;
     93        usb_hid_report_parser_t *parser;
    9494       
    9595        /** Arbitrary data (e.g. a special structure for handling keyboard). */
  • uspace/drv/usbkbd/kbddev.c

    r9e929a0 r152ec79  
    128128        0x15, 0x00,  //   Logical Minimum (0),
    129129        0x25, 0x01,  //   Logical Maximum (1),
    130         //0x85, 0x00,  //   Report ID,
    131         //0xA4,      //   Push
    132130        0x81, 0x02,  //   Input (Data, Variable, Absolute),   ; Modifier byte
    133         //0xB4,      //   Pop
    134         0x75, 0x08,  //   Report Size (1),
    135         0x95, 0x01,  //   Report Count (8),       
     131        0x95, 0x01,  //   Report Count (1),
     132        0x75, 0x08,  //   Report Size (8),
    136133        0x81, 0x01,  //   Input (Constant),                   ; Reserved byte
    137134        0x95, 0x05,  //   Report Count (5),
     
    271268                return;
    272269        }
    273 
     270       
    274271        unsigned i = 0;
    275272       
     
    293290       
    294291        usb_log_debug("Creating output report.\n");
    295 
    296         usb_hid_report_output_set_data(kbd_dev->parser, kbd_dev->led_path,
    297                                        USB_HID_PATH_COMPARE_END , kbd_dev->led_data,
    298                                        kbd_dev->led_output_size);
    299         int rc = usb_hid_report_output_translate(kbd_dev->parser, 0,
    300             kbd_dev->output_buffer, kbd_dev->output_size);
     292       
     293        int rc = usb_hid_report_output_translate(kbd_dev->parser,
     294            kbd_dev->led_path,
     295            USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
     296            kbd_dev->output_buffer,
     297            kbd_dev->output_size, kbd_dev->led_data, kbd_dev->led_output_size);
    301298       
    302299        if (rc != EOK) {
     
    566563        assert(kbd_dev != NULL);
    567564
    568         usb_log_debug("Got keys from parser (report id: %d): %s\n", report_id,
    569             usb_debug_str_buffer(key_codes, count, 0));
     565        usb_log_debug("Got keys from parser (report id: %u): %s\n",
     566            report_id, usb_debug_str_buffer(key_codes, count, 0));
    570567       
    571568        if (count != kbd_dev->key_count) {
     
    617614        usb_hid_report_path_t *path = usb_hid_report_path();
    618615        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
    619 
    620         uint8_t report_id;
    621         int rc = usb_hid_parse_report(kbd_dev->parser, buffer, actual_size, &report_id);
    622         usb_hid_descriptor_print (kbd_dev->parser);
     616        usb_hid_report_path_set_report_id(path, 0);
     617       
     618        int rc = usb_hid_parse_report(kbd_dev->parser, buffer,
     619            actual_size, path,
     620            USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
     621            callbacks, kbd_dev);
    623622
    624623        usb_hid_report_path_free (path);
     
    664663        memset(kbd_dev, 0, sizeof(usb_kbd_t));
    665664       
    666         kbd_dev->parser = (usb_hid_report_t *)(malloc(sizeof(
    667             usb_hid_report_t)));
     665        kbd_dev->parser = (usb_hid_report_parser_t *)(malloc(sizeof(
     666            usb_hid_report_parser_t)));
    668667        if (kbd_dev->parser == NULL) {
    669668                usb_log_fatal("No memory!\n");
     
    733732       
    734733        /* Initialize the report parser. */
    735         //rc = usb_hid_parser_init(kbd_dev->parser);
    736         //if (rc != EOK) {
    737         //      usb_log_error("Failed to initialize report parser.\n");
    738         //      return rc;
    739         //}
     734        rc = usb_hid_parser_init(kbd_dev->parser);
     735        if (rc != EOK) {
     736                usb_log_error("Failed to initialize report parser.\n");
     737                return rc;
     738        }
    740739       
    741740        /* Get the report descriptor and parse it. */
     
    772771       
    773772        kbd_dev->key_count = usb_hid_report_input_length(
    774             kbd_dev->parser, path, USB_HID_PATH_COMPARE_END);
     773            kbd_dev->parser, path,
     774            USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY);
    775775        usb_hid_report_path_free (path);
    776776       
     
    789789        kbd_dev->output_size = 0;
    790790        kbd_dev->output_buffer = usb_hid_report_output(kbd_dev->parser,
    791             &kbd_dev->output_size, 0x00);
    792         if (kbd_dev->output_buffer == NULL) {
     791            &kbd_dev->output_size);
     792        if (kbd_dev->output_buffer == NULL && kbd_dev->output_size != 0) {
    793793                usb_log_warning("Error creating output report buffer.\n");
    794794                free(kbd_dev->keys);
     
    801801        usb_hid_report_path_append_item(
    802802            kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0);
    803         usb_hid_report_path_set_report_id(kbd_dev->led_path, 0x00);
    804803       
    805804        kbd_dev->led_output_size = usb_hid_report_output_size(kbd_dev->parser,
     
    850849         * Set Idle rate
    851850         */
    852         usb_kbd_set_led(kbd_dev);       
     851        usb_kbd_set_led(kbd_dev);
    853852       
    854853        usbhid_req_set_idle(&kbd_dev->usb_dev->ctrl_pipe,
     
    935934        // destroy the parser
    936935        if ((*kbd_dev)->parser != NULL) {
    937                 usb_hid_free_report((*kbd_dev)->parser);
     936                usb_hid_free_report_parser((*kbd_dev)->parser);
    938937        }
    939938       
  • uspace/drv/usbkbd/kbddev.h

    r9e929a0 r152ec79  
    106106
    107107        /** HID Report parser. */
    108         usb_hid_report_t *parser;
     108        usb_hid_report_parser_t *parser;
    109109       
    110110        /** State of the structure (for checking before use).
  • uspace/lib/usb/include/usb/classes/hid.h

    r9e929a0 r152ec79  
    5050        USB_HIDREQ_SET_PROTOCOL = 11
    5151} usb_hid_request_t;
     52
     53typedef enum {
     54        USB_HID_REPORT_TYPE_INPUT = 1,
     55        USB_HID_REPORT_TYPE_OUTPUT = 2,
     56        USB_HID_REPORT_TYPE_FEATURE = 3
     57} usb_hid_report_type_t;
    5258
    5359typedef enum {
  • uspace/lib/usb/include/usb/classes/hidparser.h

    r9e929a0 r152ec79  
    7373#define USB_HID_PATH_COMPARE_END                                1
    7474#define USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY    4
    75 #define USB_HID_PATH_COMPARE_COLLECTION_ONLY    2 /* porovnava jenom cestu z Kolekci */
    76 
    77 
    78 #define USB_HID_MAX_USAGES      20
    79 
    80 typedef enum {
    81         USB_HID_REPORT_TYPE_INPUT = 1,
    82         USB_HID_REPORT_TYPE_OUTPUT = 2,
    83         USB_HID_REPORT_TYPE_FEATURE = 3
    84 } usb_hid_report_type_t;
    85 
    86 /** Collection usage path structure */
     75
     76/** */
    8777typedef struct {
    8878        /** */
    89         uint32_t usage_page;
    90         /** */ 
    91         uint32_t usage;
    92 
    93         uint8_t flags;
     79        int32_t usage_page;
     80        /** */ 
     81        int32_t usage;
    9482        /** */
    9583        link_t link;
     
    10391       
    10492        /** */ 
    105         link_t link; /* list */
    106 
    107         link_t head; /* head of list of usage paths */
     93        link_t link;
    10894
    10995} usb_hid_report_path_t;
    11096
    111 
     97/**
     98 * Description of report items
     99 */
    112100typedef struct {
     101        /** */ 
     102        int32_t id;
     103        /** */ 
     104        int32_t usage_minimum;
     105        /** */ 
     106        int32_t usage_maximum;
     107        /** */ 
     108        int32_t logical_minimum;
     109        /** */ 
     110        int32_t logical_maximum;
     111        /** */ 
     112        int32_t size;
     113        /** */ 
     114        int32_t count;
     115        /** */ 
     116        size_t offset;
     117        /** */ 
     118        int32_t delimiter;
     119        /** */ 
     120        int32_t unit_exponent;
     121        /** */ 
     122        int32_t unit;
     123
    113124        /** */
    114         int report_count;
    115         link_t reports;         /** list of usb_hid_report_description_t */
    116 
    117         link_t collection_paths;
    118         int collection_paths_count;
    119 
    120         int use_report_ids;
    121         uint8_t last_report_id;
    122        
    123 } usb_hid_report_t;
    124 
    125 typedef struct {
    126         uint8_t report_id;
    127         usb_hid_report_type_t type;
    128 
    129         size_t bit_length;
    130         size_t item_length;
    131        
    132         link_t report_items;    /** list of report items (fields) */
    133 
    134         link_t link;
    135 } usb_hid_report_description_t;
    136 
    137 typedef struct {
    138 
    139         int offset;
    140         size_t size;
    141 
    142         uint16_t usage_page;
    143         uint16_t usage;
    144 
     125        int32_t string_index;
     126        /** */ 
     127        int32_t string_minimum;
     128        /** */ 
     129        int32_t string_maximum;
     130        /** */ 
     131        int32_t designator_index;
     132        /** */ 
     133        int32_t designator_minimum;
     134        /** */ 
     135        int32_t designator_maximum;
     136        /** */ 
     137        int32_t physical_minimum;
     138        /** */ 
     139        int32_t physical_maximum;
     140
     141        /** */ 
    145142        uint8_t item_flags;
    146         usb_hid_report_path_t *collection_path;
    147 
    148         int32_t logical_minimum;
    149         int32_t logical_maximum;
    150         int32_t physical_minimum;
    151         int32_t physical_maximum;
    152         uint32_t usage_minimum;
    153         uint32_t usage_maximum;
    154         uint32_t unit;
    155         uint32_t unit_exponent;
    156        
    157 
    158         int32_t value;
    159 
    160         link_t link;
    161 } usb_hid_report_field_t;
    162 
    163 
    164 
    165 /**
    166  * state table
    167  */
    168 typedef struct {
    169         /** report id */       
    170         int32_t id;
    171        
    172         /** */
    173         uint16_t extended_usage_page;
    174         uint32_t usages[USB_HID_MAX_USAGES];
    175         int usages_count;
    176 
    177         /** */
    178         uint32_t usage_page;
    179 
    180         /** */ 
    181         uint32_t usage_minimum;
    182         /** */ 
    183         uint32_t usage_maximum;
    184         /** */ 
    185         int32_t logical_minimum;
    186         /** */ 
    187         int32_t logical_maximum;
    188         /** */ 
    189         int32_t size;
    190         /** */ 
    191         int32_t count;
    192         /** */ 
    193         size_t offset;
    194         /** */ 
    195         int32_t unit_exponent;
    196         /** */ 
    197         int32_t unit;
    198 
    199         /** */
    200         uint32_t string_index;
    201         /** */ 
    202         uint32_t string_minimum;
    203         /** */ 
    204         uint32_t string_maximum;
    205         /** */ 
    206         uint32_t designator_index;
    207         /** */ 
    208         uint32_t designator_minimum;
    209         /** */ 
    210         uint32_t designator_maximum;
    211         /** */ 
    212         int32_t physical_minimum;
    213         /** */ 
    214         int32_t physical_maximum;
    215 
    216         /** */ 
    217         uint8_t item_flags;
    218 
    219         usb_hid_report_type_t type;
    220 
    221         /** current collection path*/   
     143
     144        /** */ 
    222145        usb_hid_report_path_t *usage_path;
    223146        /** */ 
    224147        link_t link;
    225148} usb_hid_report_item_t;
     149
     150
     151/** HID report parser structure. */
     152typedef struct {       
     153        /** */ 
     154        link_t input;
     155        /** */ 
     156        link_t output;
     157        /** */ 
     158        link_t feature;
     159       
     160        int use_report_id;
     161
     162        /** */
     163        link_t stack;
     164} usb_hid_report_parser_t;     
     165
    226166
    227167/** HID parser callbacks for IN items. */
     
    249189} usb_hid_modifiers_t;
    250190
     191//typedef enum {
     192//      USB_HID_LED_NUM_LOCK = 0x1,
     193//      USB_HID_LED_CAPS_LOCK = 0x2,
     194//      USB_HID_LED_SCROLL_LOCK = 0x4,
     195//      USB_HID_LED_COMPOSE = 0x8,
     196//      USB_HID_LED_KANA = 0x10,
     197//      USB_HID_LED_COUNT = 5
     198//} usb_hid_led_t;
     199
    251200static const usb_hid_modifiers_t
    252201    usb_hid_modifiers_consts[USB_HID_MOD_COUNT] = {
     
    261210};
    262211
     212//static const usb_hid_led_t usb_hid_led_consts[USB_HID_LED_COUNT] = {
     213//      USB_HID_LED_NUM_LOCK,
     214//      USB_HID_LED_CAPS_LOCK,
     215//      USB_HID_LED_SCROLL_LOCK,
     216//      USB_HID_LED_COMPOSE,
     217//      USB_HID_LED_KANA
     218//};
     219
     220//#define USB_HID_BOOT_KEYBOARD_NUM_LOCK                0x01
     221//#define USB_HID_BOOT_KEYBOARD_CAPS_LOCK               0x02
     222//#define USB_HID_BOOT_KEYBOARD_SCROLL_LOCK     0x04
     223//#define USB_HID_BOOT_KEYBOARD_COMPOSE         0x08
     224//#define USB_HID_BOOT_KEYBOARD_KANA                    0x10
     225
    263226/*
    264227 * Descriptor parser functions
    265228 */
    266 
    267 /** */
    268 int usb_hid_parse_report_descriptor(usb_hid_report_t *report,
     229/** */
     230int usb_hid_parser_init(usb_hid_report_parser_t *parser);
     231
     232/** */
     233int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser,
    269234    const uint8_t *data, size_t size);
    270235
    271236/** */
    272 void usb_hid_free_report(usb_hid_report_t *report);
    273 
    274 /** */
    275 void usb_hid_descriptor_print(usb_hid_report_t *report);
     237void usb_hid_free_report_parser(usb_hid_report_parser_t *parser);
     238
     239/** */
     240void usb_hid_descriptor_print(usb_hid_report_parser_t *parser);
     241
     242/*
     243 * Boot protocol functions
     244 */
     245/** */
     246int usb_hid_boot_keyboard_input_report(const uint8_t *data, size_t size,
     247        const usb_hid_report_in_callbacks_t *callbacks, void *arg);
     248
     249/** */
     250int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size);
    276251
    277252
     
    280255 */
    281256/** */
    282 int usb_hid_parse_report(const usb_hid_report_t *report, const uint8_t *data, size_t size, uint8_t *report_id);
    283 
    284 /** */
    285 size_t usb_hid_report_input_length(const usb_hid_report_t *report,
     257int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 
     258    const uint8_t *data, size_t size,
     259    usb_hid_report_path_t *path, int flags,
     260    const usb_hid_report_in_callbacks_t *callbacks, void *arg);
     261
     262/** */
     263size_t usb_hid_report_input_length(const usb_hid_report_parser_t *parser,
    286264        usb_hid_report_path_t *path, int flags);
    287265
     
    318296usb_hid_report_path_t *usb_hid_report_path_clone(usb_hid_report_path_t *usage_path);
    319297
    320 usb_hid_report_field_t *usb_hid_report_get_sibling(usb_hid_report_t *report, usb_hid_report_field_t *field, usb_hid_report_path_t *path, int flags, usb_hid_report_type_t type);
    321 
    322 uint8_t usb_hid_report_get_report_id(usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type);
    323 
    324298
    325299/*
     
    327301 */
    328302/** Allocates output report buffer*/
    329 uint8_t *usb_hid_report_output(usb_hid_report_t *report, size_t *size, uint8_t report_id);
     303uint8_t *usb_hid_report_output(usb_hid_report_parser_t *parser, size_t *size);
    330304
    331305/** Frees output report buffer*/
     
    333307
    334308/** Returns size of output for given usage path */
    335 size_t usb_hid_report_output_size(usb_hid_report_t *report,
     309size_t usb_hid_report_output_size(usb_hid_report_parser_t *parser,
    336310                                  usb_hid_report_path_t *path, int flags);
    337311
    338 /** Sets data in report structure */
    339 int usb_hid_report_output_set_data(usb_hid_report_t *report,
    340                                    usb_hid_report_path_t *path, int flags,
    341                                   int *data, size_t data_size);
    342 
    343 /** Makes the output report buffer by translated given data */
    344 int usb_hid_report_output_translate(usb_hid_report_t *report, uint8_t report_id, uint8_t *buffer, size_t size);
     312/** Updates the output report buffer by translated given data */
     313int usb_hid_report_output_translate(usb_hid_report_parser_t *parser,
     314                                    usb_hid_report_path_t *path, int flags,
     315                                    uint8_t *buffer, size_t size,
     316                                    int32_t *data, size_t data_size);
    345317#endif
    346318/**
  • uspace/lib/usb/include/usb/classes/hidreport.h

    r9e929a0 r152ec79  
    5757 */
    5858int usb_hid_process_report_descriptor(usb_device_t *dev,
    59     usb_hid_report_t *report);
     59    usb_hid_report_parser_t *parser);
    6060
    6161#endif /* LIBUSB_HIDREPORT_H_ */
  • uspace/lib/usb/include/usb/classes/hidut.h

    r9e929a0 r152ec79  
    4646        USB_HIDUT_PAGE_KEYBOARD = 7,
    4747        USB_HIDUT_PAGE_LED = 8,
    48         USB_HIDUT_PAGE_BUTTON = 9,
    49         USB_HIDUT_PAGE_ORDINAL = 0x0a,
    50         USB_HIDUT_PAGE_TELEPHONY_DEVICE = 0x0b,
    51         USB_HIDUT_PAGE_CONSUMER = 0x0c
     48        USB_HIDUT_PAGE_BUTTON = 9
     49        /* USB_HIDUT_PAGE_ = , */
    5250} usb_hidut_usage_page_t;
    5351
  • uspace/lib/usb/src/hidparser.c

    r9e929a0 r152ec79  
    3939#include <mem.h>
    4040#include <usb/debug.h>
    41 #include <assert.h>
    42 
    43 /** The new report item flag. Used to determine when the item is completly
    44  * configured and should be added to the report structure
    45  */
     41
     42/** */
    4643#define USB_HID_NEW_REPORT_ITEM 1
    4744
    48 /** No special action after the report descriptor tag is processed should be
    49  * done
    50  */
    51 #define USB_HID_NO_ACTION       2
    52 
    53 #define USB_HID_RESET_OFFSET    3
    54 
    55 /** Unknown tag was founded in report descriptor data*/
     45/** */
     46#define USB_HID_NO_ACTION               2
     47
     48/** */
    5649#define USB_HID_UNKNOWN_TAG             -99
    5750
     
    5952 * Private descriptor parser functions
    6053 */
    61 int usb_hid_report_init(usb_hid_report_t *report);
    62 int usb_hid_report_append_fields(usb_hid_report_t *report, usb_hid_report_item_t *report_item);
    63 usb_hid_report_description_t * usb_hid_report_find_description(const usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type);
    6454int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size,
    6555                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
     
    7161                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
    7262
    73 void usb_hid_print_usage_path(usb_hid_report_path_t *path);
    7463void usb_hid_descriptor_print_list(link_t *head);
    75 void usb_hid_report_reset_local_items(usb_hid_report_item_t *report_item);
     64int usb_hid_report_reset_local_items();
    7665void usb_hid_free_report_list(link_t *head);
    7766usb_hid_report_item_t *usb_hid_report_item_clone(const usb_hid_report_item_t *item);
     
    7968 * Data translation private functions
    8069 */
    81 uint32_t usb_hid_report_tag_data_uint32(const uint8_t *data, size_t size);
     70int32_t usb_hid_report_tag_data_int32(const uint8_t *data, size_t size);
    8271inline size_t usb_hid_count_item_offset(usb_hid_report_item_t * report_item, size_t offset);
    83 int usb_hid_translate_data(usb_hid_report_field_t *item, const uint8_t *data);
    84 uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, int32_t value);
     72int usb_hid_translate_data(usb_hid_report_item_t *item, const uint8_t *data, size_t j);
     73int32_t usb_hid_translate_data_reverse(usb_hid_report_item_t *item, int32_t value);
    8574int usb_pow(int a, int b);
    8675
    87 #define USB_HID_UINT32_TO_INT32(x, size)        ((((x) & (1 << ((size) - 1))) != 0) ? -(~(x - 1) & ((1 << size) - 1)) : (x)) //(-(~((x) - 1)))
    88 #define USB_HID_INT32_TO_UINT32(x, size)        (((x) < 0 ) ? ((1 << (size)) + (x)) : (x))
    8976// TODO: tohle ma bejt asi jinde
    9077int usb_pow(int a, int b)
     
    10996 * @return Error code
    11097 */
    111 int usb_hid_report_init(usb_hid_report_t *report)
    112 {
    113         if(report == NULL) {
     98int usb_hid_parser_init(usb_hid_report_parser_t *parser)
     99{
     100        if(parser == NULL) {
    114101                return EINVAL;
    115102        }
    116103
    117         memset(report, 0, sizeof(usb_hid_report_t));
    118         list_initialize(&report->reports);
    119         list_initialize(&report->collection_paths);
    120 
    121         report->use_report_ids = 0;
     104        list_initialize(&(parser->input));
     105    list_initialize(&(parser->output));
     106    list_initialize(&(parser->feature));
     107
     108        list_initialize(&(parser->stack));
     109
     110        parser->use_report_id = 0;
    122111    return EOK;   
    123112}
    124113
    125 int usb_hid_report_append_fields(usb_hid_report_t *report, usb_hid_report_item_t *report_item)
    126 {
    127         usb_hid_report_field_t *field;
    128         int i;
    129 
    130 
    131         /* find or append current collection path to the list */
    132         link_t *path_it = report->collection_paths.next;
    133         usb_hid_report_path_t *path = NULL;
    134         while(path_it != &report->collection_paths) {
    135                 path = list_get_instance(path_it, usb_hid_report_path_t, link);
    136                
    137                 if(usb_hid_report_compare_usage_path(path, report_item->usage_path, USB_HID_PATH_COMPARE_STRICT) == EOK){
    138                         break;
    139                 }                       
    140                 path_it = path_it->next;
    141         }
    142         if(path_it == &report->collection_paths) {
    143                 path = usb_hid_report_path_clone(report_item->usage_path);                     
    144                 list_append(&path->link, &report->collection_paths);                                   
    145                 report->collection_paths_count++;
    146         }
    147 
    148         for(i=0; i<report_item->usages_count; i++){
    149                 usb_log_debug("usages (%d) - %x\n", i, report_item->usages[i]);
    150         }
    151 
    152        
    153         for(i=0; i<report_item->count; i++){
    154 
    155                 field = malloc(sizeof(usb_hid_report_field_t));
    156                 memset(field, 0, sizeof(usb_hid_report_field_t));
    157                 list_initialize(&field->link);
    158 
    159                 /* fill the attributes */               
    160                 field->collection_path = path;
    161                 field->logical_minimum = report_item->logical_minimum;
    162                 field->logical_maximum = report_item->logical_maximum;
    163                 field->physical_minimum = report_item->physical_minimum;
    164                 field->physical_maximum = report_item->physical_maximum;
    165 
    166                 field->usage_minimum = report_item->usage_minimum;
    167                 field->usage_maximum = report_item->usage_maximum;
    168                 if(report_item->extended_usage_page != 0){
    169                         field->usage_page = report_item->extended_usage_page;
    170                 }
    171                 else {
    172                         field->usage_page = report_item->usage_page;
    173                 }
    174 
    175                 if(report_item->usages_count > 0 && ((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0))) {
    176                         uint32_t usage;
    177                         if(report_item->type != USB_HID_REPORT_TYPE_INPUT) {
    178                                 if(i < report_item->usages_count){
    179                                         usage = report_item->usages[i];
    180                                 }
    181                                 else {
    182                                         usage = report_item->usages[report_item->usages_count - 1];
    183                                 }
    184                         }
    185                         else {
    186                                 if((report_item->count - i - 1) < report_item->usages_count){
    187                                         usage = report_item->usages[(report_item->count - i - 1)];
    188                                 }
    189                                 else {
    190                                         usage = report_item->usages[report_item->usages_count - 1];
    191                                 }
    192                         }
    193 
    194                                                
    195                         if((usage & 0xFFFF0000) != 0){
    196                                 field->usage_page = (usage >> 16);                                     
    197                                 field->usage = (usage & 0xFFFF);
    198                         }
    199                         else {
    200                                 field->usage = usage;
    201                         }
    202 
    203                        
    204                 }       
    205 
    206                 if((USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) != 0) && (!((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0)))) {
    207                         if(report_item->type == USB_HID_REPORT_TYPE_INPUT) {
    208                                 field->usage = report_item->usage_maximum - i;
    209                         }
    210                         else {
    211                                 field->usage = report_item->usage_minimum + i;                                 
    212                         }
    213 
    214                 }
    215                
    216                 field->size = report_item->size;
    217                 field->offset = report_item->offset + (i * report_item->size);
    218                 if(report_item->id != 0) {
    219                         field->offset += 8;
    220                         report->use_report_ids = 1;
    221                 }
    222                 field->item_flags = report_item->item_flags;
    223 
    224                 /* find the right report list*/
    225                 usb_hid_report_description_t *report_des;
    226                 report_des = usb_hid_report_find_description(report, report_item->id, report_item->type);
    227                 if(report_des == NULL){
    228                         report_des = malloc(sizeof(usb_hid_report_description_t));
    229                         memset(report_des, 0, sizeof(usb_hid_report_description_t));
    230 
    231                         report_des->type = report_item->type;
    232                         report_des->report_id = report_item->id;
    233                         list_initialize (&report_des->link);
    234                         list_initialize (&report_des->report_items);
    235 
    236                         list_append(&report_des->link, &report->reports);
    237                         report->report_count++;
    238                 }
    239 
    240                 /* append this field to the end of founded report list */
    241                 list_append (&field->link, &report_des->report_items);
    242                
    243                 /* update the sizes */
    244                 report_des->bit_length += field->size;
    245                 report_des->item_length++;
    246 
    247         }
    248 
    249 
    250         return EOK;
    251 }
    252 
    253 usb_hid_report_description_t * usb_hid_report_find_description(const usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type)
    254 {
    255         link_t *report_it = report->reports.next;
    256         usb_hid_report_description_t *report_des = NULL;
    257        
    258         while(report_it != &report->reports) {
    259                 report_des = list_get_instance(report_it, usb_hid_report_description_t, link);
    260 
    261                 if((report_des->report_id == report_id) && (report_des->type == type)){
    262                         return report_des;
    263                 }
    264                
    265                 report_it = report_it->next;
    266         }
    267 
    268         return NULL;
    269 }
    270114
    271115/** Parse HID report descriptor.
     
    275119 * @return Error code.
    276120 */
    277 int usb_hid_parse_report_descriptor(usb_hid_report_t *report,
     121int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser,
    278122    const uint8_t *data, size_t size)
    279123{
     
    286130        usb_hid_report_item_t *new_report_item;
    287131        usb_hid_report_path_t *usage_path;
     132        usb_hid_report_path_t *tmp_usage_path;
    288133
    289134        size_t offset_input=0;
    290135        size_t offset_output=0;
    291136        size_t offset_feature=0;
    292 
    293         link_t stack;
    294         list_initialize(&stack);       
     137       
    295138
    296139        /* parser structure initialization*/
    297         if(usb_hid_report_init(report) != EOK) {
     140        if(usb_hid_parser_init(parser) != EOK) {
    298141                return EINVAL;
    299142        }
    300143       
     144
    301145        /*report item initialization*/
    302146        if(!(report_item=malloc(sizeof(usb_hid_report_item_t)))){
     
    315159
    316160                        if((i+USB_HID_ITEM_SIZE(data[i]))>= size){
    317                                 return EINVAL;
     161                                return EINVAL; // TODO ERROR CODE
    318162                        }
    319163                       
     
    321165                        item_size = USB_HID_ITEM_SIZE(data[i]);
    322166                        class = USB_HID_ITEM_TAG_CLASS(data[i]);
     167
     168                        usb_log_debug2(
     169                                "i(%zu) data(%X) value(%X): TAG %d, class %u, size %u - ", i,
     170                            data[i], usb_hid_report_tag_data_int32(data+i+1,item_size),
     171                            tag, class, item_size);
    323172                       
    324173                        ret = usb_hid_report_parse_tag(tag,class,data+i+1,
    325174                                                       item_size,report_item, usage_path);
     175                        usb_log_debug2("ret: %u\n", ret);
    326176                        switch(ret){
    327177                                case USB_HID_NEW_REPORT_ITEM:
    328178                                        // store report item to report and create the new one
    329                                         // store current collection path
     179                                        usb_log_debug("\nNEW REPORT ITEM: %X",ret);
     180
     181                                        // store current usage path
    330182                                        report_item->usage_path = usage_path;
    331183                                       
     184                                        // clone path to the new one
     185                                        tmp_usage_path = usb_hid_report_path_clone(usage_path);
     186
     187                                        // swap
     188                                        usage_path = tmp_usage_path;
     189                                        tmp_usage_path = NULL;
     190
    332191                                        usb_hid_report_path_set_report_id(report_item->usage_path, report_item->id);   
    333192                                        if(report_item->id != 0){
    334                                                 report->use_report_ids = 1;
     193                                                parser->use_report_id = 1;
    335194                                        }
    336195                                       
    337196                                        switch(tag) {
    338197                                                case USB_HID_REPORT_TAG_INPUT:
    339                                                         report_item->type = USB_HID_REPORT_TYPE_INPUT;
    340198                                                        report_item->offset = offset_input;
    341199                                                        offset_input += report_item->count * report_item->size;
     200                                                        usb_log_debug(" - INPUT\n");
     201                                                        list_append(&(report_item->link), &(parser->input));
    342202                                                        break;
    343203                                                case USB_HID_REPORT_TAG_OUTPUT:
    344                                                         report_item->type = USB_HID_REPORT_TYPE_OUTPUT;
    345204                                                        report_item->offset = offset_output;
    346205                                                        offset_output += report_item->count * report_item->size;
     206                                                        usb_log_debug(" - OUTPUT\n");
     207                                                                list_append(&(report_item->link), &(parser->output));
    347208
    348209                                                        break;
    349210                                                case USB_HID_REPORT_TAG_FEATURE:
    350                                                         report_item->type = USB_HID_REPORT_TYPE_FEATURE;
    351211                                                        report_item->offset = offset_feature;
    352212                                                        offset_feature += report_item->count * report_item->size;
     213                                                        usb_log_debug(" - FEATURE\n");
     214                                                                list_append(&(report_item->link), &(parser->feature));
    353215                                                        break;
    354216                                                default:
     
    356218                                                    break;
    357219                                        }
     220
     221                                        /* clone current state table to the new item */
     222                                        if(!(new_report_item = malloc(sizeof(usb_hid_report_item_t)))) {
     223                                                return ENOMEM;
     224                                        }                                       
     225                                        memcpy(new_report_item,report_item, sizeof(usb_hid_report_item_t));
     226                                        link_initialize(&(new_report_item->link));
    358227                                       
    359                                         /*
    360                                          * append new fields to the report
    361                                          * structure                                     
    362                                          */
    363                                         usb_hid_report_append_fields(report, report_item);
    364 
    365228                                        /* reset local items */
    366                                         usb_hid_report_reset_local_items (report_item);
    367 
     229                                        new_report_item->usage_minimum = 0;
     230                                        new_report_item->usage_maximum = 0;
     231                                        new_report_item->designator_index = 0;
     232                                        new_report_item->designator_minimum = 0;
     233                                        new_report_item->designator_maximum = 0;
     234                                        new_report_item->string_index = 0;
     235                                        new_report_item->string_minimum = 0;
     236                                        new_report_item->string_maximum = 0;
     237
     238                                        /* reset usage from current usage path */
     239                                        usb_hid_report_usage_path_t *path = list_get_instance(&usage_path->link, usb_hid_report_usage_path_t, link);
     240                                        path->usage = 0;
     241                                       
     242                                        report_item = new_report_item;
     243                                                                               
    368244                                        break;
    369 
    370                                 case USB_HID_RESET_OFFSET:
    371                                         offset_input = 0;
    372                                         offset_output = 0;
    373                                         offset_feature = 0;
    374                                         usb_hid_report_path_set_report_id (usage_path, report_item->id);
    375                                         break;
    376 
    377245                                case USB_HID_REPORT_TAG_PUSH:
    378246                                        // push current state to stack
    379247                                        new_report_item = usb_hid_report_item_clone(report_item);
    380                                         usb_hid_report_path_t *tmp_path = usb_hid_report_path_clone(usage_path);
    381                                         new_report_item->usage_path = tmp_path;
    382 
    383                                         list_prepend (&new_report_item->link, &stack);
     248                                        list_prepend (&parser->stack, &new_report_item->link);
     249                                       
    384250                                        break;
    385251                                case USB_HID_REPORT_TAG_POP:
    386252                                        // restore current state from stack
    387                                         if(list_empty (&stack)) {
     253                                        if(list_empty (&parser->stack)) {
    388254                                                return EINVAL;
    389255                                        }
    390                                         free(report_item);
    391                                                
    392                                         report_item = list_get_instance(stack.next, usb_hid_report_item_t, link);
    393256                                       
    394                                         usb_hid_report_usage_path_t *tmp_usage_path;
    395                                         tmp_usage_path = list_get_instance(report_item->usage_path->link.prev, usb_hid_report_usage_path_t, link);
    396                                        
    397                                         usb_hid_report_set_last_item(usage_path, tmp_usage_path->usage_page, tmp_usage_path->usage);
    398 
    399                                         usb_hid_report_path_free(report_item->usage_path);
    400                                         list_initialize(&report_item->usage_path->link);
    401                                         list_remove (stack.next);
     257                                        report_item = list_get_instance(&parser->stack, usb_hid_report_item_t, link);
     258                                        list_remove (parser->stack.next);
    402259                                       
    403260                                        break;
     
    422279}
    423280
     281
     282/**
     283 * Parse input report.
     284 *
     285 * @param data Data for report
     286 * @param size Size of report
     287 * @param callbacks Callbacks for report actions
     288 * @param arg Custom arguments
     289 *
     290 * @return Error code
     291 */
     292int usb_hid_boot_keyboard_input_report(const uint8_t *data, size_t size,
     293        const usb_hid_report_in_callbacks_t *callbacks, void *arg)
     294{
     295        int i;
     296        usb_hid_report_item_t item;
     297
     298        /* fill item due to the boot protocol report descriptor */
     299        // modifier keys are in the first byte
     300        uint8_t modifiers = data[0];
     301
     302        item.offset = 2; /* second byte is reserved */
     303        item.size = 8;
     304        item.count = 6;
     305        item.usage_minimum = 0;
     306        item.usage_maximum = 255;
     307        item.logical_minimum = 0;
     308        item.logical_maximum = 255;
     309
     310        if (size != 8) {
     311                return -1; //ERANGE;
     312        }
     313
     314        uint8_t keys[6];
     315        for (i = 0; i < item.count; i++) {
     316                keys[i] = data[i + item.offset];
     317        }
     318
     319        callbacks->keyboard(keys, 6, modifiers, arg);
     320        return EOK;
     321}
     322
     323/**
     324 * Makes output report for keyboard boot protocol
     325 *
     326 * @param leds
     327 * @param output Output report data buffer
     328 * @param size Size of the output buffer
     329 * @return Error code
     330 */
     331int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size)
     332{
     333        if(size != 1){
     334                return -1;
     335        }
     336
     337        /* used only first five bits, others are only padding*/
     338        *data = leds;
     339        return EOK;
     340}
    424341
    425342/**
     
    484401                       
    485402                case USB_HID_REPORT_TAG_COLLECTION:
    486                         // TODO usage_path->flags = *data;
    487                         usb_hid_report_path_append_item(usage_path, report_item->usage_page, report_item->usages[report_item->usages_count-1]);                                         
    488                         usb_hid_report_reset_local_items (report_item);
     403                        usb_hid_report_path_append_item(usage_path, 0, 0);
     404                                               
    489405                        return USB_HID_NO_ACTION;
    490406                        break;
    491407                       
    492408                case USB_HID_REPORT_TAG_END_COLLECTION:
     409                        // TODO
     410                        // znici posledni uroven ve vsech usage paths
     411                        // otazka jestli nema nicit dve, respektive novou posledni vynulovat?
    493412                        usb_hid_report_remove_last_item(usage_path);
    494413                        return USB_HID_NO_ACTION;
     
    517436        {
    518437                case USB_HID_REPORT_TAG_USAGE_PAGE:
    519                         report_item->usage_page = usb_hid_report_tag_data_uint32(data, item_size);
     438                        // zmeni to jenom v poslednim poli aktualni usage path
     439                        usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL,
     440                                usb_hid_report_tag_data_int32(data,item_size));
    520441                        break;
    521442                case USB_HID_REPORT_TAG_LOGICAL_MINIMUM:
    522                         report_item->logical_minimum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
     443                        report_item->logical_minimum = usb_hid_report_tag_data_int32(data,item_size);
    523444                        break;
    524445                case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM:
    525                         report_item->logical_maximum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
     446                        report_item->logical_maximum = usb_hid_report_tag_data_int32(data,item_size);
    526447                        break;
    527448                case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM:
    528                         report_item->physical_minimum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
     449                        report_item->physical_minimum = usb_hid_report_tag_data_int32(data,item_size);
    529450                        break;                 
    530451                case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM:
    531                         report_item->physical_maximum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
    532 
     452                        report_item->physical_maximum = usb_hid_report_tag_data_int32(data,item_size);
    533453                        break;
    534454                case USB_HID_REPORT_TAG_UNIT_EXPONENT:
    535                         report_item->unit_exponent = usb_hid_report_tag_data_uint32(data,item_size);
     455                        report_item->unit_exponent = usb_hid_report_tag_data_int32(data,item_size);
    536456                        break;
    537457                case USB_HID_REPORT_TAG_UNIT:
    538                         report_item->unit = usb_hid_report_tag_data_uint32(data,item_size);
     458                        report_item->unit = usb_hid_report_tag_data_int32(data,item_size);
    539459                        break;
    540460                case USB_HID_REPORT_TAG_REPORT_SIZE:
    541                         report_item->size = usb_hid_report_tag_data_uint32(data,item_size);
     461                        report_item->size = usb_hid_report_tag_data_int32(data,item_size);
    542462                        break;
    543463                case USB_HID_REPORT_TAG_REPORT_COUNT:
    544                         report_item->count = usb_hid_report_tag_data_uint32(data,item_size);
     464                        report_item->count = usb_hid_report_tag_data_int32(data,item_size);
    545465                        break;
    546466                case USB_HID_REPORT_TAG_REPORT_ID:
    547                         report_item->id = usb_hid_report_tag_data_uint32(data,item_size);
    548                         return USB_HID_RESET_OFFSET;
     467                        report_item->id = usb_hid_report_tag_data_int32(data,item_size);
    549468                        break;
    550469                case USB_HID_REPORT_TAG_PUSH:
    551470                case USB_HID_REPORT_TAG_POP:
    552                         /*
    553                          * stack operations are done in top level parsing
    554                          * function
    555                          */
    556471                        return tag;
    557472                        break;
     
    560475                        return USB_HID_NO_ACTION;
    561476        }
    562 
     477       
    563478        return EOK;
    564479}
     
    579494        {
    580495                case USB_HID_REPORT_TAG_USAGE:
    581                         report_item->usages[report_item->usages_count] = usb_hid_report_tag_data_uint32(data,item_size);
    582                         report_item->usages_count++;
     496                        usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL,
     497                                usb_hid_report_tag_data_int32(data,item_size));
    583498                        break;
    584499                case USB_HID_REPORT_TAG_USAGE_MINIMUM:
    585                         if (item_size == 3) {
    586                                 // usage extended usages
    587                                 report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16;
    588                                 report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size) & 0xFF;
    589                         }
    590                         else {
    591                                 report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size);
    592                         }
     500                        report_item->usage_minimum = usb_hid_report_tag_data_int32(data,item_size);
    593501                        break;
    594502                case USB_HID_REPORT_TAG_USAGE_MAXIMUM:
    595                         if (item_size == 3) {
    596                                 // usage extended usages
    597                                 report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16;
    598                                 report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size) & 0xFF;
    599                         }
    600                         else {
    601                                 report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size);
    602                         }
     503                        report_item->usage_maximum = usb_hid_report_tag_data_int32(data,item_size);
    603504                        break;
    604505                case USB_HID_REPORT_TAG_DESIGNATOR_INDEX:
    605                         report_item->designator_index = usb_hid_report_tag_data_uint32(data,item_size);
     506                        report_item->designator_index = usb_hid_report_tag_data_int32(data,item_size);
    606507                        break;
    607508                case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM:
    608                         report_item->designator_minimum = usb_hid_report_tag_data_uint32(data,item_size);
     509                        report_item->designator_minimum = usb_hid_report_tag_data_int32(data,item_size);
    609510                        break;
    610511                case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM:
    611                         report_item->designator_maximum = usb_hid_report_tag_data_uint32(data,item_size);
     512                        report_item->designator_maximum = usb_hid_report_tag_data_int32(data,item_size);
    612513                        break;
    613514                case USB_HID_REPORT_TAG_STRING_INDEX:
    614                         report_item->string_index = usb_hid_report_tag_data_uint32(data,item_size);
     515                        report_item->string_index = usb_hid_report_tag_data_int32(data,item_size);
    615516                        break;
    616517                case USB_HID_REPORT_TAG_STRING_MINIMUM:
    617                         report_item->string_minimum = usb_hid_report_tag_data_uint32(data,item_size);
     518                        report_item->string_minimum = usb_hid_report_tag_data_int32(data,item_size);
    618519                        break;
    619520                case USB_HID_REPORT_TAG_STRING_MAXIMUM:
    620                         report_item->string_maximum = usb_hid_report_tag_data_uint32(data,item_size);
     521                        report_item->string_maximum = usb_hid_report_tag_data_int32(data,item_size);
    621522                        break;                 
    622523                case USB_HID_REPORT_TAG_DELIMITER:
    623                         //report_item->delimiter = usb_hid_report_tag_data_uint32(data,item_size);
    624                         //TODO:
    625                         //      DELIMITER STUFF
     524                        report_item->delimiter = usb_hid_report_tag_data_int32(data,item_size);
    626525                        break;
    627526               
     
    634533
    635534/**
    636  * Converts raw data to uint32 (thats the maximum length of short item data)
     535 * Converts raw data to int32 (thats the maximum length of short item data)
    637536 *
    638537 * @param Data buffer
     
    640539 * @return Converted int32 number
    641540 */
    642 uint32_t usb_hid_report_tag_data_uint32(const uint8_t *data, size_t size)
     541int32_t usb_hid_report_tag_data_int32(const uint8_t *data, size_t size)
    643542{
    644543        unsigned int i;
    645         uint32_t result;
     544        int32_t result;
    646545
    647546        result = 0;
     
    653552}
    654553
     554
     555
    655556/**
    656557 * Prints content of given list of report items.
     
    661562void usb_hid_descriptor_print_list(link_t *head)
    662563{
    663         usb_hid_report_field_t *report_item;
     564        usb_hid_report_item_t *report_item;
     565        usb_hid_report_usage_path_t *path_item;
     566        link_t *path;
    664567        link_t *item;
    665 
    666 
     568       
    667569        if(head == NULL || list_empty(head)) {
    668570            usb_log_debug("\tempty\n");
     
    672574        for(item = head->next; item != head; item = item->next) {
    673575               
    674                 report_item = list_get_instance(item, usb_hid_report_field_t, link);
    675 
    676                 usb_log_debug("\t\tOFFSET: %X\n", report_item->offset);
    677                 usb_log_debug("\t\tSIZE: %X\n", report_item->size);                             
    678                 usb_log_debug("\t\tLOGMIN: %d\n", report_item->logical_minimum);
    679                 usb_log_debug("\t\tLOGMAX: %d\n", report_item->logical_maximum);               
    680                 usb_log_debug("\t\tPHYMIN: %d\n", report_item->physical_minimum);               
    681                 usb_log_debug("\t\tPHYMAX: %d\n", report_item->physical_maximum);                               
    682                 usb_log_debug("\t\ttUSAGEMIN: %X\n", report_item->usage_minimum);
    683                 usb_log_debug("\t\tUSAGEMAX: %X\n", report_item->usage_maximum);
    684 
    685                 usb_log_debug("\t\tVALUE: %X\n", report_item->value);
    686                 usb_log_debug("\t\ttUSAGE: %X\n", report_item->usage);
    687                 usb_log_debug("\t\tUSAGE PAGE: %X\n", report_item->usage_page);
    688                                                
    689 //              usb_log_debug("\n");           
     576                report_item = list_get_instance(item, usb_hid_report_item_t, link);
     577
     578                usb_log_debug("\tOFFSET: %zX\n", report_item->offset);
     579                usb_log_debug("\tCOUNT: %X\n", report_item->count);
     580                usb_log_debug("\tSIZE: %X\n", report_item->size);
     581                usb_log_debug("\tCONSTANT/VAR: %X\n", USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags));
     582                usb_log_debug("\tVARIABLE/ARRAY: %X\n", USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags));
     583                usb_log_debug("\tUSAGE PATH:\n");
     584
     585                path = report_item->usage_path->link.next;
     586                while(path != &report_item->usage_path->link)   {
     587                        path_item = list_get_instance(path, usb_hid_report_usage_path_t, link);
     588                        usb_log_debug("\t\tUSAGE PAGE: %X, USAGE: %X\n", path_item->usage_page, path_item->usage);
     589                        path = path->next;
     590                }
     591                               
     592                usb_log_debug("\tLOGMIN: %X\n", report_item->logical_minimum);
     593                usb_log_debug("\tLOGMAX: %X\n", report_item->logical_maximum);         
     594                usb_log_debug("\tPHYMIN: %X\n", report_item->physical_minimum);         
     595                usb_log_debug("\tPHYMAX: %X\n", report_item->physical_maximum);                         
     596                usb_log_debug("\tUSAGEMIN: %X\n", report_item->usage_minimum);
     597                usb_log_debug("\tUSAGEMAX: %X\n", report_item->usage_maximum);
     598               
     599                usb_log_debug("\n");           
    690600
    691601        }
     
    699609 * @return void
    700610 */
    701 void usb_hid_descriptor_print(usb_hid_report_t *report)
    702 {
    703         if(report == NULL) {
     611void usb_hid_descriptor_print(usb_hid_report_parser_t *parser)
     612{
     613        if(parser == NULL) {
    704614                return;
    705615        }
    706 
    707         link_t *report_it = report->reports.next;
    708         usb_hid_report_description_t *report_des;
    709 
    710         while(report_it != &report->reports) {
    711                 report_des = list_get_instance(report_it, usb_hid_report_description_t, link);
    712                 usb_log_debug("Report ID: %d\n", report_des->report_id);
    713                 usb_log_debug("\tType: %d\n", report_des->type);
    714                 usb_log_debug("\tLength: %d\n", report_des->bit_length);               
    715                 usb_log_debug("\tItems: %d\n", report_des->item_length);               
    716 
    717                 usb_hid_descriptor_print_list(&report_des->report_items);
    718 
    719 
    720                 link_t *path_it = report->collection_paths.next;
    721                 while(path_it != &report->collection_paths) {
    722                         usb_hid_print_usage_path (list_get_instance(path_it, usb_hid_report_path_t, link));
    723                         path_it = path_it->next;
    724                 }
    725                
    726                 report_it = report_it->next;
    727         }
     616       
     617        usb_log_debug("INPUT:\n");
     618        usb_hid_descriptor_print_list(&parser->input);
     619       
     620        usb_log_debug("OUTPUT: \n");
     621        usb_hid_descriptor_print_list(&parser->output);
     622       
     623        usb_log_debug("FEATURE:\n");   
     624        usb_hid_descriptor_print_list(&parser->feature);
     625
    728626}
    729627
     
    769667 * @return void
    770668 */
    771 void usb_hid_free_report(usb_hid_report_t *report)
    772 {
    773         if(report == NULL){
     669void usb_hid_free_report_parser(usb_hid_report_parser_t *parser)
     670{
     671        if(parser == NULL){
    774672                return;
    775673        }
    776674
    777         // free collection paths
    778         usb_hid_report_path_t *path;
    779         while(!list_empty(&report->collection_paths)) {
    780                 path = list_get_instance(report->collection_paths.next, usb_hid_report_path_t, link);
    781                 usb_hid_report_path_free(path);         
    782         }
    783        
    784         // free report items
    785         usb_hid_report_description_t *report_des;
    786         usb_hid_report_field_t *field;
    787         while(!list_empty(&report->reports)) {
    788                 report_des = list_get_instance(report->reports.next, usb_hid_report_description_t, link);
    789                 list_remove(&report_des->link);
    790                
    791                 while(!list_empty(&report_des->report_items)) {
    792                         field = list_get_instance(report_des->report_items.next, usb_hid_report_field_t, link);
    793                         list_remove(&field->link);
    794 
    795                         free(field);
    796                 }
    797                
    798                 free(report_des);
    799         }
    800        
     675        parser->use_report_id = 0;
     676
     677        usb_hid_free_report_list(&parser->input);
     678        usb_hid_free_report_list(&parser->output);
     679        usb_hid_free_report_list(&parser->feature);
     680
    801681        return;
    802682}
     
    808688 * @param parser Opaque HID report parser structure.
    809689 * @param data Data for the report.
     690 * @param callbacks Callbacks for report actions.
     691 * @param arg Custom argument (passed through to the callbacks).
    810692 * @return Error code.
    811693 */
    812 int usb_hid_parse_report(const usb_hid_report_t *report, 
    813     const uint8_t *data, size_t size, uint8_t *report_id)
     694int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 
     695    const uint8_t *data, size_t size,
     696    usb_hid_report_path_t *path, int flags,
     697    const usb_hid_report_in_callbacks_t *callbacks, void *arg)
    814698{
    815699        link_t *list_item;
    816         usb_hid_report_field_t *item;
    817 
    818         usb_hid_report_description_t *report_des;
    819         usb_hid_report_type_t type = USB_HID_REPORT_TYPE_INPUT;
    820 
    821         if(report == NULL) {
     700        usb_hid_report_item_t *item;
     701        uint8_t *keys;
     702        uint8_t item_value;
     703        size_t key_count=0;
     704        size_t i=0;
     705        size_t j=0;
     706        uint8_t report_id = 0;
     707
     708        if(parser == NULL) {
    822709                return EINVAL;
    823710        }
    824 
    825         if(report->use_report_ids != 0) {
    826                 *report_id = data[0];
    827         }       
    828         else {
    829                 *report_id = 0;
    830         }
    831 
    832 
    833         report_des = usb_hid_report_find_description(report, *report_id, type);
     711       
     712        /* get the size of result array */
     713        key_count = usb_hid_report_input_length(parser, path, flags);
     714
     715        if(!(keys = malloc(sizeof(uint8_t) * key_count))){
     716                return ENOMEM;
     717        }
     718
     719        if(parser->use_report_id != 0) {
     720                report_id = data[0];
     721                usb_hid_report_path_set_report_id(path, report_id);
     722        }
    834723
    835724        /* read data */
    836         list_item = report_des->report_items.next;         
    837         while(list_item != &(report_des->report_items)) {
    838 
    839                 item = list_get_instance(list_item, usb_hid_report_field_t, link);
    840 
    841                 if(USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) == 0) {
    842                        
    843                         if(USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0) {
    844 
    845                                 // array
    846                                 item->value = usb_hid_translate_data(item, data);
    847                             item->usage = (item->value - item->physical_minimum) + item->usage_minimum;
     725        list_item = parser->input.next;   
     726        while(list_item != &(parser->input)) {
     727
     728                item = list_get_instance(list_item, usb_hid_report_item_t, link);
     729
     730                if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) &&
     731                   (usb_hid_report_compare_usage_path(item->usage_path, path, flags) == EOK)) {
     732                        for(j=0; j<(size_t)(item->count); j++) {
     733                                if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0) ||
     734                                   ((item->usage_minimum == 0) && (item->usage_maximum == 0))) {
     735                                        // variable item
     736                                        keys[i++] = usb_hid_translate_data(item, data,j);
     737                                }
     738                                else {
     739                                        // bitmapa
     740                                        if((item_value = usb_hid_translate_data(item, data, j)) != 0) {
     741                                                keys[i++] = (item->count - 1 - j) + item->usage_minimum;
     742                                        }
     743                                        else {
     744                                                keys[i++] = 0;
     745                                        }
     746                                }
    848747                        }
    849                         else {
    850                                 // variable item
    851                                 item->value = usb_hid_translate_data(item, data);                               
    852                         }                               
    853748                }
    854749                list_item = list_item->next;
    855750        }
     751
     752        callbacks->keyboard(keys, key_count, report_id, arg);
    856753           
     754        free(keys);     
    857755        return EOK;
    858756       
     
    860758
    861759/**
    862  * Translate data from the report as specified in report descriptor item
     760 * Translate data from the report as specified in report descriptor
    863761 *
    864762 * @param item Report descriptor item with definition of translation
     
    867765 * @return Translated data
    868766 */
    869 int usb_hid_translate_data(usb_hid_report_field_t *item, const uint8_t *data)
     767int usb_hid_translate_data(usb_hid_report_item_t *item, const uint8_t *data, size_t j)
    870768{
    871769        int resolution;
     
    873771        int part_size;
    874772       
    875         int32_t value=0;
     773        int32_t value;
    876774        int32_t mask;
    877775        const uint8_t *foo;
    878776
    879         // now only shot tags are allowed
     777        // now only common numbers llowed
    880778        if(item->size > 32) {
    881779                return 0;
    882780        }
    883781
    884         if((item->physical_minimum == 0) && (item->physical_maximum == 0)){
     782        if((item->physical_minimum == 0) && (item->physical_maximum == 0)) {
    885783                item->physical_minimum = item->logical_minimum;
    886                 item->physical_maximum = item->logical_maximum;                 
    887         }
    888        
     784                item->physical_maximum = item->logical_maximum;         
     785        }
    889786
    890787        if(item->physical_maximum == item->physical_minimum){
     
    897794        }
    898795
    899         offset = item->offset;
     796        offset = item->offset + (j * item->size);
     797        if(item->id != 0) {
     798                offset += 8;
     799                usb_log_debug("MOVED OFFSET BY 1Byte, REPORT_ID(%d)\n", item->id);
     800        }
     801       
    900802        // FIXME
    901         if((size_t)(offset/8) != (size_t)((offset+item->size-1)/8)) {
     803        if((offset/8) != ((offset+item->size)/8)) {
     804                usb_log_debug2("offset %d\n", offset);
    902805               
    903806                part_size = ((offset+item->size)%8);
    904 
    905                 size_t i=0;
    906                 for(i=(size_t)(offset/8); i<=(size_t)(offset+item->size-1)/8; i++){
    907                         if(i == (size_t)(offset/8)) {
    908                                 // the higher one
    909                                 foo = data + i;
    910                                 mask =  ((1 << (item->size-part_size))-1);
    911                                 value = (*foo & mask) << part_size;
    912                         }
    913                         else if(i == ((offset+item->size-1)/8)){
    914                                 // the lower one
    915                                 foo = data + i;
    916                                 mask =  ((1 << part_size)-1) << (8-part_size);
    917                                 value += ((*foo & mask) >> (8-part_size));
    918                         }
    919                         else {
    920                                 value = value << 8;
    921                                 value += *(data + 1);
    922                         }
    923                 }
     807                usb_log_debug2("part size %d\n",part_size);
     808
     809                // the higher one
     810                foo = data+(offset/8);
     811                mask =  ((1 << (item->size-part_size))-1);
     812                value = (*foo & mask) << part_size;
     813
     814                usb_log_debug2("hfoo %x\n", *foo);
     815                usb_log_debug2("hmaska %x\n",  mask);
     816                usb_log_debug2("hval %d\n", value);             
     817
     818                // the lower one
     819                foo = data+((offset+item->size)/8);
     820                mask =  ((1 << part_size)-1) << (8-part_size);
     821                value += ((*foo & mask) >> (8-part_size));
     822
     823                usb_log_debug2("lfoo %x\n", *foo);
     824                usb_log_debug2("lmaska %x\n",  mask);
     825                usb_log_debug2("lval %d\n", ((*foo & mask) >> (8-(item->size-part_size))));             
     826                usb_log_debug2("val %d\n", value);
     827               
     828               
    924829        }
    925830        else {         
     
    927832                mask =  ((1 << item->size)-1) << (8-((offset%8)+item->size));
    928833                value = (*foo & mask) >> (8-((offset%8)+item->size));
    929         }
    930 
    931         if((item->logical_minimum < 0) || (item->logical_maximum < 0)){
    932                 value = USB_HID_UINT32_TO_INT32(value, item->size);
    933         }
     834
     835                usb_log_debug2("offset %d\n", offset);
     836       
     837                usb_log_debug2("foo %x\n", *foo);
     838                usb_log_debug2("maska %x\n",  mask);
     839                usb_log_debug2("val %d\n", value);                             
     840        }
     841
     842        usb_log_debug2("---\n\n");
    934843
    935844        return (int)(((value - item->logical_minimum) / resolution) + item->physical_minimum);
     
    938847
    939848/**
    940  * Returns number of items in input report which are accessible by given usage path
    941  *
    942  * @param parser Opaque report descriptor structure
    943  * @param path Usage path specification
    944  * @param flags Usage path comparison flags
    945  * @return Number of items in input report
    946  */
    947 size_t usb_hid_report_input_length(const usb_hid_report_t *report,
     849 *
     850 *
     851 * @param parser
     852 * @param path
     853 * @param flags
     854 * @return
     855 */
     856size_t usb_hid_report_input_length(const usb_hid_report_parser_t *parser,
    948857        usb_hid_report_path_t *path, int flags)
    949858{       
    950        
    951859        size_t ret = 0;
    952 
    953         if(report == NULL) {
     860        link_t *item;
     861        usb_hid_report_item_t *report_item;
     862
     863        if(parser == NULL) {
    954864                return 0;
    955865        }
    956 
    957         usb_hid_report_description_t *report_des;
    958         report_des = usb_hid_report_find_description (report, path->report_id, USB_HID_REPORT_TYPE_INPUT);
    959         if(report_des == NULL) {
    960                 return 0;
    961         }
    962 
    963         link_t *field_it = report_des->report_items.next;
    964         usb_hid_report_field_t *field;
    965         while(field_it != &report_des->report_items) {
    966 
    967                 field = list_get_instance(field_it, usb_hid_report_field_t, link);
    968                 if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) {
    969                        
    970                         usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage);
    971                         if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK) {
    972                                 ret++;
    973                         }
    974                         usb_hid_report_remove_last_item (field->collection_path);
     866       
     867        item = parser->input.next;
     868        while(&parser->input != item) {
     869                report_item = list_get_instance(item, usb_hid_report_item_t, link);
     870                if(!USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags) &&
     871                   (usb_hid_report_compare_usage_path(report_item->usage_path, path, flags) == EOK)) {
     872                        ret += report_item->count;
    975873                }
    976                
    977                 field_it = field_it->next;
    978         }
     874
     875                item = item->next;
     876        } 
    979877
    980878        return ret;
    981         }
    982 
    983 
    984 /**
    985  * Appends one item (couple of usage_path and usage) into the usage path
    986  * structure
    987  *
    988  * @param usage_path Usage path structure
    989  * @param usage_page Usage page constant
    990  * @param usage Usage constant
    991  * @return Error code
     879}
     880
     881
     882/**
     883 *
     884 * @param usage_path
     885 * @param usage_page
     886 * @param usage
     887 * @return
    992888 */
    993889int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path,
     
    1003899        item->usage = usage;
    1004900        item->usage_page = usage_page;
    1005         item->flags = 0;
    1006        
    1007         list_append (&item->link, &usage_path->head);
     901       
     902        usb_log_debug("Appending usage %d, usage page %d\n", usage, usage_page);
     903       
     904        list_append (&usage_path->link, &item->link);
    1008905        usage_path->depth++;
    1009906        return EOK;
     
    1011908
    1012909/**
    1013  * Removes last item from the usage path structure
    1014  * @param usage_path 
    1015  * @return void
     910 *
     911 * @param usage_path
     912 * @return
    1016913 */
    1017914void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path)
     
    1019916        usb_hid_report_usage_path_t *item;
    1020917       
    1021         if(!list_empty(&usage_path->head)){
    1022                 item = list_get_instance(usage_path->head.prev, usb_hid_report_usage_path_t, link);             
    1023                 list_remove(usage_path->head.prev);
     918        if(!list_empty(&usage_path->link)){
     919                item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link);             
     920                list_remove(usage_path->link.prev);
    1024921                usage_path->depth--;
    1025922                free(item);
     
    1028925
    1029926/**
    1030  * Nulls last item of the usage path structure.
    1031927 *
    1032928 * @param usage_path
    1033  * @return void
     929 * @return
    1034930 */
    1035931void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path)
     
    1037933        usb_hid_report_usage_path_t *item;
    1038934       
    1039         if(!list_empty(&usage_path->head)){     
    1040                 item = list_get_instance(usage_path->head.prev, usb_hid_report_usage_path_t, link);
     935        if(!list_empty(&usage_path->link)){     
     936                item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link);
    1041937                memset(item, 0, sizeof(usb_hid_report_usage_path_t));
    1042938        }
     
    1044940
    1045941/**
    1046  * Modifies last item of usage path structure by given usage page or usage
    1047  *
    1048  * @param usage_path Opaque usage path structure
    1049  * @param tag Class of currently processed tag (Usage page tag falls into Global
    1050  * class but Usage tag into the Local)
    1051  * @param data Value of the processed tag
    1052  * @return void
     942 *
     943 * @param usage_path
     944 * @param tag
     945 * @param data
     946 * @return
    1053947 */
    1054948void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, int32_t tag, int32_t data)
     
    1056950        usb_hid_report_usage_path_t *item;
    1057951       
    1058         if(!list_empty(&usage_path->head)){     
    1059                 item = list_get_instance(usage_path->head.prev, usb_hid_report_usage_path_t, link);
     952        if(!list_empty(&usage_path->link)){     
     953                item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link);
    1060954
    1061955                switch(tag) {
     
    1071965}
    1072966
    1073 
    1074 void usb_hid_print_usage_path(usb_hid_report_path_t *path)
    1075 {
    1076         usb_log_debug("USAGE_PATH FOR RId(%d):\n", path->report_id);
    1077         usb_log_debug("\tLENGTH: %d\n", path->depth);
    1078 
    1079         link_t *item = path->head.next;
    1080         usb_hid_report_usage_path_t *path_item;
    1081         while(item != &path->head) {
    1082 
    1083                 path_item = list_get_instance(item, usb_hid_report_usage_path_t, link);
    1084                 usb_log_debug("\tUSAGE_PAGE: %X\n", path_item->usage_page);
    1085                 usb_log_debug("\tUSAGE: %X\n", path_item->usage);
    1086                 usb_log_debug("\tFLAGS: %d\n", path_item->flags);               
    1087                
    1088                 item = item->next;
    1089         }
    1090 }
    1091 
    1092 /**
    1093  * Compares two usage paths structures
    1094  *
    1095  * If USB_HID_PATH_COMPARE_COLLECTION_ONLY flag is given, the last item in report_path structure is forgotten
    1096  *
    1097  * @param report_path usage path structure to compare
    1098  * @param path usage patrh structure to compare
    1099  * @param flags Flags determining the mode of comparison
    1100  * @return EOK if both paths are identical, non zero number otherwise
     967/**
     968 *
     969 *
     970 * @param report_path
     971 * @param path
     972 * @param flags
     973 * @return
    1101974 */
    1102975int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path,
     
    11321005                                }
    11331006
    1134                                 report_link = report_path->head.next;
    1135                                 path_link = path->head.next;
     1007                                report_link = report_path->link.next;
     1008                                path_link = path->link.next;
    11361009                       
    1137                                 while((report_link != &report_path->head) && (path_link != &path->head)) {
     1010                                while((report_link != &report_path->link) && (path_link != &path->link)) {
    11381011                                        report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link);
    11391012                                        path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link);           
     
    11491022                                }
    11501023
    1151                                 if(((report_link == &report_path->head) && (path_link == &path->head)) ||
    1152                                    (((flags & USB_HID_PATH_COMPARE_COLLECTION_ONLY) != 0) && (path_link = &path->head) && (report_link == report_path->head.prev))) {
     1024                                if((report_link == &report_path->link) && (path_link == &path->link)) {
    11531025                                        return EOK;
    11541026                                }
     
    11601032                /* compare with only the end of path*/
    11611033                case USB_HID_PATH_COMPARE_END:
    1162 
    1163                                 if((flags & USB_HID_PATH_COMPARE_COLLECTION_ONLY) != 0) {
    1164                                         report_link = report_path->head.prev->prev;
    1165                                 }
    1166                                 else {
    1167                                         report_link = report_path->head.prev;
    1168                                 }
    1169                                 path_link = path->head.prev;
    1170 
    1171                                 if(list_empty(&path->head)){
     1034                                report_link = report_path->link.prev;
     1035                                path_link = path->link.prev;
     1036
     1037                                if(list_empty(&path->link)){
    11721038                                        return EOK;
    11731039                                }
    11741040                       
    1175                                 while((report_link != &report_path->head) && (path_link != &path->head)) {
     1041                                while((report_link != &report_path->link) && (path_link != &path->link)) {
    11761042                                        report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link);
    11771043                                        path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link);           
     
    11871053                                }
    11881054
    1189                                 if(path_link == &path->head) {
     1055                                if(path_link == &path->link) {
    11901056                                        return EOK;
    11911057                                }
     
    12061072
    12071073/**
    1208  * Allocates and initializes new usage path structure.
    1209  *
    1210  * @return Initialized usage path structure
     1074 *
     1075 * @return
    12111076 */
    12121077usb_hid_report_path_t *usb_hid_report_path(void)
     
    12141079        usb_hid_report_path_t *path;
    12151080        path = malloc(sizeof(usb_hid_report_path_t));
    1216         if(path == NULL){
     1081        if(!path){
    12171082                return NULL;
    12181083        }
     
    12211086                path->report_id = 0;
    12221087                list_initialize(&path->link);
    1223                 list_initialize(&path->head);
    12241088                return path;
    12251089        }
     
    12271091
    12281092/**
    1229  * Releases given usage path structure.
    1230  *
    1231  * @param path usage path structure to release
     1093 *
     1094 * @param path
    12321095 * @return void
    12331096 */
    12341097void usb_hid_report_path_free(usb_hid_report_path_t *path)
    12351098{
    1236         while(!list_empty(&path->head)){
     1099        while(!list_empty(&path->link)){
    12371100                usb_hid_report_remove_last_item(path);
    12381101        }
    1239 
    1240         list_remove(&path->link);
    1241         free(path);
    12421102}
    12431103
     
    12461106 * Clone content of given usage path to the new one
    12471107 *
    1248  * @param usage_path Usage path structure to clone
    1249  * @return New copy of given usage path structure
     1108 * @param usage_path
     1109 * @return
    12501110 */
    12511111usb_hid_report_path_t *usb_hid_report_path_clone(usb_hid_report_path_t *usage_path)
    12521112{
     1113        usb_hid_report_usage_path_t *path_item;
    12531114        link_t *path_link;
    1254         usb_hid_report_usage_path_t *path_item;
    1255         usb_hid_report_usage_path_t *new_path_item;
    12561115        usb_hid_report_path_t *new_usage_path = usb_hid_report_path ();
    12571116
     
    12591118                return NULL;
    12601119        }
    1261 
    1262         new_usage_path->report_id = usage_path->report_id;
    1263        
    1264         if(list_empty(&usage_path->head)){
     1120       
     1121        if(list_empty(&usage_path->link)){
    12651122                return new_usage_path;
    12661123        }
    12671124
    1268         path_link = usage_path->head.next;
    1269         while(path_link != &usage_path->head) {
     1125        path_link = usage_path->link.next;
     1126        while(path_link != &usage_path->link) {
    12701127                path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link);
    1271                 new_path_item = malloc(sizeof(usb_hid_report_usage_path_t));
    1272                 if(new_path_item == NULL) {
    1273                         return NULL;
    1274                 }
    1275                
    1276                 list_initialize (&new_path_item->link);         
    1277                 new_path_item->usage_page = path_item->usage_page;
    1278                 new_path_item->usage = path_item->usage;               
    1279                 new_path_item->flags = path_item->flags;               
    1280                
    1281                 list_append(&new_path_item->link, &new_usage_path->head);
    1282                 new_usage_path->depth++;
     1128                usb_hid_report_path_append_item (new_usage_path, path_item->usage_page, path_item->usage);
    12831129
    12841130                path_link = path_link->next;
     
    12911137/*** OUTPUT API **/
    12921138
    1293 /**
    1294  * Allocates output report buffer for output report
    1295  *
    1296  * @param parser Report parsed structure
    1297  * @param size Size of returned buffer
    1298  * @param report_id Report id of created output report
    1299  * @return Returns allocated output buffer for specified output
    1300  */
    1301 uint8_t *usb_hid_report_output(usb_hid_report_t *report, size_t *size, uint8_t report_id)
    1302 {
    1303         if(report == NULL) {
     1139/** Allocates output report buffer
     1140 *
     1141 * @param parser
     1142 * @param size
     1143 * @return
     1144 */
     1145uint8_t *usb_hid_report_output(usb_hid_report_parser_t *parser, size_t *size)
     1146{
     1147        if(parser == NULL) {
    13041148                *size = 0;
    13051149                return NULL;
    13061150        }
    1307 
    1308         link_t *report_it = report->reports.next;
    1309         usb_hid_report_description_t *report_des = NULL;
    1310         while(report_it != &report->reports) {
    1311                 report_des = list_get_instance(report_it, usb_hid_report_description_t, link);
    1312                 if((report_des->report_id == report_id) && (report_des->type == USB_HID_REPORT_TYPE_OUTPUT)){
    1313                         break;
    1314                 }
    1315 
    1316                 report_it = report_it->next;
    1317         }
    1318 
    1319         if(report_des == NULL){
    1320                 *size = 0;
     1151       
     1152        // read the last output report item
     1153        usb_hid_report_item_t *last;
     1154        link_t *link;
     1155
     1156        link = parser->output.prev;
     1157        if(link != &parser->output) {
     1158                last = list_get_instance(link, usb_hid_report_item_t, link);
     1159                *size = (last->offset + (last->size * last->count)) / 8;
     1160
     1161                uint8_t *buffer = malloc(sizeof(uint8_t) * (*size));
     1162                memset(buffer, 0, sizeof(uint8_t) * (*size));
     1163                usb_log_debug("output buffer: %s\n", usb_debug_str_buffer(buffer, *size, 0));
     1164
     1165                return buffer;
     1166        }
     1167        else {
     1168                *size = 0;             
    13211169                return NULL;
    13221170        }
    1323         else {
    1324                 *size = (report_des->bit_length + (8 - 1))/8;
    1325                 uint8_t *ret = malloc((*size) * sizeof(uint8_t));
    1326                 memset(ret, 0, (*size) * sizeof(uint8_t));
    1327                 return ret;
    1328         }
    13291171}
    13301172
     
    13331175 *
    13341176 * @param output Output report buffer
    1335  * @return void
     1177 * @return
    13361178 */
    13371179void usb_hid_report_output_free(uint8_t *output)
     
    13451187/** Returns size of output for given usage path
    13461188 *
    1347  * @param parser Opaque report parser structure
    1348  * @param path Usage path specified which items will be thought for the output
    1349  * @param flags Flags of usage path structure comparison
    1350  * @return Number of items matching the given usage path
    1351  */
    1352 size_t usb_hid_report_output_size(usb_hid_report_t *report,
     1189 * @param parser
     1190 * @param path
     1191 * @param flags
     1192 * @return
     1193 */
     1194size_t usb_hid_report_output_size(usb_hid_report_parser_t *parser,
    13531195                                  usb_hid_report_path_t *path, int flags)
    13541196{
    1355         size_t ret = 0;
    1356         usb_hid_report_description_t *report_des;
    1357 
    1358         if(report == NULL) {
     1197        size_t ret = 0;
     1198        link_t *item;
     1199        usb_hid_report_item_t *report_item;
     1200
     1201        if(parser == NULL) {
    13591202                return 0;
    13601203        }
    13611204
    1362         report_des = usb_hid_report_find_description (report, path->report_id, USB_HID_REPORT_TYPE_OUTPUT);
    1363         if(report_des == NULL){
    1364                 return 0;
    1365         }
    1366        
    1367         link_t *field_it = report_des->report_items.next;
    1368         usb_hid_report_field_t *field;
    1369         while(field_it != &report_des->report_items) {
    1370 
    1371                 field = list_get_instance(field_it, usb_hid_report_field_t, link);
    1372                 if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0){
    1373                         usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage);
    1374                         if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK) {
    1375                                 ret++;
    1376                         }
    1377                         usb_hid_report_remove_last_item (field->collection_path);
     1205        item = parser->output.next;
     1206        while(&parser->output != item) {
     1207                report_item = list_get_instance(item, usb_hid_report_item_t, link);
     1208                if(!USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags) &&
     1209                   (usb_hid_report_compare_usage_path(report_item->usage_path, path, flags) == EOK)) {
     1210                        ret += report_item->count;
    13781211                }
    1379                
    1380                 field_it = field_it->next;
    1381         }
     1212
     1213                item = item->next;
     1214        } 
    13821215
    13831216        return ret;
     
    13851218}
    13861219
    1387 /** Makes the output report buffer for data given in the report structure
    1388  *
    1389  * @param parser Opaque report parser structure
    1390  * @param path Usage path specifing which parts of output will be set
    1391  * @param flags Usage path structure comparison flags
    1392  * @param buffer Output buffer
    1393  * @param size Size of output buffer
    1394  * @return Error code
    1395  */
    1396 int usb_hid_report_output_translate(usb_hid_report_t *report, uint8_t report_id,
    1397                                     uint8_t *buffer, size_t size)
    1398 {
     1220/** Updates the output report buffer by translated given data
     1221 *
     1222 * @param parser
     1223 * @param path
     1224 * @param flags
     1225 * @param buffer
     1226 * @param size
     1227 * @param data
     1228 * @param data_size
     1229 * @return
     1230 */
     1231int usb_hid_report_output_translate(usb_hid_report_parser_t *parser,
     1232                                    usb_hid_report_path_t *path, int flags,
     1233                                    uint8_t *buffer, size_t size,
     1234                                    int32_t *data, size_t data_size)
     1235{
     1236        usb_hid_report_item_t *report_item;
    13991237        link_t *item;   
     1238        size_t idx=0;
     1239        int i=0;
    14001240        int32_t value=0;
    14011241        int offset;
    14021242        int length;
    14031243        int32_t tmp_value;
    1404        
    1405         if(report == NULL) {
     1244        size_t offset_prefix = 0;
     1245       
     1246        if(parser == NULL) {
    14061247                return EINVAL;
    14071248        }
    14081249
    1409         if(report->use_report_ids != 0) {
    1410                 buffer[0] = report_id;         
     1250        if(parser->use_report_id != 0) {
     1251                buffer[0] = path->report_id;
     1252                offset_prefix = 8;
    14111253        }
    14121254
    14131255        usb_log_debug("OUTPUT BUFFER: %s\n", usb_debug_str_buffer(buffer,size, 0));
    1414        
    1415         usb_hid_report_description_t *report_des;
    1416         report_des = usb_hid_report_find_description (report, report_id, USB_HID_REPORT_TYPE_OUTPUT);
    1417         if(report_des == NULL){
    1418                 return EINVAL;
    1419         }
    1420 
    1421         usb_hid_report_field_t *report_item;   
    1422         item = report_des->report_items.next;   
    1423         while(item != &report_des->report_items) {
    1424                 report_item = list_get_instance(item, usb_hid_report_field_t, link);
    1425 
    1426                         if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) {
     1256        usb_log_debug("OUTPUT DATA[0]: %d, DATA[1]: %d, DATA[2]: %d\n", data[0], data[1], data[2]);
     1257
     1258        item = parser->output.next;     
     1259        while(item != &parser->output) {
     1260                report_item = list_get_instance(item, usb_hid_report_item_t, link);
     1261
     1262                for(i=0; i<report_item->count; i++) {
     1263
     1264                        if(idx >= data_size) {
     1265                                break;
     1266                        }
     1267
     1268                        if((USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) ||
     1269                                ((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0))) {
    14271270                                       
    1428                                 // array
    1429                                 value = usb_hid_translate_data_reverse(report_item, report_item->value);
    1430                                 offset = report_item->offset;
     1271//                              // variable item
     1272                                value = usb_hid_translate_data_reverse(report_item, data[idx++]);
     1273                                offset = report_item->offset + (i * report_item->size) + offset_prefix;
    14311274                                length = report_item->size;
    14321275                        }
    14331276                        else {
    1434                                 // variable item
    1435                                 value  = usb_hid_translate_data_reverse(report_item, report_item->value);
    1436                                 offset = report_item->offset;
    1437                                 length = report_item->size;
     1277                                //bitmap
     1278                                value += usb_hid_translate_data_reverse(report_item, data[idx++]);
     1279                                offset = report_item->offset + offset_prefix;
     1280                                length = report_item->size * report_item->count;
    14381281                        }
    14391282
     
    14541297                        }
    14551298                        else {
    1456                                 int i = 0;
     1299                                // je to ve dvou!! FIXME: melo by to umet delsi jak 2
     1300
     1301                                // konec prvniho -- dolni x bitu
     1302                                tmp_value = value;
     1303                                tmp_value = tmp_value & ((1 << (8-(offset%8)))-1);                             
     1304                                tmp_value = tmp_value << (offset%8);
     1305
    14571306                                uint8_t mask = 0;
    1458                                 for(i = (offset/8); i <= ((offset+length-1)/8); i++) {
    1459                                         if(i == (offset/8)) {
    1460                                                 tmp_value = value;
    1461                                                 tmp_value = tmp_value & ((1 << (8-(offset%8)))-1);                             
    1462                                                 tmp_value = tmp_value << (offset%8);
    1463        
    1464                                                 mask = ~(((1 << (8-(offset%8)))-1) << (offset%8));
    1465                                                 buffer[i] = (buffer[i] & mask) | tmp_value;                     
    1466                                         }
    1467                                         else if (i == ((offset + length -1)/8)) {
    1468                                                
    1469                                                 value = value >> (length - ((offset + length) % 8));
    1470                                                 value = value & ((1 << (length - ((offset + length) % 8))) - 1);
     1307                                mask = ~(((1 << (8-(offset%8)))-1) << (offset%8));
     1308                                buffer[offset/8] = (buffer[offset/8] & mask) | tmp_value;
     1309
     1310                                // a ted druhej -- hornich length-x bitu
     1311                                value = value >> (8 - (offset % 8));
     1312                                value = value & ((1 << (length - (8 - (offset % 8)))) - 1);
    14711313                               
    1472                                                 mask = (1 << (length - ((offset + length) % 8))) - 1;
    1473                                                 buffer[i] = (buffer[i] & mask) | value;
    1474                                         }
    1475                                         else {
    1476                                                 buffer[i] = value & (0xFF << i);
    1477                                         }
    1478                                 }
     1314                                mask = ((1 << (length - (8 - (offset % 8)))) - 1);
     1315                                buffer[(offset+length-1)/8] = (buffer[(offset+length-1)/8] & mask) | value;
    14791316                        }
    14801317
    1481 
    1482                 // reset value
    1483                 report_item->value = 0;
    1484                
     1318                }
     1319
    14851320                item = item->next;
    14861321        }
    1487        
     1322
    14881323        usb_log_debug("OUTPUT BUFFER: %s\n", usb_debug_str_buffer(buffer,size, 0));
    14891324
     
    14921327
    14931328/**
    1494  * Translate given data for putting them into the outoput report
    1495  * @param item Report item structure
    1496  * @param value Value to translate
    1497  * @return ranslated value
    1498  */
    1499 uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, int value)
     1329 *
     1330 * @param item
     1331 * @param value
     1332 * @return
     1333 */
     1334int32_t usb_hid_translate_data_reverse(usb_hid_report_item_t *item, int value)
    15001335{
    15011336        int ret=0;
     
    15061341        }
    15071342
    1508         if((item->physical_minimum == 0) && (item->physical_maximum == 0)){
    1509                 item->physical_minimum = item->logical_minimum;
    1510                 item->physical_maximum = item->logical_maximum;                 
    1511         }
    1512        
    1513 
    15141343        if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0)) {
    15151344
    15161345                // variable item
     1346                if((item->physical_minimum == 0) && (item->physical_maximum == 0)) {
     1347                        item->physical_minimum = item->logical_minimum;
     1348                        item->physical_maximum = item->logical_maximum;
     1349                }
     1350
    15171351                if(item->physical_maximum == item->physical_minimum){
    15181352                    resolution = 1;
     
    15371371        }
    15381372
    1539         if((item->logical_minimum < 0) || (item->logical_maximum < 0)){
    1540                 return USB_HID_INT32_TO_UINT32(ret, item->size);
    1541         }
    1542         return (int32_t)ret;
    1543 }
    1544 
    1545 /**
    1546  * Sets report id in usage path structure
    1547  *
    1548  * @param path Usage path structure
    1549  * @param report_id Report id to set
    1550  * @return Error code
    1551  */
     1373
     1374        return ret;
     1375}
     1376
     1377
    15521378int usb_hid_report_path_set_report_id(usb_hid_report_path_t *path, uint8_t report_id)
    15531379{
     
    15571383
    15581384        path->report_id = report_id;
    1559         return EOK;
    1560 }
    1561 
    1562 /**
    1563  *
    1564  *
    1565  *
    1566  *
    1567  *
    1568  */
    1569 int usb_hid_report_output_set_data(usb_hid_report_t *report,
    1570                                    usb_hid_report_path_t *path, int flags,
    1571                                   int *data, size_t data_size)
    1572 {
    1573         size_t data_idx = 0;
    1574         if(report == NULL){
    1575                 return EINVAL;
    1576         }
    1577 
    1578         usb_hid_report_description_t *report_des;
    1579         report_des = usb_hid_report_find_description (report, path->report_id,
    1580                                                       USB_HID_REPORT_TYPE_OUTPUT);
    1581         if(report_des == NULL){
    1582                 return EINVAL;
    1583         }
    1584 
    1585         usb_hid_report_field_t *field;
    1586         link_t *field_it = report_des->report_items.next;       
    1587         while(field_it != &report_des->report_items){
    1588 
    1589                 field = list_get_instance(field_it, usb_hid_report_field_t, link);             
    1590                 if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) {
    1591                         usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage);
    1592                         if(usb_hid_report_compare_usage_path (field->collection_path, path,
    1593                                                       flags) == EOK) {
    1594                                 if(data_idx < data_size) {
    1595                                         if((data[data_idx] >= field->physical_minimum) && (data[data_idx] >= field->physical_minimum)) {
    1596                                                 field->value = data[data_idx];
    1597                                         }
    1598                                         else {
    1599                                                 return ERANGE;
    1600                                         }
    1601 
    1602                                         data_idx++;
    1603                                 }
    1604                                 else {
    1605                                         field->value = 0;
    1606                                 }
    1607                         }
    1608                         usb_hid_report_remove_last_item (field->collection_path);
    1609                 }
    1610                
    1611                 field_it = field_it->next;
    1612         }
    1613 
    16141385        return EOK;
    16151386}
     
    16291400}
    16301401
    1631 
    1632 usb_hid_report_field_t *usb_hid_report_get_sibling(usb_hid_report_t *report,
    1633                                                         usb_hid_report_field_t *field,
    1634                             usb_hid_report_path_t *path, int flags,
    1635                             usb_hid_report_type_t type)
    1636 {
    1637         usb_hid_report_description_t *report_des = usb_hid_report_find_description (report, path->report_id, type);
    1638         link_t *field_it;
    1639        
    1640         if(report_des == NULL){
    1641                 return NULL;
    1642         }
    1643 
    1644         if(field == NULL){
    1645                 // vezmu prvni co mathuje podle path!!
    1646                 field_it = report_des->report_items.next;
    1647         }
    1648         else {
    1649                 field_it = field->link.next;
    1650         }
    1651 
    1652         while(field_it != &report_des->report_items) {
    1653                 field = list_get_instance(field_it, usb_hid_report_field_t, link);
    1654 
    1655                 if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) {
    1656                         usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage);
    1657                         if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK){
    1658                                 usb_hid_report_remove_last_item (field->collection_path);
    1659                                 return field;
    1660                         }
    1661                         usb_hid_report_remove_last_item (field->collection_path);
    1662                 }
    1663                 field_it = field_it->next;
    1664         }
    1665 
    1666         return NULL;
    1667 }
    1668 
    1669 uint8_t usb_hid_report_get_report_id(usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type)
    1670 {
    1671         if(report == NULL){
    1672                 return 0;
    1673         }
    1674 
    1675         usb_hid_report_description_t *report_des;
    1676         link_t *report_it;
    1677        
    1678         if(report_id == 0) {
    1679                 report_it = usb_hid_report_find_description (report, report_id, type)->link.next;               
    1680         }
    1681         else {
    1682                 report_it = report->reports.next;
    1683         }
    1684 
    1685         while(report_it != &report->reports) {
    1686                 report_des = list_get_instance(report_it, usb_hid_report_description_t, link);
    1687                 if(report_des->type == type){
    1688                         return report_des->report_id;
    1689                 }
    1690         }
    1691 
    1692         return 0;
    1693 }
    1694 
    1695 void usb_hid_report_reset_local_items(usb_hid_report_item_t *report_item)
    1696 {
    1697         if(report_item == NULL) {
    1698                 return;
    1699         }
    1700        
    1701         report_item->usages_count = 0;
    1702         memset(report_item->usages, 0, USB_HID_MAX_USAGES);
    1703        
    1704         report_item->extended_usage_page = 0;
    1705         report_item->usage_minimum = 0;
    1706         report_item->usage_maximum = 0;
    1707         report_item->designator_index = 0;
    1708         report_item->designator_minimum = 0;
    1709         report_item->designator_maximum = 0;
    1710         report_item->string_index = 0;
    1711         report_item->string_minimum = 0;
    1712         report_item->string_maximum = 0;
    1713 
    1714         return;
    1715 }
    17161402/**
    17171403 * @}
  • uspace/lib/usb/src/hidreport.c

    r9e929a0 r152ec79  
    164164
    165165int usb_hid_process_report_descriptor(usb_device_t *dev,
    166     usb_hid_report_t *report)
     166    usb_hid_report_parser_t *parser)
    167167{
    168         if (dev == NULL || report == NULL) {
     168        if (dev == NULL || parser == NULL) {
    169169                usb_log_error("Failed to process Report descriptor: wrong "
    170170                    "parameters given.\n");
     
    189189        assert(report_desc != NULL);
    190190       
    191         rc = usb_hid_parse_report_descriptor(report, report_desc, report_size);
     191        rc = usb_hid_parse_report_descriptor(parser, report_desc, report_size);
    192192        if (rc != EOK) {
    193193                usb_log_error("Problem parsing Report descriptor: %s.\n",
     
    197197        }
    198198       
    199         usb_hid_descriptor_print(report);
     199        usb_hid_descriptor_print(parser);
    200200        free(report_desc);
    201201       
Note: See TracChangeset for help on using the changeset viewer.