Changeset d208f3f in mainline for uspace/lib/usbhid/src/hiddescriptor.c
- Timestamp:
- 2011-05-27T12:14:02Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2df648c2
- Parents:
- fb2de0a (diff), 74341ed (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhid/src/hiddescriptor.c
rfb2de0a rd208f3f 41 41 #include <assert.h> 42 42 43 43 /*---------------------------------------------------------------------------*/ 44 /* 45 * Constants defining current parsing mode for correct parsing of the set of 46 * local tags (usage) enclosed in delimter tags. 47 */ 48 /** 49 * Second delimiter tag was read. The set of local items (usage) ended. 50 */ 44 51 #define OUTSIDE_DELIMITER_SET 0 52 53 /** 54 * First delimiter tag was read. The set of local items (usage) started. 55 */ 45 56 #define START_DELIMITER_SET 1 57 58 /** 59 * Parser is in the set of local items. 60 */ 46 61 #define INSIDE_DELIMITER_SET 2 62 63 /*---------------------------------------------------------------------------*/ 47 64 48 65 /** The new report item flag. Used to determine when the item is completly … … 61 78 #define USB_HID_UNKNOWN_TAG -99 62 79 63 usb_hid_report_path_t *usb_hid_report_path_try_insert(usb_hid_report_t *report, usb_hid_report_path_t *cmp_path) 64 { 65 /* find or append current collection path to the list */ 66 //link_t *path_it = report->collection_paths.next; 80 /*---------------------------------------------------------------------------*/ 81 /** 82 * Checks if given collection path is already present in report structure and 83 * inserts it if not. 84 * 85 * @param report Report structure 86 * @param cmp_path The collection path 87 * @return Pointer to the result collection path in report structure. 88 * @retval NULL If some error occurs 89 */ 90 usb_hid_report_path_t *usb_hid_report_path_try_insert( 91 usb_hid_report_t *report, usb_hid_report_path_t *cmp_path) { 92 67 93 link_t *path_it = report->collection_paths.prev->next; 68 94 usb_hid_report_path_t *path = NULL; 69 95 96 if((report == NULL) || (cmp_path == NULL)) { 97 return NULL; 98 } 70 99 71 100 while(path_it != &report->collection_paths) { 72 path = list_get_instance(path_it, usb_hid_report_path_t, link); 73 74 if(usb_hid_report_compare_usage_path(path, cmp_path, USB_HID_PATH_COMPARE_STRICT) == EOK){ 101 path = list_get_instance(path_it, usb_hid_report_path_t, 102 link); 103 104 if(usb_hid_report_compare_usage_path(path, cmp_path, 105 USB_HID_PATH_COMPARE_STRICT) == EOK){ 75 106 break; 76 107 } … … 78 109 } 79 110 if(path_it == &report->collection_paths) { 80 path = usb_hid_report_path_clone(cmp_path); 111 path = usb_hid_report_path_clone(cmp_path); 112 if(path == NULL) { 113 return NULL; 114 } 81 115 list_append(&path->link, &report->collection_paths); 82 116 report->collection_paths_count++; … … 85 119 } 86 120 else { 87 return list_get_instance(path_it, usb_hid_report_path_t, link); 88 } 89 } 90 121 return list_get_instance(path_it, usb_hid_report_path_t, 122 link); 123 } 124 } 125 126 /*---------------------------------------------------------------------------*/ 91 127 /** 92 128 * Initialize the report descriptor parser structure … … 94 130 * @param parser Report descriptor parser structure 95 131 * @return Error code 132 * @retval EINVAL If no report structure was given 133 * @retval EOK If report structure was successfully initialized 96 134 */ 97 135 int usb_hid_report_init(usb_hid_report_t *report) … … 109 147 } 110 148 111 112 /* 113 * 114 * 115 */ 116 int usb_hid_report_append_fields(usb_hid_report_t *report, usb_hid_report_item_t *report_item) 117 { 149 /*---------------------------------------------------------------------------*/ 150 151 /** 152 * 153 * 154 * @param report Report structure in which the new report items should be 155 * stored 156 * @param report_item Current report descriptor's parsing state table 157 * @return Error code 158 * @retval EOK If all fields were successfully append to report 159 * @retval EINVAL If invalid parameters (NULL) was given 160 * @retval ENOMEM If there is no memmory to store new report description 161 * 162 */ 163 int usb_hid_report_append_fields(usb_hid_report_t *report, 164 usb_hid_report_item_t *report_item) { 165 118 166 usb_hid_report_field_t *field; 119 167 int i; … … 121 169 uint32_t *usages; 122 170 int usages_used=0; 171 172 if((report == NULL) || (report_item == NULL)) { 173 return EINVAL; 174 } 175 123 176 if(report_item->usages_count > 0){ 124 177 usages = malloc(sizeof(int32_t) * report_item->usages_count); 125 memcpy(usages, report_item->usages, sizeof(int32_t) * report_item->usages_count); 178 memcpy(usages, report_item->usages, sizeof(int32_t) * 179 report_item->usages_count); 126 180 } 127 181 else { … … 144 198 if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0){ 145 199 /* 146 Store usage array. The Correct Usage Page and Usage is depending147 200 Store usage array. The Correct Usage Page and Usage is 201 depending on data in report and will be filled later 148 202 */ 149 203 field->usage = 0; … … 162 216 } 163 217 else { 164 usage = report_item->usages[report_item->usages_count - 1]; 218 usage = report_item->usages[ 219 report_item->usages_count- 1]; 165 220 } 166 221 167 222 if(USB_HID_IS_EXTENDED_USAGE(usage)){ 168 223 field->usage = USB_HID_EXTENDED_USAGE(usage); 169 field->usage_page = USB_HID_EXTENDED_USAGE_PAGE(usage); 224 field->usage_page = 225 USB_HID_EXTENDED_USAGE_PAGE(usage); 170 226 } 171 227 else { … … 176 232 } 177 233 178 usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_GLOBAL, field->usage_page); 179 usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_LOCAL, field->usage); 180 181 field->collection_path = usb_hid_report_path_try_insert(report, path); 234 usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_GLOBAL, 235 field->usage_page); 236 usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_LOCAL, 237 field->usage); 238 239 field->collection_path = 240 usb_hid_report_path_try_insert(report, path); 182 241 183 242 field->size = report_item->size; 184 243 185 size_t offset_byte = (report_item->offset + (i * report_item->size)) / 8; 186 size_t offset_bit = 8 - ((report_item->offset + (i * report_item->size)) % 8) - report_item->size; 244 size_t offset_byte = (report_item->offset + (i * 245 report_item->size)) / 8; 246 247 size_t offset_bit = 8 - ((report_item->offset + (i * 248 report_item->size)) % 8) - report_item->size; 187 249 188 250 field->offset = 8 * offset_byte + offset_bit; … … 195 257 /* find the right report list*/ 196 258 usb_hid_report_description_t *report_des; 197 report_des = usb_hid_report_find_description(report, report_item->id, report_item->type); 259 report_des = usb_hid_report_find_description(report, 260 report_item->id, report_item->type); 261 198 262 if(report_des == NULL){ 199 report_des = malloc(sizeof(usb_hid_report_description_t)); 200 memset(report_des, 0, sizeof(usb_hid_report_description_t)); 263 report_des = malloc( 264 sizeof(usb_hid_report_description_t)); 265 if(report_des == NULL) { 266 return ENOMEM; 267 } 268 269 memset(report_des, 0, 270 sizeof(usb_hid_report_description_t)); 201 271 202 272 report_des->type = report_item->type; 203 273 report_des->report_id = report_item->id; 274 if(report_des->report_id != 0) { 275 /* set up the bit length by report_id field */ 276 report_des->bit_length = 8; 277 } 278 204 279 list_initialize (&report_des->link); 205 280 list_initialize (&report_des->report_items); … … 225 300 return EOK; 226 301 } 227 228 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) 229 { 302 /*---------------------------------------------------------------------------*/ 303 /** 304 * Finds description of report with given report_id and of given type in 305 * opaque report structure. 306 * 307 * @param report Opaque structure containing the parsed report descriptor 308 * @param report_id ReportId of report we are searching 309 * @param type Type of report we are searching 310 * @return Pointer to the particular report description 311 * @retval NULL If no description is founded 312 */ 313 usb_hid_report_description_t * usb_hid_report_find_description( 314 const usb_hid_report_t *report, uint8_t report_id, 315 usb_hid_report_type_t type) { 316 230 317 link_t *report_it = report->reports.next; 231 318 usb_hid_report_description_t *report_des = NULL; 232 319 233 320 while(report_it != &report->reports) { 234 report_des = list_get_instance(report_it, usb_hid_report_description_t, link); 235 236 if((report_des->report_id == report_id) && (report_des->type == type)){ 321 report_des = list_get_instance(report_it, 322 usb_hid_report_description_t, link); 323 324 if((report_des->report_id == report_id) && 325 (report_des->type == type)) { 237 326 return report_des; 238 327 } … … 243 332 return NULL; 244 333 } 334 /*---------------------------------------------------------------------------*/ 245 335 246 336 /** Parse HID report descriptor. … … 249 339 * @param data Data describing the report. 250 340 * @return Error code. 341 * @retval ENOMEM If no more memmory is available 342 * @retval EINVAL If invalid data are founded 343 * @retval EOK If report descriptor is successfully parsed 251 344 */ 252 345 int usb_hid_parse_report_descriptor(usb_hid_report_t *report, … … 299 392 300 393 ret = usb_hid_report_parse_tag(tag,class,data+i+1, 301 item_size,report_item, usage_path); 394 item_size,report_item, usage_path); 395 302 396 switch(ret){ 303 case USB_HID_NEW_REPORT_ITEM: 304 // store report item to report and create the new one 305 // store current collection path 306 report_item->usage_path = usage_path; 397 case USB_HID_NEW_REPORT_ITEM: 398 /* store report item to report and create the 399 * new one store current collection path 400 */ 401 report_item->usage_path = usage_path; 307 402 308 usb_hid_report_path_set_report_id(report_item->usage_path, report_item->id); 309 if(report_item->id != 0){ 310 report->use_report_ids = 1; 311 } 403 usb_hid_report_path_set_report_id( 404 report_item->usage_path, report_item->id); 405 406 if(report_item->id != 0){ 407 report->use_report_ids = 1; 408 } 312 409 313 switch(tag) { 314 case USB_HID_REPORT_TAG_INPUT: 315 report_item->type = USB_HID_REPORT_TYPE_INPUT; 316 report_item->offset = offset_input; 317 offset_input += report_item->count * report_item->size; 318 break; 319 case USB_HID_REPORT_TAG_OUTPUT: 320 report_item->type = USB_HID_REPORT_TYPE_OUTPUT; 321 report_item->offset = offset_output; 322 offset_output += report_item->count * report_item->size; 323 324 break; 325 case USB_HID_REPORT_TAG_FEATURE: 326 report_item->type = USB_HID_REPORT_TYPE_FEATURE; 327 report_item->offset = offset_feature; 328 offset_feature += report_item->count * report_item->size; 329 break; 330 default: 331 usb_log_debug("\tjump over - tag %X\n", tag); 332 break; 333 } 410 switch(tag) { 411 case USB_HID_REPORT_TAG_INPUT: 412 report_item->type = 413 USB_HID_REPORT_TYPE_INPUT; 414 415 report_item->offset = offset_input; 416 offset_input += report_item->count * 417 report_item->size; 418 break; 419 420 case USB_HID_REPORT_TAG_OUTPUT: 421 report_item->type = 422 USB_HID_REPORT_TYPE_OUTPUT; 334 423 335 /* 336 * append new fields to the report 337 * structure 338 */ 339 usb_hid_report_append_fields(report, report_item); 340 341 /* reset local items */ 342 usb_hid_report_reset_local_items (report_item); 343 424 report_item->offset = offset_output; 425 offset_output += report_item->count * 426 report_item->size; 344 427 break; 345 346 case USB_HID_RESET_OFFSET: 347 offset_input = 0; 348 offset_output = 0; 349 offset_feature = 0; 350 usb_hid_report_path_set_report_id (usage_path, report_item->id); 428 429 case USB_HID_REPORT_TAG_FEATURE: 430 report_item->type = 431 USB_HID_REPORT_TYPE_FEATURE; 432 433 report_item->offset = offset_feature; 434 offset_feature += report_item->count * 435 report_item->size; 351 436 break; 352 353 case USB_HID_REPORT_TAG_PUSH: 354 // push current state to stack 355 new_report_item = usb_hid_report_item_clone(report_item); 356 usb_hid_report_path_t *tmp_path = usb_hid_report_path_clone(usage_path); 357 new_report_item->usage_path = tmp_path; 358 359 list_prepend (&new_report_item->link, &stack); 360 break; 361 case USB_HID_REPORT_TAG_POP: 362 // restore current state from stack 363 if(list_empty (&stack)) { 364 return EINVAL; 365 } 366 free(report_item); 437 438 default: 439 usb_log_debug2( 440 "\tjump over - tag %X\n", tag); 441 break; 442 } 443 444 /* 445 * append new fields to the report structure 446 */ 447 usb_hid_report_append_fields(report, 448 report_item); 449 450 /* reset local items */ 451 usb_hid_report_reset_local_items (report_item); 452 break; 453 454 case USB_HID_RESET_OFFSET: 455 offset_input = 0; 456 offset_output = 0; 457 offset_feature = 0; 458 usb_hid_report_path_set_report_id (usage_path, 459 report_item->id); 460 break; 461 462 case USB_HID_REPORT_TAG_PUSH: 463 // push current state to stack 464 new_report_item = usb_hid_report_item_clone( 465 report_item); 466 467 usb_hid_report_path_t *tmp_path = 468 usb_hid_report_path_clone(usage_path); 469 470 new_report_item->usage_path = tmp_path; 471 472 list_prepend (&new_report_item->link, &stack); 473 break; 474 case USB_HID_REPORT_TAG_POP: 475 // restore current state from stack 476 if(list_empty (&stack)) { 477 return EINVAL; 478 } 479 free(report_item); 367 480 368 report_item = list_get_instance(stack.next, usb_hid_report_item_t, link); 481 report_item = list_get_instance(stack.next, 482 usb_hid_report_item_t, link); 369 483 370 usb_hid_report_usage_path_t *tmp_usage_path; 371 tmp_usage_path = list_get_instance(report_item->usage_path->link.prev, usb_hid_report_usage_path_t, link); 484 usb_hid_report_usage_path_t *tmp_usage_path; 485 tmp_usage_path = list_get_instance( 486 report_item->usage_path->link.prev, 487 usb_hid_report_usage_path_t, link); 372 488 373 usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL, tmp_usage_path->usage_page); 374 usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL, tmp_usage_path->usage); 375 376 usb_hid_report_path_free(report_item->usage_path); 377 list_initialize(&report_item->usage_path->link); 378 list_remove (stack.next); 489 usb_hid_report_set_last_item(usage_path, 490 USB_HID_TAG_CLASS_GLOBAL, tmp_usage_path->usage_page); 491 492 usb_hid_report_set_last_item(usage_path, 493 USB_HID_TAG_CLASS_LOCAL, tmp_usage_path->usage); 494 495 usb_hid_report_path_free(report_item->usage_path); 496 list_initialize(&report_item->usage_path->link); 497 list_remove (stack.next); 379 498 380 499 break; 381 500 382 383 384 501 default: 502 // nothing special to do 503 break; 385 504 } 386 505 … … 399 518 } 400 519 520 /*---------------------------------------------------------------------------*/ 401 521 402 522 /** … … 409 529 * @return Code of action to be done next 410 530 */ 411 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size, 412 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 413 { 531 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, 532 size_t item_size, usb_hid_report_item_t *report_item, 533 usb_hid_report_path_t *usage_path) { 534 414 535 int ret; 415 536 416 537 switch(class){ 417 case USB_HID_TAG_CLASS_MAIN: 418 419 if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item, usage_path)) == EOK) { 420 return USB_HID_NEW_REPORT_ITEM; 421 } 422 else { 423 /*TODO process the error */ 424 return ret; 425 } 426 break; 427 428 case USB_HID_TAG_CLASS_GLOBAL: 429 return usb_hid_report_parse_global_tag(tag,data,item_size,report_item, usage_path); 430 break; 431 432 case USB_HID_TAG_CLASS_LOCAL: 433 return usb_hid_report_parse_local_tag(tag,data,item_size,report_item, usage_path); 434 break; 435 default: 436 return USB_HID_NO_ACTION; 538 case USB_HID_TAG_CLASS_MAIN: 539 540 if((ret=usb_hid_report_parse_main_tag(tag, data, item_size, 541 report_item, usage_path)) == EOK) { 542 543 return USB_HID_NEW_REPORT_ITEM; 544 } 545 else { 546 return ret; 547 } 548 break; 549 550 case USB_HID_TAG_CLASS_GLOBAL: 551 return usb_hid_report_parse_global_tag(tag, data, item_size, 552 report_item, usage_path); 553 break; 554 555 case USB_HID_TAG_CLASS_LOCAL: 556 return usb_hid_report_parse_local_tag(tag, data, item_size, 557 report_item, usage_path); 558 break; 559 560 default: 561 return USB_HID_NO_ACTION; 437 562 } 438 563 } … … 448 573 */ 449 574 450 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size, 451 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 575 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, 576 size_t item_size, usb_hid_report_item_t *report_item, 577 usb_hid_report_path_t *usage_path) 452 578 { 453 579 usb_hid_report_usage_path_t *path_item; … … 455 581 switch(tag) 456 582 { 457 458 459 460 461 462 583 case USB_HID_REPORT_TAG_INPUT: 584 case USB_HID_REPORT_TAG_OUTPUT: 585 case USB_HID_REPORT_TAG_FEATURE: 586 report_item->item_flags = *data; 587 return EOK; 588 break; 463 589 464 case USB_HID_REPORT_TAG_COLLECTION: 465 466 // store collection atributes 467 path_item = list_get_instance(usage_path->head.prev, usb_hid_report_usage_path_t, link); 468 path_item->flags = *data; 590 case USB_HID_REPORT_TAG_COLLECTION: 591 592 /* store collection atributes */ 593 path_item = list_get_instance(usage_path->head.prev, 594 usb_hid_report_usage_path_t, link); 595 path_item->flags = *data; 469 596 470 // set last item 471 usb_hid_report_set_last_item(usage_path, 472 USB_HID_TAG_CLASS_GLOBAL, 473 USB_HID_EXTENDED_USAGE_PAGE(report_item->usages[report_item->usages_count-1])); 474 usb_hid_report_set_last_item(usage_path, 475 USB_HID_TAG_CLASS_LOCAL, 476 USB_HID_EXTENDED_USAGE(report_item->usages[report_item->usages_count-1])); 597 /* set last item */ 598 usb_hid_report_set_last_item(usage_path, 599 USB_HID_TAG_CLASS_GLOBAL, 600 USB_HID_EXTENDED_USAGE_PAGE(report_item->usages[ 601 report_item->usages_count-1])); 602 603 usb_hid_report_set_last_item(usage_path, 604 USB_HID_TAG_CLASS_LOCAL, 605 USB_HID_EXTENDED_USAGE(report_item->usages[ 606 report_item->usages_count-1])); 477 607 478 // append the new one which will be set by common 479 // usage/usage page 480 usb_hid_report_path_append_item(usage_path, report_item->usage_page, report_item->usages[report_item->usages_count-1]); 481 usb_hid_report_reset_local_items (report_item); 482 return USB_HID_NO_ACTION; 483 break; 608 /* append the new one which will be set by common usage/usage 609 * page */ 610 usb_hid_report_path_append_item(usage_path, 611 report_item->usage_page, 612 report_item->usages[report_item->usages_count-1]); 613 614 usb_hid_report_reset_local_items (report_item); 615 return USB_HID_NO_ACTION; 616 break; 484 617 485 case USB_HID_REPORT_TAG_END_COLLECTION: 486 usb_hid_report_remove_last_item(usage_path); 487 return USB_HID_NO_ACTION; 488 break; 489 default: 490 return USB_HID_NO_ACTION; 618 case USB_HID_REPORT_TAG_END_COLLECTION: 619 usb_hid_report_remove_last_item(usage_path); 620 return USB_HID_NO_ACTION; 621 break; 622 623 default: 624 return USB_HID_NO_ACTION; 491 625 } 492 626 … … 503 637 * @return Error code 504 638 */ 505 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size,506 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 507 { 508 // TODO take care about the bit length of data639 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, 640 size_t item_size, usb_hid_report_item_t *report_item, 641 usb_hid_report_path_t *usage_path) { 642 509 643 switch(tag) 510 644 { 511 case USB_HID_REPORT_TAG_USAGE_PAGE: 512 report_item->usage_page = usb_hid_report_tag_data_uint32(data, item_size); 513 break; 514 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM: 515 report_item->logical_minimum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8); 516 break; 517 case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM: 518 report_item->logical_maximum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8); 519 break; 520 case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM: 521 report_item->physical_minimum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8); 522 break; 523 case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM: 524 report_item->physical_maximum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8); 525 526 break; 527 case USB_HID_REPORT_TAG_UNIT_EXPONENT: 528 report_item->unit_exponent = usb_hid_report_tag_data_uint32(data,item_size); 529 break; 530 case USB_HID_REPORT_TAG_UNIT: 531 report_item->unit = usb_hid_report_tag_data_uint32(data,item_size); 532 break; 533 case USB_HID_REPORT_TAG_REPORT_SIZE: 534 report_item->size = usb_hid_report_tag_data_uint32(data,item_size); 535 break; 536 case USB_HID_REPORT_TAG_REPORT_COUNT: 537 report_item->count = usb_hid_report_tag_data_uint32(data,item_size); 538 break; 539 case USB_HID_REPORT_TAG_REPORT_ID: 540 report_item->id = usb_hid_report_tag_data_uint32(data,item_size); 541 return USB_HID_RESET_OFFSET; 542 break; 543 case USB_HID_REPORT_TAG_PUSH: 544 case USB_HID_REPORT_TAG_POP: 545 /* 546 * stack operations are done in top level parsing 547 * function 548 */ 549 return tag; 550 break; 645 case USB_HID_REPORT_TAG_USAGE_PAGE: 646 report_item->usage_page = 647 usb_hid_report_tag_data_uint32(data, item_size); 648 break; 649 650 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM: 651 report_item->logical_minimum = USB_HID_UINT32_TO_INT32( 652 usb_hid_report_tag_data_uint32(data,item_size), 653 item_size * 8); 654 break; 655 656 case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM: 657 report_item->logical_maximum = USB_HID_UINT32_TO_INT32( 658 usb_hid_report_tag_data_uint32(data,item_size), 659 item_size * 8); 660 break; 661 662 case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM: 663 report_item->physical_minimum = USB_HID_UINT32_TO_INT32( 664 usb_hid_report_tag_data_uint32(data,item_size), 665 item_size * 8); 666 break; 667 668 case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM: 669 report_item->physical_maximum = USB_HID_UINT32_TO_INT32( 670 usb_hid_report_tag_data_uint32(data,item_size), 671 item_size * 8); 672 break; 673 674 case USB_HID_REPORT_TAG_UNIT_EXPONENT: 675 report_item->unit_exponent = usb_hid_report_tag_data_uint32( 676 data,item_size); 677 break; 678 679 case USB_HID_REPORT_TAG_UNIT: 680 report_item->unit = usb_hid_report_tag_data_uint32( 681 data,item_size); 682 break; 683 684 case USB_HID_REPORT_TAG_REPORT_SIZE: 685 report_item->size = usb_hid_report_tag_data_uint32( 686 data,item_size); 687 break; 688 689 case USB_HID_REPORT_TAG_REPORT_COUNT: 690 report_item->count = usb_hid_report_tag_data_uint32( 691 data,item_size); 692 break; 693 694 case USB_HID_REPORT_TAG_REPORT_ID: 695 report_item->id = usb_hid_report_tag_data_uint32(data, 696 item_size); 697 return USB_HID_RESET_OFFSET; 698 break; 699 700 case USB_HID_REPORT_TAG_PUSH: 701 case USB_HID_REPORT_TAG_POP: 702 /* 703 * stack operations are done in top level parsing 704 * function 705 */ 706 return tag; 707 break; 551 708 552 553 709 default: 710 return USB_HID_NO_ACTION; 554 711 } 555 712 … … 566 723 * @return Error code 567 724 */ 568 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size, 569 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 725 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, 726 size_t item_size, usb_hid_report_item_t *report_item, 727 usb_hid_report_path_t *usage_path) 570 728 { 571 729 int32_t extended_usage; 572 730 573 731 switch(tag) { 574 case USB_HID_REPORT_TAG_USAGE: 575 switch(report_item->in_delimiter) { 576 case INSIDE_DELIMITER_SET: 577 // nothing to do 578 break; 579 case START_DELIMITER_SET: 580 report_item->in_delimiter = INSIDE_DELIMITER_SET; 581 case OUTSIDE_DELIMITER_SET: 582 extended_usage = ((report_item->usage_page) << 16); 583 extended_usage += usb_hid_report_tag_data_uint32(data,item_size); 584 report_item->usages[report_item->usages_count] = extended_usage; 585 report_item->usages_count++; 586 break; 732 case USB_HID_REPORT_TAG_USAGE: 733 switch(report_item->in_delimiter) { 734 case INSIDE_DELIMITER_SET: 735 /* nothing to do 736 * we catch only the first one 737 */ 738 break; 739 740 case START_DELIMITER_SET: 741 report_item->in_delimiter = INSIDE_DELIMITER_SET; 742 case OUTSIDE_DELIMITER_SET: 743 extended_usage = ((report_item->usage_page) << 16); 744 extended_usage += usb_hid_report_tag_data_uint32( 745 data,item_size); 746 747 report_item->usages[report_item->usages_count] = 748 extended_usage; 749 750 report_item->usages_count++; 751 break; 752 } 753 break; 754 755 case USB_HID_REPORT_TAG_USAGE_MINIMUM: 756 if (item_size == 3) { 757 // usage extended usages 758 report_item->extended_usage_page = 759 USB_HID_EXTENDED_USAGE_PAGE( 760 usb_hid_report_tag_data_uint32(data,item_size)); 761 762 763 report_item->usage_minimum = 764 USB_HID_EXTENDED_USAGE( 765 usb_hid_report_tag_data_uint32(data,item_size)); 766 } 767 else { 768 report_item->usage_minimum = 769 usb_hid_report_tag_data_uint32(data,item_size); 770 } 771 break; 772 773 case USB_HID_REPORT_TAG_USAGE_MAXIMUM: 774 if (item_size == 3) { 775 if(report_item->extended_usage_page != 776 USB_HID_EXTENDED_USAGE_PAGE( 777 usb_hid_report_tag_data_uint32(data,item_size))) { 778 779 return EINVAL; 587 780 } 588 break; 589 case USB_HID_REPORT_TAG_USAGE_MINIMUM: 590 if (item_size == 3) { 591 // usage extended usages 592 report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16; 593 report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size) & 0xFF; 781 782 // usage extended usages 783 report_item->extended_usage_page = 784 USB_HID_EXTENDED_USAGE_PAGE( 785 usb_hid_report_tag_data_uint32(data,item_size)); 786 787 report_item->usage_maximum = 788 USB_HID_EXTENDED_USAGE( 789 usb_hid_report_tag_data_uint32(data,item_size)); 790 } 791 else { 792 report_item->usage_maximum = 793 usb_hid_report_tag_data_uint32(data,item_size); 794 } 795 796 // vlozit zaznamy do pole usages 797 int32_t i; 798 for(i = report_item->usage_minimum; 799 i <= report_item->usage_maximum; i++) { 800 801 if(report_item->extended_usage_page) { 802 report_item->usages[report_item->usages_count++] = 803 (report_item->extended_usage_page << 16) + i; 594 804 } 595 else { 596 report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size); 805 else { 806 report_item->usages[report_item->usages_count++] = 807 (report_item->usage_page << 16) + i; 597 808 } 598 break; 599 case USB_HID_REPORT_TAG_USAGE_MAXIMUM: 600 if (item_size == 3) { 601 602 if(report_item->extended_usage_page != ((usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16)) { 603 return EINVAL; 604 } 605 606 // usage extended usages 607 report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16; 608 report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size) & 0xFF; 609 } 610 else { 611 report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size); 612 } 613 614 // vlozit zaznamy do pole usages 615 int32_t i; 616 for(i=report_item->usage_minimum; i<=report_item->usage_maximum; i++) { 617 if(report_item->extended_usage_page) { 618 report_item->usages[report_item->usages_count++] = (report_item->extended_usage_page << 16) + i; 619 } 620 else { 621 622 report_item->usages[report_item->usages_count++] = (report_item->usage_page << 16) + i; 623 } 624 } 625 report_item->extended_usage_page = 0; 809 } 810 report_item->extended_usage_page = 0; 626 811 627 break; 628 case USB_HID_REPORT_TAG_DESIGNATOR_INDEX: 629 report_item->designator_index = usb_hid_report_tag_data_uint32(data,item_size); 630 break; 631 case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM: 632 report_item->designator_minimum = usb_hid_report_tag_data_uint32(data,item_size); 633 break; 634 case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM: 635 report_item->designator_maximum = usb_hid_report_tag_data_uint32(data,item_size); 636 break; 637 case USB_HID_REPORT_TAG_STRING_INDEX: 638 report_item->string_index = usb_hid_report_tag_data_uint32(data,item_size); 639 break; 640 case USB_HID_REPORT_TAG_STRING_MINIMUM: 641 report_item->string_minimum = usb_hid_report_tag_data_uint32(data,item_size); 642 break; 643 case USB_HID_REPORT_TAG_STRING_MAXIMUM: 644 report_item->string_maximum = usb_hid_report_tag_data_uint32(data,item_size); 645 break; 646 case USB_HID_REPORT_TAG_DELIMITER: 647 report_item->in_delimiter = usb_hid_report_tag_data_uint32(data,item_size); 648 break; 649 650 default: 651 return USB_HID_NO_ACTION; 812 break; 813 814 case USB_HID_REPORT_TAG_DESIGNATOR_INDEX: 815 report_item->designator_index = 816 usb_hid_report_tag_data_uint32(data,item_size); 817 break; 818 819 case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM: 820 report_item->designator_minimum = 821 usb_hid_report_tag_data_uint32(data,item_size); 822 break; 823 824 case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM: 825 report_item->designator_maximum = 826 usb_hid_report_tag_data_uint32(data,item_size); 827 break; 828 829 case USB_HID_REPORT_TAG_STRING_INDEX: 830 report_item->string_index = 831 usb_hid_report_tag_data_uint32(data,item_size); 832 break; 833 834 case USB_HID_REPORT_TAG_STRING_MINIMUM: 835 report_item->string_minimum = 836 usb_hid_report_tag_data_uint32(data,item_size); 837 break; 838 839 case USB_HID_REPORT_TAG_STRING_MAXIMUM: 840 report_item->string_maximum = 841 usb_hid_report_tag_data_uint32(data,item_size); 842 break; 843 844 case USB_HID_REPORT_TAG_DELIMITER: 845 report_item->in_delimiter = 846 usb_hid_report_tag_data_uint32(data,item_size); 847 break; 848 849 default: 850 return USB_HID_NO_ACTION; 652 851 } 653 852 654 853 return EOK; 655 854 } 855 /*---------------------------------------------------------------------------*/ 656 856 657 857 /** … … 674 874 return result; 675 875 } 876 /*---------------------------------------------------------------------------*/ 676 877 677 878 /** … … 694 895 for(item = head->next; item != head; item = item->next) { 695 896 696 report_item = list_get_instance(item, usb_hid_report_field_t, link); 897 report_item = list_get_instance(item, usb_hid_report_field_t, 898 link); 697 899 698 900 usb_log_debug("\t\tOFFSET: %X\n", report_item->offset); 699 usb_log_debug("\t\tSIZE: %zu\n", report_item->size); 700 usb_log_debug("\t\tLOGMIN: %d\n", report_item->logical_minimum); 701 usb_log_debug("\t\tLOGMAX: %d\n", report_item->logical_maximum); 702 usb_log_debug("\t\tPHYMIN: %d\n", report_item->physical_minimum); 703 usb_log_debug("\t\tPHYMAX: %d\n", report_item->physical_maximum); 704 usb_log_debug("\t\ttUSAGEMIN: %X\n", report_item->usage_minimum); 705 usb_log_debug("\t\tUSAGEMAX: %X\n", report_item->usage_maximum); 706 usb_log_debug("\t\tUSAGES COUNT: %zu\n", report_item->usages_count); 901 usb_log_debug("\t\tSIZE: %zu\n", report_item->size); 902 usb_log_debug("\t\tLOGMIN: %d\n", 903 report_item->logical_minimum); 904 usb_log_debug("\t\tLOGMAX: %d\n", 905 report_item->logical_maximum); 906 usb_log_debug("\t\tPHYMIN: %d\n", 907 report_item->physical_minimum); 908 usb_log_debug("\t\tPHYMAX: %d\n", 909 report_item->physical_maximum); 910 usb_log_debug("\t\ttUSAGEMIN: %X\n", 911 report_item->usage_minimum); 912 usb_log_debug("\t\tUSAGEMAX: %X\n", 913 report_item->usage_maximum); 914 usb_log_debug("\t\tUSAGES COUNT: %zu\n", 915 report_item->usages_count); 707 916 708 917 usb_log_debug("\t\tVALUE: %X\n", report_item->value); … … 716 925 } 717 926 718 719 } 927 } 928 /*---------------------------------------------------------------------------*/ 929 720 930 /** 721 931 * Prints content of given report descriptor in human readable format. … … 734 944 735 945 while(report_it != &report->reports) { 736 report_des = list_get_instance(report_it, usb_hid_report_description_t, link); 946 report_des = list_get_instance(report_it, 947 usb_hid_report_description_t, link); 737 948 usb_log_debug("Report ID: %d\n", report_des->report_id); 738 949 usb_log_debug("\tType: %d\n", report_des->type); 739 950 usb_log_debug("\tLength: %zu\n", report_des->bit_length); 951 usb_log_debug("\tB Size: %zu\n", 952 usb_hid_report_byte_size(report, 953 report_des->report_id, 954 report_des->type)); 740 955 usb_log_debug("\tItems: %zu\n", report_des->item_length); 741 956 742 957 usb_hid_descriptor_print_list(&report_des->report_items); 743 958 744 /*745 link_t *path_it = report->collection_paths.next;746 while(path_it != &report->collection_paths) {747 usb_hid_print_usage_path (list_get_instance(path_it, usb_hid_report_path_t, link));748 path_it = path_it->next;749 }750 */751 959 report_it = report_it->next; 752 960 } 753 961 } 962 /*---------------------------------------------------------------------------*/ 754 963 755 964 /** … … 776 985 777 986 while(!list_empty(&report_item->usage_path->link)) { 778 987 usb_hid_report_remove_last_item(report_item->usage_path); 779 988 } 780 989 … … 788 997 789 998 } 999 /*---------------------------------------------------------------------------*/ 790 1000 791 1001 /** Frees the HID report descriptor parser structure … … 803 1013 usb_hid_report_path_t *path; 804 1014 while(!list_empty(&report->collection_paths)) { 805 path = list_get_instance(report->collection_paths.next, usb_hid_report_path_t, link); 1015 path = list_get_instance(report->collection_paths.next, 1016 usb_hid_report_path_t, link); 1017 806 1018 usb_hid_report_path_free(path); 807 1019 } … … 811 1023 usb_hid_report_field_t *field; 812 1024 while(!list_empty(&report->reports)) { 813 report_des = list_get_instance(report->reports.next, usb_hid_report_description_t, link); 1025 report_des = list_get_instance(report->reports.next, 1026 usb_hid_report_description_t, link); 1027 814 1028 list_remove(&report_des->link); 815 1029 816 1030 while(!list_empty(&report_des->report_items)) { 817 field = list_get_instance(report_des->report_items.next, usb_hid_report_field_t, link); 1031 field = list_get_instance( 1032 report_des->report_items.next, 1033 usb_hid_report_field_t, link); 1034 818 1035 list_remove(&field->link); 819 1036 … … 826 1043 return; 827 1044 } 1045 /*---------------------------------------------------------------------------*/ 828 1046 829 1047 /**
Note:
See TracChangeset
for help on using the changeset viewer.