Changes in uspace/lib/usbhid/src/hiddescriptor.c [160b75e:1432fcf3] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhid/src/hiddescriptor.c
r160b75e r1432fcf3 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 93 link_t *path_it = report->collection_paths.prev->next; 67 94 usb_hid_report_path_t *path = NULL; 95 96 if((report == NULL) || (cmp_path == NULL)) { 97 return NULL; 98 } 99 68 100 while(path_it != &report->collection_paths) { 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){ 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){ 72 106 break; 73 107 } … … 75 109 } 76 110 if(path_it == &report->collection_paths) { 77 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 } 78 115 list_append(&path->link, &report->collection_paths); 79 116 report->collection_paths_count++; … … 82 119 } 83 120 else { 84 return list_get_instance(path_it, usb_hid_report_path_t, link); 85 } 86 } 87 121 return list_get_instance(path_it, usb_hid_report_path_t, 122 link); 123 } 124 } 125 126 /*---------------------------------------------------------------------------*/ 88 127 /** 89 128 * Initialize the report descriptor parser structure … … 91 130 * @param parser Report descriptor parser structure 92 131 * @return Error code 132 * @retval EINVAL If no report structure was given 133 * @retval EOK If report structure was successfully initialized 93 134 */ 94 135 int usb_hid_report_init(usb_hid_report_t *report) … … 106 147 } 107 148 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 { 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 115 166 usb_hid_report_field_t *field; 116 167 int i; 117 168 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 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 122 185 usb_hid_report_path_t *path = report_item->usage_path; 123 186 for(i=0; i<report_item->count; i++){ … … 133 196 field->physical_maximum = report_item->physical_maximum; 134 197 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; 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; 139 209 } 140 210 else { 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){ 211 212 /* Fill the correct Usage and Usage Page */ 213 int32_t usage; 214 if(i < report_item->usages_count) { 147 215 usage = report_item->usages[i]; 148 216 } 149 217 else { 150 usage = report_item->usages[report_item->usages_count - 1]; 218 usage = report_item->usages[ 219 report_item->usages_count- 1]; 151 220 } 152 221 153 154 if((usage & 0xFFFF0000) != 0){155 field->usage_page = (usage >> 16);156 field->usage = (usage & 0xFFFF);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); 157 226 } 158 227 else { 228 // should not occur 159 229 field->usage = usage; 230 field->usage_page = report_item->usage_page; 160 231 } 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); 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); 173 241 174 242 field->size = report_item->size; 175 243 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; 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; 178 249 179 250 field->offset = 8 * offset_byte + offset_bit; … … 186 257 /* find the right report list*/ 187 258 usb_hid_report_description_t *report_des; 188 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 189 262 if(report_des == NULL){ 190 report_des = malloc(sizeof(usb_hid_report_description_t)); 191 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)); 192 271 193 272 report_des->type = report_item->type; 194 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 195 279 list_initialize (&report_des->link); 196 280 list_initialize (&report_des->report_items); … … 209 293 } 210 294 295 // free only when not used!!! 296 if(usages && usages_used == 0) { 297 free(usages); 298 } 211 299 212 300 return EOK; 213 301 } 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 { 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 217 317 link_t *report_it = report->reports.next; 218 318 usb_hid_report_description_t *report_des = NULL; 219 319 220 320 while(report_it != &report->reports) { 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 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)) { 224 326 return report_des; 225 327 } … … 230 332 return NULL; 231 333 } 334 /*---------------------------------------------------------------------------*/ 232 335 233 336 /** Parse HID report descriptor. … … 236 339 * @param data Data describing the report. 237 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 238 344 */ 239 345 int usb_hid_parse_report_descriptor(usb_hid_report_t *report, … … 286 392 287 393 ret = usb_hid_report_parse_tag(tag,class,data+i+1, 288 item_size,report_item, usage_path); 394 item_size,report_item, usage_path); 395 289 396 switch(ret){ 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 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; 294 402 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 } 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 } 299 409 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 } 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; 321 423 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 424 report_item->offset = offset_output; 425 offset_output += report_item->count * 426 report_item->size; 331 427 break; 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); 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; 338 436 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); 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); 354 480 355 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); 356 483 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); 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); 359 488 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); 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); 366 498 367 499 break; 368 500 369 370 371 501 default: 502 // nothing special to do 503 break; 372 504 } 373 505 … … 386 518 } 387 519 520 /*---------------------------------------------------------------------------*/ 388 521 389 522 /** … … 396 529 * @return Code of action to be done next 397 530 */ 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 { 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 401 535 int ret; 402 536 403 537 switch(class){ 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; 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; 424 562 } 425 563 } … … 435 573 */ 436 574 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) 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) 439 578 { 440 579 usb_hid_report_usage_path_t *path_item; … … 442 581 switch(tag) 443 582 { 444 445 446 447 448 449 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; 450 589 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; 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; 455 596 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]); 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])); 459 607 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; 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; 466 617 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; 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; 473 625 } 474 626 … … 485 637 * @return Error code 486 638 */ 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 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 491 643 switch(tag) 492 644 { 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; 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; 533 708 534 535 709 default: 710 return USB_HID_NO_ACTION; 536 711 } 537 712 … … 548 723 * @return Error code 549 724 */ 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) 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) 552 728 { 729 int32_t extended_usage; 730 553 731 switch(tag) { 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; 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; 565 780 } 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; 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; 572 804 } 573 else { 574 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; 575 808 } 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; 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; 611 851 } 612 852 613 853 return EOK; 614 854 } 855 /*---------------------------------------------------------------------------*/ 615 856 616 857 /** … … 633 874 return result; 634 875 } 876 /*---------------------------------------------------------------------------*/ 635 877 636 878 /** … … 653 895 for(item = head->next; item != head; item = item->next) { 654 896 655 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); 656 899 657 900 usb_log_debug("\t\tOFFSET: %X\n", report_item->offset); 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); 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); 665 916 666 917 usb_log_debug("\t\tVALUE: %X\n", report_item->value); … … 668 919 usb_log_debug("\t\tUSAGE PAGE: %X\n", report_item->usage_page); 669 920 670 //usb_hid_print_usage_path(report_item->collection_path);921 usb_hid_print_usage_path(report_item->collection_path); 671 922 672 923 usb_log_debug("\n"); … … 674 925 } 675 926 676 677 } 927 } 928 /*---------------------------------------------------------------------------*/ 929 678 930 /** 679 931 * Prints content of given report descriptor in human readable format. … … 692 944 693 945 while(report_it != &report->reports) { 694 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); 695 948 usb_log_debug("Report ID: %d\n", report_des->report_id); 696 949 usb_log_debug("\tType: %d\n", report_des->type); 697 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)); 698 955 usb_log_debug("\tItems: %zu\n", report_des->item_length); 699 956 700 957 usb_hid_descriptor_print_list(&report_des->report_items); 701 958 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 709 959 report_it = report_it->next; 710 960 } 711 961 } 962 /*---------------------------------------------------------------------------*/ 712 963 713 964 /** … … 734 985 735 986 while(!list_empty(&report_item->usage_path->link)) { 736 987 usb_hid_report_remove_last_item(report_item->usage_path); 737 988 } 738 989 … … 746 997 747 998 } 999 /*---------------------------------------------------------------------------*/ 748 1000 749 1001 /** Frees the HID report descriptor parser structure … … 761 1013 usb_hid_report_path_t *path; 762 1014 while(!list_empty(&report->collection_paths)) { 763 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 764 1018 usb_hid_report_path_free(path); 765 1019 } … … 769 1023 usb_hid_report_field_t *field; 770 1024 while(!list_empty(&report->reports)) { 771 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 772 1028 list_remove(&report_des->link); 773 1029 774 1030 while(!list_empty(&report_des->report_items)) { 775 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 776 1035 list_remove(&field->link); 777 1036 … … 784 1043 return; 785 1044 } 1045 /*---------------------------------------------------------------------------*/ 786 1046 787 1047 /**
Note:
See TracChangeset
for help on using the changeset viewer.