X-Git-Url: https://git.cryptolib.org/?p=labortage2013badge.git;a=blobdiff_plain;f=hostware%2Fcommandline%2Fopendevice.c;fp=hostware%2Fcommandline%2Fopendevice.c;h=791175b3f34284b658542dcb822706559ff51d74;hp=0000000000000000000000000000000000000000;hb=14a4df0d4392a668439c879c89e135d5ac345688;hpb=2da43c43d4818a4f2e3af7e8ec138c1f98019d9e diff --git a/hostware/commandline/opendevice.c b/hostware/commandline/opendevice.c new file mode 100644 index 0000000..791175b --- /dev/null +++ b/hostware/commandline/opendevice.c @@ -0,0 +1,203 @@ +/* Name: opendevice.c + * Project: AVR-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 692 2008-11-07 15:07:40Z cs $ + */ + +/* +General Description: +The functions in this module can be used to find and open a device based on +libusb or libusb-win32. +*/ + +#include +#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 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; +} + +/* ------------------------------------------------------------------------- */