Changes in uspace/lib/usbhid/src/hiddescriptor.c [d861c22:160b75e] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhid/src/hiddescriptor.c
rd861c22 r160b75e 41 41 #include <assert.h> 42 42 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 */ 43 51 44 #define OUTSIDE_DELIMITER_SET 0 52 53 /**54 * First delimiter tag was read. The set of local items (usage) started.55 */56 45 #define START_DELIMITER_SET 1 57 58 /**59 * Parser is in the set of local items.60 */61 46 #define INSIDE_DELIMITER_SET 2 62 63 /*---------------------------------------------------------------------------*/64 47 65 48 /** The new report item flag. Used to determine when the item is completly … … 78 61 #define USB_HID_UNKNOWN_TAG -99 79 62 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 93 link_t *path_it = report->collection_paths.prev->next; 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; 94 67 usb_hid_report_path_t *path = NULL; 95 96 if((report == NULL) || (cmp_path == NULL)) {97 return NULL;98 }99 100 68 while(path_it != &report->collection_paths) { 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){ 69 path = list_get_instance(path_it, usb_hid_report_path_t, link); 70 71 if(usb_hid_report_compare_usage_path(path, cmp_path, USB_HID_PATH_COMPARE_STRICT) == EOK){ 106 72 break; 107 73 } … … 109 75 } 110 76 if(path_it == &report->collection_paths) { 111 path = usb_hid_report_path_clone(cmp_path); 112 if(path == NULL) { 113 return NULL; 114 } 77 path = usb_hid_report_path_clone(cmp_path); 115 78 list_append(&path->link, &report->collection_paths); 116 79 report->collection_paths_count++; … … 119 82 } 120 83 else { 121 return list_get_instance(path_it, usb_hid_report_path_t, 122 link); 123 } 124 } 125 126 /*---------------------------------------------------------------------------*/ 84 return list_get_instance(path_it, usb_hid_report_path_t, link); 85 } 86 } 87 127 88 /** 128 89 * Initialize the report descriptor parser structure … … 130 91 * @param parser Report descriptor parser structure 131 92 * @return Error code 132 * @retval EINVAL If no report structure was given133 * @retval EOK If report structure was successfully initialized134 93 */ 135 94 int usb_hid_report_init(usb_hid_report_t *report) … … 147 106 } 148 107 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 108 109 /* 110 * 111 * 112 */ 113 int usb_hid_report_append_fields(usb_hid_report_t *report, usb_hid_report_item_t *report_item) 114 { 166 115 usb_hid_report_field_t *field; 167 116 int i; 168 117 169 uint32_t *usages; 170 int usages_used=0; 171 172 if((report == NULL) || (report_item == NULL)) { 173 return EINVAL; 174 } 175 176 if(report_item->usages_count > 0){ 177 usages = malloc(sizeof(int32_t) * report_item->usages_count); 178 memcpy(usages, report_item->usages, sizeof(int32_t) * 179 report_item->usages_count); 180 } 181 else { 182 usages = NULL; 183 } 184 118 for(i=0; i<report_item->usages_count; i++){ 119 usb_log_debug("usages (%d) - %x\n", i, report_item->usages[i]); 120 } 121 185 122 usb_hid_report_path_t *path = report_item->usage_path; 186 123 for(i=0; i<report_item->count; i++){ … … 196 133 field->physical_maximum = report_item->physical_maximum; 197 134 198 if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0){ 199 /* 200 Store usage array. The Correct Usage Page and Usage is 201 depending on data in report and will be filled later 202 */ 203 field->usage = 0; 204 field->usage_page = 0; //report_item->usage_page; 205 206 field->usages_count = report_item->usages_count; 207 field->usages = usages; 208 usages_used = 1; 135 field->usage_minimum = report_item->usage_minimum; 136 field->usage_maximum = report_item->usage_maximum; 137 if(report_item->extended_usage_page != 0){ 138 field->usage_page = report_item->extended_usage_page; 209 139 } 210 140 else { 211 212 /* Fill the correct Usage and Usage Page */ 213 int32_t usage; 214 if(i < report_item->usages_count) { 141 field->usage_page = report_item->usage_page; 142 } 143 144 if(report_item->usages_count > 0 && ((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0))) { 145 uint32_t usage; 146 if(i < report_item->usages_count){ 215 147 usage = report_item->usages[i]; 216 148 } 217 149 else { 218 usage = report_item->usages[ 219 report_item->usages_count- 1]; 220 } 221 222 if(USB_HID_IS_EXTENDED_USAGE(usage)){ 223 field->usage = USB_HID_EXTENDED_USAGE(usage); 224 field->usage_page = 225 USB_HID_EXTENDED_USAGE_PAGE(usage); 150 usage = report_item->usages[report_item->usages_count - 1]; 151 } 152 153 154 if((usage & 0xFFFF0000) != 0){ 155 field->usage_page = (usage >> 16); 156 field->usage = (usage & 0xFFFF); 226 157 } 227 158 else { 228 // should not occur229 159 field->usage = usage; 230 field->usage_page = report_item->usage_page; 231 } 232 } 233 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); 160 } 161 162 163 } 164 165 if((USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) != 0) && (!((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0)))) { 166 field->usage = report_item->usage_minimum + i; 167 } 168 169 usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_GLOBAL, field->usage_page); 170 usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_LOCAL, field->usage); 171 172 field->collection_path = usb_hid_report_path_try_insert(report, path); 241 173 242 174 field->size = report_item->size; 243 175 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; 176 size_t offset_byte = (report_item->offset + (i * report_item->size)) / 8; 177 size_t offset_bit = 8 - ((report_item->offset + (i * report_item->size)) % 8) - report_item->size; 249 178 250 179 field->offset = 8 * offset_byte + offset_bit; … … 257 186 /* find the right report list*/ 258 187 usb_hid_report_description_t *report_des; 259 report_des = usb_hid_report_find_description(report, 260 report_item->id, report_item->type); 261 188 report_des = usb_hid_report_find_description(report, report_item->id, report_item->type); 262 189 if(report_des == NULL){ 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)); 190 report_des = malloc(sizeof(usb_hid_report_description_t)); 191 memset(report_des, 0, sizeof(usb_hid_report_description_t)); 271 192 272 193 report_des->type = report_item->type; … … 288 209 } 289 210 290 // free only when not used!!!291 if(usages && usages_used == 0) {292 free(usages);293 }294 211 295 212 return EOK; 296 213 } 297 /*---------------------------------------------------------------------------*/ 298 /** 299 * Finds description of report with given report_id and of given type in 300 * opaque report structure. 301 * 302 * @param report Opaque structure containing the parsed report descriptor 303 * @param report_id ReportId of report we are searching 304 * @param type Type of report we are searching 305 * @return Pointer to the particular report description 306 * @retval NULL If no description is founded 307 */ 308 usb_hid_report_description_t * usb_hid_report_find_description( 309 const usb_hid_report_t *report, uint8_t report_id, 310 usb_hid_report_type_t type) { 311 214 215 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) 216 { 312 217 link_t *report_it = report->reports.next; 313 218 usb_hid_report_description_t *report_des = NULL; 314 219 315 220 while(report_it != &report->reports) { 316 report_des = list_get_instance(report_it, 317 usb_hid_report_description_t, link); 318 319 if((report_des->report_id == report_id) && 320 (report_des->type == type)) { 221 report_des = list_get_instance(report_it, usb_hid_report_description_t, link); 222 223 if((report_des->report_id == report_id) && (report_des->type == type)){ 321 224 return report_des; 322 225 } … … 327 230 return NULL; 328 231 } 329 /*---------------------------------------------------------------------------*/330 232 331 233 /** Parse HID report descriptor. … … 334 236 * @param data Data describing the report. 335 237 * @return Error code. 336 * @retval ENOMEM If no more memmory is available337 * @retval EINVAL If invalid data are founded338 * @retval EOK If report descriptor is successfully parsed339 238 */ 340 239 int usb_hid_parse_report_descriptor(usb_hid_report_t *report, … … 387 286 388 287 ret = usb_hid_report_parse_tag(tag,class,data+i+1, 389 item_size,report_item, usage_path); 390 288 item_size,report_item, usage_path); 391 289 switch(ret){ 392 case USB_HID_NEW_REPORT_ITEM: 393 /* store report item to report and create the 394 * new one store current collection path 395 */ 396 report_item->usage_path = usage_path; 290 case USB_HID_NEW_REPORT_ITEM: 291 // store report item to report and create the new one 292 // store current collection path 293 report_item->usage_path = usage_path; 397 294 398 usb_hid_report_path_set_report_id( 399 report_item->usage_path, report_item->id); 400 401 if(report_item->id != 0){ 402 report->use_report_ids = 1; 403 } 295 usb_hid_report_path_set_report_id(report_item->usage_path, report_item->id); 296 if(report_item->id != 0){ 297 report->use_report_ids = 1; 298 } 404 299 405 switch(tag) { 406 case USB_HID_REPORT_TAG_INPUT: 407 report_item->type = 408 USB_HID_REPORT_TYPE_INPUT; 409 410 report_item->offset = offset_input; 411 offset_input += report_item->count * 412 report_item->size; 300 switch(tag) { 301 case USB_HID_REPORT_TAG_INPUT: 302 report_item->type = USB_HID_REPORT_TYPE_INPUT; 303 report_item->offset = offset_input; 304 offset_input += report_item->count * report_item->size; 305 break; 306 case USB_HID_REPORT_TAG_OUTPUT: 307 report_item->type = USB_HID_REPORT_TYPE_OUTPUT; 308 report_item->offset = offset_output; 309 offset_output += report_item->count * report_item->size; 310 311 break; 312 case USB_HID_REPORT_TAG_FEATURE: 313 report_item->type = USB_HID_REPORT_TYPE_FEATURE; 314 report_item->offset = offset_feature; 315 offset_feature += report_item->count * report_item->size; 316 break; 317 default: 318 usb_log_debug("\tjump over - tag %X\n", tag); 319 break; 320 } 321 322 /* 323 * append new fields to the report 324 * structure 325 */ 326 usb_hid_report_append_fields(report, report_item); 327 328 /* reset local items */ 329 usb_hid_report_reset_local_items (report_item); 330 413 331 break; 414 415 case USB_HID_REPORT_TAG_OUTPUT: 416 report_item->type = 417 USB_HID_REPORT_TYPE_OUTPUT; 332 333 case USB_HID_RESET_OFFSET: 334 offset_input = 0; 335 offset_output = 0; 336 offset_feature = 0; 337 usb_hid_report_path_set_report_id (usage_path, report_item->id); 338 break; 339 340 case USB_HID_REPORT_TAG_PUSH: 341 // push current state to stack 342 new_report_item = usb_hid_report_item_clone(report_item); 343 usb_hid_report_path_t *tmp_path = usb_hid_report_path_clone(usage_path); 344 new_report_item->usage_path = tmp_path; 345 346 list_prepend (&new_report_item->link, &stack); 347 break; 348 case USB_HID_REPORT_TAG_POP: 349 // restore current state from stack 350 if(list_empty (&stack)) { 351 return EINVAL; 352 } 353 free(report_item); 354 355 report_item = list_get_instance(stack.next, usb_hid_report_item_t, link); 418 356 419 report_item->offset = offset_output; 420 offset_output += report_item->count * 421 report_item->size; 357 usb_hid_report_usage_path_t *tmp_usage_path; 358 tmp_usage_path = list_get_instance(report_item->usage_path->link.prev, usb_hid_report_usage_path_t, link); 359 360 usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL, tmp_usage_path->usage_page); 361 usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL, tmp_usage_path->usage); 362 363 usb_hid_report_path_free(report_item->usage_path); 364 list_initialize(&report_item->usage_path->link); 365 list_remove (stack.next); 366 422 367 break; 423 424 case USB_HID_REPORT_TAG_FEATURE: 425 report_item->type = 426 USB_HID_REPORT_TYPE_FEATURE; 427 428 report_item->offset = offset_feature; 429 offset_feature += report_item->count * 430 report_item->size; 368 369 default: 370 // nothing special to do 431 371 break; 432 433 default:434 usb_log_debug2(435 "\tjump over - tag %X\n", tag);436 break;437 }438 439 /*440 * append new fields to the report structure441 */442 usb_hid_report_append_fields(report,443 report_item);444 445 /* reset local items */446 usb_hid_report_reset_local_items (report_item);447 break;448 449 case USB_HID_RESET_OFFSET:450 offset_input = 0;451 offset_output = 0;452 offset_feature = 0;453 usb_hid_report_path_set_report_id (usage_path,454 report_item->id);455 break;456 457 case USB_HID_REPORT_TAG_PUSH:458 // push current state to stack459 new_report_item = usb_hid_report_item_clone(460 report_item);461 462 usb_hid_report_path_t *tmp_path =463 usb_hid_report_path_clone(usage_path);464 465 new_report_item->usage_path = tmp_path;466 467 list_prepend (&new_report_item->link, &stack);468 break;469 case USB_HID_REPORT_TAG_POP:470 // restore current state from stack471 if(list_empty (&stack)) {472 return EINVAL;473 }474 free(report_item);475 476 report_item = list_get_instance(stack.next,477 usb_hid_report_item_t, link);478 479 usb_hid_report_usage_path_t *tmp_usage_path;480 tmp_usage_path = list_get_instance(481 report_item->usage_path->link.prev,482 usb_hid_report_usage_path_t, link);483 484 usb_hid_report_set_last_item(usage_path,485 USB_HID_TAG_CLASS_GLOBAL, tmp_usage_path->usage_page);486 487 usb_hid_report_set_last_item(usage_path,488 USB_HID_TAG_CLASS_LOCAL, tmp_usage_path->usage);489 490 usb_hid_report_path_free(report_item->usage_path);491 list_initialize(&report_item->usage_path->link);492 list_remove (stack.next);493 494 break;495 496 default:497 // nothing special to do498 break;499 372 } 500 373 … … 513 386 } 514 387 515 /*---------------------------------------------------------------------------*/516 388 517 389 /** … … 524 396 * @return Code of action to be done next 525 397 */ 526 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, 527 size_t item_size, usb_hid_report_item_t *report_item, 528 usb_hid_report_path_t *usage_path) { 529 398 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size, 399 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 400 { 530 401 int ret; 531 402 532 403 switch(class){ 533 case USB_HID_TAG_CLASS_MAIN: 534 535 if((ret=usb_hid_report_parse_main_tag(tag, data, item_size, 536 report_item, usage_path)) == EOK) { 537 538 return USB_HID_NEW_REPORT_ITEM; 539 } 540 else { 541 return ret; 542 } 543 break; 544 545 case USB_HID_TAG_CLASS_GLOBAL: 546 return usb_hid_report_parse_global_tag(tag, data, item_size, 547 report_item, usage_path); 548 break; 549 550 case USB_HID_TAG_CLASS_LOCAL: 551 return usb_hid_report_parse_local_tag(tag, data, item_size, 552 report_item, usage_path); 553 break; 554 555 default: 556 return USB_HID_NO_ACTION; 404 case USB_HID_TAG_CLASS_MAIN: 405 406 if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item, usage_path)) == EOK) { 407 return USB_HID_NEW_REPORT_ITEM; 408 } 409 else { 410 /*TODO process the error */ 411 return ret; 412 } 413 break; 414 415 case USB_HID_TAG_CLASS_GLOBAL: 416 return usb_hid_report_parse_global_tag(tag,data,item_size,report_item, usage_path); 417 break; 418 419 case USB_HID_TAG_CLASS_LOCAL: 420 return usb_hid_report_parse_local_tag(tag,data,item_size,report_item, usage_path); 421 break; 422 default: 423 return USB_HID_NO_ACTION; 557 424 } 558 425 } … … 568 435 */ 569 436 570 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, 571 size_t item_size, usb_hid_report_item_t *report_item, 572 usb_hid_report_path_t *usage_path) 437 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size, 438 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 573 439 { 574 440 usb_hid_report_usage_path_t *path_item; … … 576 442 switch(tag) 577 443 { 578 case USB_HID_REPORT_TAG_INPUT:579 case USB_HID_REPORT_TAG_OUTPUT:580 case USB_HID_REPORT_TAG_FEATURE:581 report_item->item_flags = *data;582 return EOK;583 break;444 case USB_HID_REPORT_TAG_INPUT: 445 case USB_HID_REPORT_TAG_OUTPUT: 446 case USB_HID_REPORT_TAG_FEATURE: 447 report_item->item_flags = *data; 448 return EOK; 449 break; 584 450 585 case USB_HID_REPORT_TAG_COLLECTION: 586 587 /* store collection atributes */ 588 path_item = list_get_instance(usage_path->head.prev, 589 usb_hid_report_usage_path_t, link); 590 path_item->flags = *data; 451 case USB_HID_REPORT_TAG_COLLECTION: 452 // store collection atributes 453 path_item = list_get_instance(usage_path->head.prev, usb_hid_report_usage_path_t, link); 454 path_item->flags = *data; 591 455 592 /* set last item */ 593 usb_hid_report_set_last_item(usage_path, 594 USB_HID_TAG_CLASS_GLOBAL, 595 USB_HID_EXTENDED_USAGE_PAGE(report_item->usages[ 596 report_item->usages_count-1])); 597 598 usb_hid_report_set_last_item(usage_path, 599 USB_HID_TAG_CLASS_LOCAL, 600 USB_HID_EXTENDED_USAGE(report_item->usages[ 601 report_item->usages_count-1])); 456 // set last item 457 usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL, report_item->usage_page); 458 usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL, report_item->usages[report_item->usages_count-1]); 602 459 603 /* append the new one which will be set by common usage/usage 604 * page */ 605 usb_hid_report_path_append_item(usage_path, 606 report_item->usage_page, 607 report_item->usages[report_item->usages_count-1]); 608 609 usb_hid_report_reset_local_items (report_item); 610 return USB_HID_NO_ACTION; 611 break; 460 // append the new one which will be set by common 461 // usage/usage page 462 usb_hid_report_path_append_item(usage_path, report_item->usage_page, report_item->usages[report_item->usages_count-1]); 463 usb_hid_report_reset_local_items (report_item); 464 return USB_HID_NO_ACTION; 465 break; 612 466 613 case USB_HID_REPORT_TAG_END_COLLECTION: 614 usb_hid_report_remove_last_item(usage_path); 615 return USB_HID_NO_ACTION; 616 break; 617 618 default: 619 return USB_HID_NO_ACTION; 467 case USB_HID_REPORT_TAG_END_COLLECTION: 468 usb_hid_report_remove_last_item(usage_path); 469 return USB_HID_NO_ACTION; 470 break; 471 default: 472 return USB_HID_NO_ACTION; 620 473 } 621 474 … … 632 485 * @return Error code 633 486 */ 634 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, 635 size_t item_size, usb_hid_report_item_t *report_item, 636 usb_hid_report_path_t *usage_path) { 637 487 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size, 488 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 489 { 490 // TODO take care about the bit length of data 638 491 switch(tag) 639 492 { 640 case USB_HID_REPORT_TAG_USAGE_PAGE: 641 report_item->usage_page = 642 usb_hid_report_tag_data_uint32(data, item_size); 643 break; 644 645 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM: 646 report_item->logical_minimum = USB_HID_UINT32_TO_INT32( 647 usb_hid_report_tag_data_uint32(data,item_size), 648 item_size * 8); 649 break; 650 651 case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM: 652 report_item->logical_maximum = USB_HID_UINT32_TO_INT32( 653 usb_hid_report_tag_data_uint32(data,item_size), 654 item_size * 8); 655 break; 656 657 case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM: 658 report_item->physical_minimum = USB_HID_UINT32_TO_INT32( 659 usb_hid_report_tag_data_uint32(data,item_size), 660 item_size * 8); 661 break; 662 663 case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM: 664 report_item->physical_maximum = USB_HID_UINT32_TO_INT32( 665 usb_hid_report_tag_data_uint32(data,item_size), 666 item_size * 8); 667 break; 668 669 case USB_HID_REPORT_TAG_UNIT_EXPONENT: 670 report_item->unit_exponent = usb_hid_report_tag_data_uint32( 671 data,item_size); 672 break; 673 674 case USB_HID_REPORT_TAG_UNIT: 675 report_item->unit = usb_hid_report_tag_data_uint32( 676 data,item_size); 677 break; 678 679 case USB_HID_REPORT_TAG_REPORT_SIZE: 680 report_item->size = usb_hid_report_tag_data_uint32( 681 data,item_size); 682 break; 683 684 case USB_HID_REPORT_TAG_REPORT_COUNT: 685 report_item->count = usb_hid_report_tag_data_uint32( 686 data,item_size); 687 break; 688 689 case USB_HID_REPORT_TAG_REPORT_ID: 690 report_item->id = usb_hid_report_tag_data_uint32(data, 691 item_size); 692 return USB_HID_RESET_OFFSET; 693 break; 694 695 case USB_HID_REPORT_TAG_PUSH: 696 case USB_HID_REPORT_TAG_POP: 697 /* 698 * stack operations are done in top level parsing 699 * function 700 */ 701 return tag; 702 break; 493 case USB_HID_REPORT_TAG_USAGE_PAGE: 494 report_item->usage_page = usb_hid_report_tag_data_uint32(data, item_size); 495 break; 496 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM: 497 report_item->logical_minimum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8); 498 break; 499 case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM: 500 report_item->logical_maximum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8); 501 break; 502 case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM: 503 report_item->physical_minimum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8); 504 break; 505 case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM: 506 report_item->physical_maximum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8); 507 508 break; 509 case USB_HID_REPORT_TAG_UNIT_EXPONENT: 510 report_item->unit_exponent = usb_hid_report_tag_data_uint32(data,item_size); 511 break; 512 case USB_HID_REPORT_TAG_UNIT: 513 report_item->unit = usb_hid_report_tag_data_uint32(data,item_size); 514 break; 515 case USB_HID_REPORT_TAG_REPORT_SIZE: 516 report_item->size = usb_hid_report_tag_data_uint32(data,item_size); 517 break; 518 case USB_HID_REPORT_TAG_REPORT_COUNT: 519 report_item->count = usb_hid_report_tag_data_uint32(data,item_size); 520 break; 521 case USB_HID_REPORT_TAG_REPORT_ID: 522 report_item->id = usb_hid_report_tag_data_uint32(data,item_size); 523 return USB_HID_RESET_OFFSET; 524 break; 525 case USB_HID_REPORT_TAG_PUSH: 526 case USB_HID_REPORT_TAG_POP: 527 /* 528 * stack operations are done in top level parsing 529 * function 530 */ 531 return tag; 532 break; 703 533 704 default:705 return USB_HID_NO_ACTION;534 default: 535 return USB_HID_NO_ACTION; 706 536 } 707 537 … … 718 548 * @return Error code 719 549 */ 720 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, 721 size_t item_size, usb_hid_report_item_t *report_item, 722 usb_hid_report_path_t *usage_path) 723 { 724 int32_t extended_usage; 725 550 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size, 551 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 552 { 726 553 switch(tag) { 727 case USB_HID_REPORT_TAG_USAGE: 728 switch(report_item->in_delimiter) { 729 case INSIDE_DELIMITER_SET: 730 /* nothing to do 731 * we catch only the first one 732 */ 733 break; 734 735 case START_DELIMITER_SET: 736 report_item->in_delimiter = INSIDE_DELIMITER_SET; 737 case OUTSIDE_DELIMITER_SET: 738 extended_usage = ((report_item->usage_page) << 16); 739 extended_usage += usb_hid_report_tag_data_uint32( 740 data,item_size); 741 742 report_item->usages[report_item->usages_count] = 743 extended_usage; 744 745 report_item->usages_count++; 746 break; 747 } 748 break; 749 750 case USB_HID_REPORT_TAG_USAGE_MINIMUM: 751 if (item_size == 3) { 752 // usage extended usages 753 report_item->extended_usage_page = 754 USB_HID_EXTENDED_USAGE_PAGE( 755 usb_hid_report_tag_data_uint32(data,item_size)); 756 757 758 report_item->usage_minimum = 759 USB_HID_EXTENDED_USAGE( 760 usb_hid_report_tag_data_uint32(data,item_size)); 761 } 762 else { 763 report_item->usage_minimum = 764 usb_hid_report_tag_data_uint32(data,item_size); 765 } 766 break; 767 768 case USB_HID_REPORT_TAG_USAGE_MAXIMUM: 769 if (item_size == 3) { 770 if(report_item->extended_usage_page != 771 USB_HID_EXTENDED_USAGE_PAGE( 772 usb_hid_report_tag_data_uint32(data,item_size))) { 773 774 return EINVAL; 775 } 776 777 // usage extended usages 778 report_item->extended_usage_page = 779 USB_HID_EXTENDED_USAGE_PAGE( 780 usb_hid_report_tag_data_uint32(data,item_size)); 781 782 report_item->usage_maximum = 783 USB_HID_EXTENDED_USAGE( 784 usb_hid_report_tag_data_uint32(data,item_size)); 785 } 786 else { 787 report_item->usage_maximum = 788 usb_hid_report_tag_data_uint32(data,item_size); 789 } 790 791 // vlozit zaznamy do pole usages 792 int32_t i; 793 for(i = report_item->usage_minimum; 794 i <= report_item->usage_maximum; i++) { 795 796 if(report_item->extended_usage_page) { 797 report_item->usages[report_item->usages_count++] = 798 (report_item->extended_usage_page << 16) + i; 799 } 800 else { 801 report_item->usages[report_item->usages_count++] = 802 (report_item->usage_page << 16) + i; 803 } 804 } 805 report_item->extended_usage_page = 0; 806 807 break; 808 809 case USB_HID_REPORT_TAG_DESIGNATOR_INDEX: 810 report_item->designator_index = 811 usb_hid_report_tag_data_uint32(data,item_size); 812 break; 813 814 case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM: 815 report_item->designator_minimum = 816 usb_hid_report_tag_data_uint32(data,item_size); 817 break; 818 819 case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM: 820 report_item->designator_maximum = 821 usb_hid_report_tag_data_uint32(data,item_size); 822 break; 823 824 case USB_HID_REPORT_TAG_STRING_INDEX: 825 report_item->string_index = 826 usb_hid_report_tag_data_uint32(data,item_size); 827 break; 828 829 case USB_HID_REPORT_TAG_STRING_MINIMUM: 830 report_item->string_minimum = 831 usb_hid_report_tag_data_uint32(data,item_size); 832 break; 833 834 case USB_HID_REPORT_TAG_STRING_MAXIMUM: 835 report_item->string_maximum = 836 usb_hid_report_tag_data_uint32(data,item_size); 837 break; 838 839 case USB_HID_REPORT_TAG_DELIMITER: 840 report_item->in_delimiter = 841 usb_hid_report_tag_data_uint32(data,item_size); 842 break; 843 844 default: 845 return USB_HID_NO_ACTION; 554 case USB_HID_REPORT_TAG_USAGE: 555 switch(report_item->in_delimiter) { 556 case INSIDE_DELIMITER_SET: 557 // nothing to do 558 break; 559 case START_DELIMITER_SET: 560 report_item->in_delimiter = INSIDE_DELIMITER_SET; 561 case OUTSIDE_DELIMITER_SET: 562 report_item->usages[report_item->usages_count] = usb_hid_report_tag_data_uint32(data,item_size); 563 report_item->usages_count++; 564 break; 565 } 566 break; 567 case USB_HID_REPORT_TAG_USAGE_MINIMUM: 568 if (item_size == 3) { 569 // usage extended usages 570 report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16; 571 report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size) & 0xFF; 572 } 573 else { 574 report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size); 575 } 576 break; 577 case USB_HID_REPORT_TAG_USAGE_MAXIMUM: 578 if (item_size == 3) { 579 // usage extended usages 580 report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16; 581 report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size) & 0xFF; 582 } 583 else { 584 report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size); 585 } 586 break; 587 case USB_HID_REPORT_TAG_DESIGNATOR_INDEX: 588 report_item->designator_index = usb_hid_report_tag_data_uint32(data,item_size); 589 break; 590 case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM: 591 report_item->designator_minimum = usb_hid_report_tag_data_uint32(data,item_size); 592 break; 593 case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM: 594 report_item->designator_maximum = usb_hid_report_tag_data_uint32(data,item_size); 595 break; 596 case USB_HID_REPORT_TAG_STRING_INDEX: 597 report_item->string_index = usb_hid_report_tag_data_uint32(data,item_size); 598 break; 599 case USB_HID_REPORT_TAG_STRING_MINIMUM: 600 report_item->string_minimum = usb_hid_report_tag_data_uint32(data,item_size); 601 break; 602 case USB_HID_REPORT_TAG_STRING_MAXIMUM: 603 report_item->string_maximum = usb_hid_report_tag_data_uint32(data,item_size); 604 break; 605 case USB_HID_REPORT_TAG_DELIMITER: 606 report_item->in_delimiter = usb_hid_report_tag_data_uint32(data,item_size); 607 break; 608 609 default: 610 return USB_HID_NO_ACTION; 846 611 } 847 612 848 613 return EOK; 849 614 } 850 /*---------------------------------------------------------------------------*/851 615 852 616 /** … … 869 633 return result; 870 634 } 871 /*---------------------------------------------------------------------------*/872 635 873 636 /** … … 890 653 for(item = head->next; item != head; item = item->next) { 891 654 892 report_item = list_get_instance(item, usb_hid_report_field_t, 893 link); 655 report_item = list_get_instance(item, usb_hid_report_field_t, link); 894 656 895 657 usb_log_debug("\t\tOFFSET: %X\n", report_item->offset); 896 usb_log_debug("\t\tSIZE: %zu\n", report_item->size); 897 usb_log_debug("\t\tLOGMIN: %d\n", 898 report_item->logical_minimum); 899 usb_log_debug("\t\tLOGMAX: %d\n", 900 report_item->logical_maximum); 901 usb_log_debug("\t\tPHYMIN: %d\n", 902 report_item->physical_minimum); 903 usb_log_debug("\t\tPHYMAX: %d\n", 904 report_item->physical_maximum); 905 usb_log_debug("\t\ttUSAGEMIN: %X\n", 906 report_item->usage_minimum); 907 usb_log_debug("\t\tUSAGEMAX: %X\n", 908 report_item->usage_maximum); 909 usb_log_debug("\t\tUSAGES COUNT: %zu\n", 910 report_item->usages_count); 658 usb_log_debug("\t\tSIZE: %zu\n", report_item->size); 659 usb_log_debug("\t\tLOGMIN: %d\n", report_item->logical_minimum); 660 usb_log_debug("\t\tLOGMAX: %d\n", report_item->logical_maximum); 661 usb_log_debug("\t\tPHYMIN: %d\n", report_item->physical_minimum); 662 usb_log_debug("\t\tPHYMAX: %d\n", report_item->physical_maximum); 663 usb_log_debug("\t\ttUSAGEMIN: %X\n", report_item->usage_minimum); 664 usb_log_debug("\t\tUSAGEMAX: %X\n", report_item->usage_maximum); 911 665 912 666 usb_log_debug("\t\tVALUE: %X\n", report_item->value); … … 914 668 usb_log_debug("\t\tUSAGE PAGE: %X\n", report_item->usage_page); 915 669 916 usb_hid_print_usage_path(report_item->collection_path);670 //usb_hid_print_usage_path(report_item->collection_path); 917 671 918 672 usb_log_debug("\n"); … … 920 674 } 921 675 922 } 923 /*---------------------------------------------------------------------------*/ 924 676 677 } 925 678 /** 926 679 * Prints content of given report descriptor in human readable format. … … 939 692 940 693 while(report_it != &report->reports) { 941 report_des = list_get_instance(report_it, 942 usb_hid_report_description_t, link); 694 report_des = list_get_instance(report_it, usb_hid_report_description_t, link); 943 695 usb_log_debug("Report ID: %d\n", report_des->report_id); 944 696 usb_log_debug("\tType: %d\n", report_des->type); 945 697 usb_log_debug("\tLength: %zu\n", report_des->bit_length); 946 usb_log_debug("\tB Size: %zu\n",947 usb_hid_report_byte_size(report,948 report_des->report_id,949 report_des->type));950 698 usb_log_debug("\tItems: %zu\n", report_des->item_length); 951 699 952 700 usb_hid_descriptor_print_list(&report_des->report_items); 953 701 702 703 link_t *path_it = report->collection_paths.next; 704 while(path_it != &report->collection_paths) { 705 usb_hid_print_usage_path (list_get_instance(path_it, usb_hid_report_path_t, link)); 706 path_it = path_it->next; 707 } 708 954 709 report_it = report_it->next; 955 710 } 956 711 } 957 /*---------------------------------------------------------------------------*/958 712 959 713 /** … … 980 734 981 735 while(!list_empty(&report_item->usage_path->link)) { 982 736 usb_hid_report_remove_last_item(report_item->usage_path); 983 737 } 984 738 … … 992 746 993 747 } 994 /*---------------------------------------------------------------------------*/995 748 996 749 /** Frees the HID report descriptor parser structure … … 1008 761 usb_hid_report_path_t *path; 1009 762 while(!list_empty(&report->collection_paths)) { 1010 path = list_get_instance(report->collection_paths.next, 1011 usb_hid_report_path_t, link); 1012 763 path = list_get_instance(report->collection_paths.next, usb_hid_report_path_t, link); 1013 764 usb_hid_report_path_free(path); 1014 765 } … … 1018 769 usb_hid_report_field_t *field; 1019 770 while(!list_empty(&report->reports)) { 1020 report_des = list_get_instance(report->reports.next, 1021 usb_hid_report_description_t, link); 1022 771 report_des = list_get_instance(report->reports.next, usb_hid_report_description_t, link); 1023 772 list_remove(&report_des->link); 1024 773 1025 774 while(!list_empty(&report_des->report_items)) { 1026 field = list_get_instance( 1027 report_des->report_items.next, 1028 usb_hid_report_field_t, link); 1029 775 field = list_get_instance(report_des->report_items.next, usb_hid_report_field_t, link); 1030 776 list_remove(&field->link); 1031 777 … … 1038 784 return; 1039 785 } 1040 /*---------------------------------------------------------------------------*/1041 786 1042 787 /**
Note:
See TracChangeset
for help on using the changeset viewer.