1 /* Name: opendevice.c -> renamed as usb_device.[ch]
2 * Project: V-USB host-side library
3 * Author: Christian Starkjohann
4 * Creation Date: 2008-04-10
6 * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
7 * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
8 * This Revision: $Id: opendevice.c 740 2009-04-13 18:23:31Z cs $
11 #include "usb_device.h"
18 /* private interface: match text and p, return MATCH_SUCCESS, MATCH_FAILED, or MATCH_ABORT. */
19 static int _shellStyleMatch(char *text, char *p)
21 int last, matched, reverse;
23 for(; *p; text++, p++){
24 if(*text == 0 && *p != '*')
28 /* Literal match with following character. */
40 /* Consecutive stars act just like one. */
43 /* Trailing star matches everything. */
46 if((matched = _shellStyleMatch(text++, p)) != MATCH_FAILED)
50 reverse = p[1] == '^';
51 if(reverse) /* Inverted character class. */
53 matched = MATCH_FAILED;
54 if(p[1] == ']' || p[1] == '-')
56 matched = MATCH_SUCCESS;
57 for(last = *p; *++p && *p != ']'; last = *p)
58 if (*p == '-' && p[1] != ']' ? *text <= *++p && *text >= last : *text == *p)
59 matched = MATCH_SUCCESS;
60 if(matched == reverse)
68 /* public interface for shell style matching: returns 0 if fails, 1 if matches */
69 static int shellStyleMatch(char *text, char *pattern)
71 if(pattern == NULL) /* NULL pattern is synonymous to "*" */
73 return _shellStyleMatch(text, pattern) == MATCH_SUCCESS;
76 /* ------------------------------------------------------------------------- */
78 int usbGetStringAscii(usb_dev_handle *dev, int index, char *buf, int buflen)
83 if((rval = usb_get_string_simple(dev, index, buf, buflen)) >= 0) /* use libusb version if it works */
85 if((rval = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, 0x0409, buffer, sizeof(buffer), 5000)) < 0)
87 if(buffer[1] != USB_DT_STRING){
91 if((unsigned char)buffer[0] < rval)
92 rval = (unsigned char)buffer[0];
94 /* lossy conversion to ISO Latin1: */
96 if(i > buflen) /* destination buffer overflow */
98 buf[i-1] = buffer[2 * i];
99 if(buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */
106 /* ------------------------------------------------------------------------- */
109 usb_dev_handle **device, int vendorID, char *vendorNamePattern,
110 int productID, char *productNamePattern,
111 char *serialNamePattern, FILE *printMatchingDevicesFp,
116 struct usb_device *dev;
117 usb_dev_handle *handle = NULL;
118 int errorCode = USBOPEN_ERR_NOTFOUND;
123 for(bus = usb_get_busses(); bus; bus = bus->next){
124 for(dev = bus->devices; dev; dev = dev->next){ /* iterate over all devices on all busses */
125 if((vendorID == 0 || dev->descriptor.idVendor == vendorID)
126 && (productID == 0 || dev->descriptor.idProduct == productID)){
127 char vendor[256], product[256], serial[256];
129 handle = usb_open(dev); /* we need to open the device in order to query strings */
131 errorCode = USBOPEN_ERR_ACCESS;
132 if(warningsFp != NULL)
133 fprintf(warningsFp, "Warning: cannot open VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror());
136 /* now check whether the names match: */
138 if(dev->descriptor.iManufacturer > 0){
139 len = usbGetStringAscii(handle, dev->descriptor.iManufacturer, vendor, sizeof(vendor));
142 errorCode = USBOPEN_ERR_ACCESS;
143 if(warningsFp != NULL)
144 fprintf(warningsFp, "Warning: cannot query manufacturer for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror());
146 errorCode = USBOPEN_ERR_NOTFOUND;
147 /* printf("seen device from vendor ->%s<-\n", vendor); */
148 if(shellStyleMatch(vendor, vendorNamePattern)){
149 len = product[0] = 0;
150 if(dev->descriptor.iProduct > 0){
151 len = usbGetStringAscii(handle, dev->descriptor.iProduct, product, sizeof(product));
154 errorCode = USBOPEN_ERR_ACCESS;
155 if(warningsFp != NULL)
156 fprintf(warningsFp, "Warning: cannot query product for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror());
158 errorCode = USBOPEN_ERR_NOTFOUND;
159 /* printf("seen product ->%s<-\n", product); */
160 if(shellStyleMatch(product, productNamePattern)){
162 if(dev->descriptor.iSerialNumber > 0){
163 len = usbGetStringAscii(handle, dev->descriptor.iSerialNumber, serial, sizeof(serial));
166 errorCode = USBOPEN_ERR_ACCESS;
167 if(warningsFp != NULL)
168 fprintf(warningsFp, "Warning: cannot query serial for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror());
170 if(shellStyleMatch(serial, serialNamePattern)){
171 if(printMatchingDevicesFp != NULL){
173 fprintf(printMatchingDevicesFp, "VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\"\n", dev->descriptor.idVendor, dev->descriptor.idProduct, vendor, product);
175 fprintf(printMatchingDevicesFp, "VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\" serial=\"%s\"\n", dev->descriptor.idVendor, dev->descriptor.idProduct, vendor, product, serial);
189 if(handle) /* we have found a deice */
196 if(printMatchingDevicesFp != NULL) /* never return an error for listing only */