Changes in / [45dd8bf:e69f10b] in mainline
- Location:
- uspace
- Files:
-
- 1 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbhid/hiddev.c
r45dd8bf re69f10b 158 158 } 159 159 160 hid_dev->report_desc_size = length; 161 160 162 usb_log_debug("Done.\n"); 161 163 … … 262 264 263 265 if (rc != EOK) { 264 usb_log_warning("Problem with parsing Report descriptor: %s.\n",266 usb_log_warning("Problem with getting Report descriptor: %s.\n", 265 267 str_error(rc)); 266 268 return rc; 267 269 } 270 271 rc = usb_hid_parse_report_descriptor(hid_dev->parser, 272 hid_dev->report_desc, hid_dev->report_desc_size); 273 if (rc != EOK) { 274 usb_log_warning("Problem parsing Report descriptor: %s.\n", 275 str_error(rc)); 276 return rc; 277 } 278 279 usb_hid_descriptor_print(hid_dev->parser); 268 280 269 281 return EOK; … … 289 301 290 302 memset(dev, 0, sizeof(usbhid_dev_t)); 303 304 dev->parser = (usb_hid_report_parser_t *)(malloc(sizeof( 305 usb_hid_report_parser_t))); 306 if (dev->parser == NULL) { 307 usb_log_fatal("No memory!\n"); 308 free(dev); 309 return NULL; 310 } 291 311 292 312 dev->initialized = 0; … … 391 411 return rc; 392 412 } 413 414 /* 415 * Initialize the report parser. 416 */ 417 rc = usb_hid_parser_init(hid_dev->parser); 418 if (rc != EOK) { 419 usb_log_error("Failed to initialize report parser.\n"); 420 return rc; 421 } 393 422 394 423 /* -
uspace/drv/usbhid/hiddev.h
r45dd8bf re69f10b 75 75 /** Report descriptor. */ 76 76 uint8_t *report_desc; 77 78 size_t report_desc_size; 79 77 80 /** HID Report parser. */ 78 81 usb_hid_report_parser_t *parser; -
uspace/drv/usbhid/kbddev.c
r45dd8bf re69f10b 541 541 callbacks->keyboard = usbhid_kbd_process_keycodes; 542 542 543 usb_log_debug("Calling usb_hid_ boot_keyboard_input_report() with "543 usb_log_debug("Calling usb_hid_parse_report() with " 544 544 "buffer %s\n", usb_debug_str_buffer(buffer, actual_size, 0)); 545 545 546 int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size, 547 callbacks, kbd_dev); 546 // int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size, 547 // callbacks, kbd_dev); 548 int rc = usb_hid_parse_report(kbd_dev->hid_dev->parser, buffer, 549 actual_size, callbacks, kbd_dev); 548 550 549 551 if (rc != EOK) { … … 614 616 free((*kbd_dev)->repeat_mtx); 615 617 } 618 619 usb_hid_free_report_parser((*kbd_dev)->parser); 616 620 617 621 free(*kbd_dev); … … 709 713 assert(kbd_dev->hid_dev != NULL); 710 714 assert(kbd_dev->hid_dev->initialized); 711 usbhid_req_set_protocol(kbd_dev->hid_dev, USB_HID_PROTOCOL_BOOT);715 //usbhid_req_set_protocol(kbd_dev->hid_dev, USB_HID_PROTOCOL_BOOT); 712 716 713 717 usbhid_kbd_set_led(kbd_dev); -
uspace/drv/usbhid/kbddev.h
r45dd8bf re69f10b 42 42 43 43 #include <usb/classes/hid.h> 44 #include <usb/classes/hidparser.h> 44 45 #include <ddf/driver.h> 45 46 #include <usb/pipes.h> … … 99 100 /** Mutex for accessing the information about auto-repeat. */ 100 101 fibril_mutex_t *repeat_mtx; 102 103 usb_hid_report_parser_t *parser; 101 104 102 105 /** State of the structure (for checking before use). */ -
uspace/lib/usb/include/usb/classes/hidparser.h
r45dd8bf re69f10b 37 37 38 38 #include <stdint.h> 39 #include <adt/list.h> 40 #include <usb/classes/hid_report_items.h> 41 42 /** 43 * Item prefix 44 */ 45 #define USB_HID_ITEM_SIZE(data) ((uint8_t)(data & 0x3)) 46 #define USB_HID_ITEM_TAG(data) ((uint8_t)((data & 0xF0) >> 4)) 47 #define USB_HID_ITEM_TAG_CLASS(data) ((uint8_t)((data & 0xC) >> 2)) 48 #define USB_HID_ITEM_IS_LONG(data) (data == 0xFE) 49 50 51 /** 52 * Input/Output/Feature Item flags 53 */ 54 #define USB_HID_ITEM_FLAG_CONSTANT(flags) (flags & 0x1) 55 #define USB_HID_ITEM_FLAG_VARIABLE(flags) (flags & 0x2) 56 #define USB_HID_ITEM_FLAG_RELATIVE(flags) (flags & 0x4) 57 #define USB_HID_ITEM_FLAG_WRAP(flags) (flags & 0x8) 58 #define USB_HID_ITEM_FLAG_LINEAR(flags) (flags & 0x10) 59 #define USB_HID_ITEM_FLAG_PREFERRED(flags) (flags & 0x20) 60 #define USB_HID_ITEM_FLAG_POSITION(flags) (flags & 0x40) 61 #define USB_HID_ITEM_FLAG_VOLATILE(flags) (flags & 0x80) 62 #define USB_HID_ITEM_FLAG_BUFFERED(flags) (flags & 0x100) 63 39 64 40 65 /** … … 42 67 */ 43 68 typedef struct { 69 int32_t id; 70 int32_t usage_page; 71 int32_t usage; 72 int32_t usage_minimum; 73 int32_t usage_maximum; 74 int32_t logical_minimum; 75 int32_t logical_maximum; 76 int32_t size; 77 int32_t count; 78 size_t offset; 79 int32_t delimiter; 44 80 45 uint8_t usage_min; 46 uint8_t usage_max; 47 uint8_t logical_min; 48 uint8_t logical_max; 49 uint8_t size; 50 uint8_t count; 51 uint8_t offset; 81 int32_t unit_exponent; 82 int32_t unit; 52 83 84 /* 85 * some not yet used fields 86 */ 87 int32_t string_index; 88 int32_t string_minimum; 89 int32_t string_maximum; 90 int32_t designator_index; 91 int32_t designator_minimum; 92 int32_t designator_maximum; 93 int32_t physical_minimum; 94 int32_t physical_maximum; 95 96 uint8_t item_flags; 97 98 link_t link; 53 99 } usb_hid_report_item_t; 54 100 55 101 56 102 /** HID report parser structure. */ 57 typedef struct { 58 } usb_hid_report_parser_t; 103 typedef struct { 104 link_t input; 105 link_t output; 106 link_t feature; 107 } usb_hid_report_parser_t; 108 59 109 60 110 … … 127 177 int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size); 128 178 179 int usb_hid_parser_init(usb_hid_report_parser_t *parser); 129 180 int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser, 130 181 const uint8_t *data, size_t size); … … 135 186 136 187 137 int usb_hid_free_report_parser(usb_hid_report_parser_t *parser); 188 void usb_hid_free_report_parser(usb_hid_report_parser_t *parser); 189 190 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser); 138 191 139 192 #endif -
uspace/lib/usb/src/hidparser.c
r45dd8bf re69f10b 36 36 #include <errno.h> 37 37 #include <stdio.h> 38 #include <malloc.h> 39 #include <mem.h> 40 #include <usb/debug.h> 41 42 #define USB_HID_NEW_REPORT_ITEM 1 43 #define USB_HID_NO_ACTION 2 44 #define USB_HID_UNKNOWN_TAG -99 45 46 #define BAD_HACK_USAGE_PAGE 0x07 47 48 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size, 49 usb_hid_report_item_t *report_item); 50 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size, 51 usb_hid_report_item_t *report_item); 52 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size, 53 usb_hid_report_item_t *report_item); 54 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size, 55 usb_hid_report_item_t *report_item); 56 57 void usb_hid_descriptor_print_list(link_t *head); 58 int usb_hid_report_reset_local_items(); 59 void usb_hid_free_report_list(link_t *head); 60 int32_t usb_hid_report_tag_data_int32(const uint8_t *data, size_t size); 61 inline size_t usb_hid_count_item_offset(usb_hid_report_item_t * report_item, size_t offset); 62 int usb_hid_translate_data(usb_hid_report_item_t *item, const uint8_t *data, size_t j); 63 int usb_pow(int a, int b); 64 65 int usb_pow(int a, int b) 66 { 67 switch(b) { 68 case 0: 69 return 1; 70 break; 71 case 1: 72 return a; 73 break; 74 default: 75 return a * usb_pow(a, b-1); 76 break; 77 } 78 } 79 80 /** 81 * 82 */ 83 int usb_hid_parser_init(usb_hid_report_parser_t *parser) 84 { 85 if(parser == NULL) { 86 return -1; 87 } 88 89 list_initialize(&(parser->input)); 90 list_initialize(&(parser->output)); 91 list_initialize(&(parser->feature)); 92 93 return EOK; 94 } 95 38 96 39 97 /** Parse HID report descriptor. … … 46 104 const uint8_t *data, size_t size) 47 105 { 48 return ENOTSUP; 106 size_t i=0; 107 uint8_t tag=0; 108 uint8_t item_size=0; 109 int class=0; 110 int ret; 111 usb_hid_report_item_t *report_item=0; 112 usb_hid_report_item_t *new_report_item; 113 114 size_t offset_input=0; 115 size_t offset_output=0; 116 size_t offset_feature=0; 117 118 119 if(!(report_item=malloc(sizeof(usb_hid_report_item_t)))){ 120 return ENOMEM; 121 } 122 memset(report_item, 0, sizeof(usb_hid_report_item_t)); 123 124 link_initialize(&(report_item->link)); 125 126 while(i<size){ 127 if(!USB_HID_ITEM_IS_LONG(data[i])){ 128 129 if((i+USB_HID_ITEM_SIZE(data[i]))>= size){ 130 return -1; // TODO ERROR CODE 131 } 132 133 tag = USB_HID_ITEM_TAG(data[i]); 134 item_size = USB_HID_ITEM_SIZE(data[i]); 135 class = USB_HID_ITEM_TAG_CLASS(data[i]); 136 137 usb_log_debug2( 138 "i(%u) data(%X) value(%X): TAG %u, class %u, size %u - ", i, 139 data[i], usb_hid_report_tag_data_int32(data+i+1,item_size), 140 tag, class, item_size); 141 142 ret = usb_hid_report_parse_tag(tag,class,data+i+1, 143 item_size,report_item); 144 usb_log_debug2("ret: %u\n", ret); 145 switch(ret){ 146 case USB_HID_NEW_REPORT_ITEM: 147 // store report item to report and create the new one 148 usb_log_debug("\nNEW REPORT ITEM: %X",tag); 149 150 switch(tag) { 151 case USB_HID_REPORT_TAG_INPUT: 152 report_item->offset = offset_input; 153 offset_input += report_item->count * report_item->size; 154 usb_log_debug(" - INPUT\n"); 155 list_append(&(report_item->link), &(parser->input)); 156 break; 157 case USB_HID_REPORT_TAG_OUTPUT: 158 report_item->offset = offset_output; 159 offset_output += report_item->count * report_item->size; 160 usb_log_debug(" - OUTPUT\n"); 161 list_append(&(report_item->link), &(parser->output)); 162 163 break; 164 case USB_HID_REPORT_TAG_FEATURE: 165 report_item->offset = offset_feature; 166 offset_feature += report_item->count * report_item->size; 167 usb_log_debug(" - FEATURE\n"); 168 list_append(&(report_item->link), &(parser->feature)); 169 break; 170 default: 171 usb_log_debug("\tjump over - tag %X\n", tag); 172 break; 173 } 174 175 /* clone current state table to the new item */ 176 if(!(new_report_item = malloc(sizeof(usb_hid_report_item_t)))) { 177 return ENOMEM; 178 } 179 memcpy(new_report_item,report_item, sizeof(usb_hid_report_item_t)); 180 link_initialize(&(new_report_item->link)); 181 report_item = new_report_item; 182 183 break; 184 case USB_HID_REPORT_TAG_PUSH: 185 // push current state to stack 186 // not yet implemented 187 break; 188 case USB_HID_REPORT_TAG_POP: 189 // restore current state from stack 190 // not yet implemented 191 break; 192 193 default: 194 // nothing special to do 195 break; 196 } 197 198 /* jump over the processed block */ 199 i += 1 + USB_HID_ITEM_SIZE(data[i]); 200 } 201 else{ 202 // TBD 203 i += 3 + USB_HID_ITEM_SIZE(data[i+1]); 204 } 205 206 207 } 208 209 return EOK; 210 } 211 212 213 /** 214 * Parse input report. 215 * 216 * @param data Data for report 217 * @param size Size of report 218 * @param callbacks Callbacks for report actions 219 * @param arg Custom arguments 220 * 221 * @return Error code 222 */ 223 int usb_hid_boot_keyboard_input_report(const uint8_t *data, size_t size, 224 const usb_hid_report_in_callbacks_t *callbacks, void *arg) 225 { 226 int i; 227 usb_hid_report_item_t item; 228 229 /* fill item due to the boot protocol report descriptor */ 230 // modifier keys are in the first byte 231 uint8_t modifiers = data[0]; 232 233 item.offset = 2; /* second byte is reserved */ 234 item.size = 8; 235 item.count = 6; 236 item.usage_minimum = 0; 237 item.usage_maximum = 255; 238 item.logical_minimum = 0; 239 item.logical_maximum = 255; 240 241 if (size != 8) { 242 return -1; //ERANGE; 243 } 244 245 uint8_t keys[6]; 246 for (i = 0; i < item.count; i++) { 247 keys[i] = data[i + item.offset]; 248 } 249 250 callbacks->keyboard(keys, 6, modifiers, arg); 251 return EOK; 252 } 253 254 /** 255 * Makes output report for keyboard boot protocol 256 * 257 * @param leds 258 * @param output Output report data buffer 259 * @param size Size of the output buffer 260 * @return Error code 261 */ 262 int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size) 263 { 264 if(size != 1){ 265 return -1; 266 } 267 268 /* used only first five bits, others are only padding*/ 269 *data = leds; 270 return EOK; 271 } 272 273 /** 274 * 275 * @param Tag to parse 276 * @param Report descriptor buffer 277 * @param Size of data belongs to this tag 278 * @param Current report item structe 279 * @return Code of action to be done next 280 */ 281 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size, 282 usb_hid_report_item_t *report_item) 283 { 284 int ret; 285 286 switch(class){ 287 case USB_HID_TAG_CLASS_MAIN: 288 289 if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item)) == EOK) { 290 return USB_HID_NEW_REPORT_ITEM; 291 } 292 else { 293 /*TODO process the error */ 294 return ret; 295 } 296 break; 297 298 case USB_HID_TAG_CLASS_GLOBAL: 299 return usb_hid_report_parse_global_tag(tag,data,item_size,report_item); 300 break; 301 302 case USB_HID_TAG_CLASS_LOCAL: 303 return usb_hid_report_parse_local_tag(tag,data,item_size,report_item); 304 break; 305 default: 306 return USB_HID_NO_ACTION; 307 } 308 } 309 310 /** 311 * Parse main tags of report descriptor 312 * 313 * @param Tag identifier 314 * @param Data buffer 315 * @param Length of data buffer 316 * @param Current state table 317 * @return Error code 318 */ 319 320 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size, 321 usb_hid_report_item_t *report_item) 322 { 323 switch(tag) 324 { 325 case USB_HID_REPORT_TAG_INPUT: 326 case USB_HID_REPORT_TAG_OUTPUT: 327 case USB_HID_REPORT_TAG_FEATURE: 328 report_item->item_flags = *data; 329 return EOK; 330 break; 331 332 case USB_HID_REPORT_TAG_COLLECTION: 333 // TODO 334 return USB_HID_NO_ACTION; 335 break; 336 337 case USB_HID_REPORT_TAG_END_COLLECTION: 338 /* should be ignored */ 339 return USB_HID_NO_ACTION; 340 break; 341 default: 342 return USB_HID_NO_ACTION; 343 } 344 345 return EOK; 346 } 347 348 /** 349 * Parse global tags of report descriptor 350 * 351 * @param Tag identifier 352 * @param Data buffer 353 * @param Length of data buffer 354 * @param Current state table 355 * @return Error code 356 */ 357 358 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size, 359 usb_hid_report_item_t *report_item) 360 { 361 // TODO take care about the bit length of data 362 switch(tag) 363 { 364 case USB_HID_REPORT_TAG_USAGE_PAGE: 365 report_item->usage_page = usb_hid_report_tag_data_int32(data,item_size); 366 break; 367 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM: 368 report_item->logical_minimum = usb_hid_report_tag_data_int32(data,item_size); 369 break; 370 case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM: 371 report_item->logical_maximum = usb_hid_report_tag_data_int32(data,item_size); 372 break; 373 case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM: 374 report_item->physical_minimum = usb_hid_report_tag_data_int32(data,item_size); 375 break; 376 case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM: 377 report_item->physical_maximum = usb_hid_report_tag_data_int32(data,item_size); 378 break; 379 case USB_HID_REPORT_TAG_UNIT_EXPONENT: 380 report_item->unit_exponent = usb_hid_report_tag_data_int32(data,item_size); 381 break; 382 case USB_HID_REPORT_TAG_UNIT: 383 report_item->unit = usb_hid_report_tag_data_int32(data,item_size); 384 break; 385 case USB_HID_REPORT_TAG_REPORT_SIZE: 386 report_item->size = usb_hid_report_tag_data_int32(data,item_size); 387 break; 388 case USB_HID_REPORT_TAG_REPORT_COUNT: 389 report_item->count = usb_hid_report_tag_data_int32(data,item_size); 390 break; 391 case USB_HID_REPORT_TAG_REPORT_ID: 392 report_item->id = usb_hid_report_tag_data_int32(data,item_size); 393 break; 394 case USB_HID_REPORT_TAG_PUSH: 395 case USB_HID_REPORT_TAG_POP: 396 return tag; 397 break; 398 399 default: 400 return USB_HID_NO_ACTION; 401 } 402 403 return EOK; 404 } 405 406 /** 407 * Parse local tags of report descriptor 408 * 409 * @param Tag identifier 410 * @param Data buffer 411 * @param Length of data buffer 412 * @param Current state table 413 * @return Error code 414 */ 415 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size, 416 usb_hid_report_item_t *report_item) 417 { 418 switch(tag) 419 { 420 case USB_HID_REPORT_TAG_USAGE: 421 report_item->usage = usb_hid_report_tag_data_int32(data,item_size); 422 break; 423 case USB_HID_REPORT_TAG_USAGE_MINIMUM: 424 report_item->usage_minimum = usb_hid_report_tag_data_int32(data,item_size); 425 break; 426 case USB_HID_REPORT_TAG_USAGE_MAXIMUM: 427 report_item->usage_maximum = usb_hid_report_tag_data_int32(data,item_size); 428 break; 429 case USB_HID_REPORT_TAG_DESIGNATOR_INDEX: 430 report_item->designator_index = usb_hid_report_tag_data_int32(data,item_size); 431 break; 432 case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM: 433 report_item->designator_minimum = usb_hid_report_tag_data_int32(data,item_size); 434 break; 435 case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM: 436 report_item->designator_maximum = usb_hid_report_tag_data_int32(data,item_size); 437 break; 438 case USB_HID_REPORT_TAG_STRING_INDEX: 439 report_item->string_index = usb_hid_report_tag_data_int32(data,item_size); 440 break; 441 case USB_HID_REPORT_TAG_STRING_MINIMUM: 442 report_item->string_minimum = usb_hid_report_tag_data_int32(data,item_size); 443 break; 444 case USB_HID_REPORT_TAG_STRING_MAXIMUM: 445 report_item->string_maximum = usb_hid_report_tag_data_int32(data,item_size); 446 break; 447 case USB_HID_REPORT_TAG_DELIMITER: 448 report_item->delimiter = usb_hid_report_tag_data_int32(data,item_size); 449 break; 450 451 default: 452 return USB_HID_NO_ACTION; 453 } 454 455 return EOK; 456 } 457 458 /** 459 * Converts raw data to int32 (thats the maximum length of short item data) 460 * 461 * @param Data buffer 462 * @param Size of buffer 463 * @return Converted int32 number 464 */ 465 int32_t usb_hid_report_tag_data_int32(const uint8_t *data, size_t size) 466 { 467 unsigned int i; 468 int32_t result; 469 470 result = 0; 471 for(i=0; i<size; i++) { 472 result = (result | (data[i]) << (i*8)); 473 } 474 475 return result; 476 } 477 478 479 480 /** 481 * Prints content of given list of report items. 482 * 483 * @param List of report items 484 * @return void 485 */ 486 void usb_hid_descriptor_print_list(link_t *head) 487 { 488 usb_hid_report_item_t *report_item; 489 link_t *item; 490 491 if(head == NULL || list_empty(head)) { 492 usb_log_debug("\tempty\n"); 493 return; 494 } 495 496 for(item = head->next; item != head; item = item->next) { 497 498 report_item = list_get_instance(item, usb_hid_report_item_t, link); 499 500 usb_log_debug("\tOFFSET: %X\n", report_item->offset); 501 usb_log_debug("\tCOUNT: %X\n", report_item->count); 502 usb_log_debug("\tSIZE: %X\n", report_item->size); 503 usb_log_debug("\tCONSTANT: %X\n", USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags)); 504 usb_log_debug("\tUSAGE: %X\n", report_item->usage); 505 usb_log_debug("\tUSAGE PAGE: %X\n", report_item->usage_page); 506 usb_log_debug("\tLOGMIN: %X\n", report_item->logical_minimum); 507 usb_log_debug("\tLOGMAX: %X\n", report_item->logical_maximum); 508 usb_log_debug("\tPHYMIN: %X\n", report_item->physical_minimum); 509 usb_log_debug("\tPHYMAX: %X\n", report_item->physical_maximum); 510 usb_log_debug("\n"); 511 512 } 513 514 515 } 516 /** 517 * Prints content of given descriptor in human readable format. 518 * 519 * @param Parsed descriptor to print 520 * @return void 521 */ 522 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser) 523 { 524 usb_log_debug("INPUT:\n"); 525 usb_hid_descriptor_print_list(&parser->input); 526 527 usb_log_debug("OUTPUT: \n"); 528 usb_hid_descriptor_print_list(&parser->output); 529 530 usb_log_debug("FEATURE:\n"); 531 usb_hid_descriptor_print_list(&parser->feature); 532 533 } 534 535 /** 536 * Releases whole linked list of report items 537 * 538 * 539 */ 540 void usb_hid_free_report_list(link_t *head) 541 { 542 return; 543 544 usb_hid_report_item_t *report_item; 545 link_t *next; 546 547 if(head == NULL || list_empty(head)) { 548 return; 549 } 550 551 next = head->next; 552 while(next != head) { 553 554 report_item = list_get_instance(next, usb_hid_report_item_t, link); 555 next = next->next; 556 557 free(report_item); 558 } 559 560 return; 561 562 } 563 564 /** Free the HID report parser structure 565 * 566 * @param parser Opaque HID report parser structure 567 * @return Error code 568 */ 569 void usb_hid_free_report_parser(usb_hid_report_parser_t *parser) 570 { 571 if(parser == NULL){ 572 return; 573 } 574 575 usb_hid_free_report_list(&parser->input); 576 usb_hid_free_report_list(&parser->output); 577 usb_hid_free_report_list(&parser->feature); 578 579 return; 49 580 } 50 581 … … 58 589 * @param arg Custom argument (passed through to the callbacks). 59 590 * @return Error code. 60 */ 591 */ 61 592 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 62 593 const uint8_t *data, size_t size, 63 594 const usb_hid_report_in_callbacks_t *callbacks, void *arg) 64 595 { 65 int i; 66 67 /* main parsing loop */ 68 while(0){ 69 } 70 71 72 uint8_t keys[6]; 73 74 for (i = 0; i < 6; ++i) { 75 keys[i] = data[i]; 76 } 77 78 callbacks->keyboard(keys, 6, 0, arg); 79 596 /* 597 * 598 * only key codes (usage page 0x07) will be processed 599 * other usages will be ignored 600 */ 601 link_t *list_item; 602 usb_hid_report_item_t *item; 603 uint8_t *keys; 604 size_t key_count=0; 605 size_t i=0; 606 size_t j=0; 607 608 // get the size of result keycodes array 609 list_item = parser->input.next; 610 while(list_item != &(parser->input)) { 611 612 item = list_get_instance(list_item, usb_hid_report_item_t, link); 613 if(item->usage_page == BAD_HACK_USAGE_PAGE) { 614 key_count += item->count; 615 } 616 617 list_item = list_item->next; 618 } 619 620 621 if(!(keys = malloc(sizeof(uint8_t) * key_count))){ 622 return ENOMEM; 623 } 624 625 // read data 626 list_item = parser->input.next; 627 while(list_item != &(parser->input)) { 628 629 item = list_get_instance(list_item, usb_hid_report_item_t, link); 630 if(item->usage_page == BAD_HACK_USAGE_PAGE) { 631 for(j=0; j<(size_t)(item->count); j++) { 632 keys[i++] = usb_hid_translate_data(item, data,j); 633 } 634 } 635 list_item = list_item->next; 636 } 637 638 callbacks->keyboard(keys, key_count, 0, arg); 639 640 free(keys); 80 641 return EOK; 81 } 82 83 /** Free the HID report parser structure 84 * 85 * @param parser Opaque HID report parser structure 86 * @return Error code 87 */ 88 int usb_hid_free_report_parser(usb_hid_report_parser_t *parser) 89 { 90 91 return EOK; 92 } 93 94 95 /** 96 * Parse input report. 97 * 98 * @param data Data for report 99 * @param size Size of report 100 * @param callbacks Callbacks for report actions 101 * @param arg Custom arguments 102 * 103 * @return Error code 104 */ 105 int usb_hid_boot_keyboard_input_report(const uint8_t *data, size_t size, 106 const usb_hid_report_in_callbacks_t *callbacks, void *arg) 107 { 108 int i; 109 usb_hid_report_item_t item; 110 111 /* fill item due to the boot protocol report descriptor */ 112 // modifier keys are in the first byte 113 uint8_t modifiers = data[0]; 114 115 item.offset = 2; /* second byte is reserved */ 116 item.size = 8; 117 item.count = 6; 118 item.usage_min = 0; 119 item.usage_max = 255; 120 item.logical_min = 0; 121 item.logical_max = 255; 122 123 if (size != 8) { 124 return ERANGE; 125 } 126 127 uint8_t keys[6]; 128 for (i = 0; i < item.count; i++) { 129 keys[i] = data[i + item.offset]; 130 } 131 132 callbacks->keyboard(keys, 6, modifiers, arg); 133 return EOK; 134 } 135 136 /** 137 * Makes output report for keyboard boot protocol 138 * 139 * @param leds 140 * @param output Output report data buffer 141 * @param size Size of the output buffer 142 * @return Error code 143 */ 144 int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size) 145 { 146 if (size < 1){ 147 return -1; 148 } 149 150 data[0] = leds; 151 return EOK; 152 } 153 642 643 } 644 645 646 int usb_hid_translate_data(usb_hid_report_item_t *item, const uint8_t *data, size_t j) 647 { 648 int resolution; 649 int offset; 650 int part_size; 651 652 int32_t value; 653 int32_t mask; 654 const uint8_t *foo; 655 656 // now only common numbers llowed 657 if(item->size > 32) { 658 return 0; 659 } 660 661 if((item->physical_minimum == 0) && (item->physical_maximum == 0)) { 662 item->physical_minimum = item->logical_minimum; 663 item->physical_maximum = item->logical_maximum; 664 } 665 666 if(item->physical_maximum == item->physical_minimum){ 667 resolution = 1; 668 } 669 else { 670 resolution = (item->logical_maximum - item->logical_minimum) / 671 ((item->physical_maximum - item->physical_minimum) * 672 (usb_pow(10,(item->unit_exponent)))); 673 } 674 offset = item->offset + (j * item->size); 675 676 // FIXME 677 if((offset/8) != ((offset+item->size)/8)) { 678 usb_log_debug2("offset %d\n", offset); 679 680 part_size = ((offset+item->size)%8); 681 usb_log_debug2("part size %d\n",part_size); 682 683 // the higher one 684 foo = data+(offset/8); 685 mask = ((1 << (item->size-part_size))-1); 686 value = (*foo & mask) << part_size; 687 688 usb_log_debug2("hfoo %x\n", *foo); 689 usb_log_debug2("hmaska %x\n", mask); 690 usb_log_debug2("hval %d\n", value); 691 692 // the lower one 693 foo = data+((offset+item->size)/8); 694 mask = ((1 << part_size)-1) << (8-part_size); 695 value += ((*foo & mask) >> (8-part_size)); 696 697 usb_log_debug2("lfoo %x\n", *foo); 698 usb_log_debug2("lmaska %x\n", mask); 699 usb_log_debug2("lval %d\n", ((*foo & mask) >> (8-(item->size-part_size)))); 700 usb_log_debug2("val %d\n", value); 701 702 703 } 704 else { 705 foo = data+(offset/8); 706 mask = ((1 << item->size)-1) << (8-((offset%8)+item->size)); 707 value = (*foo & mask) >> (8-((offset%8)+item->size)); 708 709 usb_log_debug2("offset %d\n", offset); 710 711 usb_log_debug2("foo %x\n", *foo); 712 usb_log_debug2("maska %x\n", mask); 713 usb_log_debug2("val %d\n", value); 714 } 715 716 usb_log_debug2("---\n\n"); 717 718 return (int)(((value - item->logical_minimum) / resolution) + item->physical_minimum); 719 720 } 154 721 /** 155 722 * @}
Note:
See TracChangeset
for help on using the changeset viewer.