From 15079e78d3cbca7e33bd7f421c00ada20599e495 Mon Sep 17 00:00:00 2001 From: Fahrzin Hemmati Date: Mon, 18 Apr 2016 22:48:42 +0200 Subject: [PATCH] Add new function ftdi_usb_get_strings2() This new version of ftdi_usb_get_strings() only closes the device if it was opened by the function, too. [minor code and changelog tweaks by Thomas Jarosch] --- src/ftdi.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---- src/ftdi.h | 10 ++++++-- 2 files changed, 73 insertions(+), 8 deletions(-) diff --git a/src/ftdi.c b/src/ftdi.c index 573080a..529b99e 100644 --- a/src/ftdi.c +++ b/src/ftdi.c @@ -406,16 +406,76 @@ void ftdi_list_free2(struct ftdi_device_list *devlist) \retval -9: get serial number failed \retval -11: libusb_get_device_descriptor() failed */ -int ftdi_usb_get_strings(struct ftdi_context * ftdi, struct libusb_device * dev, - char * manufacturer, int mnf_len, char * description, int desc_len, char * serial, int serial_len) +int ftdi_usb_get_strings(struct ftdi_context *ftdi, + struct libusb_device *dev, + char *manufacturer, int mnf_len, + char *description, int desc_len, + char *serial, int serial_len) { - struct libusb_device_descriptor desc; + int ret; if ((ftdi==NULL) || (dev==NULL)) return -1; if (ftdi->usb_dev == NULL && libusb_open(dev, &ftdi->usb_dev) < 0) - ftdi_error_return(-4, "libusb_open() failed"); + ftdi_error_return(-4, "libusb_open() failed"); + + // ftdi->usb_dev will not be NULL when entering ftdi_usb_get_strings2(), so + // it won't be closed either. This allows us to close it whether we actually + // called libusb_open() up above or not. This matches the expected behavior + // (and note) for ftdi_usb_get_strings(). + ret = ftdi_usb_get_strings2(ftdi, dev, + manufacturer, mnf_len, + description, desc_len, + serial, serial_len); + + // only close it if it was successful, as all other return codes close + // before returning already. + if (ret == 0) + ftdi_usb_close_internal(ftdi); + + return ret; +} + +/** + Return device ID strings from the usb device. + + The parameters manufacturer, description and serial may be NULL + or pointer to buffers to store the fetched strings. + + \note The old function ftdi_usb_get_strings() always closes the device. + This version only closes the device if it was opened by it. + + \param ftdi pointer to ftdi_context + \param dev libusb usb_dev to use + \param manufacturer Store manufacturer string here if not NULL + \param mnf_len Buffer size of manufacturer string + \param description Store product description string here if not NULL + \param desc_len Buffer size of product description string + \param serial Store serial string here if not NULL + \param serial_len Buffer size of serial string + + \retval 0: all fine + \retval -1: wrong arguments + \retval -4: unable to open device + \retval -7: get product manufacturer failed + \retval -8: get product description failed + \retval -9: get serial number failed + \retval -11: libusb_get_device_descriptor() failed +*/ +int ftdi_usb_get_strings2(struct ftdi_context *ftdi, struct libusb_device *dev, + char *manufacturer, int mnf_len, + char *description, int desc_len, + char *serial, int serial_len) +{ + struct libusb_device_descriptor desc; + + if ((ftdi==NULL) || (dev==NULL)) + return -1; + + char need_open = (ftdi->usb_dev == NULL); + if (need_open && libusb_open(dev, &ftdi->usb_dev) < 0) + ftdi_error_return(-4, "libusb_open() failed"); if (libusb_get_device_descriptor(dev, &desc) < 0) ftdi_error_return(-11, "libusb_get_device_descriptor() failed"); @@ -447,7 +507,8 @@ int ftdi_usb_get_strings(struct ftdi_context * ftdi, struct libusb_device * dev, } } - ftdi_usb_close_internal (ftdi); + if (need_open) + ftdi_usb_close_internal (ftdi); return 0; } diff --git a/src/ftdi.h b/src/ftdi.h index fa53b29..ca38bbe 100644 --- a/src/ftdi.h +++ b/src/ftdi.h @@ -480,9 +480,13 @@ extern "C" void ftdi_list_free(struct ftdi_device_list **devlist); void ftdi_list_free2(struct ftdi_device_list *devlist); int ftdi_usb_get_strings(struct ftdi_context *ftdi, struct libusb_device *dev, - char * manufacturer, int mnf_len, - char * description, int desc_len, - char * serial, int serial_len); + char *manufacturer, int mnf_len, + char *description, int desc_len, + char *serial, int serial_len); + int ftdi_usb_get_strings2(struct ftdi_context *ftdi, struct libusb_device *dev, + char *manufacturer, int mnf_len, + char *description, int desc_len, + char *serial, int serial_len); int ftdi_eeprom_set_strings(struct ftdi_context *ftdi, char * manufacturer, char * product, char * serial); -- 1.7.1