Changes in / [a9c674e0:a80849c] in mainline
- Location:
- uspace
- Files:
-
- 1 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/usbinfo/dump.c
ra9c674e0 ra80849c 53 53 54 54 55 staticconst char *get_indent(size_t level)55 const char *get_indent(size_t level) 56 56 { 57 57 static const char *indents[] = { -
uspace/app/usbinfo/info.c
ra9c674e0 ra80849c 129 129 config_descriptor.total_length); 130 130 131 /* 132 * Get supported languages of STRING descriptors. 133 */ 134 l18_win_locales_t *langs; 135 size_t langs_count; 136 rc = usb_request_get_supported_languages(&ctrl_pipe, 137 &langs, &langs_count); 138 if (rc != EOK) { 139 fprintf(stderr, 140 NAME ": failed to get list of supported languages: %s.\n", 141 str_error(rc)); 142 goto skip_strings; 143 } 144 145 printf("String languages (%zu):", langs_count); 146 size_t i; 147 for (i = 0; i < langs_count; i++) { 148 printf(" 0x%04x", (int) langs[i]); 149 } 150 printf(".\n"); 151 152 /* 153 * Dump all strings in all available langages; 154 */ 155 for (i = 0; i < langs_count; i++) { 156 l18_win_locales_t lang = langs[i]; 157 158 printf("%sStrings for language 0x%04x:\n", get_indent(0), 159 (int) lang); 160 161 /* 162 * Try all indexes - we will see what pops-up ;-). 163 * However, to speed things up, we will stop after 164 * encountering several broken (or nonexistent ones) 165 * descriptors in line. 166 */ 167 size_t idx; 168 size_t failed_count = 0; 169 for (idx = 1; idx < 0xFF; idx++) { 170 char *string; 171 rc = usb_request_get_string(&ctrl_pipe, idx, lang, 172 &string); 173 if (rc != EOK) { 174 failed_count++; 175 if (failed_count > 3) { 176 break; 177 } 178 continue; 179 } 180 printf("%sString #%zu: \"%s\"\n", get_indent(1), 181 idx, string); 182 free(string); 183 failed_count = 0; /* Reset failed counter. */ 184 } 185 } 186 187 188 skip_strings: 189 131 190 rc = EOK; 191 132 192 leave: 133 193 /* Ignoring errors here. */ -
uspace/app/usbinfo/usbinfo.h
ra9c674e0 ra80849c 45 45 46 46 void dump_buffer(const char *, size_t, const uint8_t *, size_t); 47 const char *get_indent(size_t); 47 48 void dump_match_ids(match_id_list_t *matches); 48 49 void dump_usb_descriptor(uint8_t *, size_t); -
uspace/lib/c/generic/str_error.c
ra9c674e0 ra80849c 77 77 case EAGAIN: 78 78 return "Resource temporarily unavailable"; 79 case EEMPTY: 80 return "Resource is empty"; 79 81 default: 80 82 break; -
uspace/lib/c/include/errno.h
ra9c674e0 ra80849c 62 62 #define ESTALL (-301) 63 63 64 /** Empty resource (no data). */ 65 #define EEMPTY (-302) 66 64 67 /** An API function is called while another blocking function is in progress. */ 65 68 #define EINPROGRESS (-10036) -
uspace/lib/usb/include/usb/request.h
ra9c674e0 ra80849c 37 37 38 38 #include <sys/types.h> 39 #include <l18n/langs.h> 39 40 #include <usb/usb.h> 40 41 #include <usb/pipes.h> … … 96 97 int usb_request_get_descriptor(usb_endpoint_pipe_t *, usb_request_type_t, 97 98 uint8_t, uint8_t, uint16_t, void *, size_t, size_t *); 99 int usb_request_get_descriptor_alloc(usb_endpoint_pipe_t *, usb_request_type_t, 100 uint8_t, uint8_t, uint16_t, void **, size_t *); 98 101 int usb_request_get_device_descriptor(usb_endpoint_pipe_t *, 99 102 usb_standard_device_descriptor_t *); … … 104 107 int usb_request_set_configuration(usb_endpoint_pipe_t *, uint8_t); 105 108 109 int usb_request_get_supported_languages(usb_endpoint_pipe_t *, 110 l18_win_locales_t **, size_t *); 111 int usb_request_get_string(usb_endpoint_pipe_t *, size_t, l18_win_locales_t, 112 char **); 113 106 114 #endif 107 115 /** -
uspace/lib/usb/src/recognise.c
ra9c674e0 ra80849c 310 310 } 311 311 312 /*313 * As a fallback, provide the simplest match id possible.314 */315 ADD_MATCHID_OR_RETURN(matches, 1, "usb&fallback");316 317 312 return EOK; 318 313 } -
uspace/lib/usb/src/request.c
ra9c674e0 ra80849c 230 230 } 231 231 232 /** Retrieve USB descriptor, allocate space for it. 233 * 234 * @param[in] pipe Control endpoint pipe (session must be already started). 235 * @param[in] request_type Request type (standard/class/vendor). 236 * @param[in] descriptor_type Descriptor type (device/configuration/HID/...). 237 * @param[in] descriptor_index Descriptor index. 238 * @param[in] language Language index. 239 * @param[out] buffer_ptr Where to store pointer to allocated buffer. 240 * @param[out] buffer_size Where to store the size of the descriptor. 241 * @return 242 */ 243 int usb_request_get_descriptor_alloc(usb_endpoint_pipe_t * pipe, 244 usb_request_type_t request_type, 245 uint8_t descriptor_type, uint8_t descriptor_index, 246 uint16_t language, 247 void **buffer_ptr, size_t *buffer_size) 248 { 249 if (buffer_ptr == NULL) { 250 return EBADMEM; 251 } 252 253 int rc; 254 255 /* 256 * Get only first byte to retrieve descriptor length. 257 */ 258 uint8_t tmp_buffer[1]; 259 size_t bytes_transfered; 260 rc = usb_request_get_descriptor(pipe, request_type, 261 descriptor_type, descriptor_index, language, 262 &tmp_buffer, 1, &bytes_transfered); 263 if (rc != EOK) { 264 return rc; 265 } 266 if (bytes_transfered != 1) { 267 /* FIXME: some better error code? */ 268 return ESTALL; 269 } 270 271 size_t size = tmp_buffer[0]; 272 if (size == 0) { 273 /* FIXME: some better error code? */ 274 return ESTALL; 275 } 276 277 /* 278 * Allocate buffer and get the descriptor again. 279 */ 280 void *buffer = malloc(size); 281 if (buffer == NULL) { 282 return ENOMEM; 283 } 284 285 rc = usb_request_get_descriptor(pipe, request_type, 286 descriptor_type, descriptor_index, language, 287 buffer, size, &bytes_transfered); 288 if (rc != EOK) { 289 free(buffer); 290 return rc; 291 } 292 if (bytes_transfered != size) { 293 free(buffer); 294 /* FIXME: some better error code? */ 295 return ESTALL; 296 } 297 298 *buffer_ptr = buffer; 299 if (buffer_size != NULL) { 300 *buffer_size = size; 301 } 302 303 return EOK; 304 } 305 232 306 /** Retrieve standard device descriptor of a USB device. 233 307 * … … 355 429 } 356 430 431 /** Get list of supported languages by USB device. 432 * 433 * @param[in] pipe Control endpoint pipe (session must be already started). 434 * @param[out] languages_ptr Where to store pointer to allocated array of 435 * supported languages. 436 * @param[out] languages_count Number of supported languages. 437 * @return Error code. 438 */ 439 int usb_request_get_supported_languages(usb_endpoint_pipe_t *pipe, 440 l18_win_locales_t **languages_ptr, size_t *languages_count) 441 { 442 int rc; 443 444 if (languages_ptr == NULL) { 445 return EBADMEM; 446 } 447 if (languages_count == NULL) { 448 return EBADMEM; 449 } 450 451 uint8_t *string_descriptor = NULL; 452 size_t string_descriptor_size = 0; 453 rc = usb_request_get_descriptor_alloc(pipe, 454 USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_STRING, 0, 0, 455 (void **) &string_descriptor, &string_descriptor_size); 456 if (rc != EOK) { 457 return rc; 458 } 459 if (string_descriptor_size <= 2) { 460 free(string_descriptor); 461 return EEMPTY; 462 } 463 /* Substract first 2 bytes (length and descriptor type). */ 464 string_descriptor_size -= 2; 465 466 /* Odd number of bytes - descriptor is broken? */ 467 if ((string_descriptor_size % 2) != 0) { 468 /* FIXME: shall we return with error or silently ignore? */ 469 free(string_descriptor); 470 return ESTALL; 471 } 472 473 size_t langs_count = string_descriptor_size / 2; 474 l18_win_locales_t *langs 475 = malloc(sizeof(l18_win_locales_t) * langs_count); 476 if (langs == NULL) { 477 free(string_descriptor); 478 return ENOMEM; 479 } 480 481 size_t i; 482 for (i = 0; i < langs_count; i++) { 483 /* Language code from the descriptor is in USB endianess. */ 484 /* FIXME: is this really correct? */ 485 uint16_t lang_code = (string_descriptor[2 + 2 * i + 1] << 8) 486 + string_descriptor[2 + 2 * i]; 487 langs[i] = uint16_usb2host(lang_code); 488 } 489 490 free(string_descriptor); 491 492 *languages_ptr = langs; 493 *languages_count =langs_count; 494 495 return EOK; 496 } 497 498 /** Get string (descriptor) from USB device. 499 * 500 * The string is returned in native encoding of the operating system. 501 * For HelenOS, that is UTF-8. 502 * 503 * @param[in] pipe Control endpoint pipe (session must be already started). 504 * @param[in] index String index (in native endianess). 505 * @param[in] lang String language (in native endianess). 506 * @param[out] string_ptr Where to store allocated string in native encoding. 507 * @return Error code. 508 */ 509 int usb_request_get_string(usb_endpoint_pipe_t *pipe, 510 size_t index, l18_win_locales_t lang, char **string_ptr) 511 { 512 if (string_ptr == NULL) { 513 return EBADMEM; 514 } 515 /* Index is actually one byte value. */ 516 if (index > 0xFF) { 517 return ERANGE; 518 } 519 /* Language is actually two byte value. */ 520 if (lang > 0xFFFF) { 521 return ERANGE; 522 } 523 524 int rc; 525 526 /* Prepare dynamically allocated variables. */ 527 uint8_t *string = NULL; 528 wchar_t *string_chars = NULL; 529 530 /* Get the actual descriptor. */ 531 size_t string_size; 532 rc = usb_request_get_descriptor_alloc(pipe, 533 USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_STRING, 534 index, uint16_host2usb(lang), 535 (void **) &string, &string_size); 536 if (rc != EOK) { 537 goto leave; 538 } 539 540 if (string_size <= 2) { 541 rc = EEMPTY; 542 goto leave; 543 } 544 /* Substract first 2 bytes (length and descriptor type). */ 545 string_size -= 2; 546 547 /* Odd number of bytes - descriptor is broken? */ 548 if ((string_size % 2) != 0) { 549 /* FIXME: shall we return with error or silently ignore? */ 550 rc = ESTALL; 551 goto leave; 552 } 553 554 size_t string_char_count = string_size / 2; 555 string_chars = malloc(sizeof(wchar_t) * (string_char_count + 1)); 556 if (string_chars == NULL) { 557 rc = ENOMEM; 558 goto leave; 559 } 560 561 /* 562 * Build a wide string. 563 * And do not forget to set NULL terminator (string descriptors 564 * do not have them). 565 */ 566 size_t i; 567 for (i = 0; i < string_char_count; i++) { 568 uint16_t uni_char = (string[2 + 2 * i + 1] << 8) 569 + string[2 + 2 * i]; 570 string_chars[i] = uni_char; 571 } 572 string_chars[string_char_count] = 0; 573 574 575 /* Convert to normal string. */ 576 char *str = wstr_to_astr(string_chars); 577 if (str == NULL) { 578 rc = ENOMEM; 579 goto leave; 580 } 581 582 *string_ptr = str; 583 rc = EOK; 584 585 leave: 586 if (string != NULL) { 587 free(string); 588 } 589 if (string_chars != NULL) { 590 free(string_chars); 591 } 592 593 return rc; 594 } 595 357 596 /** 358 597 * @}
Note:
See TracChangeset
for help on using the changeset viewer.