FreeCalypso > hg > fc-usbser-tools
diff libuwrap/find_matchspec.c @ 9:ab506f6aa57c
libuwrap started
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 07 Sep 2023 04:00:56 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libuwrap/find_matchspec.c Thu Sep 07 04:00:56 2023 +0000 @@ -0,0 +1,92 @@ +/* + * 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; +}