diff --git a/libnfc/buses/usbbus.c b/libnfc/buses/usbbus.c index 120090aa..b1979a6a 100644 --- a/libnfc/buses/usbbus.c +++ b/libnfc/buses/usbbus.c @@ -84,10 +84,10 @@ int usbbus_prepare() { } -TODO kenspeckle -beim ende vom programm libusb dinge wieder freigeben +//TODO kenspeckle +//beim ende vom programm libusb dinge wieder freigeben -size_t usbbus_usb_scan(char **connstrings, +size_t usbbus_usb_scan(nfc_connstring connstrings[], const size_t connstrings_len, struct usbbus_device *nfc_usb_devices, const size_t num_nfc_usb_devices, @@ -132,6 +132,7 @@ size_t usbbus_usb_scan(char **connstrings, break; } if (!found_valid_config) { + libusb_unref_device(dev); continue; } } @@ -139,6 +140,7 @@ size_t usbbus_usb_scan(char **connstrings, libusb_device_handle *udev; int res = libusb_open(dev, &udev); if (res < 0 && udev == NULL) { + libusb_unref_device(dev); continue; } @@ -151,6 +153,7 @@ size_t usbbus_usb_scan(char **connstrings, "Unable to set USB configuration (%s)", libusb_strerror(res)); libusb_close(udev); + libusb_unref_device(dev); // we failed to use the device continue; } @@ -160,25 +163,33 @@ size_t usbbus_usb_scan(char **connstrings, libusb_close(udev); uint8_t dev_address = libusb_get_device_address(dev); + printf("%s:%03d:%03d", + "Test", + dev_address, + (int) valid_config_idx); size_t size_new_str = snprintf( connstrings[device_found], - sizeof(nfc_connstring), + sizeof(connstrings[device_found]), "%s:%03d:%03d", usb_driver_name, - dev_address, (int) valid_config_idx); + dev_address, + (int) valid_config_idx); + if (size_new_str >= (int) sizeof(nfc_connstring)) { // truncation occurred, skipping that one + libusb_unref_device(dev); continue; } device_found++; // Test if we reach the maximum "wanted" devices if (device_found == connstrings_len) { + libusb_free_device_list(devices, 0); return device_found; } } } } - + libusb_free_device_list(devices, 0); return device_found; } @@ -273,15 +284,15 @@ void usbbus_get_usb_device_name(struct libusb_device *dev, libusb_device_handle } -void usbbus_get_device(uint8_t dev_address, struct libusb_device * dev, struct libusb_device_handle * dev_handle) { +void usbbus_get_device(uint8_t dev_address, struct libusb_device ** dev, struct libusb_device_handle ** dev_handle) { struct libusb_device ** device_list; ssize_t num_devices = libusb_get_device_list(ctx, &device_list); for (size_t i = 0; i < num_devices; i++) { if (libusb_get_device_address(device_list[i]) != dev_address) { continue; } else { - dev = device_list[i]; - int res = libusb_open(dev, &dev_handle); + *dev = device_list[i]; + int res = libusb_open(*dev, dev_handle); if (res != 0 || dev_handle == NULL) { log_put(LOG_GROUP,LOG_CATEGORY,NFC_LOG_PRIORITY_ERROR, "Unable to open libusb device (%s)",libusb_strerror(res)); @@ -293,10 +304,15 @@ void usbbus_get_device(uint8_t dev_address, struct libusb_device * dev, struct l // libusb works with a reference counter which is set to 1 for each device when calling libusb_get_device_list and increased // by libusb_open. Thus we decrease the counter by 1 for all devices and only the "real" device will survive libusb_free_device_list(device_list, num_devices); - } +void usbbus_close(struct libusb_device * dev, struct libusb_device_handle * dev_handle) { + libusb_close(dev_handle); + libusb_unref_device(dev); + libusb_exit(ctx); +} + uint16_t usbbus_get_vendor_id(struct libusb_device *dev) { struct libusb_device_descriptor descriptor; libusb_get_device_descriptor(dev, &descriptor); diff --git a/libnfc/buses/usbbus.h b/libnfc/buses/usbbus.h index 8da762dc..ba18c3bb 100644 --- a/libnfc/buses/usbbus.h +++ b/libnfc/buses/usbbus.h @@ -30,8 +30,10 @@ #define __NFC_BUS_USBBUS_H__ #include +#include +#include "nfc/nfc-types.h" -#define EMPTY_STRING "\0"; +#define EMPTY_STRING ((unsigned char *)"\0") struct usbbus_device { uint16_t vendor_id; @@ -44,10 +46,11 @@ struct usbbus_device { int usbbus_prepare(); -size_t usbbus_usb_scan(char ** connstrings, size_t connstrings_len, struct usbbus_device * nfc_usb_devices, size_t num_nfc_usb_devices, char * usb_driver_name); +size_t usbbus_usb_scan(nfc_connstring connstrings[], size_t connstrings_len, struct usbbus_device * nfc_usb_devices, size_t num_nfc_usb_devices, char * usb_driver_name); void usbbus_get_usb_endpoints(struct libusb_device *dev, uint8_t * endpoint_in, uint8_t * endpoint_out, uint16_t * max_packet_size); void usbbus_get_usb_device_name(struct libusb_device * dev, libusb_device_handle *udev, char *buffer, size_t len); -void usbbus_get_device(uint8_t dev_address, struct libusb_device * dev, struct libusb_device_handle * dev_handle); +void usbbus_get_device(uint8_t dev_address, struct libusb_device ** dev, struct libusb_device_handle ** dev_handle); +void usbbus_close(struct libusb_device * dev, struct libusb_device_handle * dev_handle); uint16_t usbbus_get_vendor_id(struct libusb_device * dev); uint16_t usbbus_get_product_id(struct libusb_device * dev); int usbbus_get_num_alternate_settings(struct libusb_device *dev, uint8_t config_idx); diff --git a/libnfc/drivers/acr122_usb.c b/libnfc/drivers/acr122_usb.c index 3438c6c4..b3ecb07e 100644 --- a/libnfc/drivers/acr122_usb.c +++ b/libnfc/drivers/acr122_usb.c @@ -297,7 +297,7 @@ acr122_usb_scan(const nfc_context *context, nfc_connstring connstrings[], const devices[i].name = acr122_usb_supported_devices[i].name; devices[i].max_packet_size = acr122_usb_supported_devices[i].max_packet_size; } - return usbbus_usb_scan((char **) connstrings, connstrings_len, devices, num_acr122_usb_supported_device, ACR122_USB_DRIVER_NAME); + return usbbus_usb_scan(connstrings, connstrings_len, devices, num_acr122_usb_supported_device, ACR122_USB_DRIVER_NAME); } @@ -337,6 +337,8 @@ acr122_usb_open(const nfc_context *context, const nfc_connstring connstring) { connstring_decode_level, connstring); if (connstring_decode_level < 2) { + free(dev_address_str); + free(config_idx_str); return NULL; } @@ -352,7 +354,8 @@ acr122_usb_open(const nfc_context *context, const nfc_connstring connstring) { .uiEndPointIn = 0, .uiEndPointOut = 0, }; - usbbus_get_device(dev_addres, data.dev, data.pudh); + + usbbus_get_device(dev_addres, &data.dev, &data.pudh); // Reset device libusb_reset_device(data.pudh); @@ -368,6 +371,8 @@ acr122_usb_open(const nfc_context *context, const nfc_connstring connstring) { libusb_strerror(res)); libusb_close(data.pudh); // we failed to use the specified device + free(dev_address_str); + free(config_idx_str); return NULL; } @@ -383,6 +388,8 @@ acr122_usb_open(const nfc_context *context, const nfc_connstring connstring) { libusb_strerror(res)); libusb_close(data.pudh); // we failed to use the specified device + free(dev_address_str); + free(config_idx_str); return NULL; } } @@ -391,6 +398,8 @@ acr122_usb_open(const nfc_context *context, const nfc_connstring connstring) { pnd = nfc_device_new(context, connstring); if (!pnd) { perror("malloc"); + free(dev_address_str); + free(config_idx_str); return NULL; } acr122_usb_get_usb_device_name(data.dev, data.pudh, pnd->name, sizeof(pnd->name)); @@ -399,6 +408,8 @@ acr122_usb_open(const nfc_context *context, const nfc_connstring connstring) { if (!pnd->driver_data) { perror("malloc"); nfc_device_free(pnd); + free(dev_address_str); + free(config_idx_str); return NULL; } *DRIVER_DATA(pnd) = data; @@ -407,6 +418,8 @@ acr122_usb_open(const nfc_context *context, const nfc_connstring connstring) { if (pn53x_data_new(pnd, &acr122_usb_io) == NULL) { perror("malloc"); nfc_device_free(pnd); + free(dev_address_str); + free(config_idx_str); return NULL; } @@ -418,10 +431,14 @@ acr122_usb_open(const nfc_context *context, const nfc_connstring connstring) { if (acr122_usb_init(pnd) < 0) { libusb_close(data.pudh); nfc_device_free(pnd); + free(dev_address_str); + free(config_idx_str); return NULL; } DRIVER_DATA(pnd)->abort_flag = false; + free(dev_address_str); + free(config_idx_str); return pnd; } @@ -439,7 +456,8 @@ acr122_usb_close(nfc_device *pnd) { libusb_strerror(res)); } - libusb_close(DRIVER_DATA(pnd)->pudh); + usbbus_close(DRIVER_DATA(pnd)->dev, DRIVER_DATA(pnd)->pudh); + pn53x_data_free(pnd); nfc_device_free(pnd); } diff --git a/libnfc/drivers/pn53x_usb.c b/libnfc/drivers/pn53x_usb.c index 8c23e68e..2bed980e 100644 --- a/libnfc/drivers/pn53x_usb.c +++ b/libnfc/drivers/pn53x_usb.c @@ -282,7 +282,7 @@ pn53x_usb_scan(const nfc_context *context, nfc_connstring connstrings[], const s devices[i].name = pn53x_usb_supported_devices[i].name; devices[i].max_packet_size = pn53x_usb_supported_devices[i].uiMaxPacketSize; } - return usbbus_usb_scan((char **) connstrings, connstrings_len, devices, num_pn53x_usb_supported_devices, PN53X_USB_DRIVER_NAME); + return usbbus_usb_scan(connstrings, connstrings_len, devices, num_pn53x_usb_supported_devices, PN53X_USB_DRIVER_NAME); } bool @@ -341,10 +341,7 @@ pn53x_usb_open(const nfc_context *context, const nfc_connstring connstring) { .possibly_corrupted_usbdesc = false, }; - usbbus_get_device(dev_addres, data.dev, data.pudh); - - - + usbbus_get_device(dev_addres, &data.dev, &data.pudh); // Retrieve end points, using hardcoded defaults if available // or using the descriptors otherwise. @@ -370,8 +367,10 @@ pn53x_usb_open(const nfc_context *context, const nfc_connstring connstring) { usbbus_get_product_id(data.dev), data.configIdx); } - libusb_close(data.pudh); // we failed to use the specified device + usbbus_close(data.dev, data.pudh); + free(dev_address_str); + free(config_idx_str); return NULL; } @@ -382,8 +381,10 @@ pn53x_usb_open(const nfc_context *context, const nfc_connstring connstring) { NFC_LOG_PRIORITY_ERROR, "Unable to claim USB interface (%s)", libusb_strerror(res)); - libusb_close(data.pudh); // we failed to use the specified device + usbbus_close(data.dev, data.pudh); + free(dev_address_str); + free(config_idx_str); return NULL; } data.model = pn53x_usb_get_device_model(usbbus_get_vendor_id(data.dev), usbbus_get_product_id(data.dev)); @@ -391,6 +392,9 @@ pn53x_usb_open(const nfc_context *context, const nfc_connstring connstring) { pnd = nfc_device_new(context, connstring); if (!pnd) { perror("malloc"); + usbbus_close(data.dev, data.pudh); + free(dev_address_str); + free(config_idx_str); return NULL; } pn53x_usb_get_usb_device_name(data.dev, data.pudh, pnd->name, sizeof(pnd->name)); @@ -399,6 +403,9 @@ pn53x_usb_open(const nfc_context *context, const nfc_connstring connstring) { if (!pnd->driver_data) { perror("malloc"); nfc_device_free(pnd); + usbbus_close(data.dev, data.pudh); + free(dev_address_str); + free(config_idx_str); return NULL; } *DRIVER_DATA(pnd) = data; @@ -407,6 +414,9 @@ pn53x_usb_open(const nfc_context *context, const nfc_connstring connstring) { if (pn53x_data_new(pnd, &pn53x_usb_io) == NULL) { perror("malloc"); nfc_device_free(pnd); + usbbus_close(data.dev, data.pudh); + free(dev_address_str); + free(config_idx_str); return NULL; } @@ -436,8 +446,10 @@ pn53x_usb_open(const nfc_context *context, const nfc_connstring connstring) { // HACK2: Then send a GetFirmware command to resync USB toggle bit between host & device // in case host used set_configuration and expects the device to have reset its toggle bit, which PN53x doesn't do if (pn53x_usb_init(pnd) < 0) { - libusb_close(data.pudh); nfc_device_free(pnd); + usbbus_close(data.dev, data.pudh); + free(dev_address_str); + free(config_idx_str); return NULL; } DRIVER_DATA(pnd)->abort_flag = false; @@ -460,7 +472,8 @@ pn53x_usb_close(nfc_device *pnd) { pn53x_idle(pnd); - libusb_close(DRIVER_DATA(pnd)->pudh); + usbbus_close(DRIVER_DATA(pnd)->dev, DRIVER_DATA(pnd)->pudh); + pn53x_data_free(pnd); nfc_device_free(pnd); }