Changeset 175ad13e in mainline


Ignore:
Timestamp:
2011-04-15T15:19:34Z (13 years ago)
Author:
Matej Klonfar <maklf@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
681f24b3
Parents:
9698695
Message:

new report structure

Location:
uspace
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/usbkbd/kbddev.c

    r9698695 r175ad13e  
    290290        usb_log_debug("Creating output report.\n");
    291291       
    292         int rc = usb_hid_report_output_translate(kbd_dev->parser,
    293             kbd_dev->led_path, USB_HID_PATH_COMPARE_END, kbd_dev->output_buffer,
    294             kbd_dev->output_size, kbd_dev->led_data, kbd_dev->led_output_size);
     292        int rc = usb_hid_report_output_translate(kbd_dev->parser, 0,
     293            kbd_dev->output_buffer, kbd_dev->output_size);
    295294       
    296295        if (rc != EOK) {
     
    612611        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
    613612
    614         int rc = usb_hid_parse_report(kbd_dev->parser, buffer,
    615             actual_size, path, USB_HID_PATH_COMPARE_STRICT, callbacks, kbd_dev);
     613        int rc = usb_hid_parse_report(kbd_dev->parser, buffer, actual_size);
    616614
    617615        usb_hid_report_path_free (path);
     
    657655        memset(kbd_dev, 0, sizeof(usb_kbd_t));
    658656       
    659         kbd_dev->parser = (usb_hid_report_parser_t *)(malloc(sizeof(
    660             usb_hid_report_parser_t)));
     657        kbd_dev->parser = (usb_hid_report_t *)(malloc(sizeof(
     658            usb_hid_report_t)));
    661659        if (kbd_dev->parser == NULL) {
    662660                usb_log_fatal("No memory!\n");
     
    726724       
    727725        /* Initialize the report parser. */
    728         rc = usb_hid_parser_init(kbd_dev->parser);
    729         if (rc != EOK) {
    730                 usb_log_error("Failed to initialize report parser.\n");
    731                 return rc;
    732         }
     726        //rc = usb_hid_parser_init(kbd_dev->parser);
     727        //if (rc != EOK) {
     728        //      usb_log_error("Failed to initialize report parser.\n");
     729        //      return rc;
     730        //}
    733731       
    734732        /* Get the report descriptor and parse it. */
     
    762760        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
    763761        kbd_dev->key_count = usb_hid_report_input_length(
    764             kbd_dev->parser, path, USB_HID_PATH_COMPARE_STRICT);
     762            kbd_dev->parser, path, USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY);
    765763        usb_hid_report_path_free (path);
    766764       
     
    924922        // destroy the parser
    925923        if ((*kbd_dev)->parser != NULL) {
    926                 usb_hid_free_report_parser((*kbd_dev)->parser);
     924                usb_hid_free_report((*kbd_dev)->parser);
    927925        }
    928926       
  • uspace/drv/usbkbd/kbddev.h

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

    r9698695 r175ad13e  
    5050        USB_HIDREQ_SET_PROTOCOL = 11
    5151} usb_hid_request_t;
    52 
    53 typedef 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;
    5852
    5953typedef enum {
  • uspace/lib/usb/include/usb/classes/hidparser.h

    r9698695 r175ad13e  
    7474#define USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY    4
    7575
    76 /** */
    77 typedef struct {
    78         /** */
    79         int32_t usage_page;
    80         /** */ 
    81         int32_t usage;
     76
     77#define USB_HID_MAX_USAGES      20
     78
     79typedef enum {
     80        USB_HID_REPORT_TYPE_INPUT = 1,
     81        USB_HID_REPORT_TYPE_OUTPUT = 2,
     82        USB_HID_REPORT_TYPE_FEATURE = 3
     83} usb_hid_report_type_t;
     84
     85/** Collection usage path structure */
     86typedef struct {
     87        /** */
     88        uint32_t usage_page;
     89        /** */ 
     90        uint32_t usage;
     91
     92        uint8_t flags;
    8293        /** */
    8394        link_t link;
     
    95106} usb_hid_report_path_t;
    96107
    97 /**
    98  * Description of report items
    99  */
    100 typedef struct {
    101         /** */ 
     108
     109typedef struct {
     110        /** */
     111        int report_count;
     112        link_t reports;         /** list of usb_hid_report_description_t */
     113
     114        link_t collection_paths;
     115        int collection_paths_count;
     116
     117        int use_report_ids;
     118       
     119} usb_hid_report_t;
     120
     121typedef struct {
     122        uint8_t report_id;
     123        usb_hid_report_type_t type;
     124
     125        size_t bit_length;
     126        size_t item_length;
     127       
     128        link_t report_items;    /** list of report items (fields) */
     129
     130        link_t link;
     131} usb_hid_report_description_t;
     132
     133typedef struct {
     134
     135        int offset;
     136        size_t size;
     137
     138        uint16_t usage_page;
     139        uint16_t usage;
     140
     141        uint8_t item_flags;
     142        usb_hid_report_path_t *collection_path;
     143
     144        int32_t logical_minimum;
     145        int32_t logical_maximum;
     146        int32_t physical_minimum;
     147        int32_t physical_maximum;
     148        uint32_t usage_minimum;
     149        uint32_t usage_maximum;
     150        uint32_t unit;
     151        uint32_t unit_exponent;
     152       
     153
     154        int32_t value;
     155
     156        link_t link;
     157} usb_hid_report_field_t;
     158
     159
     160
     161/**
     162 * state table
     163 */
     164typedef struct {
     165        /** report id */       
    102166        int32_t id;
    103         /** */ 
    104         int32_t usage_minimum;
    105         /** */ 
    106         int32_t usage_maximum;
     167       
     168        /** */
     169        uint16_t extended_usage_page;
     170        uint32_t usages[USB_HID_MAX_USAGES];
     171        int usages_count;
     172
     173        /** */
     174        uint32_t usage_page;
     175
     176        /** */ 
     177        uint32_t usage_minimum;
     178        /** */ 
     179        uint32_t usage_maximum;
    107180        /** */ 
    108181        int32_t logical_minimum;
     
    116189        size_t offset;
    117190        /** */ 
    118         int32_t delimiter;
    119         /** */ 
    120191        int32_t unit_exponent;
    121192        /** */ 
     
    123194
    124195        /** */
    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;
     196        uint32_t string_index;
     197        /** */ 
     198        uint32_t string_minimum;
     199        /** */ 
     200        uint32_t string_maximum;
     201        /** */ 
     202        uint32_t designator_index;
     203        /** */ 
     204        uint32_t designator_minimum;
     205        /** */ 
     206        uint32_t designator_maximum;
    136207        /** */ 
    137208        int32_t physical_minimum;
     
    142213        uint8_t item_flags;
    143214
    144         /** */ 
     215        usb_hid_report_type_t type;
     216
     217        /** current collection path*/   
    145218        usb_hid_report_path_t *usage_path;
    146219        /** */ 
    147220        link_t link;
    148221} usb_hid_report_item_t;
    149 
    150 
    151 /** HID report parser structure. */
    152 typedef 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 
    166222
    167223/** HID parser callbacks for IN items. */
     
    189245} usb_hid_modifiers_t;
    190246
    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 
    200247static const usb_hid_modifiers_t
    201248    usb_hid_modifiers_consts[USB_HID_MOD_COUNT] = {
     
    210257};
    211258
    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 
    226259/*
    227260 * Descriptor parser functions
    228261 */
    229 /** */
    230 int usb_hid_parser_init(usb_hid_report_parser_t *parser);
    231 
    232 /** */
    233 int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser,
     262
     263/** */
     264int usb_hid_parse_report_descriptor(usb_hid_report_t *report,
    234265    const uint8_t *data, size_t size);
    235266
    236267/** */
    237 void usb_hid_free_report_parser(usb_hid_report_parser_t *parser);
    238 
    239 /** */
    240 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser);
     268void usb_hid_free_report(usb_hid_report_t *report);
     269
     270/** */
     271void usb_hid_descriptor_print(usb_hid_report_t *report);
    241272
    242273
     
    245276 */
    246277/** */
    247 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 
    248     const uint8_t *data, size_t size,
    249     usb_hid_report_path_t *path, int flags,
    250     const usb_hid_report_in_callbacks_t *callbacks, void *arg);
    251 
    252 /** */
    253 size_t usb_hid_report_input_length(const usb_hid_report_parser_t *parser,
     278int usb_hid_parse_report(const usb_hid_report_t *report, const uint8_t *data, size_t size);
     279
     280/** */
     281size_t usb_hid_report_input_length(const usb_hid_report_t *report,
    254282        usb_hid_report_path_t *path, int flags);
    255283
     
    291319 */
    292320/** Allocates output report buffer*/
    293 uint8_t *usb_hid_report_output(usb_hid_report_parser_t *parser, size_t *size, uint8_t report_id);
     321uint8_t *usb_hid_report_output(usb_hid_report_t *report, size_t *size, uint8_t report_id);
    294322
    295323/** Frees output report buffer*/
     
    297325
    298326/** Returns size of output for given usage path */
    299 size_t usb_hid_report_output_size(usb_hid_report_parser_t *parser,
     327size_t usb_hid_report_output_size(usb_hid_report_t *report,
    300328                                  usb_hid_report_path_t *path, int flags);
    301329
    302 /** Updates the output report buffer by translated given data */
    303 int usb_hid_report_output_translate(usb_hid_report_parser_t *parser,
    304                                     usb_hid_report_path_t *path, int flags,
    305                                     uint8_t *buffer, size_t size,
    306                                     int32_t *data, size_t data_size);
     330/** Sets data in report structure */
     331int usb_hid_report_output_set_data(usb_hid_report_t *report,
     332                                   usb_hid_report_path_t *path, int flags,
     333                                  int *data, size_t data_size);
     334
     335/** Makes the output report buffer by translated given data */
     336int usb_hid_report_output_translate(usb_hid_report_t *report, uint8_t report_id, uint8_t *buffer, size_t size);
    307337#endif
    308338/**
  • uspace/lib/usb/include/usb/classes/hidreport.h

    r9698695 r175ad13e  
    5757 */
    5858int usb_hid_process_report_descriptor(usb_device_t *dev,
    59     usb_hid_report_parser_t *parser);
     59    usb_hid_report_t *report);
    6060
    6161#endif /* LIBUSB_HIDREPORT_H_ */
  • uspace/lib/usb/src/hidparser.c

    r9698695 r175ad13e  
    5050#define USB_HID_NO_ACTION       2
    5151
     52#define USB_HID_RESET_OFFSET    3
     53
    5254/** Unknown tag was founded in report descriptor data*/
    5355#define USB_HID_UNKNOWN_TAG             -99
     
    5658 * Private descriptor parser functions
    5759 */
     60int usb_hid_report_init(usb_hid_report_t *report);
     61int usb_hid_report_append_fields(usb_hid_report_t *report, usb_hid_report_item_t *report_item);
     62usb_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);
    5863int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size,
    5964                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
     
    6570                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
    6671
     72void usb_hid_print_usage_path(usb_hid_report_path_t *path);
    6773void usb_hid_descriptor_print_list(link_t *head);
    6874int usb_hid_report_reset_local_items();
     
    7480int32_t usb_hid_report_tag_data_int32(const uint8_t *data, size_t size);
    7581inline size_t usb_hid_count_item_offset(usb_hid_report_item_t * report_item, size_t offset);
    76 int usb_hid_translate_data(const usb_hid_report_parser_t *parser, usb_hid_report_item_t *item, const uint8_t *data, size_t j);
    77 int32_t usb_hid_translate_data_reverse(usb_hid_report_item_t *item, int32_t value);
     82int usb_hid_translate_data(usb_hid_report_field_t *item, const uint8_t *data, size_t j);
     83uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, int32_t value);
    7884int usb_pow(int a, int b);
    7985
     
    100106 * @return Error code
    101107 */
    102 int usb_hid_parser_init(usb_hid_report_parser_t *parser)
    103 {
    104         if(parser == NULL) {
     108int usb_hid_report_init(usb_hid_report_t *report)
     109{
     110        if(report == NULL) {
    105111                return EINVAL;
    106112        }
    107113
    108         list_initialize(&(parser->input));
    109         list_initialize(&(parser->output));
    110         list_initialize(&(parser->feature));
    111 
    112         list_initialize(&(parser->stack));
    113 
    114         parser->use_report_id = 0;
     114        memset(report, 0, sizeof(usb_hid_report_t));
     115        list_initialize(&report->reports);
     116        list_initialize(&report->collection_paths);
     117
     118        report->use_report_ids = 0;
    115119    return EOK;   
    116120}
    117121
     122int usb_hid_report_append_fields(usb_hid_report_t *report, usb_hid_report_item_t *report_item)
     123{
     124        usb_hid_report_field_t *field;
     125        int i;
     126
     127
     128        /* find or append current collection path to the list */
     129        link_t *path_it = report->collection_paths.next;
     130        usb_hid_report_path_t *path = NULL;
     131        while(path_it != &report->collection_paths) {
     132                path = list_get_instance(path_it, usb_hid_report_path_t, link);
     133               
     134                if(usb_hid_report_compare_usage_path(path, report_item->usage_path, USB_HID_PATH_COMPARE_STRICT) == EOK){
     135                        break;
     136                }                       
     137                path_it = path_it->next;
     138        }
     139        if(path_it == &report->collection_paths) {
     140                path = usb_hid_report_path_clone(report_item->usage_path);                     
     141
     142                usb_log_debug("PUVODNI: \n");
     143                usb_hid_print_usage_path (report_item->usage_path);
     144                usb_log_debug("KLON - path: \n");
     145                usb_hid_print_usage_path (path);               
     146                usb_log_debug("KLON - clone: \n");
     147                usb_hid_print_usage_path (usb_hid_report_path_clone(report_item->usage_path));         
     148
     149                list_append(&path->link, &report->collection_paths);                   
     150
     151                // PROC SE KRUVA VLOZI NESMYSLY??
     152                usb_log_debug("VLOZENO: \n");
     153                usb_hid_print_usage_path (list_get_instance(report->collection_paths.prev, usb_hid_report_path_t, link));
     154                usb_log_debug("\n");
     155                report->collection_paths_count++;
     156        }
     157
     158       
     159        for(i=0; i<report_item->count; i++){
     160
     161                field = malloc(sizeof(usb_hid_report_field_t));
     162                memset(field, 0, sizeof(usb_hid_report_field_t));
     163                list_initialize(&field->link);
     164
     165                /* fill the attributes */
     166                field->collection_path = path;
     167                field->logical_minimum = report_item->logical_minimum;
     168                field->logical_maximum = report_item->logical_maximum;
     169                field->physical_minimum = report_item->physical_minimum;
     170                field->physical_maximum = report_item->physical_maximum;
     171                field->usage_minimum = report_item->usage_minimum;
     172                field->usage_maximum = report_item->usage_maximum;
     173                if(report_item->extended_usage_page != 0){
     174                        field->usage_page = report_item->extended_usage_page;
     175                }
     176                else {
     177                        field->usage_page = report_item->usage_page;
     178                }
     179               
     180                if(report_item->usages_count > 0 && ((report_item->usage_minimum = 0) && (report_item->usage_maximum = 0))) {
     181                        if(i < report_item->usages_count){
     182                                if((report_item->usages[i] & 0xFF00) > 0){
     183                                        field->usage_page = (report_item->usages[i] >> 16);                                     
     184                                        field->usage = (report_item->usages[i] & 0xFF);
     185                                }
     186                                else {
     187                                        field->usage = report_item->usages[i];
     188                                }
     189                        }
     190                        else {
     191                                field->usage = report_item->usages[report_item->usages_count - 1];
     192                        }
     193                }               
     194               
     195                field->size = report_item->size;
     196                field->offset = report_item->offset + (i * report_item->size);
     197                if(report_item->id != 0) {
     198                        field->offset += 8;
     199                        report->use_report_ids = 1;
     200                }
     201                field->item_flags = report_item->item_flags;
     202
     203                /* find the right report list*/
     204                usb_hid_report_description_t *report_des;
     205                report_des = usb_hid_report_find_description(report, report_item->id, report_item->type);
     206                if(report_des == NULL){
     207                        report_des = malloc(sizeof(usb_hid_report_description_t));
     208                        memset(report_des, 0, sizeof(usb_hid_report_description_t));
     209
     210                        report_des->type = report_item->type;
     211                        report_des->report_id = report_item->id;
     212                        list_initialize (&report_des->link);
     213                        list_initialize (&report_des->report_items);
     214
     215                        list_append(&report_des->link, &report->reports);
     216                        report->report_count++;
     217                }
     218
     219                /* append this field to the end of founded report list */
     220                list_append (&field->link, &report_des->report_items);
     221               
     222                /* update the sizes */
     223                report_des->bit_length += field->size;
     224                report_des->item_length++;
     225
     226        }
     227
     228
     229        return EOK;
     230}
     231
     232usb_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)
     233{
     234        link_t *report_it = report->reports.next;
     235        usb_hid_report_description_t *report_des = NULL;
     236       
     237        while(report_it != &report->reports) {
     238                report_des = list_get_instance(report_it, usb_hid_report_description_t, link);
     239                if((report_des->report_id == report_id) && (report_des->type == type)){
     240                        break;
     241                }
     242                report_it = report_it->next;
     243        }
     244        if(report_it ==&report->reports){
     245                return NULL;
     246        }
     247
     248        return report_des;
     249}
    118250
    119251/** Parse HID report descriptor.
     
    123255 * @return Error code.
    124256 */
    125 int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser,
     257int usb_hid_parse_report_descriptor(usb_hid_report_t *report,
    126258    const uint8_t *data, size_t size)
    127259{
     
    134266        usb_hid_report_item_t *new_report_item;
    135267        usb_hid_report_path_t *usage_path;
    136         usb_hid_report_path_t *tmp_usage_path;
    137268
    138269        size_t offset_input=0;
    139270        size_t offset_output=0;
    140271        size_t offset_feature=0;
    141        
     272
     273        link_t stack;
     274        list_initialize(&stack);       
    142275
    143276        /* parser structure initialization*/
    144         if(usb_hid_parser_init(parser) != EOK) {
     277        if(usb_hid_report_init(report) != EOK) {
    145278                return EINVAL;
    146279        }
    147280       
    148 
    149281        /*report item initialization*/
    150282        if(!(report_item=malloc(sizeof(usb_hid_report_item_t)))){
     
    163295
    164296                        if((i+USB_HID_ITEM_SIZE(data[i]))>= size){
    165                                 return EINVAL; // TODO ERROR CODE
     297                                return EINVAL;
    166298                        }
    167299                       
     
    169301                        item_size = USB_HID_ITEM_SIZE(data[i]);
    170302                        class = USB_HID_ITEM_TAG_CLASS(data[i]);
    171 
    172                         usb_log_debug2(
    173                                 "i(%u) data(%X) value(%X): TAG %u, class %u, size %u - ", i,
    174                             data[i], usb_hid_report_tag_data_int32(data+i+1,item_size),
    175                             tag, class, item_size);
    176303                       
    177304                        ret = usb_hid_report_parse_tag(tag,class,data+i+1,
    178305                                                       item_size,report_item, usage_path);
    179                         usb_log_debug2("ret: %u\n", ret);
    180306                        switch(ret){
    181307                                case USB_HID_NEW_REPORT_ITEM:
    182308                                        // store report item to report and create the new one
    183                                         usb_log_debug("\nNEW REPORT ITEM: %X",ret);
    184 
    185                                         // store current usage path
     309                                        // store current collection path
    186310                                        report_item->usage_path = usage_path;
    187311                                       
    188                                         // clone path to the new one
    189                                         tmp_usage_path = usb_hid_report_path_clone(usage_path);
    190 
    191                                         // swap
    192                                         usage_path = tmp_usage_path;
    193                                         tmp_usage_path = NULL;
    194 
    195312                                        usb_hid_report_path_set_report_id(report_item->usage_path, report_item->id);   
    196313                                        if(report_item->id != 0){
    197                                                 parser->use_report_id = 1;
     314                                                report->use_report_ids = 1;
    198315                                        }
    199316                                       
    200317                                        switch(tag) {
    201318                                                case USB_HID_REPORT_TAG_INPUT:
     319                                                        report_item->type = USB_HID_REPORT_TYPE_INPUT;
    202320                                                        report_item->offset = offset_input;
    203321                                                        offset_input += report_item->count * report_item->size;
    204                                                         usb_log_debug(" - INPUT\n");
    205                                                         list_append(&(report_item->link), &(parser->input));
    206322                                                        break;
    207323                                                case USB_HID_REPORT_TAG_OUTPUT:
     324                                                        report_item->type = USB_HID_REPORT_TYPE_OUTPUT;
    208325                                                        report_item->offset = offset_output;
    209326                                                        offset_output += report_item->count * report_item->size;
    210                                                         usb_log_debug(" - OUTPUT\n");
    211                                                                 list_append(&(report_item->link), &(parser->output));
    212327
    213328                                                        break;
    214329                                                case USB_HID_REPORT_TAG_FEATURE:
     330                                                        report_item->type = USB_HID_REPORT_TYPE_FEATURE;
    215331                                                        report_item->offset = offset_feature;
    216332                                                        offset_feature += report_item->count * report_item->size;
    217                                                         usb_log_debug(" - FEATURE\n");
    218                                                                 list_append(&(report_item->link), &(parser->feature));
    219333                                                        break;
    220334                                                default:
     
    222336                                                    break;
    223337                                        }
    224 
    225                                         /* clone current state table to the new item */
    226                                         if(!(new_report_item = malloc(sizeof(usb_hid_report_item_t)))) {
    227                                                 return ENOMEM;
    228                                         }                                       
    229                                         memcpy(new_report_item,report_item, sizeof(usb_hid_report_item_t));
    230                                         link_initialize(&(new_report_item->link));
    231338                                       
     339                                        /*
     340                                         * append new fields to the report
     341                                         * structure                                     
     342                                         */
     343                                        usb_log_debug("PRED: \n");
     344                                        if(report->collection_paths.next == &report->collection_paths) {
     345                                                usb_log_debug("PRAZDNY\n");
     346                                        }
     347                                        else {
     348                                                usb_hid_print_usage_path (list_get_instance(report->collection_paths.prev,usb_hid_report_path_t, link));
     349                                        }
     350                                        usb_log_debug("-----------\n");
     351                                        usb_hid_report_append_fields(report, report_item);
     352
    232353                                        /* reset local items */
    233                                         new_report_item->usage_minimum = 0;
    234                                         new_report_item->usage_maximum = 0;
    235                                         new_report_item->designator_index = 0;
    236                                         new_report_item->designator_minimum = 0;
    237                                         new_report_item->designator_maximum = 0;
    238                                         new_report_item->string_index = 0;
    239                                         new_report_item->string_minimum = 0;
    240                                         new_report_item->string_maximum = 0;
    241 
    242                                         /* set the report id */
    243                                         new_report_item->id = report_item->id;
    244 
    245                                         /* reset usage from current usage path */
    246                                         usb_hid_report_usage_path_t *path = list_get_instance(&usage_path->link, usb_hid_report_usage_path_t, link);
    247                                         path->usage = 0;
    248                                        
    249                                         report_item = new_report_item;
    250                                                                                
     354                                        while(report_item->usages_count > 0){
     355                                                report_item->usages[--(report_item->usages_count)] = 0;
     356                                        }
     357
     358                                        report_item->extended_usage_page = 0;
     359                                        report_item->usage_minimum = 0;
     360                                        report_item->usage_maximum = 0;
     361                                        report_item->designator_index = 0;
     362                                        report_item->designator_minimum = 0;
     363                                        report_item->designator_maximum = 0;
     364                                        report_item->string_index = 0;
     365                                        report_item->string_minimum = 0;
     366                                        report_item->string_maximum = 0;
     367
    251368                                        break;
     369
     370                                case USB_HID_RESET_OFFSET:
     371                                        offset_input = 0;
     372                                        offset_output = 0;
     373                                        offset_feature = 0;
     374                                        break;
     375
    252376                                case USB_HID_REPORT_TAG_PUSH:
    253377                                        // push current state to stack
     
    256380                                        new_report_item->usage_path = tmp_path;
    257381
    258                                         list_prepend (&new_report_item->link, &parser->stack);
     382                                        list_prepend (&new_report_item->link, &stack);
    259383                                        break;
    260384                                case USB_HID_REPORT_TAG_POP:
    261385                                        // restore current state from stack
    262                                         if(list_empty (&parser->stack)) {
     386                                        if(list_empty (&stack)) {
    263387                                                return EINVAL;
    264388                                        }
    265389                                        free(report_item);
    266390                                               
    267                                         report_item = list_get_instance(parser->stack.next, usb_hid_report_item_t, link);
     391                                        report_item = list_get_instance(stack.next, usb_hid_report_item_t, link);
    268392                                       
    269393                                        usb_hid_report_usage_path_t *tmp_usage_path;
     
    274398                                        usb_hid_report_path_free(report_item->usage_path);
    275399                                        list_initialize(&report_item->usage_path->link);
    276                                         list_remove (parser->stack.next);
     400                                        list_remove (stack.next);
    277401                                       
    278402                                        break;
     
    359483                       
    360484                case USB_HID_REPORT_TAG_COLLECTION:
    361                         usb_hid_report_path_append_item(usage_path, 0, 0);
    362                                                
     485                        // TODO usage_path->flags = *data;
     486                        usb_hid_report_path_append_item(usage_path, report_item->usage_page, report_item->usages[report_item->usages_count-1]);                                        
    363487                        return USB_HID_NO_ACTION;
    364488                        break;
    365489                       
    366490                case USB_HID_REPORT_TAG_END_COLLECTION:
    367                         // TODO
    368                         // znici posledni uroven ve vsech usage paths
    369                         // otazka jestli nema nicit dve, respektive novou posledni vynulovat?
    370491                        usb_hid_report_remove_last_item(usage_path);
    371492                        return USB_HID_NO_ACTION;
     
    394515        {
    395516                case USB_HID_REPORT_TAG_USAGE_PAGE:
    396                         // zmeni to jenom v poslednim poli aktualni usage path
    397                         usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL,
    398                                 usb_hid_report_tag_data_int32(data,item_size));
     517                        report_item->usage_page = usb_hid_report_tag_data_int32(data, item_size);
    399518                        break;
    400519                case USB_HID_REPORT_TAG_LOGICAL_MINIMUM:
     
    424543                case USB_HID_REPORT_TAG_REPORT_ID:
    425544                        report_item->id = usb_hid_report_tag_data_int32(data,item_size);
     545                        return USB_HID_RESET_OFFSET;
    426546                        break;
    427547                case USB_HID_REPORT_TAG_PUSH:
    428548                case USB_HID_REPORT_TAG_POP:
    429                         usb_log_debug("PUSH/POP processed\n");
     549                        /*
     550                         * stack operations are done in top level parsing
     551                         * function
     552                         */
    430553                        return tag;
    431554                        break;
     
    453576        {
    454577                case USB_HID_REPORT_TAG_USAGE:
    455                         usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL,
    456                                 usb_hid_report_tag_data_int32(data,item_size));
     578                        report_item->usages[report_item->usages_count++] = usb_hid_report_tag_data_int32(data,item_size);
    457579                        break;
    458580                case USB_HID_REPORT_TAG_USAGE_MINIMUM:
    459                         report_item->usage_minimum = usb_hid_report_tag_data_int32(data,item_size);
     581                        if (item_size == 3) {
     582                                // usage extended usages
     583                                report_item->extended_usage_page = (usb_hid_report_tag_data_int32(data,item_size) & 0xFF00) >> 16;
     584                                report_item->usage_minimum = usb_hid_report_tag_data_int32(data,item_size) & 0xFF;
     585                        }
     586                        else {
     587                                report_item->usage_minimum = usb_hid_report_tag_data_int32(data,item_size);
     588                        }
    460589                        break;
    461590                case USB_HID_REPORT_TAG_USAGE_MAXIMUM:
    462                         report_item->usage_maximum = usb_hid_report_tag_data_int32(data,item_size);
     591                        if (item_size == 3) {
     592                                // usage extended usages
     593                                report_item->extended_usage_page = (usb_hid_report_tag_data_int32(data,item_size) & 0xFF00) >> 16;
     594                                report_item->usage_maximum = usb_hid_report_tag_data_int32(data,item_size) & 0xFF;
     595                        }
     596                        else {
     597                                report_item->usage_maximum = usb_hid_report_tag_data_int32(data,item_size);
     598                        }
    463599                        break;
    464600                case USB_HID_REPORT_TAG_DESIGNATOR_INDEX:
     
    481617                        break;                 
    482618                case USB_HID_REPORT_TAG_DELIMITER:
    483                         report_item->delimiter = usb_hid_report_tag_data_int32(data,item_size);
     619                        //report_item->delimiter = usb_hid_report_tag_data_int32(data,item_size);
     620                        //TODO:
     621                        //      DELIMITER STUFF
    484622                        break;
    485623               
     
    521659void usb_hid_descriptor_print_list(link_t *head)
    522660{
    523         usb_hid_report_item_t *report_item;
    524         usb_hid_report_usage_path_t *path_item;
    525         link_t *path;
     661        usb_hid_report_field_t *report_item;
    526662        link_t *item;
    527        
     663
     664
    528665        if(head == NULL || list_empty(head)) {
    529666            usb_log_debug("\tempty\n");
     
    533670        for(item = head->next; item != head; item = item->next) {
    534671               
    535                 report_item = list_get_instance(item, usb_hid_report_item_t, link);
    536 
    537                 usb_log_debug("\tOFFSET: %X\n", report_item->offset);
    538                 usb_log_debug("\tCOUNT: %X\n", report_item->count);
    539                 usb_log_debug("\tSIZE: %X\n", report_item->size);
    540                 usb_log_debug("\tCONSTANT/VAR: %X\n", USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags));
    541                 usb_log_debug("\tVARIABLE/ARRAY: %X\n", USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags));
    542                 usb_log_debug("\tUSAGE PATH:\n");
    543 
    544                 path = report_item->usage_path->link.next;
    545                 while(path != &report_item->usage_path->link)   {
    546                         path_item = list_get_instance(path, usb_hid_report_usage_path_t, link);
    547                         usb_log_debug("\t\tUSAGE PAGE: %X, USAGE: %X\n", path_item->usage_page, path_item->usage);
    548                         path = path->next;
    549                 }
    550                                
    551                 usb_log_debug("\tLOGMIN: %X\n", report_item->logical_minimum);
    552                 usb_log_debug("\tLOGMAX: %X\n", report_item->logical_maximum);         
    553                 usb_log_debug("\tPHYMIN: %X\n", report_item->physical_minimum);         
    554                 usb_log_debug("\tPHYMAX: %X\n", report_item->physical_maximum);                         
    555                 usb_log_debug("\tUSAGEMIN: %X\n", report_item->usage_minimum);
    556                 usb_log_debug("\tUSAGEMAX: %X\n", report_item->usage_maximum);
    557                
     672                report_item = list_get_instance(item, usb_hid_report_field_t, link);
     673
     674                usb_log_debug("\t\tOFFSET: %X\n", report_item->offset);
     675                usb_log_debug("\t\tSIZE: %X\n", report_item->size);                             
     676                usb_log_debug("\t\tLOGMIN: %X\n", report_item->logical_minimum);
     677                usb_log_debug("\t\tLOGMAX: %X\n", report_item->logical_maximum);               
     678                usb_log_debug("\t\tPHYMIN: %X\n", report_item->physical_minimum);               
     679                usb_log_debug("\t\tPHYMAX: %X\n", report_item->physical_maximum);                               
     680                usb_log_debug("\t\ttUSAGEMIN: %X\n", report_item->usage_minimum);
     681                usb_log_debug("\t\tUSAGEMAX: %X\n", report_item->usage_maximum);
     682
     683                usb_log_debug("\t\ttUSAGE: %X\n", report_item->usage);
     684                usb_log_debug("\t\tUSAGE PAGE: %X\n", report_item->usage_page);
     685                                               
    558686                usb_log_debug("\n");           
    559687
     
    568696 * @return void
    569697 */
    570 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser)
    571 {
    572         if(parser == NULL) {
     698void usb_hid_descriptor_print(usb_hid_report_t *report)
     699{
     700        if(report == NULL) {
    573701                return;
    574702        }
    575        
    576         usb_log_debug("INPUT:\n");
    577         usb_hid_descriptor_print_list(&parser->input);
    578        
    579         usb_log_debug("OUTPUT: \n");
    580         usb_hid_descriptor_print_list(&parser->output);
    581        
    582         usb_log_debug("FEATURE:\n");   
    583         usb_hid_descriptor_print_list(&parser->feature);
    584 
     703
     704        link_t *report_it = report->reports.next;
     705        usb_hid_report_description_t *report_des;
     706
     707        while(report_it != &report->reports) {
     708                report_des = list_get_instance(report_it, usb_hid_report_description_t, link);
     709                usb_log_debug("Report ID: %d\n", report_des->report_id);
     710                usb_log_debug("\tType: %d\n", report_des->type);
     711                usb_log_debug("\tLength: %d\n", report_des->bit_length);               
     712                usb_log_debug("\tItems: %d\n", report_des->item_length);               
     713
     714                usb_hid_descriptor_print_list(&report_des->report_items);
     715
     716
     717                link_t *path_it = report->collection_paths.next;
     718                while(path_it != &report->collection_paths) {
     719                        usb_hid_print_usage_path (list_get_instance(path_it, usb_hid_report_path_t, link));
     720                        path_it = path_it->next;
     721                }
     722               
     723                report_it = report_it->next;
     724        }
    585725}
    586726
     
    626766 * @return void
    627767 */
    628 void usb_hid_free_report_parser(usb_hid_report_parser_t *parser)
    629 {
    630         if(parser == NULL){
     768void usb_hid_free_report(usb_hid_report_t *report)
     769{
     770        if(report == NULL){
    631771                return;
    632772        }
    633773
    634         parser->use_report_id = 0;
    635 
    636         usb_hid_free_report_list(&parser->input);
    637         usb_hid_free_report_list(&parser->output);
    638         usb_hid_free_report_list(&parser->feature);
    639         usb_hid_free_report_list(&parser->stack);
     774        // free collection paths
     775        usb_hid_report_path_t *path;
     776        while(!list_empty(&report->collection_paths)) {
     777                path = list_get_instance(report->collection_paths.next, usb_hid_report_path_t, link);
     778                usb_hid_report_path_free(path);         
     779        }
     780       
     781        // free report items
     782        usb_hid_report_description_t *report_des;
     783        usb_hid_report_field_t *field;
     784        while(!list_empty(&report->reports)) {
     785                report_des = list_get_instance(report->reports.next, usb_hid_report_description_t, link);
     786                list_remove(&report_des->link);
     787               
     788                while(!list_empty(&report_des->report_items)) {
     789                        field = list_get_instance(report_des->report_items.next, usb_hid_report_field_t, link);
     790                        list_remove(&field->link);
     791
     792                        free(field);
     793                }
     794               
     795                free(report_des);
     796        }
     797       
    640798        return;
    641799}
     
    647805 * @param parser Opaque HID report parser structure.
    648806 * @param data Data for the report.
    649  * @param callbacks Callbacks for report actions.
    650  * @param arg Custom argument (passed through to the callbacks).
    651807 * @return Error code.
    652808 */
    653 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 
    654     const uint8_t *data, size_t size,
    655     usb_hid_report_path_t *path, int flags,
    656     const usb_hid_report_in_callbacks_t *callbacks, void *arg)
     809int usb_hid_parse_report(const usb_hid_report_t *report, 
     810    const uint8_t *data, size_t size)
    657811{
    658812        link_t *list_item;
    659         usb_hid_report_item_t *item;
    660         uint8_t *keys;
    661         uint8_t item_value;
    662         size_t key_count=0;
    663         size_t i=0;
    664         size_t j=0;
     813        usb_hid_report_field_t *item;
     814
    665815        uint8_t report_id = 0;
    666 
    667         if(parser == NULL) {
     816        usb_hid_report_description_t *report_des;
     817        usb_hid_report_type_t type = USB_HID_REPORT_TYPE_INPUT;
     818
     819        if(report == NULL) {
    668820                return EINVAL;
    669821        }
    670822
    671         if(parser->use_report_id != 0) {
     823        if(report->use_report_ids != 0) {
    672824                report_id = data[0];
    673                 usb_hid_report_path_set_report_id(path, report_id);
    674         }
    675 
    676 
    677         /* get the size of result array */
    678         key_count = usb_hid_report_input_length(parser, path, flags);
    679 
    680         if(!(keys = malloc(sizeof(uint8_t) * key_count))){
    681                 return ENOMEM;
    682         }
     825        }
     826
     827        report_des = usb_hid_report_find_description(report, report_id, type);
    683828
    684829        /* read data */
    685         list_item = parser->input.next;   
    686         while(list_item != &(parser->input)) {
    687 
    688                 item = list_get_instance(list_item, usb_hid_report_item_t, link);
    689 
    690                 if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) &&
    691                    (usb_hid_report_compare_usage_path(item->usage_path, path, flags) == EOK)) {
    692                         for(j=0; j<(size_t)(item->count); j++) {
    693                                 if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0) ||
    694                                    ((item->usage_minimum == 0) && (item->usage_maximum == 0))) {
    695                                         // variable item
    696                                         keys[i++] = usb_hid_translate_data(parser, item, data,j);
     830        list_item = report_des->report_items.next;         
     831        while(list_item != &(report_des->report_items)) {
     832
     833                item = list_get_instance(list_item, usb_hid_report_field_t, link);
     834
     835                if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags)) {
     836                       
     837                        if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0) ||
     838                           ((item->usage_minimum == 0) && (item->usage_maximum == 0))) {
     839
     840                                // variable item
     841                                item->value = usb_hid_translate_data(item, data,0);
     842
     843                                // array item ???
     844                                if(!((item->usage_minimum == 0) && (item->usage_maximum == 0))) {
     845                                        item->usage = item->value + item->usage_minimum;
    697846                                }
    698                                 else {
    699                                         // bitmapa
    700                                         if((item_value = usb_hid_translate_data(parser, item, data, j)) != 0) {
    701                                                 keys[i++] = (item->count - 1 - j) + item->usage_minimum;
    702                                         }
    703                                         else {
    704                                                 keys[i++] = 0;
    705                                         }
    706                                 }
    707                         }
     847                        }
     848                        else {
     849                                // bitmapa
     850                                // TODO: overit jestli vraci hodnoty podle phy min/max
     851                                item->value = usb_hid_translate_data(item, data, 0);
     852                        }                       
    708853                }
    709854                list_item = list_item->next;
    710855        }
    711 
    712         callbacks->keyboard(keys, key_count, report_id, arg);
    713856           
    714         free(keys);     
    715857        return EOK;
    716858       
     
    725867 * @return Translated data
    726868 */
    727 int usb_hid_translate_data(const usb_hid_report_parser_t *parser, usb_hid_report_item_t *item, const uint8_t *data, size_t j)
     869int usb_hid_translate_data(usb_hid_report_field_t *item, const uint8_t *data, size_t j)
    728870{
    729871        int resolution;
     
    731873        int part_size;
    732874       
    733         int32_t value;
     875        int32_t value=0;
    734876        int32_t mask;
    735877        const uint8_t *foo;
     
    755897
    756898        offset = item->offset + (j * item->size);
    757         if(parser->use_report_id != 0) {
    758                 offset += 8;
    759         }
    760899       
    761900        // FIXME
    762         if((offset/8) != ((offset+item->size)/8)) {
    763                 usb_log_debug2("offset %d\n", offset);
     901        if((size_t)(offset/8) != (size_t)((offset+item->size-1)/8)) {
    764902               
    765903                part_size = ((offset+item->size)%8);
    766                 usb_log_debug2("part size %d\n",part_size);
    767 
    768                 // the higher one
    769                 foo = data+(offset/8);
    770                 mask =  ((1 << (item->size-part_size))-1);
    771                 value = (*foo & mask) << part_size;
    772 
    773                 usb_log_debug2("hfoo %x\n", *foo);
    774                 usb_log_debug2("hmaska %x\n",  mask);
    775                 usb_log_debug2("hval %d\n", value);             
    776 
    777                 // the lower one
    778                 foo = data+((offset+item->size)/8);
    779                 mask =  ((1 << part_size)-1) << (8-part_size);
    780                 value += ((*foo & mask) >> (8-part_size));
    781 
    782                 usb_log_debug2("lfoo %x\n", *foo);
    783                 usb_log_debug2("lmaska %x\n",  mask);
    784                 usb_log_debug2("lval %d\n", ((*foo & mask) >> (8-(item->size-part_size))));             
    785                 usb_log_debug2("val %d\n", value);
    786                
    787                
     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                }
    788924        }
    789925        else {         
     
    791927                mask =  ((1 << item->size)-1) << (8-((offset%8)+item->size));
    792928                value = (*foo & mask) >> (8-((offset%8)+item->size));
    793 
    794                 usb_log_debug2("offset %d\n", offset);
    795        
    796                 usb_log_debug2("foo %x\n", *foo);
    797                 usb_log_debug2("maska %x\n",  mask);
    798                 usb_log_debug2("val %d\n", value);                             
    799         }
    800 
    801         usb_log_debug2("---\n\n");
     929        }
     930
     931        if(!(item->logical_minimum >= 0 && item->logical_maximum >= 0)){
     932                value = (int32_t)value;
     933        }
     934        else {
     935                value = (uint32_t)value;
     936        }
     937
    802938
    803939        return (int)(((value - item->logical_minimum) / resolution) + item->physical_minimum);
     
    813949 * @return Number of items in input report
    814950 */
    815 size_t usb_hid_report_input_length(const usb_hid_report_parser_t *parser,
     951size_t usb_hid_report_input_length(const usb_hid_report_t *report,
    816952        usb_hid_report_path_t *path, int flags)
    817953{       
     954       
    818955        size_t ret = 0;
    819         link_t *item;
    820         usb_hid_report_item_t *report_item;
    821 
    822         if(parser == NULL) {
     956
     957        if(report == NULL) {
    823958                return 0;
    824959        }
    825        
    826         item = parser->input.next;
    827         while(&parser->input != item) {
    828                 report_item = list_get_instance(item, usb_hid_report_item_t, link);
    829                 if(!USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags) &&
    830                    (usb_hid_report_compare_usage_path(report_item->usage_path, path, flags) == EOK)) {
    831                         ret += report_item->count;
    832                 }
    833 
    834                 item = item->next;
    835         }
     960
     961        usb_hid_report_description_t *report_des;
     962        report_des = usb_hid_report_find_description (report, path->report_id, USB_HID_REPORT_TYPE_INPUT);
     963        if(report_des == NULL) {
     964                return 0;
     965        }
     966
     967        link_t *field_it = report_des->report_items.next;
     968        usb_hid_report_field_t *field;
     969        while(field_it != &report_des->report_items) {
     970
     971                field = list_get_instance(field_it, usb_hid_report_field_t, link);
     972                if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) {
     973                        if(usb_hid_report_compare_usage_path (path, field->collection_path, flags) == EOK) {
     974                                ret++;
     975                        }
     976                }
     977               
     978                field_it = field_it->next;
     979        }
    836980
    837981        return ret;
    838 }
     982        }
    839983
    840984
     
    8601004        item->usage = usage;
    8611005        item->usage_page = usage_page;
    862        
    863         list_append (&usage_path->link, &item->link);
     1006        item->flags = 0;
     1007       
     1008        list_append (&item->link, &usage_path->link);
    8641009        usage_path->depth++;
    8651010        return EOK;
     
    9271072}
    9281073
     1074
     1075void usb_hid_print_usage_path(usb_hid_report_path_t *path)
     1076{
     1077        usb_log_debug("USAGE_PATH FOR RId(%d):\n", path->report_id);
     1078        usb_log_debug("\tLENGTH: %d\n", path->depth);
     1079
     1080        link_t *item = path->link.next;
     1081        usb_hid_report_usage_path_t *path_item;
     1082        while(item != &path->link) {
     1083
     1084                path_item = list_get_instance(item, usb_hid_report_usage_path_t, link);
     1085                usb_log_debug("\tUSAGE_PAGE: %X\n", path_item->usage_page);
     1086                usb_log_debug("\tUSAGE: %X\n", path_item->usage);
     1087                usb_log_debug("\tFLAGS: %d\n", path_item->flags);               
     1088               
     1089                item = item->next;
     1090        }
     1091}
     1092
    9291093/**
    9301094 * Compares two usage paths structures
     
    9551119        }
    9561120
     1121        //usb_log_debug("---------- PATH COMPARISON ----------\n\n");
     1122        //usb_hid_print_usage_path(report_path);
     1123        //usb_hid_print_usage_path(path);
     1124       
    9571125
    9581126        if((only_page = flags & USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY) != 0){
     
    10421210        usb_hid_report_path_t *path;
    10431211        path = malloc(sizeof(usb_hid_report_path_t));
    1044         if(!path){
     1212        if(path == NULL){
    10451213                return NULL;
    10461214        }
     
    10641232                usb_hid_report_remove_last_item(path);
    10651233        }
     1234
     1235        list_remove(&path->link);
     1236        free(path);
    10661237}
    10671238
     
    10751246usb_hid_report_path_t *usb_hid_report_path_clone(usb_hid_report_path_t *usage_path)
    10761247{
     1248        link_t *path_link;
    10771249        usb_hid_report_usage_path_t *path_item;
    1078         link_t *path_link;
     1250        usb_hid_report_usage_path_t *new_path_item;
    10791251        usb_hid_report_path_t *new_usage_path = usb_hid_report_path ();
    10801252
     
    10901262        while(path_link != &usage_path->link) {
    10911263                path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link);
    1092                 usb_hid_report_path_append_item (new_usage_path, path_item->usage_page, path_item->usage);
     1264                new_path_item = malloc(sizeof(usb_hid_report_usage_path_t));
     1265                if(new_path_item == NULL) {
     1266                        return NULL;
     1267                }
     1268
     1269                list_initialize (&new_path_item->link);
     1270                new_path_item->usage_page = path_item->usage_page;
     1271                new_path_item->usage = path_item->usage;               
     1272                new_path_item->flags = path_item->flags;               
     1273               
     1274                list_append(&new_path_item->link, &new_usage_path->link);
     1275                new_usage_path->depth++;
    10931276
    10941277                path_link = path_link->next;
     
    11091292 * @return Returns allocated output buffer for specified output
    11101293 */
    1111 uint8_t *usb_hid_report_output(usb_hid_report_parser_t *parser, size_t *size, uint8_t report_id)
    1112 {
    1113         if(parser == NULL) {
     1294uint8_t *usb_hid_report_output(usb_hid_report_t *report, size_t *size, uint8_t report_id)
     1295{
     1296        if(report == NULL) {
    11141297                *size = 0;
    11151298                return NULL;
    11161299        }
    1117        
    1118         // read the last output report item
    1119         usb_hid_report_item_t *last;
    1120         link_t *link;
    1121 
    1122         link = parser->output.prev;
    1123         while((link != &parser->output)){
    1124                 last = list_get_instance(link, usb_hid_report_item_t, link);
    1125 
    1126                 usb_log_debug("pro id: %d, posledni %d\n", report_id, last->id);
    1127                 if(last->id == report_id){
    1128                         break;
    1129                 }
    1130                 else {
    1131                         link =  link->prev;
    1132                 }
    1133         }
    1134 
    1135        
    1136 
    1137         if(link != &parser->output) {
    1138                 last = list_get_instance(link, usb_hid_report_item_t, link);
    1139                 *size = (last->offset + (last->size * last->count)) / 8;
    1140 
    1141                 if(parser->use_report_id != 0) {
    1142                         *size += 1;
    1143                 }
    1144 
    1145                 uint8_t *buffer = malloc(sizeof(uint8_t) * (*size));
    1146                 memset(buffer, 0, sizeof(uint8_t) * (*size));
    1147                 usb_log_debug("output buffer: %s\n", usb_debug_str_buffer(buffer, *size, 0));
    1148 
    1149                 return buffer;
     1300
     1301        link_t *report_it = report->reports.next;
     1302        usb_hid_report_description_t *report_des = NULL;
     1303        while(report_it != &report->reports) {
     1304                report_des = list_get_instance(report_it, usb_hid_report_description_t, link);
     1305                if((report_des->report_id == report_id) && (report_des->type = USB_HID_REPORT_TYPE_OUTPUT)){
     1306                        break;
     1307                }
     1308
     1309                report_it = report_it->next;
     1310        }
     1311
     1312        if(report_des == NULL){
     1313                *size = 0;
     1314                return NULL;
    11501315        }
    11511316        else {
    1152                 *size = 0;             
    1153                 return NULL;
     1317                *size = (report_des->bit_length + (8 - 1))/8;
     1318                uint8_t *ret = malloc((*size) * sizeof(uint8_t));
     1319                memset(ret, 0, (*size) * sizeof(uint8_t));
     1320                return ret;
    11541321        }
    11551322}
     
    11761343 * @return Number of items matching the given usage path
    11771344 */
    1178 size_t usb_hid_report_output_size(usb_hid_report_parser_t *parser,
     1345size_t usb_hid_report_output_size(usb_hid_report_t *report,
    11791346                                  usb_hid_report_path_t *path, int flags)
    11801347{
    1181         size_t ret = 0;
    1182         link_t *item;
    1183         usb_hid_report_item_t *report_item;
    1184 
    1185         if(parser == NULL) {
     1348        size_t ret = 0;
     1349        usb_hid_report_description_t *report_des;
     1350
     1351        if(report == NULL) {
    11861352                return 0;
    11871353        }
    11881354
    1189         item = parser->output.next;
    1190         while(&parser->output != item) {
    1191                 report_item = list_get_instance(item, usb_hid_report_item_t, link);
    1192                 if(!USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags) &&
    1193                    (usb_hid_report_compare_usage_path(report_item->usage_path, path, flags) == EOK)) {
    1194                         ret += report_item->count;
    1195                 }
    1196 
    1197                 item = item->next;
     1355        report_des = usb_hid_report_find_description (report, path->report_id, USB_HID_REPORT_TYPE_OUTPUT);
     1356        if(report_des == NULL){
     1357                return 0;
     1358        }
     1359
     1360        link_t *field_it = report_des->report_items.next;
     1361        usb_hid_report_field_t *field;
     1362        while(field_it != &report_des->report_items) {
     1363
     1364                field = list_get_instance(field_it, usb_hid_report_field_t, link);
     1365                // TODO: bacha na porovnani - posledni prvek v ceste uz jsou usage/page z inputu a ne kolekce!!!
     1366                if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK) {
     1367                        ret++;
     1368                }
     1369               
     1370                field_it = field_it->next;
    11981371        }
    11991372
     
    12021375}
    12031376
    1204 /** Updates the output report buffer by given data
     1377/** Makes the output report buffer for data given in the report structure
    12051378 *
    12061379 * @param parser Opaque report parser structure
     
    12091382 * @param buffer Output buffer
    12101383 * @param size Size of output buffer
    1211  * @param data Data buffer
    1212  * @param data_size Size of data buffer
    12131384 * @return Error code
    12141385 */
    1215 int usb_hid_report_output_translate(usb_hid_report_parser_t *parser,
    1216                                     usb_hid_report_path_t *path, int flags,
    1217                                     uint8_t *buffer, size_t size,
    1218                                     int32_t *data, size_t data_size)
    1219 {
    1220         usb_hid_report_item_t *report_item;
     1386int usb_hid_report_output_translate(usb_hid_report_t *report, uint8_t report_id,
     1387                                    uint8_t *buffer, size_t size)
     1388{
    12211389        link_t *item;   
    1222         size_t idx=0;
    1223         int i=0;
    12241390        int32_t value=0;
    12251391        int offset;
    12261392        int length;
    12271393        int32_t tmp_value;
    1228         size_t offset_prefix = 0;
    1229        
    1230         if(parser == NULL) {
     1394       
     1395        if(report == NULL) {
    12311396                return EINVAL;
    12321397        }
    12331398
    1234         if(parser->use_report_id != 0) {
    1235                 buffer[0] = path->report_id;
    1236                 offset_prefix = 8;
     1399        if(report->use_report_ids != 0) {
     1400                buffer[0] = report_id;         
    12371401        }
    12381402
    12391403        usb_log_debug("OUTPUT BUFFER: %s\n", usb_debug_str_buffer(buffer,size, 0));
    1240         usb_log_debug("OUTPUT DATA[0]: %d, DATA[1]: %d, DATA[2]: %d\n", data[0], data[1], data[2]);
    1241 
    1242         item = parser->output.next;     
    1243         while(item != &parser->output) {
    1244                 report_item = list_get_instance(item, usb_hid_report_item_t, link);
    1245 
    1246                 for(i=0; i<report_item->count; i++) {
    1247 
    1248                         if(idx >= data_size) {
    1249                                 break;
    1250                         }
     1404
     1405        usb_hid_report_description_t *report_des;
     1406        report_des = usb_hid_report_find_description (report, report_id, USB_HID_REPORT_TYPE_OUTPUT);
     1407        if(report_des == NULL){
     1408                return EINVAL;
     1409        }
     1410
     1411        usb_hid_report_field_t *report_item;   
     1412        item = report_des->report_items.next;   
     1413        while(item != &report_des->report_items) {
     1414                report_item = list_get_instance(item, usb_hid_report_field_t, link);
    12511415
    12521416                        if((USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) ||
    12531417                                ((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0))) {
    12541418                                       
    1255 //                              // variable item
    1256                                 value = usb_hid_translate_data_reverse(report_item, data[idx++]);
    1257                                 offset = report_item->offset + (i * report_item->size) + offset_prefix;
     1419                                // variable item
     1420                                value = usb_hid_translate_data_reverse(report_item, report_item->value);
     1421                                offset = report_item->offset;
    12581422                                length = report_item->size;
    12591423                        }
    12601424                        else {
    12611425                                //bitmap
    1262                                 value += usb_hid_translate_data_reverse(report_item, data[idx++]);
    1263                                 offset = report_item->offset + offset_prefix;
    1264                                 length = report_item->size * report_item->count;
     1426                                value += usb_hid_translate_data_reverse(report_item, report_item->value);
     1427                                offset = report_item->offset;
     1428                                length = report_item->size;
    12651429                        }
    12661430
     
    12811445                        }
    12821446                        else {
    1283                                 // je to ve dvou!! FIXME: melo by to umet delsi jak 2
    1284 
    1285                                 // konec prvniho -- dolni x bitu
    1286                                 tmp_value = value;
    1287                                 tmp_value = tmp_value & ((1 << (8-(offset%8)))-1);                             
    1288                                 tmp_value = tmp_value << (offset%8);
    1289 
     1447                                int i = 0;
    12901448                                uint8_t mask = 0;
    1291                                 mask = ~(((1 << (8-(offset%8)))-1) << (offset%8));
    1292                                 buffer[offset/8] = (buffer[offset/8] & mask) | tmp_value;
    1293 
    1294                                 // a ted druhej -- hornich length-x bitu
    1295                                 value = value >> (8 - (offset % 8));
    1296                                 value = value & ((1 << (length - (8 - (offset % 8)))) - 1);
     1449                                for(i = (offset/8); i <= ((offset+length-1)/8); i++) {
     1450                                        if(i == (offset/8)) {
     1451                                                tmp_value = value;
     1452                                                tmp_value = tmp_value & ((1 << (8-(offset%8)))-1);                             
     1453                                                tmp_value = tmp_value << (offset%8);
     1454       
     1455                                                mask = ~(((1 << (8-(offset%8)))-1) << (offset%8));
     1456                                                buffer[i] = (buffer[i] & mask) | tmp_value;                     
     1457                                        }
     1458                                        else if (i == ((offset + length -1)/8)) {
     1459                                               
     1460                                                value = value >> (length - ((offset + length) % 8));
     1461                                                value = value & ((1 << (length - ((offset + length) % 8))) - 1);
    12971462                               
    1298                                 mask = ((1 << (length - (8 - (offset % 8)))) - 1);
    1299                                 buffer[(offset+length-1)/8] = (buffer[(offset+length-1)/8] & mask) | value;
    1300                         }
    1301 
    1302                 }
     1463                                                mask = (1 << (length - ((offset + length) % 8))) - 1;
     1464                                                buffer[i] = (buffer[i] & mask) | value;
     1465                                        }
     1466                                        else {
     1467                                                buffer[i] = value & (0xFF << i);
     1468                                        }
     1469                                }
     1470                        }
     1471
    13031472
    13041473                item = item->next;
     
    13161485 * @return ranslated value
    13171486 */
    1318 int32_t usb_hid_translate_data_reverse(usb_hid_report_item_t *item, int value)
     1487uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, int value)
    13191488{
    13201489        int ret=0;
     
    13561525
    13571526
    1358         return ret;
     1527        return (uint32_t)ret;
    13591528}
    13601529
     
    13951564}
    13961565
     1566
     1567/**
     1568 *
     1569 *
     1570 *
     1571 *
     1572 *
     1573 */
     1574int usb_hid_report_output_set_data(usb_hid_report_t *report,
     1575                                   usb_hid_report_path_t *path, int flags,
     1576                                  int *data, size_t data_size)
     1577{
     1578        size_t data_idx = 0;
     1579        if(report == NULL){
     1580                return EINVAL;
     1581        }
     1582
     1583        usb_hid_report_description_t *report_des;
     1584        report_des = usb_hid_report_find_description (report, path->report_id,
     1585                                                      USB_HID_REPORT_TYPE_OUTPUT);
     1586        if(report_des == NULL){
     1587                return EINVAL;
     1588        }
     1589
     1590        usb_hid_report_field_t *field;
     1591        link_t *field_it = report_des->report_items.next;       
     1592        while(field_it != &report_des->report_items){
     1593
     1594                field = list_get_instance(field_it, usb_hid_report_field_t, link);             
     1595                if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) {
     1596                        if(usb_hid_report_compare_usage_path (path, field->collection_path,
     1597                                                      flags) == EOK) {
     1598
     1599                                if(data_idx < data_size) {
     1600                                        field->value = data[data_idx++];
     1601                                }
     1602                                else {
     1603                                        field->value = 0;
     1604                                }
     1605                        }
     1606                }
     1607               
     1608                field_it = field_it->next;
     1609        }
     1610
     1611        return EOK;
     1612}
     1613
    13971614/**
    13981615 * @}
  • uspace/lib/usb/src/hidreport.c

    r9698695 r175ad13e  
    185185
    186186int usb_hid_process_report_descriptor(usb_device_t *dev,
    187     usb_hid_report_parser_t *parser)
     187    usb_hid_report_t *report)
    188188{
    189         if (dev == NULL || parser == NULL) {
     189        if (dev == NULL || report == NULL) {
    190190                usb_log_error("Failed to process Report descriptor: wrong "
    191191                    "parameters given.\n");
     
    210210        assert(report_desc != NULL);
    211211       
    212         rc = usb_hid_parse_report_descriptor(parser, report_desc, report_size);
     212        rc = usb_hid_parse_report_descriptor(report, report_desc, report_size);
    213213        if (rc != EOK) {
    214214                usb_log_error("Problem parsing Report descriptor: %s.\n",
     
    218218        }
    219219       
    220         usb_hid_descriptor_print(parser);
     220        usb_hid_descriptor_print(report);
    221221        free(report_desc);
    222222       
Note: See TracChangeset for help on using the changeset viewer.