123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 |
- /*
- * Name: opendevice.c Project: V-USB host-side library Author: Christian
- * Starkjohann Creation Date: 2008-04-10 Tabsize: 4 Copyright: (c) 2008 by
- * OBJECTIVE DEVELOPMENT Software GmbH License: GNU GPL v2 (see License.txt),
- * GNU GPL v3 or proprietary (CommercialLicense.txt) This Revision: $Id:
- * opendevice.c 740 2009-04-13 18:23:31Z cs $
- */
- /*
- * General Description: The functions in this module can be used to find and
- * open a device based on libusb or libusb-win32.
- */
- #include <stdio.h>
- #include "opendevice.h"
- /*
- * -------------------------------------------------------------------------
- */
- #define MATCH_SUCCESS 1
- #define MATCH_FAILED 0
- #define MATCH_ABORT -1
- /*
- * private interface: match text and p, return MATCH_SUCCESS, MATCH_FAILED, or
- * MATCH_ABORT.
- */
- static int _shellStyleMatch(char *text, char *p)
- {
- int last,
- matched,
- reverse;
- for (; *p; text++, p++) {
- if (*text == 0 && *p != '*')
- return MATCH_ABORT;
- switch (*p) {
- case '\\':
- /*
- * Literal match with following character.
- */
- p++;
- /*
- * FALLTHROUGH
- */
- default:
- if (*text != *p)
- return MATCH_FAILED;
- continue;
- case '?':
- /*
- * Match anything.
- */
- continue;
- case '*':
- while (*++p == '*')
- /*
- * Consecutive stars act just like one.
- */
- continue;
- if (*p == 0)
- /*
- * Trailing star matches everything.
- */
- return MATCH_SUCCESS;
- while (*text)
- if ((matched = _shellStyleMatch(text++, p)) != MATCH_FAILED)
- return matched;
- return MATCH_ABORT;
- case '[':
- reverse = p[1] == '^';
- if (reverse) /* Inverted character class. */
- p++;
- matched = MATCH_FAILED;
- if (p[1] == ']' || p[1] == '-')
- if (*++p == *text)
- matched = MATCH_SUCCESS;
- for (last = *p; *++p && *p != ']'; last = *p)
- if (*p == '-' && p[1] != ']' ? *text <= *++p
- && *text >= last : *text == *p)
- matched = MATCH_SUCCESS;
- if (matched == reverse)
- return MATCH_FAILED;
- continue;
- }
- }
- return *text == 0;
- }
- /*
- * public interface for shell style matching: returns 0 if fails, 1 if matches
- */
- static int shellStyleMatch(char *text, char *pattern)
- {
- if (pattern == NULL) /* NULL pattern is synonymous to "*" */
- return 1;
- return _shellStyleMatch(text, pattern) == MATCH_SUCCESS;
- }
- /*
- * -------------------------------------------------------------------------
- */
- int usbGetStringAscii(usb_dev_handle * dev, int index, char *buf, int buflen)
- {
- char buffer[256];
- int rval,
- i;
- if ((rval = usb_get_string_simple(dev, index, buf, buflen)) >= 0) /* use
- * libusb
- * version
- * if
- * it
- * works
- */
- return rval;
- if ((rval =
- usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR,
- (USB_DT_STRING << 8) + index, 0x0409, buffer,
- sizeof(buffer), 5000)) < 0)
- return rval;
- if (buffer[1] != USB_DT_STRING) {
- *buf = 0;
- return 0;
- }
- if ((unsigned char) buffer[0] < rval)
- rval = (unsigned char) buffer[0];
- rval /= 2;
- /*
- * lossy conversion to ISO Latin1:
- */
- for (i = 1; i < rval; i++) {
- if (i > buflen) /* destination buffer overflow */
- break;
- buf[i - 1] = buffer[2 * i];
- if (buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */
- buf[i - 1] = '?';
- }
- buf[i - 1] = 0;
- return i - 1;
- }
- /*
- * -------------------------------------------------------------------------
- */
- int usbOpenDevice(usb_dev_handle ** device, int vendorID,
- char *vendorNamePattern, int productID,
- char *productNamePattern, char *serialNamePattern,
- FILE * printMatchingDevicesFp, FILE * warningsFp)
- {
- struct usb_bus *bus;
- struct usb_device *dev;
- usb_dev_handle *handle = NULL;
- int errorCode = USBOPEN_ERR_NOTFOUND;
- usb_find_busses();
- usb_find_devices();
- for (bus = usb_get_busses(); bus; bus = bus->next) {
- for (dev = bus->devices; dev; dev = dev->next) { /* iterate over
- * all devices
- * on all
- * busses */
- if ((vendorID == 0 || dev->descriptor.idVendor == vendorID)
- && (productID == 0 || dev->descriptor.idProduct == productID)) {
- char vendor[256],
- product[256],
- serial[256];
- int len;
- handle = usb_open(dev); /* we need to open the device in order
- * to query strings */
- if (!handle) {
- errorCode = USBOPEN_ERR_ACCESS;
- if (warningsFp != NULL)
- fprintf(warningsFp,
- "Warning: cannot open VID=0x%04x PID=0x%04x: %s\n",
- dev->descriptor.idVendor,
- dev->descriptor.idProduct, usb_strerror());
- continue;
- }
- /*
- * now check whether the names match:
- */
- len = vendor[0] = 0;
- if (dev->descriptor.iManufacturer > 0) {
- len =
- usbGetStringAscii(handle, dev->descriptor.iManufacturer,
- vendor, sizeof(vendor));
- }
- if (len < 0) {
- errorCode = USBOPEN_ERR_ACCESS;
- if (warningsFp != NULL)
- fprintf(warningsFp,
- "Warning: cannot query manufacturer for VID=0x%04x PID=0x%04x: %s\n",
- dev->descriptor.idVendor,
- dev->descriptor.idProduct, usb_strerror());
- } else {
- errorCode = USBOPEN_ERR_NOTFOUND;
- /*
- * printf("seen device from vendor ->%s<-\n", vendor);
- */
- if (shellStyleMatch(vendor, vendorNamePattern)) {
- len = product[0] = 0;
- if (dev->descriptor.iProduct > 0) {
- len =
- usbGetStringAscii(handle,
- dev->descriptor.iProduct,
- product, sizeof(product));
- }
- if (len < 0) {
- errorCode = USBOPEN_ERR_ACCESS;
- if (warningsFp != NULL)
- fprintf(warningsFp,
- "Warning: cannot query product for VID=0x%04x PID=0x%04x: %s\n",
- dev->descriptor.idVendor,
- dev->descriptor.idProduct,
- usb_strerror());
- } else {
- errorCode = USBOPEN_ERR_NOTFOUND;
- /*
- * printf("seen product ->%s<-\n", product);
- */
- if (shellStyleMatch(product, productNamePattern)) {
- len = serial[0] = 0;
- if (dev->descriptor.iSerialNumber > 0) {
- len =
- usbGetStringAscii(handle,
- dev->descriptor.
- iSerialNumber, serial,
- sizeof(serial));
- }
- if (len < 0) {
- errorCode = USBOPEN_ERR_ACCESS;
- if (warningsFp != NULL)
- fprintf(warningsFp,
- "Warning: cannot query serial for VID=0x%04x PID=0x%04x: %s\n",
- dev->descriptor.idVendor,
- dev->descriptor.idProduct,
- usb_strerror());
- }
- if (shellStyleMatch(serial, serialNamePattern)) {
- if (printMatchingDevicesFp != NULL) {
- if (serial[0] == 0) {
- fprintf(printMatchingDevicesFp,
- "VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\"\n",
- dev->descriptor.idVendor,
- dev->descriptor.idProduct,
- vendor, product);
- } else {
- fprintf(printMatchingDevicesFp,
- "VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\" serial=\"%s\"\n",
- dev->descriptor.idVendor,
- dev->descriptor.idProduct,
- vendor, product, serial);
- }
- } else {
- break;
- }
- }
- }
- }
- }
- }
- usb_close(handle);
- handle = NULL;
- }
- }
- if (handle) /* we have found a deice */
- break;
- }
- if (handle != NULL) {
- errorCode = 0;
- *device = handle;
- }
- if (printMatchingDevicesFp != NULL) /* never return an error for listing
- * only */
- errorCode = 0;
- return errorCode;
- }
- /*
- * -------------------------------------------------------------------------
- */
|