Changes in uspace/lib/usbhid/src/hiddescriptor.c [1432fcf3:160b75e] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhid/src/hiddescriptor.c
r1432fcf3 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; 273 194 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 279 195 list_initialize (&report_des->link); 280 196 list_initialize (&report_des->report_items); … … 293 209 } 294 210 295 // free only when not used!!!296 if(usages && usages_used == 0) {297 free(usages);298 }299 211 300 212 return EOK; 301 213 } 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 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 { 317 217 link_t *report_it = report->reports.next; 318 218 usb_hid_report_description_t *report_des = NULL; 319 219 320 220 while(report_it != &report->reports) { 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)) { 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)){ 326 224 return report_des; 327 225 } … … 332 230 return NULL; 333 231 } 334 /*---------------------------------------------------------------------------*/335 232 336 233 /** Parse HID report descriptor. … … 339 236 * @param data Data describing the report. 340 237 * @return Error code. 341 * @retval ENOMEM If no more memmory is available342 * @retval EINVAL If invalid data are founded343 * @retval EOK If report descriptor is successfully parsed344 238 */ 345 239 int usb_hid_parse_report_descriptor(usb_hid_report_t *report, … … 392 286 393 287 ret = usb_hid_report_parse_tag(tag,class,data+i+1, 394 item_size,report_item, usage_path); 395 288 item_size,report_item, usage_path); 396 289 switch(ret){ 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; 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; 402 294 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 } 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 } 409 299 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; 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 418 331 break; 419 420 case USB_HID_REPORT_TAG_OUTPUT: 421 report_item->type = 422 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); 423 356 424 report_item->offset = offset_output; 425 offset_output += report_item->count * 426 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 427 367 break; 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; 368 369 default: 370 // nothing special to do 436 371 break; 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 structure446 */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 stack464 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 stack476 if(list_empty (&stack)) {477 return EINVAL;478 }479 free(report_item);480 481 report_item = list_get_instance(stack.next,482 usb_hid_report_item_t, link);483 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);488 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);498 499 break;500 501 default:502 // nothing special to do503 break;504 372 } 505 373 … … 518 386 } 519 387 520 /*---------------------------------------------------------------------------*/521 388 522 389 /** … … 529 396 * @return Code of action to be done next 530 397 */ 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 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 { 535 401 int ret; 536 402 537 403 switch(class){ 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; 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; 562 424 } 563 425 } … … 573 435 */ 574 436 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) 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) 578 439 { 579 440 usb_hid_report_usage_path_t *path_item; … … 581 442 switch(tag) 582 443 { 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;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; 589 450 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; 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; 596 455 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])); 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]); 607 459 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; 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; 617 466 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; 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; 625 473 } 626 474 … … 637 485 * @return Error code 638 486 */ 639 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 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 643 491 switch(tag) 644 492 { 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; 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; 708 533 709 default:710 return USB_HID_NO_ACTION;534 default: 535 return USB_HID_NO_ACTION; 711 536 } 712 537 … … 723 548 * @return Error code 724 549 */ 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) 728 { 729 int32_t extended_usage; 730 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 { 731 553 switch(tag) { 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; 780 } 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; 804 } 805 else { 806 report_item->usages[report_item->usages_count++] = 807 (report_item->usage_page << 16) + i; 808 } 809 } 810 report_item->extended_usage_page = 0; 811 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; 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; 851 611 } 852 612 853 613 return EOK; 854 614 } 855 /*---------------------------------------------------------------------------*/856 615 857 616 /** … … 874 633 return result; 875 634 } 876 /*---------------------------------------------------------------------------*/877 635 878 636 /** … … 895 653 for(item = head->next; item != head; item = item->next) { 896 654 897 report_item = list_get_instance(item, usb_hid_report_field_t, 898 link); 655 report_item = list_get_instance(item, usb_hid_report_field_t, link); 899 656 900 657 usb_log_debug("\t\tOFFSET: %X\n", report_item->offset); 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); 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); 916 665 917 666 usb_log_debug("\t\tVALUE: %X\n", report_item->value); … … 919 668 usb_log_debug("\t\tUSAGE PAGE: %X\n", report_item->usage_page); 920 669 921 usb_hid_print_usage_path(report_item->collection_path);670 //usb_hid_print_usage_path(report_item->collection_path); 922 671 923 672 usb_log_debug("\n"); … … 925 674 } 926 675 927 } 928 /*---------------------------------------------------------------------------*/ 929 676 677 } 930 678 /** 931 679 * Prints content of given report descriptor in human readable format. … … 944 692 945 693 while(report_it != &report->reports) { 946 report_des = list_get_instance(report_it, 947 usb_hid_report_description_t, link); 694 report_des = list_get_instance(report_it, usb_hid_report_description_t, link); 948 695 usb_log_debug("Report ID: %d\n", report_des->report_id); 949 696 usb_log_debug("\tType: %d\n", report_des->type); 950 697 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));955 698 usb_log_debug("\tItems: %zu\n", report_des->item_length); 956 699 957 700 usb_hid_descriptor_print_list(&report_des->report_items); 958 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 959 709 report_it = report_it->next; 960 710 } 961 711 } 962 /*---------------------------------------------------------------------------*/963 712 964 713 /** … … 985 734 986 735 while(!list_empty(&report_item->usage_path->link)) { 987 736 usb_hid_report_remove_last_item(report_item->usage_path); 988 737 } 989 738 … … 997 746 998 747 } 999 /*---------------------------------------------------------------------------*/1000 748 1001 749 /** Frees the HID report descriptor parser structure … … 1013 761 usb_hid_report_path_t *path; 1014 762 while(!list_empty(&report->collection_paths)) { 1015 path = list_get_instance(report->collection_paths.next, 1016 usb_hid_report_path_t, link); 1017 763 path = list_get_instance(report->collection_paths.next, usb_hid_report_path_t, link); 1018 764 usb_hid_report_path_free(path); 1019 765 } … … 1023 769 usb_hid_report_field_t *field; 1024 770 while(!list_empty(&report->reports)) { 1025 report_des = list_get_instance(report->reports.next, 1026 usb_hid_report_description_t, link); 1027 771 report_des = list_get_instance(report->reports.next, usb_hid_report_description_t, link); 1028 772 list_remove(&report_des->link); 1029 773 1030 774 while(!list_empty(&report_des->report_items)) { 1031 field = list_get_instance( 1032 report_des->report_items.next, 1033 usb_hid_report_field_t, link); 1034 775 field = list_get_instance(report_des->report_items.next, usb_hid_report_field_t, link); 1035 776 list_remove(&field->link); 1036 777 … … 1043 784 return; 1044 785 } 1045 /*---------------------------------------------------------------------------*/1046 786 1047 787 /**
Note:
See TracChangeset
for help on using the changeset viewer.