USB-Host: how to get array of string descriptors?

greengnu
Posts: 66
Joined: Wed May 08, 2019 8:45 pm

USB-Host: how to get array of string descriptors?

Postby greengnu » Wed Mar 26, 2025 1:13 pm

with

Code: Select all

esp_err_t usb_host_get_device_descriptor(usb_device_handle_t dev_hdl, const usb_device_desc_t **device_desc)
https://docs.espressif.com/projects/esp ... ice_desc_t I get a

Code: Select all

usb_device_desc_t
, which contains fields like

Code: Select all

iManufacturer
which are indices into an array of strings.

How can I access this array of strings?

igi540
Espressif staff
Espressif staff
Posts: 7
Joined: Thu Jan 23, 2025 1:00 pm

Re: USB-Host: how to get array of string descriptors?

Postby igi540 » Wed Mar 26, 2025 3:03 pm

Hi @greengnu

You're right — usb_device_desc_t gives you indices like iManufacturer, iProduct, and iSerialNumber, but not the actual strings. To get the string descriptors, you need to manually send a GET_DESCRIPTOR control transfer using:

usb_host_transfer_alloc()

usb_host_device_transfer()

usb_host_transfer_free()
Here’s a helper function to get a string descriptor:

Code: Select all

esp_err_t get_string_descriptor(usb_device_handle_t dev_hdl, uint8_t index, uint16_t langid, char *out_str, size_t max_len)
{
    usb_transfer_t *transfer;
    if (usb_host_transfer_alloc(128, 0, &transfer) != ESP_OK) return ESP_FAIL;

    transfer->setup.bmRequestType = 0x80;
    transfer->setup.bRequest = USB_B_REQUEST_GET_DESCRIPTOR;
    transfer->setup.wValue = (USB_B_DESCRIPTOR_TYPE_STRING << 8) | index;
    transfer->setup.wIndex = langid;
    transfer->setup.wLength = 128;

    if (usb_host_device_transfer(dev_hdl, transfer) != ESP_OK ||
        transfer->status != USB_TRANSFER_STATUS_COMPLETED) {
        usb_host_transfer_free(transfer);
        return ESP_FAIL;
    }

    size_t len = transfer->actual_num_bytes;
    if (len < 2 || transfer->data_buffer[1] != USB_B_DESCRIPTOR_TYPE_STRING) {
        usb_host_transfer_free(transfer);
        return ESP_FAIL;
    }

    for (int i = 2, j = 0; i < len && j < max_len - 1; i += 2) {
        out_str[j++] = transfer->data_buffer[i];
        out_str[j] = '\0';
    }

    usb_host_transfer_free(transfer);
    return ESP_OK;
}

Example usage:

Code: Select all

char manufacturer[64];
get_string_descriptor(dev_hdl, device_desc->iManufacturer, 0x0409, manufacturer, sizeof(manufacturer));
printf("Manufacturer: %s\n", manufacturer);


Who is online

Users browsing this forum: Bing [Bot], ChatGPT-User, PetalBot and 2 guests