0

I'm trying to get the serial number of a USB device using libusb-1.0.

The problem I have is that sometimes the libusb_get_string_descriptor_ascii() function returns -7 (LIBUSB_ERROR_TIMEOUT) in my code, but other times the serial number is correctly written in my array and I can't figure out what is happening. Am I using libusb incorrectly? Thank you.

void EnumerateUsbDevices(uint16_t uVendorId, uint16_t uProductId) {
libusb_context *pContext;
libusb_device **ppDeviceList;
libusb_device_descriptor oDeviceDescriptor;
libusb_device_handle *hHandle;

int iReturnValue = libusb_init(&pContext);
if (iReturnValue != LIBUSB_SUCCESS) {
    return;
}
libusb_set_debug(pContext, 3);

ssize_t nbUsbDevices = libusb_get_device_list(pContext, &ppDeviceList);
for (ssize_t i = 0; i < nbUsbDevices; ++i) {
    libusb_device *pDevice = ppDeviceList[i];
    iReturnValue = libusb_get_device_descriptor(pDevice, &oDeviceDescriptor);
    if (iReturnValue != LIBUSB_SUCCESS) {
        continue;
    }
    if (oDeviceDescriptor.idVendor == uVendorId && oDeviceDescriptor.idProduct == uProductId) {
        iReturnValue = libusb_open(pDevice, &hHandle);
        if (iReturnValue != LIBUSB_SUCCESS) {
            continue;
        }
        unsigned char uSerialNumber[255] = {};
        int iSerialNumberSize = libusb_get_string_descriptor_ascii(hHandle, oDeviceDescriptor.iSerialNumber, uSerialNumber, sizeof(uSerialNumber));
        std::cout << iSerialNumberSize << std::endl; // Print size of serial number <--
        libusb_close(hHandle);
    }
}
libusb_free_device_list(ppDeviceList, 1);
libusb_exit(pContext); 
}

2 Answers2

0

I see nothing wrong with your code. I would not care to much about timeouts in the context of USB. It is a bus after all and can be occupied with different traffic.

As you may know there is depending on the version of USB a portion of the bandwidth reserved for control transfers. libusb_get_string_descriptor_ascii simply sends all the required control transfers to get the string. If any of those times out it will abort. You can try to send this control transfers yourself and use bigger timeout values but I guess the possibility of a timeout will always be there to wait for you (pun intended).

dryman
  • 660
  • 6
  • 16
  • Alright, thanks for your answer! I guess ill have to investigate more on why I'm getting timeouts with libusb. I find it a bit weird since when I'm using the command usb-devices https://linux.die.net/man/1/usb-devices, I reliably get the serial number. Maybe its because I'm on a VM? – LavaCharizard Oct 06 '16 at 13:58
  • Have you investigated whether usb-devices sends the transfers with bigger timouts or maybe sometimes multiple times? With libusb your dealing with low level in contrast to the higher level usb-devices tool. Of course if it is a VM this **may** lead to longer reaction times. But if you start to not only read properties but communicate with an USB device you will sooner than later come across different errors that simply occur even if everythings fine. Fault tolerance is the key. That is how computers work. ;) – dryman Oct 07 '16 at 09:27
  • But if your in doubt just use an usb sniffer and compare your tool to usb-devices. It is as easy as that. – dryman Oct 07 '16 at 09:27
0

So it turns out my device was getting into weird states, possibly not being closed properly or the like. Anyway, calling libusb_reset_device(hHandle); just after the libusb_open() call seems to fix my sporadic timeout issue.

libusb_reset_device()