Open the device by name with libftdi or libusb
I am using libftdi with multiple ftdi devices for a program running on Ubuntu 14.04. I have a udev rule that detects devices based on a custom manufacturer string and gives them a symbolic link in the dev directory. It will look like /dev/my-device
. I would like to use libftdi to open the device using this line instead of pid / vid / serial number.
I didn't see this feature available in libftdi, so I checked libusb and didn't see this functionality.
+3
source to share
1 answer
You can try this:
static int usbGetDescriptorString(usb_dev_handle *dev, int index, int langid, char *buf, int buflen) {
char buffer[256];
int rval, i;
// make standard request GET_DESCRIPTOR, type string and given index
// (e.g. dev->iProduct)
rval = usb_control_msg(dev,
USB_TYPE_STANDARD | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, langid,
buffer, sizeof(buffer), 1000);
if (rval < 0) // error
return rval;
// rval should be bytes read, but buffer[0] contains the actual response size
if ((unsigned char)buffer[0] < rval)
rval = (unsigned char)buffer[0]; // string is shorter than bytes read
if (buffer[1] != USB_DT_STRING) // second byte is the data type
return 0; // invalid return type
// we're dealing with UTF-16LE here so actual chars is half of rval,
// and index 0 doesn't count
rval /= 2;
/* lossy conversion to ISO Latin1 */
for (i = 1; i < rval && i < buflen; i++) {
if (buffer[2 * i + 1] == 0)
buf[i - 1] = buffer[2 * i];
else
buf[i - 1] = '?'; /* outside of ISO Latin1 range */
}
buf[i - 1] = 0;
return i - 1;
}
static usb_dev_handle * usbOpenDevice(int vendor, char *vendorName, int product, char *productName) {
struct usb_bus *bus;
struct usb_device *dev;
char devVendor[256], devProduct[256];
usb_dev_handle * handle = NULL;
usb_init();
usb_find_busses();
usb_find_devices();
for (bus = usb_get_busses(); bus; bus = bus->next) {
for (dev = bus->devices; dev; dev = dev->next) {
if (dev->descriptor.idVendor != vendor ||
dev->descriptor.idProduct != product)
continue;
/* we need to open the device in order to query strings */
if (!(handle = usb_open(dev))) {
fprintf(stderr, "Warning: cannot open USB device: %sn",
usb_strerror());
continue;
}
/* get vendor name */
if (usbGetDescriptorString(handle, dev->descriptor.iManufacturer, 0x0409, devVendor, sizeof(devVendor)) < 0) {
fprintf(stderr,
"Warning: cannot query manufacturer for device: %sn",
usb_strerror());
usb_close(handle);
continue;
}
/* get product name */
if (usbGetDescriptorString(handle, dev->descriptor.iProduct, 0x0409, devProduct, sizeof(devVendor)) < 0) {
fprintf(stderr,
"Warning: cannot query product for device: %sn",
usb_strerror());
usb_close(handle);
continue;
}
if (strcmp(devVendor, vendorName) == 0 &&
strcmp(devProduct, productName) == 0)
return handle;
else
usb_close(handle);
}
}
return NULL;
}
0
source to share