From 66c4bd3524724c5b18f79a8d624e314d6010924c Mon Sep 17 00:00:00 2001 From: Krzysztof Opasiak Date: Tue, 30 Jun 2015 09:35:36 +0200 Subject: [PATCH] Add API functions for opening device. Based on Stanislaw Wadas commit. Change-Id: Ie2d675645d31c17391f26717ea81c85e96f31263 Signed-off-by: Krzysztof Opasiak --- include/libhusb.h | 7 +++ src/libhusb.c | 124 +++++++++++++++++++++++++++++++++++++--------- 2 files changed, 107 insertions(+), 24 deletions(-) diff --git a/include/libhusb.h b/include/libhusb.h index 1e739d1..fdc02e9 100644 --- a/include/libhusb.h +++ b/include/libhusb.h @@ -151,8 +151,15 @@ int libhusb_init(libhusb_context **ctx); void libhusb_exit(libhusb_context *ctx); +libhusb_device_handle *libhusb_open(libhusb_device *dev); + void libhusb_close(libhusb_device_handle *handle); +libhusb_device_handle *libhusb_device_open_with_vid_pid(libhusb_context *ctx, + uint16_t vendor_id, uint16_t product_id); + +libhusb_device *libhusb_get_device(libhusb_device_handle *handle); + ssize_t libhusb_get_devices(libhusb_context *ctx, libhusb_device ***devs); void libhusb_free_devices(libhusb_device **list, int unref_devices); diff --git a/src/libhusb.c b/src/libhusb.c index 0323c6b..7ad28ea 100644 --- a/src/libhusb.c +++ b/src/libhusb.c @@ -44,6 +44,7 @@ static inline struct libhusb_device *to_libhusb_device(struct uref *_uref) } struct libhusb_device_handle { + struct libhusb_device *device; struct libusb_device_handle *lusb_dev_handle; /* TODO: replace with bit fields */ unsigned char driver_detached[MAX_NMB_OF_CONFIGS]; @@ -98,6 +99,30 @@ static int translate_error(int error_code) } } +static void free_device(struct uref *uref) +{ + struct libhusb_device *dev = to_libhusb_device(uref); + + libusb_unref_device(dev->lusb_dev); + free(dev); +} + +static struct libhusb_device *alloc_device(libusb_device *lusb_dev) +{ + struct libhusb_device *dev; + + dev = malloc(sizeof(*dev)); + if (!dev) + goto out; + + uref_init(&dev->ref, free_device); + + libusb_ref_device(lusb_dev); + dev->lusb_dev = lusb_dev; +out: + return dev; +} + int libhusb_init(libhusb_context **ctx) { int ret = LIBHUSB_ERROR_NO_MEM; @@ -138,15 +163,90 @@ void libhusb_exit(libhusb_context *context) free(context); } +libhusb_device_handle *libhusb_open(libhusb_device *dev) +{ + libhusb_device_handle *handle; + int ret = LIBHUSB_ERROR_NO_MEM; + + assert(dev); + + handle = malloc(sizeof(*handle)); + if (!handle) + goto out; + + memset(handle, 0, sizeof(*handle)); + + handle->device = libhusb_ref_device(dev); + + ret = libusb_open(dev->lusb_dev, &(handle->lusb_dev_handle)); + if (ret < 0) { + ret = translate_error(ret); + goto unref_dev; + } + + return handle; + +unref_dev: + libhusb_unref_device(handle->device); + free(handle); +out: + return NULL; +} + void libhusb_close(libhusb_device_handle *handle) { assert(handle); libusb_close(handle->lusb_dev_handle); + libhusb_unref_device(handle->device); free(handle); } +libhusb_device_handle *libhusb_device_open_with_vid_pid(libhusb_context *ctx, + uint16_t vendor_id, uint16_t product_id) +{ + struct libhusb_device_handle *handle; + struct libhusb_device *dev; + libusb_device_handle *ldev_handle; + libusb_device *ldev; + + handle = malloc(sizeof(*handle)); + if (!handle) + goto out; + + ldev_handle = libusb_open_device_with_vid_pid(ctx->lusb_ctx, + vendor_id, product_id); + if (ldev_handle == NULL) + goto free_handle; + + handle->lusb_dev_handle = ldev_handle; + + ldev = libusb_get_device(ldev_handle); + + dev = alloc_device(ldev); + if (!dev) + goto close_handle; + + handle->device = dev; + + return handle; + +close_handle: + libusb_close(ldev_handle); +free_handle: + free(handle); +out: + return NULL; +} + +libhusb_device *libhusb_get_device(libhusb_device_handle *handle) +{ + assert(handle); + + return handle->device; +} + uint8_t libhusb_get_bus_number(libhusb_device *dev) { assert(dev); @@ -176,30 +276,6 @@ int libhusb_get_port_numbers(libhusb_device *dev, uint8_t* port_numbers, int por return port_num; } -static void free_device(struct uref *uref) -{ - struct libhusb_device *dev = to_libhusb_device(uref); - - libusb_unref_device(dev->lusb_dev); - free(dev); -} - -static struct libhusb_device *alloc_device(libusb_device *lusb_dev) -{ - struct libhusb_device *dev; - - dev = malloc(sizeof(*dev)); - if (!dev) - goto out; - - uref_init(&dev->ref, free_device); - - libusb_ref_device(lusb_dev); - dev->lusb_dev = lusb_dev; -out: - return dev; -} - ssize_t libhusb_get_devices(libhusb_context *context, libhusb_device ***devs) { ssize_t len; -- 2.34.1