Changes in uspace/lib/usb/src/request.c [b84e114:0f21c0c] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/src/request.c
rb84e114 r0f21c0c 35 35 #include <usb/request.h> 36 36 #include <errno.h> 37 #include <assert.h>38 37 39 38 #define MAX_DATA_LENGTH ((size_t)(0xFFFF)) … … 230 229 } 231 230 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 * @return242 */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 306 231 /** Retrieve standard device descriptor of a USB device. 307 232 * … … 429 354 } 430 355 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 of435 * 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 *langs475 = 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 descriptors564 * 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 596 356 /** 597 357 * @}
Note:
See TracChangeset
for help on using the changeset viewer.