comparison 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
comparison
equal deleted inserted replaced
8:1415508e7ea2 9:ab506f6aa57c
1 /*
2 * In this module we implement the function that locates a USB device
3 * by matchspec structure: looking for specific VID/PID, possibly qualified
4 * by strings and/or index.
5 */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <strings.h>
11 #include <usb.h>
12 #include "find_dev.h"
13 #include "prelim_init.h"
14
15 static void
16 get_string(usb_dev_handle *usbh, int index, char *buf, size_t buflen)
17 {
18 int rc;
19
20 rc = usb_get_string_simple(usbh, index, buf, buflen);
21 if (rc <= 0) {
22 fprintf(stderr, "error: USB string retrieval failed\n");
23 exit(1);
24 }
25 }
26
27 static int
28 is_match(struct usb_device *dev, const struct usbdev_matchspec *match)
29 {
30 struct usb_device_descriptor *desc = &dev->descriptor;
31 usb_dev_handle *usbh;
32 char strbuf[1024];
33
34 if (desc->idVendor != match->usb_vid)
35 return 0;
36 if (desc->idProduct != match->usb_pid)
37 return 0;
38 if (match->manuf_string || match->product_string || match->serial) {
39 usbh = usb_open(dev);
40 if (!usbh) {
41 fprintf(stderr, "error: usb_open() failed\n");
42 exit(1);
43 }
44 if (match->manuf_string) {
45 get_string(usbh, desc->iManufacturer,
46 strbuf, sizeof strbuf);
47 if (strncmp(match->manuf_string,
48 strbuf, sizeof strbuf)) {
49 usb_close(usbh);
50 return 0;
51 }
52 }
53 if (match->product_string) {
54 get_string(usbh, desc->iProduct, strbuf, sizeof strbuf);
55 if (strncmp(match->product_string,
56 strbuf, sizeof strbuf)) {
57 usb_close(usbh);
58 return 0;
59 }
60 }
61 if (match->serial) {
62 get_string(usbh, desc->iSerialNumber,
63 strbuf, sizeof strbuf);
64 if (strncmp(match->serial, strbuf, sizeof strbuf)) {
65 usb_close(usbh);
66 return 0;
67 }
68 }
69 usb_close(usbh);
70 }
71 return 1;
72 }
73
74 struct usb_device *
75 find_usbdev_by_matchspec(const struct usbdev_matchspec *match)
76 {
77 struct usb_bus *bus;
78 struct usb_device *dev;
79 unsigned index = match->index;
80
81 libusb_prelim_init();
82 for (bus = usb_get_busses(); bus; bus = bus->next) {
83 for (dev = bus->devices; dev; dev = dev->next) {
84 if (is_match(dev, match)) {
85 if (!index)
86 return dev;
87 index--;
88 }
89 }
90 }
91 return 0;
92 }