简体   繁体   English

使用libftdi或libusb按名称打开设备

[英]Open a device by name using libftdi or libusb

I am using libftdi with multiple ftdi devices for a program running on Ubuntu 14.04. 我正在使用带有多个ftdi设备的libftdi来运行在Ubuntu 14.04上运行的程序。 I have a udev rule that detects the devices based on a custom manufacturer string and gives them a symlink in the dev directory. 我有一个udev规则,它根据自定义制造商字符串检测设备,并在dev目录中为它们提供符号链接。 It would look similar to /dev/my-device . 它看起来与/dev/my-device类似。 I would like to use libftdi to open the device using this string instead of the pid/vid/serial number. 我想使用libftdi来使用此字符串而不是pid / vid /序列号打开设备。

I did not see that this capability was available in libftdi so I checked libusb and didn't see that functionality either. 我没有看到这个功能在libftdi中可用,所以我检查了libusb并且没有看到该功能。

You could 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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM