Changeset b84e114 in mainline


Ignore:
Timestamp:
2011-02-23T21:55:24Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d0dcfa80
Parents:
7eebe2a
Message:

Retrieval of USB string

Location:
uspace/lib/usb
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usb/include/usb/request.h

    r7eebe2a rb84e114  
    109109int usb_request_get_supported_languages(usb_endpoint_pipe_t *,
    110110    l18_win_locales_t **, size_t *);
     111int usb_request_get_string(usb_endpoint_pipe_t *, size_t, l18_win_locales_t,
     112    char **);
    111113
    112114#endif
  • uspace/lib/usb/src/request.c

    r7eebe2a rb84e114  
    496496}
    497497
     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 */
     509int 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
     585leave:
     586        if (string != NULL) {
     587                free(string);
     588        }
     589        if (string_chars != NULL) {
     590                free(string_chars);
     591        }
     592
     593        return rc;
     594}
     595
    498596/**
    499597 * @}
Note: See TracChangeset for help on using the changeset viewer.