FreeCalypso > hg > fc-usbser-tools
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 } |