FreeCalypso > hg > fc-usbser-tools
view libuwrap/find_matchspec.c @ 68:5cbde3c80c24
fteeprom-{erase,prog}: detach logic: change to detach by default
As it turns out, detaching all ttyUSB interfaces of a multichannel device
does not require outside knowledge of how many channels there are, as in
our previous -d option design that is being removed here - instead we can
read the bNumInterfaces constant from the USB device's config descriptor
and thus know how many interfaces there are in total. Based on this
discovery, change the design of fteeprom-{erase,prog} as follows:
* remove -d option;
* flip the default to where we detach all interfaces by default;
* add -n option to NOT detach any interfaces.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Wed, 13 Sep 2023 06:37:03 +0000 |
parents | ab506f6aa57c |
children |
line wrap: on
line source
/* * In this module we implement the function that locates a USB device * by matchspec structure: looking for specific VID/PID, possibly qualified * by strings and/or index. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include <usb.h> #include "find_dev.h" #include "prelim_init.h" static void get_string(usb_dev_handle *usbh, int index, char *buf, size_t buflen) { int rc; rc = usb_get_string_simple(usbh, index, buf, buflen); if (rc <= 0) { fprintf(stderr, "error: USB string retrieval failed\n"); exit(1); } } static int is_match(struct usb_device *dev, const struct usbdev_matchspec *match) { struct usb_device_descriptor *desc = &dev->descriptor; usb_dev_handle *usbh; char strbuf[1024]; if (desc->idVendor != match->usb_vid) return 0; if (desc->idProduct != match->usb_pid) return 0; if (match->manuf_string || match->product_string || match->serial) { usbh = usb_open(dev); if (!usbh) { fprintf(stderr, "error: usb_open() failed\n"); exit(1); } if (match->manuf_string) { get_string(usbh, desc->iManufacturer, strbuf, sizeof strbuf); if (strncmp(match->manuf_string, strbuf, sizeof strbuf)) { usb_close(usbh); return 0; } } if (match->product_string) { get_string(usbh, desc->iProduct, strbuf, sizeof strbuf); if (strncmp(match->product_string, strbuf, sizeof strbuf)) { usb_close(usbh); return 0; } } if (match->serial) { get_string(usbh, desc->iSerialNumber, strbuf, sizeof strbuf); if (strncmp(match->serial, strbuf, sizeof strbuf)) { usb_close(usbh); return 0; } } usb_close(usbh); } return 1; } struct usb_device * find_usbdev_by_matchspec(const struct usbdev_matchspec *match) { struct usb_bus *bus; struct usb_device *dev; unsigned index = match->index; libusb_prelim_init(); for (bus = usb_get_busses(); bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { if (is_match(dev, match)) { if (!index) return dev; index--; } } } return 0; }