From 5ebbdab950bfb75ae93d90d60f369e20ef64e667 Mon Sep 17 00:00:00 2001 From: Gerd v. Egidy Date: Sun, 13 Dec 2009 00:29:10 +0100 Subject: [PATCH] add new open functions: ftdi_usb_open_desc_index() and ftdi_usb_open_string() --- src/ftdi.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/ftdi.h | 3 + 2 files changed, 142 insertions(+), 0 deletions(-) diff --git a/src/ftdi.c b/src/ftdi.c index a87d653..8c0862c 100644 --- a/src/ftdi.c +++ b/src/ftdi.c @@ -582,6 +582,35 @@ int ftdi_usb_open(struct ftdi_context *ftdi, int vendor, int product) int ftdi_usb_open_desc(struct ftdi_context *ftdi, int vendor, int product, const char* description, const char* serial) { + return ftdi_usb_open_desc_index(ftdi,vendor,product,description,serial,0); +} + +/** + Opens the index-th device with a given, vendor id, product id, + description and serial. + + \param ftdi pointer to ftdi_context + \param vendor Vendor ID + \param product Product ID + \param description Description to search for. Use NULL if not needed. + \param serial Serial to search for. Use NULL if not needed. + \param index Number of matching device to open if there are more than one, starts with 0. + + \retval 0: all fine + \retval -1: usb_find_busses() failed + \retval -2: usb_find_devices() failed + \retval -3: usb device not found + \retval -4: unable to open device + \retval -5: unable to claim device + \retval -6: reset failed + \retval -7: set baudrate failed + \retval -8: get product description failed + \retval -9: get serial number failed + \retval -10: unable to close device +*/ +int ftdi_usb_open_desc_index(struct ftdi_context *ftdi, int vendor, int product, + const char* description, const char* serial, unsigned int index) +{ struct usb_bus *bus; struct usb_device *dev; char string[256]; @@ -635,6 +664,12 @@ int ftdi_usb_open_desc(struct ftdi_context *ftdi, int vendor, int product, if (ftdi_usb_close_internal (ftdi) != 0) ftdi_error_return(-10, "unable to close device"); + if (index > 0) + { + index--; + continue; + } + return ftdi_usb_open_dev(ftdi, dev); } } @@ -645,6 +680,110 @@ int ftdi_usb_open_desc(struct ftdi_context *ftdi, int vendor, int product, } /** + Opens the ftdi-device described by a description-string. + Intended to be used for parsing a device-description given as commandline argument. + + \param ftdi pointer to ftdi_context + \param description NULL-terminated description-string, using this format: + \li d:\ path of bus and device-node (e.g. "003/001") within usb device tree (usually at /proc/bus/usb/) + \li i:\:\ first device with given vendor and product id, ids can be decimal, octal (preceded by "0") or hex (preceded by "0x") + \li i:\:\:\ as above with index being the number of the device (starting with 0) if there are more than one + \li s:\:\:\ first device with given vendor id, product id and serial string + + \note The description format may be extended in later versions. + + \retval 0: all fine + \retval -1: usb_find_busses() failed + \retval -2: usb_find_devices() failed + \retval -3: usb device not found + \retval -4: unable to open device + \retval -5: unable to claim device + \retval -6: reset failed + \retval -7: set baudrate failed + \retval -8: get product description failed + \retval -9: get serial number failed + \retval -10: unable to close device + \retval -11: illegal description format +*/ +int ftdi_usb_open_string(struct ftdi_context *ftdi, const char* description) +{ + if (description[0] == 0 || description[1] != ':') + ftdi_error_return(-11, "illegal description format"); + + if (description[0] == 'd') + { + struct usb_bus *bus; + struct usb_device *dev; + char dev_name[PATH_MAX+1]; + + usb_init(); + + if (usb_find_busses() < 0) + ftdi_error_return(-1, "usb_find_busses() failed"); + if (usb_find_devices() < 0) + ftdi_error_return(-2, "usb_find_devices() failed"); + + for (bus = usb_get_busses(); bus; bus = bus->next) + { + for (dev = bus->devices; dev; dev = dev->next) + { + snprintf(dev_name, sizeof(dev_name), "%s/%s",bus->dirname,dev->filename); + if (strcmp(description+2,dev_name) == 0) + return ftdi_usb_open_dev(ftdi, dev); + } + } + + // device not found + ftdi_error_return(-3, "device not found"); + } + else if (description[0] == 'i' || description[0] == 's') + { + unsigned int vendor; + unsigned int product; + unsigned int index=0; + const char *serial; + const char *startp, *endp; + + errno=0; + startp=description+2; + vendor=strtoul((char*)startp,(char**)&endp,0); + if (*endp != ':' || endp == startp || errno != 0) + ftdi_error_return(-11, "illegal description format"); + + startp=endp+1; + product=strtoul((char*)startp,(char**)&endp,0); + if (endp == startp || errno != 0) + ftdi_error_return(-11, "illegal description format"); + + if (description[0] == 'i' && *endp != 0) + { + /* optional index field in i-mode */ + if (*endp != ':') + ftdi_error_return(-11, "illegal description format"); + + startp=endp+1; + index=strtoul((char*)startp,(char**)&endp,0); + if (*endp != 0 || endp == startp || errno != 0) + ftdi_error_return(-11, "illegal description format"); + } + if (description[0] == 's') + { + if (*endp != ':') + ftdi_error_return(-11, "illegal description format"); + + /* rest of the description is the serial */ + serial=endp+1; + } + + return ftdi_usb_open_desc_index(ftdi, vendor, product, NULL, serial, index); + } + else + { + ftdi_error_return(-11, "illegal description format"); + } +} + +/** Resets the ftdi device. \param ftdi pointer to ftdi_context diff --git a/src/ftdi.h b/src/ftdi.h index 9c19734..bee3c2d 100644 --- a/src/ftdi.h +++ b/src/ftdi.h @@ -289,7 +289,10 @@ extern "C" int ftdi_usb_open(struct ftdi_context *ftdi, int vendor, int product); int ftdi_usb_open_desc(struct ftdi_context *ftdi, int vendor, int product, const char* description, const char* serial); + int ftdi_usb_open_desc_index(struct ftdi_context *ftdi, int vendor, int product, + const char* description, const char* serial, unsigned int index); int ftdi_usb_open_dev(struct ftdi_context *ftdi, struct usb_device *dev); + int ftdi_usb_open_string(struct ftdi_context *ftdi, const char* description); int ftdi_usb_close(struct ftdi_context *ftdi); int ftdi_usb_reset(struct ftdi_context *ftdi); -- 1.7.1