Changeset 175ad13e in mainline
- Timestamp:
- 2011-04-15T15:19:34Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 681f24b3
- Parents:
- 9698695
- Location:
- uspace
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbkbd/kbddev.c
r9698695 r175ad13e 290 290 usb_log_debug("Creating output report.\n"); 291 291 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); 295 294 296 295 if (rc != EOK) { … … 612 611 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0); 613 612 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); 616 614 617 615 usb_hid_report_path_free (path); … … 657 655 memset(kbd_dev, 0, sizeof(usb_kbd_t)); 658 656 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))); 661 659 if (kbd_dev->parser == NULL) { 662 660 usb_log_fatal("No memory!\n"); … … 726 724 727 725 /* 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 //} 733 731 734 732 /* Get the report descriptor and parse it. */ … … 762 760 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0); 763 761 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); 765 763 usb_hid_report_path_free (path); 766 764 … … 924 922 // destroy the parser 925 923 if ((*kbd_dev)->parser != NULL) { 926 usb_hid_free_report _parser((*kbd_dev)->parser);924 usb_hid_free_report((*kbd_dev)->parser); 927 925 } 928 926 -
uspace/drv/usbkbd/kbddev.h
r9698695 r175ad13e 106 106 107 107 /** HID Report parser. */ 108 usb_hid_report_ parser_t *parser;108 usb_hid_report_t *parser; 109 109 110 110 /** State of the structure (for checking before use). -
uspace/lib/usb/include/usb/classes/hid.h
r9698695 r175ad13e 50 50 USB_HIDREQ_SET_PROTOCOL = 11 51 51 } 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 = 357 } usb_hid_report_type_t;58 52 59 53 typedef enum { -
uspace/lib/usb/include/usb/classes/hidparser.h
r9698695 r175ad13e 74 74 #define USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY 4 75 75 76 /** */ 77 typedef struct { 78 /** */ 79 int32_t usage_page; 80 /** */ 81 int32_t usage; 76 77 #define USB_HID_MAX_USAGES 20 78 79 typedef 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 */ 86 typedef struct { 87 /** */ 88 uint32_t usage_page; 89 /** */ 90 uint32_t usage; 91 92 uint8_t flags; 82 93 /** */ 83 94 link_t link; … … 95 106 } usb_hid_report_path_t; 96 107 97 /** 98 * Description of report items 99 */ 100 typedef struct { 101 /** */ 108 109 typedef 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 121 typedef 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 133 typedef 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 */ 164 typedef struct { 165 /** report id */ 102 166 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; 107 180 /** */ 108 181 int32_t logical_minimum; … … 116 189 size_t offset; 117 190 /** */ 118 int32_t delimiter;119 /** */120 191 int32_t unit_exponent; 121 192 /** */ … … 123 194 124 195 /** */ 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; 136 207 /** */ 137 208 int32_t physical_minimum; … … 142 213 uint8_t item_flags; 143 214 144 /** */ 215 usb_hid_report_type_t type; 216 217 /** current collection path*/ 145 218 usb_hid_report_path_t *usage_path; 146 219 /** */ 147 220 link_t link; 148 221 } 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 166 222 167 223 /** HID parser callbacks for IN items. */ … … 189 245 } usb_hid_modifiers_t; 190 246 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 = 5198 //} usb_hid_led_t;199 200 247 static const usb_hid_modifiers_t 201 248 usb_hid_modifiers_consts[USB_HID_MOD_COUNT] = { … … 210 257 }; 211 258 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_KANA218 //};219 220 //#define USB_HID_BOOT_KEYBOARD_NUM_LOCK 0x01221 //#define USB_HID_BOOT_KEYBOARD_CAPS_LOCK 0x02222 //#define USB_HID_BOOT_KEYBOARD_SCROLL_LOCK 0x04223 //#define USB_HID_BOOT_KEYBOARD_COMPOSE 0x08224 //#define USB_HID_BOOT_KEYBOARD_KANA 0x10225 226 259 /* 227 260 * Descriptor parser functions 228 261 */ 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 /** */ 264 int usb_hid_parse_report_descriptor(usb_hid_report_t *report, 234 265 const uint8_t *data, size_t size); 235 266 236 267 /** */ 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);268 void usb_hid_free_report(usb_hid_report_t *report); 269 270 /** */ 271 void usb_hid_descriptor_print(usb_hid_report_t *report); 241 272 242 273 … … 245 276 */ 246 277 /** */ 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, 278 int usb_hid_parse_report(const usb_hid_report_t *report, const uint8_t *data, size_t size); 279 280 /** */ 281 size_t usb_hid_report_input_length(const usb_hid_report_t *report, 254 282 usb_hid_report_path_t *path, int flags); 255 283 … … 291 319 */ 292 320 /** Allocates output report buffer*/ 293 uint8_t *usb_hid_report_output(usb_hid_report_ parser_t *parser, size_t *size, uint8_t report_id);321 uint8_t *usb_hid_report_output(usb_hid_report_t *report, size_t *size, uint8_t report_id); 294 322 295 323 /** Frees output report buffer*/ … … 297 325 298 326 /** Returns size of output for given usage path */ 299 size_t usb_hid_report_output_size(usb_hid_report_ parser_t *parser,327 size_t usb_hid_report_output_size(usb_hid_report_t *report, 300 328 usb_hid_report_path_t *path, int flags); 301 329 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 */ 331 int 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 */ 336 int usb_hid_report_output_translate(usb_hid_report_t *report, uint8_t report_id, uint8_t *buffer, size_t size); 307 337 #endif 308 338 /** -
uspace/lib/usb/include/usb/classes/hidreport.h
r9698695 r175ad13e 57 57 */ 58 58 int usb_hid_process_report_descriptor(usb_device_t *dev, 59 usb_hid_report_ parser_t *parser);59 usb_hid_report_t *report); 60 60 61 61 #endif /* LIBUSB_HIDREPORT_H_ */ -
uspace/lib/usb/src/hidparser.c
r9698695 r175ad13e 50 50 #define USB_HID_NO_ACTION 2 51 51 52 #define USB_HID_RESET_OFFSET 3 53 52 54 /** Unknown tag was founded in report descriptor data*/ 53 55 #define USB_HID_UNKNOWN_TAG -99 … … 56 58 * Private descriptor parser functions 57 59 */ 60 int usb_hid_report_init(usb_hid_report_t *report); 61 int usb_hid_report_append_fields(usb_hid_report_t *report, usb_hid_report_item_t *report_item); 62 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); 58 63 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size, 59 64 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); … … 65 70 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); 66 71 72 void usb_hid_print_usage_path(usb_hid_report_path_t *path); 67 73 void usb_hid_descriptor_print_list(link_t *head); 68 74 int usb_hid_report_reset_local_items(); … … 74 80 int32_t usb_hid_report_tag_data_int32(const uint8_t *data, size_t size); 75 81 inline 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);82 int usb_hid_translate_data(usb_hid_report_field_t *item, const uint8_t *data, size_t j); 83 uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, int32_t value); 78 84 int usb_pow(int a, int b); 79 85 … … 100 106 * @return Error code 101 107 */ 102 int usb_hid_ parser_init(usb_hid_report_parser_t *parser)103 { 104 if( parser== NULL) {108 int usb_hid_report_init(usb_hid_report_t *report) 109 { 110 if(report == NULL) { 105 111 return EINVAL; 106 112 } 107 113 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; 115 119 return EOK; 116 120 } 117 121 122 int 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 232 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) 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 } 118 250 119 251 /** Parse HID report descriptor. … … 123 255 * @return Error code. 124 256 */ 125 int usb_hid_parse_report_descriptor(usb_hid_report_ parser_t *parser,257 int usb_hid_parse_report_descriptor(usb_hid_report_t *report, 126 258 const uint8_t *data, size_t size) 127 259 { … … 134 266 usb_hid_report_item_t *new_report_item; 135 267 usb_hid_report_path_t *usage_path; 136 usb_hid_report_path_t *tmp_usage_path;137 268 138 269 size_t offset_input=0; 139 270 size_t offset_output=0; 140 271 size_t offset_feature=0; 141 272 273 link_t stack; 274 list_initialize(&stack); 142 275 143 276 /* parser structure initialization*/ 144 if(usb_hid_ parser_init(parser) != EOK) {277 if(usb_hid_report_init(report) != EOK) { 145 278 return EINVAL; 146 279 } 147 280 148 149 281 /*report item initialization*/ 150 282 if(!(report_item=malloc(sizeof(usb_hid_report_item_t)))){ … … 163 295 164 296 if((i+USB_HID_ITEM_SIZE(data[i]))>= size){ 165 return EINVAL; // TODO ERROR CODE297 return EINVAL; 166 298 } 167 299 … … 169 301 item_size = USB_HID_ITEM_SIZE(data[i]); 170 302 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);176 303 177 304 ret = usb_hid_report_parse_tag(tag,class,data+i+1, 178 305 item_size,report_item, usage_path); 179 usb_log_debug2("ret: %u\n", ret);180 306 switch(ret){ 181 307 case USB_HID_NEW_REPORT_ITEM: 182 308 // 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 186 310 report_item->usage_path = usage_path; 187 311 188 // clone path to the new one189 tmp_usage_path = usb_hid_report_path_clone(usage_path);190 191 // swap192 usage_path = tmp_usage_path;193 tmp_usage_path = NULL;194 195 312 usb_hid_report_path_set_report_id(report_item->usage_path, report_item->id); 196 313 if(report_item->id != 0){ 197 parser->use_report_id= 1;314 report->use_report_ids = 1; 198 315 } 199 316 200 317 switch(tag) { 201 318 case USB_HID_REPORT_TAG_INPUT: 319 report_item->type = USB_HID_REPORT_TYPE_INPUT; 202 320 report_item->offset = offset_input; 203 321 offset_input += report_item->count * report_item->size; 204 usb_log_debug(" - INPUT\n");205 list_append(&(report_item->link), &(parser->input));206 322 break; 207 323 case USB_HID_REPORT_TAG_OUTPUT: 324 report_item->type = USB_HID_REPORT_TYPE_OUTPUT; 208 325 report_item->offset = offset_output; 209 326 offset_output += report_item->count * report_item->size; 210 usb_log_debug(" - OUTPUT\n");211 list_append(&(report_item->link), &(parser->output));212 327 213 328 break; 214 329 case USB_HID_REPORT_TAG_FEATURE: 330 report_item->type = USB_HID_REPORT_TYPE_FEATURE; 215 331 report_item->offset = offset_feature; 216 332 offset_feature += report_item->count * report_item->size; 217 usb_log_debug(" - FEATURE\n");218 list_append(&(report_item->link), &(parser->feature));219 333 break; 220 334 default: … … 222 336 break; 223 337 } 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));231 338 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 232 353 /* 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 251 368 break; 369 370 case USB_HID_RESET_OFFSET: 371 offset_input = 0; 372 offset_output = 0; 373 offset_feature = 0; 374 break; 375 252 376 case USB_HID_REPORT_TAG_PUSH: 253 377 // push current state to stack … … 256 380 new_report_item->usage_path = tmp_path; 257 381 258 list_prepend (&new_report_item->link, & parser->stack);382 list_prepend (&new_report_item->link, &stack); 259 383 break; 260 384 case USB_HID_REPORT_TAG_POP: 261 385 // restore current state from stack 262 if(list_empty (& parser->stack)) {386 if(list_empty (&stack)) { 263 387 return EINVAL; 264 388 } 265 389 free(report_item); 266 390 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); 268 392 269 393 usb_hid_report_usage_path_t *tmp_usage_path; … … 274 398 usb_hid_report_path_free(report_item->usage_path); 275 399 list_initialize(&report_item->usage_path->link); 276 list_remove ( parser->stack.next);400 list_remove (stack.next); 277 401 278 402 break; … … 359 483 360 484 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]); 363 487 return USB_HID_NO_ACTION; 364 488 break; 365 489 366 490 case USB_HID_REPORT_TAG_END_COLLECTION: 367 // TODO368 // znici posledni uroven ve vsech usage paths369 // otazka jestli nema nicit dve, respektive novou posledni vynulovat?370 491 usb_hid_report_remove_last_item(usage_path); 371 492 return USB_HID_NO_ACTION; … … 394 515 { 395 516 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); 399 518 break; 400 519 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM: … … 424 543 case USB_HID_REPORT_TAG_REPORT_ID: 425 544 report_item->id = usb_hid_report_tag_data_int32(data,item_size); 545 return USB_HID_RESET_OFFSET; 426 546 break; 427 547 case USB_HID_REPORT_TAG_PUSH: 428 548 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 */ 430 553 return tag; 431 554 break; … … 453 576 { 454 577 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); 457 579 break; 458 580 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 } 460 589 break; 461 590 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 } 463 599 break; 464 600 case USB_HID_REPORT_TAG_DESIGNATOR_INDEX: … … 481 617 break; 482 618 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 484 622 break; 485 623 … … 521 659 void usb_hid_descriptor_print_list(link_t *head) 522 660 { 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; 526 662 link_t *item; 527 663 664 528 665 if(head == NULL || list_empty(head)) { 529 666 usb_log_debug("\tempty\n"); … … 533 670 for(item = head->next; item != head; item = item->next) { 534 671 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 558 686 usb_log_debug("\n"); 559 687 … … 568 696 * @return void 569 697 */ 570 void usb_hid_descriptor_print(usb_hid_report_ parser_t *parser)571 { 572 if( parser== NULL) {698 void usb_hid_descriptor_print(usb_hid_report_t *report) 699 { 700 if(report == NULL) { 573 701 return; 574 702 } 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 } 585 725 } 586 726 … … 626 766 * @return void 627 767 */ 628 void usb_hid_free_report _parser(usb_hid_report_parser_t *parser)629 { 630 if( parser== NULL){768 void usb_hid_free_report(usb_hid_report_t *report) 769 { 770 if(report == NULL){ 631 771 return; 632 772 } 633 773 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 640 798 return; 641 799 } … … 647 805 * @param parser Opaque HID report parser structure. 648 806 * @param data Data for the report. 649 * @param callbacks Callbacks for report actions.650 * @param arg Custom argument (passed through to the callbacks).651 807 * @return Error code. 652 808 */ 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) 809 int usb_hid_parse_report(const usb_hid_report_t *report, 810 const uint8_t *data, size_t size) 657 811 { 658 812 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 665 815 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) { 668 820 return EINVAL; 669 821 } 670 822 671 if( parser->use_report_id!= 0) {823 if(report->use_report_ids != 0) { 672 824 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); 683 828 684 829 /* 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; 697 846 } 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 } 708 853 } 709 854 list_item = list_item->next; 710 855 } 711 712 callbacks->keyboard(keys, key_count, report_id, arg);713 856 714 free(keys);715 857 return EOK; 716 858 … … 725 867 * @return Translated data 726 868 */ 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)869 int usb_hid_translate_data(usb_hid_report_field_t *item, const uint8_t *data, size_t j) 728 870 { 729 871 int resolution; … … 731 873 int part_size; 732 874 733 int32_t value ;875 int32_t value=0; 734 876 int32_t mask; 735 877 const uint8_t *foo; … … 755 897 756 898 offset = item->offset + (j * item->size); 757 if(parser->use_report_id != 0) {758 offset += 8;759 }760 899 761 900 // 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)) { 764 902 765 903 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 } 788 924 } 789 925 else { … … 791 927 mask = ((1 << item->size)-1) << (8-((offset%8)+item->size)); 792 928 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 802 938 803 939 return (int)(((value - item->logical_minimum) / resolution) + item->physical_minimum); … … 813 949 * @return Number of items in input report 814 950 */ 815 size_t usb_hid_report_input_length(const usb_hid_report_ parser_t *parser,951 size_t usb_hid_report_input_length(const usb_hid_report_t *report, 816 952 usb_hid_report_path_t *path, int flags) 817 953 { 954 818 955 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) { 823 958 return 0; 824 959 } 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 } 836 980 837 981 return ret; 838 }982 } 839 983 840 984 … … 860 1004 item->usage = usage; 861 1005 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); 864 1009 usage_path->depth++; 865 1010 return EOK; … … 927 1072 } 928 1073 1074 1075 void 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 929 1093 /** 930 1094 * Compares two usage paths structures … … 955 1119 } 956 1120 1121 //usb_log_debug("---------- PATH COMPARISON ----------\n\n"); 1122 //usb_hid_print_usage_path(report_path); 1123 //usb_hid_print_usage_path(path); 1124 957 1125 958 1126 if((only_page = flags & USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY) != 0){ … … 1042 1210 usb_hid_report_path_t *path; 1043 1211 path = malloc(sizeof(usb_hid_report_path_t)); 1044 if( !path){1212 if(path == NULL){ 1045 1213 return NULL; 1046 1214 } … … 1064 1232 usb_hid_report_remove_last_item(path); 1065 1233 } 1234 1235 list_remove(&path->link); 1236 free(path); 1066 1237 } 1067 1238 … … 1075 1246 usb_hid_report_path_t *usb_hid_report_path_clone(usb_hid_report_path_t *usage_path) 1076 1247 { 1248 link_t *path_link; 1077 1249 usb_hid_report_usage_path_t *path_item; 1078 link_t *path_link;1250 usb_hid_report_usage_path_t *new_path_item; 1079 1251 usb_hid_report_path_t *new_usage_path = usb_hid_report_path (); 1080 1252 … … 1090 1262 while(path_link != &usage_path->link) { 1091 1263 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++; 1093 1276 1094 1277 path_link = path_link->next; … … 1109 1292 * @return Returns allocated output buffer for specified output 1110 1293 */ 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) {1294 uint8_t *usb_hid_report_output(usb_hid_report_t *report, size_t *size, uint8_t report_id) 1295 { 1296 if(report == NULL) { 1114 1297 *size = 0; 1115 1298 return NULL; 1116 1299 } 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; 1150 1315 } 1151 1316 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; 1154 1321 } 1155 1322 } … … 1176 1343 * @return Number of items matching the given usage path 1177 1344 */ 1178 size_t usb_hid_report_output_size(usb_hid_report_ parser_t *parser,1345 size_t usb_hid_report_output_size(usb_hid_report_t *report, 1179 1346 usb_hid_report_path_t *path, int flags) 1180 1347 { 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) { 1186 1352 return 0; 1187 1353 } 1188 1354 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; 1198 1371 } 1199 1372 … … 1202 1375 } 1203 1376 1204 /** Updates the output report buffer by given data1377 /** Makes the output report buffer for data given in the report structure 1205 1378 * 1206 1379 * @param parser Opaque report parser structure … … 1209 1382 * @param buffer Output buffer 1210 1383 * @param size Size of output buffer 1211 * @param data Data buffer1212 * @param data_size Size of data buffer1213 1384 * @return Error code 1214 1385 */ 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; 1386 int usb_hid_report_output_translate(usb_hid_report_t *report, uint8_t report_id, 1387 uint8_t *buffer, size_t size) 1388 { 1221 1389 link_t *item; 1222 size_t idx=0;1223 int i=0;1224 1390 int32_t value=0; 1225 1391 int offset; 1226 1392 int length; 1227 1393 int32_t tmp_value; 1228 size_t offset_prefix = 0; 1229 1230 if(parser == NULL) { 1394 1395 if(report == NULL) { 1231 1396 return EINVAL; 1232 1397 } 1233 1398 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; 1237 1401 } 1238 1402 1239 1403 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 re port_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); 1251 1415 1252 1416 if((USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) || 1253 1417 ((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0))) { 1254 1418 1255 //// variable item1256 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; 1258 1422 length = report_item->size; 1259 1423 } 1260 1424 else { 1261 1425 //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; 1265 1429 } 1266 1430 … … 1281 1445 } 1282 1446 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; 1290 1448 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); 1297 1462 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 1303 1472 1304 1473 item = item->next; … … 1316 1485 * @return ranslated value 1317 1486 */ 1318 int32_t usb_hid_translate_data_reverse(usb_hid_report_item_t *item, int value)1487 uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, int value) 1319 1488 { 1320 1489 int ret=0; … … 1356 1525 1357 1526 1358 return ret;1527 return (uint32_t)ret; 1359 1528 } 1360 1529 … … 1395 1564 } 1396 1565 1566 1567 /** 1568 * 1569 * 1570 * 1571 * 1572 * 1573 */ 1574 int 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 1397 1614 /** 1398 1615 * @} -
uspace/lib/usb/src/hidreport.c
r9698695 r175ad13e 185 185 186 186 int usb_hid_process_report_descriptor(usb_device_t *dev, 187 usb_hid_report_ parser_t *parser)187 usb_hid_report_t *report) 188 188 { 189 if (dev == NULL || parser== NULL) {189 if (dev == NULL || report == NULL) { 190 190 usb_log_error("Failed to process Report descriptor: wrong " 191 191 "parameters given.\n"); … … 210 210 assert(report_desc != NULL); 211 211 212 rc = usb_hid_parse_report_descriptor( parser, report_desc, report_size);212 rc = usb_hid_parse_report_descriptor(report, report_desc, report_size); 213 213 if (rc != EOK) { 214 214 usb_log_error("Problem parsing Report descriptor: %s.\n", … … 218 218 } 219 219 220 usb_hid_descriptor_print( parser);220 usb_hid_descriptor_print(report); 221 221 free(report_desc); 222 222
Note:
See TracChangeset
for help on using the changeset viewer.