api: Switch to Tizen Native API conventions 95/64795/42
authorPaweł Szewczyk <p.szewczyk@samsung.com>
Thu, 7 Apr 2016 13:55:29 +0000 (15:55 +0200)
committertaeyoung <ty317.kim@samsung.com>
Thu, 1 Sep 2016 00:22:14 +0000 (09:22 +0900)
Change-Id: I41fa22da669864b161f4d6ac8baed19d9f1916dd
Signed-off-by: Paweł Szewczyk <p.szewczyk@samsung.com>
20 files changed:
.gitignore
CMakeLists.txt
doc/usb_host_doc.h [new file with mode: 0644]
doxygen.cfg
example/lsdev.c
example/packaging/usbhost-test.spec
example/simple_sync.c
include/common.h
include/libhusb.h [deleted file]
include/libhusb_internal.h [deleted file]
include/log.h
include/usb_host.h [new file with mode: 0644]
include/usb_host_internal.h [new file with mode: 0644]
packaging/capi-system-usbhost.spec
src/libhusb.c [deleted file]
src/usb_host.c [new file with mode: 0644]
tests/libhusb-test.c [deleted file]
tests/libusb-wrap.c [deleted file]
tests/libusb_wrap.c [new file with mode: 0644]
tests/usb_host_test.c [new file with mode: 0644]

index 31809ca89e19035528aef913a25f813f4b362ff1..ca5a89c8be6942e37d8cdbdbf9691ca1dc1753e7 100644 (file)
@@ -32,11 +32,6 @@ series
 cscope.*
 ncscope.*
 
-#
-# ignore doxygen documentation
-#
-doc/
-
 #
 #ignode build directory
 #
index 28abf5c2d5a68d4d946683dbf5e30323fa6d25ab..00fb460f45e52f4711f474f9d4821c022f3dd7e7 100644 (file)
@@ -43,7 +43,7 @@ pkg_check_modules(pkgs REQUIRED ${PKG_MODULES})
 IF(BUILD_SHARED_LIBS)
 
        SET(HOST_CAPI_SRCS
-       src/libhusb.c
+       src/usb_host.c
        )
 
        INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
@@ -69,7 +69,7 @@ IF(BUILD_SHARED_LIBS)
                VERSION 0.1.0
        )
 
-       INSTALL(FILES include/libhusb.h DESTINATION ${INCLUDEDIR}/)
+       INSTALL(FILES include/usb_host.h DESTINATION ${INCLUDEDIR}/)
        INSTALL(FILES src/40-usb.rules DESTINATION /usr/lib/udev/rules.d)
 
        INSTALL(TARGETS ${LIBNAME} DESTINATION ${LIBDIR})
@@ -121,9 +121,9 @@ ENDIF(BUILD_DOC)
 IF(BUILD_TESTS)
        ENABLE_TESTING()
        SET( TESTS_SRCS
-               tests/libhusb-test.c
-               tests/libusb-wrap.c
-               src/libhusb.c
+               tests/usb_host_test.c
+               tests/libusb_wrap.c
+               src/usb_host.c
        )
 
        INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/doc/usb_host_doc.h b/doc/usb_host_doc.h
new file mode 100644 (file)
index 0000000..62a426f
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_USB_HOST_DOC_H__
+#define __TIZEN_USB_HOST_DOC_H__
+
+/**
+ * @ingroup CAPI_SYSTEM_FRAMEWORK
+ * @defgroup CAPI_USB_HOST_MODULE USB Host
+ * @brief This module provides an API for raw access to USB devices.
+ *
+ * @section CAPI_USB_HOST_MODULE_HEADER Required Header
+ * \#include <usb_host.h>
+ *
+ * @section CAPI_USB_HOST_MODULE_OVERVIEW Overview
+ * USB host API provides direct access to USB devices. Before using it, become
+ * familiar with USB protocol specification.
+ * Note, that this API is created for *host* mode USB, i.e. communication with
+ * connected devices.
+ *
+ * @defgroup CAPI_USB_HOST_INIT_MODULE Library init/cleanup
+ * @brief This API is used to initialize and cleanup the library
+ * @ingroup CAPI_USB_HOST_MODULE
+ * @section CAPI_USB_HOST_INIT_MOUDLE_OVERVIEW Overview
+ * Before using any of usb_host API functions you must initialize API context.
+ * Also you must cleanup context after using USB host API.
+ *
+ * @defgroup CAPI_USB_HOST_DEV_MODULE Device handling and enumeration
+ * @brief This API is used to manage USB devices
+ * @ingroup CAPI_USB_HOST_MODULE
+ * @section CAPI_USB_HOST_DEV_MOUDLE_OVERVIEW Overview
+ * Operations described here help with enumerating, opening and closing devices.
+ *
+ * @section CAPI_USB_HOST_DEV_MOUDLE_OPENING Opening a device node
+ * In order to communicate with device, you must open a device.
+ * The easiest way to do this is to use usb_host_device_open_with_vid_pid() function.
+ * However, it is not recommended in most of real-life applications, since there can be more than
+ * one device with given vendor id and product id. Another way is to list all available devices
+ * and choose the one we want to communicate with.
+ *
+ * @code
+ * usb_host_device_h *devs;
+ * usb_host_device_h found = NULL;
+ * n = usb_host_get_device_list(ctx, &devs);
+ *
+ * for (i = 0; i < n; ++i) {
+ *     if (check(devs[i]) {
+ *             found = devs[i];
+ *             break;
+ *     }
+ * }
+ *
+ * if (found) {
+ *     usb_host_device_open(found);
+ *
+ *     //perform communication
+ *     ...
+ *
+ *     usb_host_device_close(dev);
+ * }
+ *
+ * usb_host_free_devices(devs);
+ * @endcode
+ *
+ * The example code above shows how to open a device for communication and clean up
+ * allocated resources afterwards.
+ * First, we iterate through all connected devices looking for the one we want to communicate with.
+ * The check() function can be implemented based on any device parameters. Use usb_host_get_*
+ * functions to get these parameters, e.g. usb_host_get_device_descriptor().
+ * If we found a device, we can open it by usb_host_device_open() and perform
+ * communication with it.
+ * After performing communication we should close device and free device list.
+ *
+ * You can check if device is opened by calling usb_host_is_device_opened().
+ *
+ * Each device has reference counter. Functions usb_host_ref_device() and
+ * usb_host_unref_device() are used to ref or unref device. When ref counter
+ * reach 0 device will be freed.
+ * Devices reached by calling usb_host_get_devices() have a reference count of
+ * 1, and usb_host_free_devices() can optionally decrease the reference count
+ * on all devices in the list. usb_host_device_open() adds another reference which is
+ * later destroyed by usb_host_device_close().
+ *
+ * @section CAPI_USB_HOST_DEV_MOUDLE_PREPARING Preparing Communication
+ * Before communicating with device, you should claim the interface you want to communicate
+ * on. Kernel driver can be attached to the interface and you should detach it if you want
+ * to use that interface. You can do it directly by calling usb_host_kernel_driver_active() and
+ * usb_host_detach_kernel_driver or pass force flag to usb_host_claim_interface();
+ *
+ * @code
+ * ret = usb_host_claim_interface(interface);
+ * @endcode
+ *
+ * In this case driver will be detached if there is an active one and will be re-attached
+ * when you release it by usb_host_release_interface().
+ *
+ * Remember to release claimed interfaces after communication and re-attach manually detached
+ * kernel drivers.
+ *
+ * @defgroup CAPI_USB_HOST_CONFIG_MODULE USB Configuration
+ * @brief USB configuration-related API
+ * @ingroup CAPI_USB_HOST_MODULE
+ * @section CAPI_USB_HOST_CONFIG_MODULE_OVERVIEW Overview
+ * Data structures and operations described here are related to USB configuration.
+ *
+ * @defgroup CAPI_USB_HOST_INTERFACE_MODULE USB Interface
+ * @brief USB interface-related API
+ * @ingroup CAPI_USB_HOST_MODULE
+ * @section CAPI_USB_HOST_INTERFACE_MODULE_OVERVIEW Overview
+ * Data structures and operations described here are related to USB interface.
+ * Each interface has number of endpoints used for performing transfer operations.
+ *
+ * @defgroup CAPI_USB_HOST_ENDPOINT_MODULE USB Endpoint
+ * @brief USB endpoint-related API
+ * @ingroup CAPI_USB_HOST_MODULE
+ * @section CAPI_USB_HOST_INTERFACE_MODULE_OVERVIEW Overview
+ * Data structures and operations described here are related to USB endpoint.
+ * Endpoints are used to perform USB transfers.
+ *
+ * @defgroup CAPI_USB_HOST_SYNCIO_MODULE Synchronous IO
+ * @brief This API is used to perform synchronous operations
+ * @ingroup CAPI_USB_HOST_MODULE
+ * @section CAPI_USB_HOST_SYNCIO_MODULE_OVERVIEW Overview
+ * A transfer is performed by single function call
+ * which returns after transfer was finished.
+ * Before transferring, you must select proper endpoint. Then you can perform transfer operations
+ * on it:
+ *
+ * @code
+ * int transferred;
+ * usb_host_cfg_h cfg;
+ * usb_host_interface_h iface;
+ * usb_host_endpoint_h ep;
+ *
+ * usb_host_device_get_config(dev, cfg_index, &cfg);
+ * usb_host_config_get_interface(cfg, interface_number, &iface);
+ * usb_host_interface_get_endpoint(iface, ep_number, &ep);
+ *
+ * ret = usb_host_transfer(ep, data, length, &transfered, 0);
+ * if (ret < 0)
+ *     error();
+ * @endcode
+ *
+ * In this example data buffer contains data received from device. Value of transfered
+ * is set to the number of received bytes.
+ *
+ * @section CAPI_USB_HOST_MOUDLE_RELATED_FEATURES Related Features
+ * This API is related with the following features:
+ *  - http://tizen.org/feature/USB.host
+ *
+ * It is recommended to design feature related codes in your application for reliability.\n
+ *
+ * You can check if a device supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.\n
+ *
+ * To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK.\n
+ *
+ * More details on featuring your application can be found from <a href="https://developer.tizen.org/development/tools/native-tools/manifest-text-editor#feature"><b>Feature List</b>.</a>
+ */
+
+#endif /* __TIZEN_USB_HOST_DOC_H__ */
index 599cd4990bdc9a8c1a29734dc64ea0093d41c4a4..04ff5ea70191956ec1c052108e2cd5cb50492973 100644 (file)
@@ -648,7 +648,7 @@ WARN_LOGFILE           =
 # directories like "/usr/src/myproject". Separate the files or directories
 # with spaces.
 
-INPUT                  = $(SRCDIR)/include/ $(SRCDIR)/src
+INPUT                  = $(SRCDIR)/include/ $(SRCDIR)/src $(SRCDIR)/doc
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
index afd4d63b2fcb67fb89a9a3da4fc4ed9881c3b2ed..441b223ae79d9328fdd5270a64d6a9c3e98f0022 100644 (file)
 #include <stdio.h>
 #include <stdint.h>
 #include <stdlib.h>
+#include <string.h>
 
-#include <libhusb.h>
+#include <usb_host.h>
 
-static void print_devs(libhusb_device **devs, libhusb_context *ctx)
+#define PORT_NUMBERS 8
+#define BUF_SIZE 256
+
+static void print_devs(usb_host_device_h *devs, usb_host_context_h ctx)
 {
-       libhusb_device *dev;
+       usb_host_device_h dev;
        int i = 0, j = 0;
-       uint8_t path[8];
+       int path[PORT_NUMBERS];
        int r;
+       int vid, pid, bus, addr, len;
 
        int data1;
-       libhusb_device_handle *dev_handle;
-       libhusb_device *dev_vp;
-       char str1[256];
-       struct libhusb_cfg_descriptor *config;
-       struct libhusb_device_descriptor desc;
-       int conf;
+       char str1[BUF_SIZE];
+       usb_host_config_h conf;
+       usb_host_interface_h iface;
 
        printf("Getting device list: \n");
 
        while ((dev = devs[i++]) != NULL) {
-               r = libhusb_get_device_descriptor(dev, &desc);
+               r = usb_host_device_get_id_vendor(dev, &vid);
+               if (r < 0) {
+                       printf("Cannot get vendor id");
+                       return;
+               }
+
+               r = usb_host_device_get_id_product(dev, &pid);
+               if (r < 0) {
+                       printf("Cannot get product id");
+                       return;
+               }
+
+               r = usb_host_device_get_bus_number(dev, &bus);
+               if (r < 0) {
+                       printf("Cannot get bus number");
+                       return;
+               }
+
+               r = usb_host_device_get_address(dev, &addr);
                if (r < 0) {
-                       fprintf(stderr, "failed to get device descriptor");
+                       printf("Cannot get device address");
                        return;
                }
 
-               printf("%04x:%04x (bus %d, device %d)",
-                       desc.idVendor, desc.idProduct,
-                       libhusb_get_bus_number(dev), libhusb_get_address(dev));
+               printf("%04x:%04x (bus %d, device %d)", vid, pid, bus, addr);
 
-               r = libhusb_get_port_numbers(dev, path, sizeof(path));
+               len = 8;
+               r = usb_host_device_get_port_numbers(dev, path, PORT_NUMBERS, &len);
                if (r < 0)
                        printf("cant get port numbers\n");
-               else if (r > 0) {
+               else {
                        printf(" path: %d", path[0]);
-                       for (j = 1; j < r; j++)
+                       for (j = 1; j < len; j++)
                                printf(".%d", path[j]);
                }
                printf("\n");
        }
 
-       int vid, pid;
        printf("provide vid and pid of device which you want to operate on\n");
        printf("\n enter device vid and hit enter(with 0x):");
        scanf("%x", &vid);
@@ -69,104 +87,87 @@ static void print_devs(libhusb_device **devs, libhusb_context *ctx)
 
        printf("\nOpening device vid:0x%x  pid:0x%x\n", vid, pid);
 
-       dev_handle = libhusb_device_open_with_vid_pid(ctx, vid, pid);
-       if (dev_handle == NULL) {
+       r = usb_host_device_open_with_vid_pid(ctx, vid, pid, &dev);
+       if (r < 0) {
                printf("cant get dev with vid pid\n");
                return;
        }
-       if (dev_handle != NULL) printf("opened\n");
-
-       dev_vp = libhusb_get_device(dev_handle);
-       if (dev_vp == NULL) {
-               printf("ERROR\n");
-               return;
-       }
+       printf("opened\n");
 
-       data1 = libhusb_get_max_packet_size(dev_vp, 1);
-       if (data1 < 0) {
-               printf("ERROR: %s", libhusb_error_name(data1));
+       r = usb_host_device_get_max_packet_size_0(dev, &data1);
+       if (r < 0) {
+               printf("ERROR: %s", strerror(r));
                return;
        }
 
        printf("\nmax packet size: %d\n", data1);
 
-       r = libhusb_get_active_config(dev_handle, &conf);
+       r = usb_host_get_active_config(dev, &conf);
        if (r < 0) {
-               printf("ERROR: %s", libhusb_error_name(r));
+               printf("ERROR: %s", strerror(r));
                return;
        }
 
-       printf("\nbconfig: %d\n", conf);
+       r = usb_host_device_get_config(dev, 1, &conf);
 
        printf("\ntrying to set 2nd config\n");
-       r = libhusb_set_config(dev_handle, 1);
-       if (r < 0) printf("failure\n");
+       r = usb_host_set_config(conf);
+       if (r < 0)
+               printf("failure\n");
+
+       r = usb_host_config_get_interface(conf, 0, &iface);
+       if (r < 0)
+               printf("failure\n");
 
        printf("claiming iface\n");
-       r = libhusb_claim_interface(dev_handle, 0, 0);
-       if (r < 0) printf("failure\n");
+       r = usb_host_claim_interface(iface, 1);
+       if (r < 0)
+               printf("failure\n");
 
        printf("releasing iface\n");
-       r = libhusb_release_interface(dev_handle, 0);
-       if (r < 0) printf("failure\n");
-
-/*
-       commented because sometime after reset device require hardware restart
-       printf("reseting device \n");
-       r = libhusb_reset_device(dev_handle);
-       if (r < 0) printf("failure\n");
-*/
-
-       printf("is kernel driver active on iface 1? \n");
-       r = libhusb_kernel_driver_active(dev_handle, 0);
-       if (r == 0)
-               printf("no active driver\n");
-       else if (r == 1)
-               printf("kernel driver is active\n");
-       else if (r != 0 || r != 1)
-               printf("ERROR\n");
-
-       printf("detaching kernel driver\n");
-       r = libhusb_detach_kernel_driver(dev_handle, 0);
-       if (r < 0) printf("failure\n");
-
-       printf("attaching kernel driver\n");
-       r = libhusb_attach_kernel_driver(dev_handle, 0);
-       if (r < 0) printf("failure\n");
-
-       r = libhusb_get_string_descriptor_ascii(dev_handle, desc.iProduct,
-                                               (unsigned char *) str1, sizeof(str1));
-       if (r < 0) printf("failure\n");
-       else printf("Product name: %s\n", str1);
-
-       r = libhusb_get_config_descriptor(dev_vp, 0, &config);
-       if (r < 0) printf("failure\n");
-
-       libhusb_free_config_descriptor(config);
-       libhusb_close(dev_handle);
+       r = usb_host_release_interface(iface);
+       if (r < 0)
+               printf("failure\n");
+
+       len = BUF_SIZE;
+       r = usb_host_device_get_product_str(dev, &len, str1);
+       if (r < 0)
+               printf("failure\n");
+       else
+               printf("Product name: %s\n", str1);
+
+       len = BUF_SIZE;
+       r = usb_host_device_get_manufacturer_str(dev, &len, str1);
+       if (r < 0)
+               printf("failure\n");
+       else
+               printf("Manufacturer name: %s\n", str1);
+
+       usb_host_config_destroy(conf);
+       usb_host_device_close(dev);
 }
 
 int main(void)
 {
-       struct libhusb_context *ctx;
-       struct libhusb_device **devs;
+       usb_host_context_h ctx;
+       usb_host_device_h *devs;
        int r;
-       ssize_t cnt;
+       int cnt;
 
-       r = libhusb_init(&ctx);
+       r = usb_host_create(&ctx);
        if (r < 0) {
-               printf("ERROR: %s", libhusb_error_name(r));
+               printf("ERROR: %s", strerror(r));
                return r;
        }
 
-       cnt = libhusb_get_devices(ctx, &devs);
-       if (cnt < 0)
-               return (int) cnt;
+       r = usb_host_get_device_list(ctx, &devs, &cnt);
+       if (r < 0)
+               return r;
 
        print_devs(devs, ctx);
-       libhusb_free_devices(devs, 1);
+       usb_host_free_device_list(devs, 1);
 
-       libhusb_exit(ctx);
+       usb_host_destroy(ctx);
 
        return 0;
 }
index ca492035bc726cf0f16d3f4adc3c4b2880b9d874..95f5ff67542102fa85dc5e80fd30bfd0347da065 100644 (file)
@@ -8,6 +8,7 @@ Source0:    %{name}-%{version}.tar.gz
 Source1001: %{name}.manifest
 BuildRequires:  cmake
 BuildRequires:  pkgconfig(capi-system-usbhost)
+BuildRequires:  pkgconfig(capi-base-common)
 
 Requires(post): /sbin/ldconfig
 Requires(postun): /sbin/ldconfig
index bac70256bbf7fe60503e119afa0e685765bcba92..2d60c654b9ed31d3d649e9b3a275f21f81b0305b 100644 (file)
 #include <unistd.h>
 #include <stdlib.h>
 
-#include <libhusb.h>
+#include <usb_host.h>
 
 #define BUF_LEN        8192
 
-libhusb_device_handle *dev_handle;
+usb_host_device_h dev;
 
-static void print_devs(libhusb_device **devs, libhusb_context *ctx)
+static void print_devs(usb_host_device_h *devs, usb_host_context_h ctx)
 {
-       libhusb_device *dev;
+       usb_host_device_h idev;
        int i = 0, j = 0;
-       uint8_t path[8];
-       int r; 
-       struct libhusb_device_descriptor desc;
-
-       while ((dev = devs[i++]) != NULL) {
-               r = libhusb_get_device_descriptor(dev, &desc);
-               if (r < 0) {
-                       fprintf(stderr, "failed to get device descriptor");
-                       return;
-               }
-
-               printf("%04x:%04x (bus id %d, device id %d)",
-                       desc.idVendor, desc.idProduct,
-                       libhusb_get_bus_number(dev), libhusb_get_address(dev));
-
-               r = libhusb_get_port_numbers(dev, path, sizeof(path));
-               if (r > 0) {
+       int path[8];
+       int r;
+       int vid, pid, bus, addr;
+       int len;
+
+       printf("Getting device list: \n");
+
+       while ((idev = devs[i++]) != NULL) {
+               usb_host_device_get_id_vendor(idev, &vid);
+               usb_host_device_get_id_product(idev, &pid);
+               usb_host_device_get_bus_number(idev, &bus);
+               usb_host_device_get_address(idev, &addr);
+               printf("%04x:%04x (bus %d, device %d)", vid, pid, bus, addr);
+
+               r = usb_host_device_get_port_numbers(idev, path, 8, &len);
+               if (r < 0)
+                       printf("cant get port numbers\n");
+               else if (r > 0) {
                        printf(" path: %d", path[0]);
-                       for (j = 1; j < r; j++)
+                       for (j = 1; j < len; j++)
                                printf(".%d", path[j]);
                }
                printf("\n");
        }
 }
 
-static int connect_to_dev_interface(int vid, int pid, struct libhusb_context *ctx)
+static int connect_to_dev_interface(int vid, int pid, usb_host_context_h ctx)
 {
        int r;
+       usb_host_interface_h iface;
+       usb_host_config_h cfg;
 
-       dev_handle = libhusb_device_open_with_vid_pid(ctx, vid, pid);
-       if (dev_handle == NULL) {
+       r = usb_host_device_open_with_vid_pid(ctx, vid, pid, &dev);
+       if (r < 0) {
                printf("cant get dev with vid pid\n");
                return -1;
        }
 
+       r = usb_host_get_active_config(dev, &cfg);
+       if (r < 0) {
+               printf("cant get active config\n");
+               return -1;
+       }
+
+       r = usb_host_config_get_interface(cfg, 0, &iface);
+       if (r < 0) {
+               printf("cant get interface 0\n");
+               return r;
+       }
+
        printf("claiming iface\n");
-       if (libhusb_claim_interface(dev_handle, 0, 0)){
-               r = libhusb_detach_kernel_driver(dev_handle, 0);
-               if (r) {
-                       printf("unable to detach kernel driver: %s\n",
-                              libhusb_error_name(r));
-                       goto out2;
-               }
-               r = libhusb_claim_interface(dev_handle, 0, 0);
-               if (r) {
-                       printf("can't claim interface: %s\n",
-                              libhusb_error_name(r));
-                       goto out3;
-               }
+       if (usb_host_claim_interface(iface, 1)) {
+               printf("can't claim interface: %s\n",
+                      strerror(r));
+               goto out;
        }
 
        return 0;
 
-out3:
-       libhusb_attach_kernel_driver(dev_handle, 0);
-
-out2:
-       libhusb_close(dev_handle);
+out:
+       usb_host_device_close(dev);
 
-       libhusb_exit(ctx);
+       usb_host_destroy(ctx);
        return 1;
 }
 
 int main(void)
 {
-       struct libhusb_context *ctx;
-       struct libhusb_device **devs;
+       usb_host_context_h ctx;
+       usb_host_device_h *devs;
        int r;
        ssize_t cnt;
        int vid,pid;
-       libhusb_device *dev_vp;
-       unsigned char in_addr, out_addr;
-       struct libhusb_cfg_descriptor *config;
-       struct libhusb_interface_descriptor const *iface;
+       usb_host_interface_h interface;
+       usb_host_config_h cfg;
+       usb_host_endpoint_h in_ep, out_ep;
        int n;
 
-       r = libhusb_init(&ctx);
+       r = usb_host_create(&ctx);
        if (r < 0)
                return r;
 
-       cnt = libhusb_get_devices(ctx, &devs);
-       if (cnt < 0)
-               return (int) cnt;
+       r = usb_host_get_device_list(ctx, &devs, &cnt);
+       if (r < 0)
+               return r;
 
        printf("Getting dev list: \n");
 
@@ -121,43 +123,37 @@ int main(void)
        printf("provide vid and pid of device which you want to operate on\n");
        printf("\n enter device vid and hit enter:");
        scanf ("%x",&vid);
-       printf("\n enter device vid and hit enter:");
+       printf("\n enter device pid and hit enter:");
        scanf ("%x",&pid);
 
        r = connect_to_dev_interface(vid, pid, ctx);
        if (r < 0) {
-               printf("failure %s\n",libhusb_error_name(r));
-               return r;
-       }
-       dev_vp = libhusb_get_device(dev_handle);
-       r = libhusb_get_config_descriptor(dev_vp, 0, &config);
-       if (r < 0) {
-               printf("failure\n");
+               printf("failure %s\n", strerror(r));
                return r;
        }
 
-       iface = &config->interface[0].altsetting[0];
-       in_addr = iface->endpoint[0].bEndpointAddress;
-       out_addr = iface->endpoint[1].bEndpointAddress;
+       usb_host_device_get_config(dev, 0, &cfg);
+       usb_host_config_get_interface(cfg, 0, &interface);
+       usb_host_interface_get_endpoint(interface, 0, &in_ep);
+       usb_host_interface_get_endpoint(interface, 1, &out_ep);
 
        for(n = 0; n < 100; n++) {
                static unsigned char buffer[BUF_LEN];
                int bytes;
-               libhusb_bulk_transfer(dev_handle, in_addr, buffer, BUF_LEN,
+               usb_host_transfer(out_ep, buffer, BUF_LEN,
                                     &bytes, 500);
-               libhusb_bulk_transfer(dev_handle, out_addr, buffer, BUF_LEN,
+               usb_host_transfer(in_ep, buffer, BUF_LEN,
                                     &bytes, 500);
        }
        printf("EXITING\n\n");
 
-       libhusb_release_interface(dev_handle, 0);
-       libhusb_attach_kernel_driver(dev_handle, 0);
+       usb_host_release_interface(interface);
 
-       libhusb_free_config_descriptor(config);
-       libhusb_free_devices(devs, 1);
+       usb_host_config_destroy(cfg);
+       usb_host_free_device_list(devs, 1);
 
-       libhusb_close(dev_handle);
-       libhusb_exit(ctx);
+       usb_host_device_close(dev);
+       usb_host_destroy(ctx);
 
        return 0;
 }
index 2475f2351355cb210f61879c215300b23c7b336d..4a23b5c059d3e78ee71f70c5a5ccbe394fb25612 100644 (file)
@@ -15,8 +15,8 @@
  * limitations under the License.
  */
 
-#ifndef LIBHUSB_COMMON_H
-#define LIBHUSB_COMMON_H
+#ifndef USB_HOST_COMMON_H
+#define USB_HOST_COMMON_H
 
 #include <stddef.h>
 
@@ -35,4 +35,4 @@ extern "C" {
 }
 #endif
 
-#endif /* LIBHUSB_COMMON_H */
+#endif /* USB_HOST_COMMON_H */
diff --git a/include/libhusb.h b/include/libhusb.h
deleted file mode 100644 (file)
index f323a43..0000000
+++ /dev/null
@@ -1,826 +0,0 @@
-/*
- * libhusb.h
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef LIBHUSB_H
-#define LIBHUSB_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdint.h>
-
-/**
- * @brief Context of library
- * @details This structure represents libhusb session.
- * Using own session allow to use of library independently.
- * For example calling libhusb_exit() will ont destroy resources
- * that are being used by another user of library.
- *
- * To create session there is need to call libhusb_init(), to
- * to destroy libhusb_exit(). Each session created by libhusb_init()
- * hast to be destroyed using libhusb_exit()
- */
-struct libhusb_context;
-
-typedef struct libhusb_context libhusb_context;
-
-/**
- * @brief Structure representing USB device.
- * @details This structure represents libhusb device found on USB bus.
- *
- * Some basic operations can be performed on a device using this struct.
- * To perform any I/O a device handle must be obtain by opening device
- * using libhusb_open() or libhusb_device_open_with_vid_pid().
- *
- */
-struct libhusb_device;
-
-typedef struct libhusb_device libhusb_device;
-
-/**
- * @brief libhusb_device_handle struct
- * @details This opaqe type, and represents handle to USB device.
- *
- * Hendle is used to perform I/O operations, when finished libhusb_close()
- * should be called.
- */
-struct libhusb_device_handle;
-
-typedef struct libhusb_device_handle libhusb_device_handle;
-
-/**
- * @brief libhusb_cfg_descriptor struct
- * @details Structure represents the standard USB configuration descriptor.
- *
- * All multiple-byte fields are represented in host-endian format.
- */
-struct libhusb_cfg_descriptor;
-
-typedef struct libhusb_cfg_descriptor libhusb_cfg_descriptor;
-
-/**
- * @brief libhusb_supported_speed
- * @details This field contain speed that USB device can support.
- */
-enum libhusb_supported_speed {
-       LIBHUSB_SPEED_UNKNOWN = 0,
-
-       /** Low speed (1.5MBit/s). */
-       LIBHUSB_SPEED_LOW = 1,
-
-       /** Full speed (12MBit/s). */
-       LIBHUSB_SPEED_FULL = 2,
-
-       /** High speed (480MBit/s). */
-       LIBHUSB_SPEED_HIGH = 3,
-
-       /** TSuper speed (5000MBit/s). */
-       LIBHUSB_SPEED_SUPER = 4,
-};
-
-/**
- * @brief libhusb_device_descriptor struct
- * @details This structure presents standard USB device descriptor.
- */
-struct libhusb_device_descriptor {
-       uint8_t  bLength;
-       uint8_t  bDescriptorType;
-       uint16_t bcdUSB;
-       uint8_t  bDeviceClass;
-       uint8_t  bDeviceSubClass;
-       uint8_t  bDeviceProtocol;
-       uint8_t  bMaxPacketSize0;
-       uint16_t idVendor;
-       uint16_t idProduct;
-       uint16_t bcdDevice;
-       uint8_t  iManufacturer;
-       uint8_t  iProduct;
-       uint8_t  iSerialNumber;
-       uint8_t  bNumConfigurations;
-};
-
-/**
- * @brief libhusb_cfg_descriptor struct
- * @details This structure presents standard USB configuration descriptor.
- */
-struct libhusb_cfg_descriptor {
-       uint8_t  bLength;
-       uint8_t  bDescriptorType;
-       uint16_t wTotalLength;
-       uint8_t  bNumInterfaces;
-       uint8_t  bConfigurationValue;
-       uint8_t  iConfiguration;
-       uint8_t  bmAttributes;
-       uint8_t  MaxPower;
-       struct libhusb_interface *interface;
-       const unsigned char *extra;
-       int extra_length;
-};
-
-/**
- * @brief libhusb_interface struct
- * @details This is collection of alternate settings for USB interface.
- */
-struct libhusb_interface {
-       struct libhusb_interface_descriptor *altsetting;
-       int num_altsetting;
-};
-
-/**
- * @brief libhusb_interface_descriptor struct
- * @details This structure presents standard USB interface descriptor.
- */
-struct libhusb_interface_descriptor {
-       uint8_t  bLength;
-       uint8_t  bDescriptorType;
-       uint8_t  bInterfaceNumber;
-       uint8_t  bAlternateSetting;
-       uint8_t  bNumEndpoints;
-       uint8_t  bInterfaceClass;
-       uint8_t  bInterfaceSubClass;
-       uint8_t  bInterfaceProtocol;
-       uint8_t  iInterface;
-       struct libhusb_endpoint_descriptor *endpoint;
-       const unsigned char *extra;
-       int extra_length;
-};
-
-/**
- * @brief libhusb_interface_descriptor struct
- * @details This structure presents standard USB endpoint descriptor.
- */
-struct libhusb_endpoint_descriptor {
-       uint8_t  bLength;
-       uint8_t  bDescriptorType;
-       uint8_t  bEndpointAddress;
-       uint8_t  bmAttributes;
-       uint16_t wMaxPacketSize;
-       uint8_t  bInterval;
-       uint8_t  bRefresh;
-       uint8_t  bSynchAddress;
-       const unsigned char *extra;
-       int extra_length;
-};
-
-/**
- * @brief usb_device_error
- * @details This field contain error codes.
- * Library return 0 on success or negative number on error.
- *
- * libhusb_error_name() can be used to translate error number
- * to string representation.
- */
-enum usb_device_error {
-       LIBHUSB_SUCCESS = 0,
-       LIBHUSB_ERROR_IO = -1,
-       LIBHUSB_ERROR_INVALID_PARAM = -2,
-       LIBHUSB_ERROR_ACCESS = -3,
-       LIBHUSB_ERROR_NO_DEVICE = -4,
-       LIBHUSB_ERROR_NOT_FOUND = -5,
-       LIBHUSB_ERROR_BUSY = -6,
-       LIBHUSB_ERROR_TIMEOUT = -7,
-       LIBHUSB_ERROR_OVERFLOW = -8,
-       LIBHUSB_ERROR_PIPE = -9,
-       LIBHUSB_ERROR_INTERRUPTED = -10,
-       LIBHUSB_ERROR_NO_MEM = -11,
-       LIBHUSB_ERROR_NOT_SUPPORTED = -12,
-       LIBHUSB_ERROR_OTHER = -99,
-};
-
-/**
- * @brief usb_device_transfer_status
- * @details Transfer status codes.
- */
-enum usb_device_transfer_status {
-       LIBHUSB_TRANSFER_COMPLETED,
-       LIBHUSB_TRANSFER_ERROR,
-       LIBHUSB_TRANSFER_TIMED_OUT,
-       LIBHUSB_TRANSFER_CANCELLED,
-       LIBHUSB_TRANSFER_STALL,
-       LIBHUSB_TRANSFER_NO_DEVICE,
-       LIBHUSB_TRANSFER_OVERFLOW,
-};
-
-/**
- * @brief Initalize libhusb.
- * @details Function must be called befor any other function.
- * @param ctx Context pointer, can`t be NULL.
- * @return 0 on success or LIBHUSB_ERROR code on failure.
- */
-int libhusb_init(libhusb_context **ctx);
-
-/**
- * @brief Deinitalize libhusb.
- * @details Function must be called after closing all devices
- * and before application close. It has to be called to cleanup
- * the memory used by library.
- * @param ctx context to deinitalize.
- */
-void libhusb_exit(libhusb_context *ctx);
-
-/**
- * @brief Opens device.
- * @details Function open device and return device handle.
- * Device handle allow to perform operations on USB device.
- * @param dev Device to open.
- * @return 0 on success
- * @return LIBHUSB_ERROR_NO_MEM mem allocation failure
- * @return LIBHUSB_ERROR_ACCESS if no proper permission to access device
- * @return LIBHUSB_ERROR_NO_DEVICE if there is no device connected
- * @return other error on failure
- */
-libhusb_device_handle *libhusb_open(libhusb_device *dev);
-
-/**
- * @brief Close device.
- * @details Function should be called before libhusb_exit().
- * It destroy reference that was added by libhusb_open().
- * @param handle Handle to device that should be closed.
- */
-void libhusb_close(libhusb_device_handle *handle);
-
-/**
- * @brief Opens device with vaild idVendor and idProduct
- * @details Function can be used to open device with known idVendor and
- * idProduct. If two or more devices have same vendor and product id only
- * first will be open.
- * @param ctx Context
- * @param vendor_id idVendor of connected device.
- * @param product_id idProduct of connected device.
- * @return handle to the first found device, NULL if no device found
- * or error occurred.
- */
-libhusb_device_handle *libhusb_device_open_with_vid_pid(libhusb_context *ctx,
-                                 uint16_t vendor_id, uint16_t product_id);
-
-/**
- * @brief Get device.
- * @details Function get elementary device for handle. Function does
- * not modify ref count of returned device. User can use returned device
- * as long as handle is opened.
- * @param handle Device handle.
- * @return Elementary device.
- */
-libhusb_device *libhusb_get_device(libhusb_device_handle *handle);
-
-/**
- * @brief Get USB device list.
- * @details This function return list of USB devices attached to system.
- * To free device list libhusb_free_devices() should be used, this
- * function can also unref devices. Do not unref device and
- * then open it.
- *
- * Each devices have reference counter. Functions libhusb_ref_device() and
- * libhusb_unref_device() are used to ref or unref device. When ref counter
- * reach 0 device will be freed.
- * Devices reached by calling libhusb_get_devices() have a reference count of
- * 1, and libhusb_free_devices() can optionally decrease the reference count
- * on all devices in the list. libhusb_open() adds another reference which is
- * later destroyed by libhusb_close().
- *
- * @param ctx Context.
- * @param devs List of devices. Mus be freed with libhusb_free_devices().
- * @return numbers of connected devices or libhusb_error() code.
- */
-ssize_t libhusb_get_devices(libhusb_context *ctx, libhusb_device ***devs);
-
-/**
- * @brief Free devices list.
- * @details Function need to be called to free device list. This
- * function can also unref devices if unref_devices is set.
- * Do not unref device and then open it.
- * @param list List of devices.
- * @param unref_devices Set to unref devices.
- */
-void libhusb_free_devices(libhusb_device **list, int unref_devices);
-
-/**
- * @brief Ref a device.
- * @details Increment ref count of device.
- * @param dev Device to reference.
- * @return The same device.
- */
-libhusb_device *libhusb_ref_device(libhusb_device *dev);
-
-/**
- * @brief Unef a device.
- * @details Decrement ref count of device. If ref count reach zero,
- * device should be destroyed.
- * @param dev Device to reference.
- */
-void libhusb_unref_device(libhusb_device *dev);
-
-/**
- * @brief Get max packet size.
- * @details Function will retrieve the wMaxPacketSize for particular endpoint
- * in active device configuration.
- * @param dev Device.
- * @param endpoint Address of endpoint.
- * @return the wMaxPacketSize value.
- * @return LIBHUSB_ERROR_NOT_FOUND if the endpoint does not exist.
- * @return LIBHUSB_ERROR_OTHER on other failure.
- */
-int libhusb_get_max_packet_size(libhusb_device *dev, uint8_t endpoint);
-
-/**
- * @brief Get bus number.
- * @details Get device bus number. This is number of the bus
- * that device is connected to.
- * @param dev Device.
- * @return Bus number.
- */
-uint8_t libhusb_get_bus_number(libhusb_device *dev);
-
-/**
- * @brief  Get address.
- * @details Get device addres. This is addres of device on the bus
- * that device is connected to.
- * @param dev Device.
- * @return Device address.
- */
-uint8_t libhusb_get_address(libhusb_device *dev);
-
-/**
- * @brief Get list of port numbers.
- * @details Get list of all port numbers from a device.
- * @param dev Device.
- * @param port_numbers Array containing port numbers.
- * @param port_numbers_len Max lenght of array.
- * @return Number of elements.
- */
-int libhusb_get_port_numbers(libhusb_device *dev, uint8_t *port_numbers, int port_numbers_len);
-
-/**
- * @brief Get device descriptor.
- * @details Get device descriptor for a device.
- * @param dev Device.
- * @param desc Location for descriptor data.
- * @return 0 on success or a LIBHUSB_ERROR code on failure.
- */
-int libhusb_get_device_descriptor(libhusb_device *dev, struct libhusb_device_descriptor *desc);
-
-/**
- * @brief Get active config.
- * @details Get bConfigurationValue of active configuration.
- * Function will return 0 value in configparameter
- * if device is unconfigured.
- * @param handle Device handle
- * @param config Location for bConfigurationValue (valid on ret 0)
- * @return 0 on success
- * @return LIBHUSB_ERROR_NO_DEVICE if the dev has been disconnected
- * @return another LIBHUSB_ERROR code on other failure
- */
-int libhusb_get_active_config(libhusb_device_handle *handle, int *config);
-
-/**
- * @brief Set configuration.
- * @details Set active configuration for a device.
- * @param handle Device handle.
- * @param configuration bConfigurationValue of configuration to active.
- * @return 0 on success
- * @return LIBHUSB_ERROR_NOT_FOUND if the req configuration does not exist
- * @return LIBHUSB_ERROR_BUSY if interfaces are currently claimed
- * @return LIBHUSB_ERROR_NO_DEVICE if the device has been disconnected
- * @return another LIBHUSB_ERROR code on other failure
- */
-int libhusb_set_config(libhusb_device_handle *handle, int configuration);
-
-/**
- * @brief Claim interface.
- * @details Claim interface on a device handle.
- * To perform I/O operations on interface user has to claim it.
- * Remember to call libhusb_release_interface() when communication 
- * with the device is finished.
- * @param handle Device Handle
- * @param interface_number The bInterfaceNumber of interface to claim.
- * @param force Set force to auto detach kernel driver.
- * @return 0 on success.
- * @return LIBHUSB_ERROR_NOT_FOUND if the requested interface does not exist.
- * @return LIBHUSB_ERROR_BUSY if another program or driver has claimed the
- * interface.
- * @return LIBHUSB_ERROR_NO_DEVICE if the device has been disconnected.
- * @return a LIBHUSB_ERROR code on other failure
-  */
-int libhusb_claim_interface(libhusb_device_handle *handle, int interface_number, int force);
-
-/**
- * @brief Release interface.
- * @details Release interface previously claimed by libhusb_claim_interface().
- * This is a blocking function.
- * @param handle Device handle.
- * @param interface_number The bInterfaceNumber of interface to release.
- * @return 0 on success
- * @return LIBHUSB_ERROR_NOT_FOUND if the interface was not claimed
- * @return LIBHUSB_ERROR_NO_DEVICE if the device has been disconnected
- * @return another LIBHUSB_ERROR code on other failure
- */
-int libhusb_release_interface(libhusb_device_handle *handle, int interface_number);
-
-/**
- * @brief Clear the halt/stall condition.
- * @details Clear the halt/stall condition for an endpoint.
- * @param handle Device handle.
- * @param endpoint The endpoint to clear halt status.
- * @return 0 on success
- * @return LIBHUSB_ERROR_NOT_FOUND if the endpoint does not exist
- * @return LIBHUSB_ERROR_NO_DEVICE if the device has been disconnected
- * @return another LIBHUSB_ERROR code on other failure
- */
-int libhusb_clear_halt(libhusb_device_handle *handle, uint8_t endpoint);
-
-/**
- * @brief Reset a device.
- * @details Reset USB port to reinitalize a device.
- * This is a blocking function.
- * @param handle Device handle.
- * @return 0 on success.
- * @return LIBHUSB_ERROR_NOT_FOUND if re-enumeration is required, or if the
- * device has been disconnected.
- * @return another LIBHUSB_ERROR code on other failure.
- */
-int libhusb_reset_device(libhusb_device_handle *handle);
-
-/**
- * @brief Determine active kernel driver.
- * @details Determine if a kernel driver is active on an interface.
- * Interface can't be claimed if driver is active unless force
- * option is used.
- * @param handle Device handle.
- * @param interface_number number of interface to check
- * @return 0 if no kernel driver is active
- * @return 1 if a kernel driver is active
- * @return LIBHUSB_ERROR_NO_DEVICE if the device has been disconnected.
- * @return LIBHUSB_ERROR_NOT_SUPPORTED on platforms where the functionality
- * is not available.
- * @return another LIBHUSB_ERROR code on other failure.
- * @see libhusb_detach_kernel_driver()
- */
-int libhusb_kernel_driver_active(libhusb_device_handle *handle, int interface_number);
-
-/**
- * @brief Detach kernel driver.
- * @details Detach a kernel driver from an interface.
- * @param handle Device handle.
- * @param interface_number Number of interface on which detach kernel driver.
- * @return 0 on success
- * @return LIBHUSB_ERROR_NOT_FOUND if no kernel driver was active
- * @return LIBHUSB_ERROR_INVALID_PARAM if the interface does not exist
- * @return LIBHUSB_ERROR_NO_DEVICE if the device has been disconnected
- * @return LIBHUSB_ERROR_NOT_SUPPORTED on platforms where the functionality
- * is not available
- * @return another LIBHUSB_ERROR code on other failure
- * @see libhusb_kernel_driver_active()
- */
-int libhusb_detach_kernel_driver(libhusb_device_handle *handle, int interface_number);
-
-/**
- * @brief Attach kernel driver
- * @details  Re-attach an interface's kernel driver, which was previously detached
- * using libhusb_detach_kernel_driver().
- * @param handle Device handle.
- * @param interface_number Interface to attach the driver.
- * @return 0 on success.
- * @return LIBHUSB_ERROR_NOT_FOUND if no kernel driver was active.
- * @return LIBHUSB_ERROR_INVALID_PARAM if the interface does not exist.
- * @return LIBHUSB_ERROR_NO_DEVICE if the device has been disconnected.
- * @return LIBHUSB_ERROR_NOT_SUPPORTED on platforms where the functionality
- * is not available.
- * @return LIBHUSB_ERROR_BUSY if the driver cannot be attached because the
- * interface is claimed by a program or driver.
- * @return another LIBHUSB_ERROR code on other failure
- * @see libhusb_kernel_driver_active()
- */
-int libhusb_attach_kernel_driver(libhusb_device_handle *handle, int interface_number);
-
-/**
- * @brief Get config descriptor.
- * @details Get a USB configuration descriptor.
- * @param dev Device
- * @param config_index index of configuration to retrieve.
- * @param config Output location for USB configuration descriptor.
- * Must be freed with libhusb_free_config_descriptor().
- * @return 0 on success
- * @return LIBHUSB_ERROR_NOT_FOUND if the configuration does not exist.
- * @return another LIBHUSB_ERROR code on error.
- */
-int libhusb_get_config_descriptor(libhusb_device *dev, uint8_t config_index,
-                                 struct libhusb_cfg_descriptor **config);
-
-/**
- * @brief Free config descriptor.
- * @details Free configuration descriptor obtained from
- * libhusb_get_config_descriptor().
- * @param config Configuration to free.
- */
-void libhusb_free_config_descriptor(struct libhusb_cfg_descriptor *config);
-
-/**
- * @brief Get string descriptor.
- * @details Retrieve a string descriptor in ASCII.
- * @param handle Device handle.
- * @param desc_index Index of descriptor to retrieve.
- * @param data Out buffer for ASCII string descriptor.
- * @param length Data bufer size.
- * @return number of bytes returned in data, or LIBHUSB_ERROR code on failure.
- */
-int libhusb_get_string_descriptor_ascii(libhusb_device_handle *handle,
-       uint8_t desc_index, unsigned char *data, int length);
-
-/* sync IO */
-
-/**
- * @brief Perform USB control transfer.
- * @details
- *
- * The wValue, wIndex and wLength fields values should be given in host-endian
- * byte order
- *
- * @param handle Device handle.
- * @param request_type Request type field for the setup packet
- * @param bRequest Request field for the setup packet
- * @param wValue Value field for the setup packet
- * @param wIndex Index field for the setup packet
- * @param data Suitably-sized data buffer for either input or output
- * (depending on direction bits within bmRequestType)
- * @param wLength Length field for the setup packet. The data buffer should
- * be at least this size.
- * @param timeout Timeout (in millseconds) that this function should wait
- * before giving up due to no response being received. For an unlimited
- * timeout, 0 value should be used.
- * @return on success, the number of bytes actually transferred
- * @return LIBHUSB_ERROR_TIMEOUT if the transfer timed out
- * @return LIBHUSB_ERROR_PIPE if the control request was not supported by the
- * device
- * @return LIBHUSB_ERROR_NO_DEVICE if the device has been disconnected
- * @return another LIBHUSB_ERROR code on other failures
- */
-int libhusb_control_transfer(libhusb_device_handle *handle,
-       uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
-       unsigned char *data, uint16_t wLength, unsigned int timeout);
-
-/**
- * @brief Perform a bulk transfer.
- * @details Perform a USB bulk transfer. The direction of the transfer is inferred from
- * the direction bits of the endpoint address.
- *
- * @param handle Device handle.
- * @param endpoint Address of a valid endpoint to communicate with
- * @param data Suitably-sized data buffer for either input or output
- * (depending on endpoint)
- * @param length For bulk writes, the number of bytes from data to be sent. for
- * bulk reads, the maximum number of bytes to receive into the data buffer.
- * @param transferred Output location for the number of bytes actually
- * transferred.
- * @param timeout Timeout (in millseconds) that this function should wait
- * before giving up due to no response being received. For an unlimited
- * timeout, 0 value should be used.
- * @return 0 on success (and populates transferred)
- * @return LIBHUSB_ERROR_TIMEOUT if the transfer timed out (and populates
- * transferred)
- * @return LIBHUSB_ERROR_PIPE if the endpoint halted
- * @return LIBHUSB_ERROR_OVERFLOW if the device offered more data
- * @return LIBHUSB_ERROR_NO_DEVICE if the device has been disconnected
- * @return another LIBHUSB_ERROR code on other failures
- */
-int libhusb_bulk_transfer(libhusb_device_handle *handle,
-       uint8_t endpoint, unsigned char *data, int length,
-       int *transferred, unsigned int timeout);
-
-/**
- * @brief Perform interrupt transfer.
- * @details Perform a USB interrupt transfer. The direction of the transfer is inferred
- * from the direction bits of the endpoint address.
- *
- * @param handle Device handle.
- * @param endpoint Address of a valid endpoint to communicate with
- * @param data Suitably-sized data buffer for either input or output
- * (depending on endpoint)
- * @param length For bulk writes, the number of bytes from data to be sent. for
- * bulk reads, the maximum number of bytes to receive into the data buffer.
- * @param transferred Output location for the number of bytes actually
- * transferred.
- * @param timeout Timeout (in millseconds) that this function should wait
- * before giving up due to no response being received. For an unlimited
- * timeout, 0 value should be used.
- * @return 0 on success (and populates transferred)
- * @return LIBHUSB_ERROR_TIMEOUT if the transfer timed out (and populates
- * transferred)
- * @return 0 on success (and populates <tt>transferred</tt>)
- * @return LIBHUSB_ERROR_TIMEOUT if the transfer timed out
- * @return LIBHUSB_ERROR_PIPE if the endpoint halted
- * @return LIBHUSB_ERROR_OVERFLOW if the device offered more data
- * @return LIBHUSB_ERROR_NO_DEVICE if the device has been disconnected
- * @return another LIBHUSB_ERROR code on other error
- */
-int libhusb_interrupt_transfer(libhusb_device_handle *handle,
-       uint8_t endpoint, unsigned char *data, int length,
-       int *transferred, unsigned int timeout);
-
-/* Async IO */
-
-/**
- * @brief Asynchronous transfer callback function
- */
-typedef void (*libhusb_transfer_cb_fn)(int status, unsigned char *buffer, int len, void *user_data);
-
-/**
- * @brief Asynchronous transfer handler
- */
-struct libhusb_transfer;
-
-typedef struct libhusb_transfer libhusb_transfer;
-
-/**
- * @brief Create an asynchronous transfer handler
- * @details To perform asynchronous transfer, we need a handler structure which will
- * be later passed to libhusb_submit_transfer(). This function allocate memory for the handler,
- * but it will be uninitialized until libhusb_fill_* function will be called.
- *
- * For isochronous transfer, iso_packets should be set to appropriate number of packet descriptors.
- * If you do not intend to use isochronous transfer, it should be set to 0.
- *
- * @param transfer Pointer to be filled with pointer to newly allocated transfer structure
- * @param iso_packets Number of iso packets descriptors to be allocated.
- * @return 0 on success, negative error code otherwise
- */
-int libhusb_create_transfer(libhusb_transfer **transfer, int iso_packets);
-
-/**
- * @brief Submit an asynchronous transfer1
- * @details The transfer structure should be initialized with transfer parameters and
- * callback function. When transfer is completed, the callback function is called.
- *
- * @param transfer Transfer handler to be submited
- * @return 0 on success, negative error code otherwise
- */
-int libhusb_submit_transfer(libhusb_transfer *transfer);
-
-/**
- * @brief Cancel a submited asynchronous transfer
- * @details If transfer was submitted, this will cancel it. Callback function will be
- * called with CANCEL status
- *
- * @param transfer Transfer handler to be canceled
- * @return 0 on success, negative error code otherwise
- */
-int libhusb_cancel_transfer(libhusb_transfer *transfer);
-
-/**
- * @brief Destroy asynchronous transfer handler
- * @details Deallocate memory allocated by libhusb_create_transfer
- *
- * @param transfer Transfer handler to be destroyed
- */
-void libhusb_destroy_transfer(libhusb_transfer *transfer);
-
-/**
- * @brief Fill an interrupt asynchronous transfer
- * @details Before submitting transfer it should be initialized. This function initialize it with
- * values required for interrupt transfer.
- *
- * @param transfer Transfer handle
- * @param dev_handle Device handle
- * @param callback Function to be called when transfer is finished
- * @param endpoint Number of endpoint
- * @param buffer Data buffer
- * @param length Length of data buffer
- * @param user_data Pointer to additional user data that will be passed to callback function
- * @param timeout Timeout for the transfer in miliseconds
- * @return 0 on success, negative error code otherwise
- */
-int libhusb_fill_interrupt_transfer(libhusb_transfer *transfer, libhusb_device_handle *dev_handle,
-       libhusb_transfer_cb_fn callback, uint8_t endpoint, unsigned char *buffer, int length,
-       void *user_data, unsigned int timeout);
-
-/**
- * @brief Fill a bulk asynchronous transfer
- * @details Before submitting transfer it should be initialized. This funtion initialize it with
- * values required for bulk transfer.
- *
- * @param transfer Transfer handle
- * @param dev_handle Device handle
- * @param callback Function to be called when transfer is finished
- * @param endpoint Number of endpoint
- * @param buffer Data buffer
- * @param length Length of data buffer
- * @param user_data Pointer to additional user data that will be passed to callback function
- * @param timeout Timeout for the transfer in miliseconds
- * @return 0 on success, negative error code otherwise
- */
-int libhusb_fill_bulk_transfer(libhusb_transfer *transfer, libhusb_device_handle *dev_handle,
-       libhusb_transfer_cb_fn callback, uint8_t endpoint, unsigned char *buffer, int length,
-       void *user_data, unsigned int timeout);
-
-/**
- * @brief Fill setup packet for a control transfer
- * @details This is helper function to populate first 8 bytes of control transfer buffer
- * with given setup values.
- *
- * @param buffer Buffer to write the setup packet into
- * @param bmRequestType Request type
- * @param bRequest Request
- * @param wValue Value
- * @param wIndex Index
- * @param wLength Length
- */
-void libhusb_fill_control_setup(unsigned char *buffer, uint8_t bmRequestType,
-               uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength);
-
-/**
- * @brief Fill an interrupt asynchronous transfer
- * @details Before submitting transfer it should be initialized. This funtion initialize it with
- * values required for control transfer.
- *
- * The first 8 bytes of buffer is interpreted as control setup packet. It contains information about
- * length of the buffer. Use libhusb_fill_control_setup() function to initialize setup packet.
- *
- * @param transfer Transfer handle
- * @param dev_handle Device handle
- * @param callback Function to be called when transfer is finished
- * @param buffer Data buffer
- * @param user_data Pointer to additional user data that will be passed to callback function
- * @param timeout Timeout for the transfer in miliseconds
- *
- * @par Example
- * @code
- * ...
- *
- * r = libhusb_create_transfer(&transfer);
- * if (r < 0) {
- *     printf("Failed to create transfer)\n";
- *     exit(1);
- * }
- *
- * ...
- *
- * libhusb_fill_control_setup(buffer, request_type, request, value, index, length);
- * r = libhusb_fill_control_transfer(transfer, dev_handle, buffer, callback, user_data, timeout);
- * if (r < 0) {
- *     printf("Failed to fill control transfer\n");
- *     libhusb_destroy_transfer(transfer);
- *     exit(1);
- * }
- *
- * ...
- * @endcode
- * @return 0 on success, negative error code otherwise
- */
-int libhusb_fill_control_transfer(libhusb_transfer *transfer, libhusb_device_handle *dev_handle,
-       libhusb_transfer_cb_fn callback, unsigned char *buffer, void *user_data, unsigned int timeout);
-
-/**
- * @brief Fill an interrupt asynchronous transfer
- * @details Before submitting transfer it should be initialized. This funtion initialize it with
- * values required for isochronous transfer.
- *
- * @param transfer Transfer handle
- * @param dev_handle Device handle
- * @param callback Function to be called when transfer is finished
- * @param endpoint Number of endpoint
- * @param buffer Buffer to store data
- * @param length Length of data buffer
- * @param iso_packets Number of iso packets
- * @param user_data Pointer to additional user data that will be passed to callback function
- * @param timeout Timeout for the transfer in miliseconds
- * @return 0 on success, negative error code otherwise
- */
-int libhusb_fill_iso_transfer(libhusb_transfer *transfer, libhusb_device_handle *dev_handle,
-       libhusb_transfer_cb_fn callback, uint8_t endpoint, unsigned char *buffer, int length,
-       int iso_packets, void *user_data, unsigned int timeout);
-/**
- * @brief Handle all pending events
- * @param ctx Library context
- * @param completed Pointer to completion integer check, or NULL
- * @return 0 on success, negative error code otherwise
- */
-int libhusb_handle_events(libhusb_context *ctx, int *completed);
-
-/**
- * @brief Translate error name
- * @details Translates error code to NULL terminated libhusb
- * error or status code.
- * @param error_code Error code to translate.
- * @return Error name
- */
-const char *libhusb_error_name(int error_code);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LIBHUSB_H */
diff --git a/include/libhusb_internal.h b/include/libhusb_internal.h
deleted file mode 100644 (file)
index 4e0c3c7..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * libhusb_internal.h
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "libhusb.h"
-#include "uref.h"
-#include "common.h"
-#include "log.h"
-#include <libusb-1.0/libusb.h>
-
-#define MAX_NMB_OF_CONFIGS 255
-
-struct libhusb_context {
-       libusb_context *lusb_ctx;
-};
-
-struct libhusb_device {
-       struct uref ref;
-       libusb_device *lusb_dev;
-       int refcnt;
-};
-
-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];
-};
-
-struct libhusb_transfer {
-       struct libusb_transfer *lusb_transfer;
-};
index 589cd353f59f47c3ee6bc28492b8a5e43213a569..3b7be8c604ccdae9529c9cc0a4ea042785050f4e 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * libhusb
+ * usb_host
  *
  * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
  *
@@ -23,7 +23,7 @@
 #include <dlog.h>
 
 #undef LOG_TAG
-#define LOG_TAG "LIBHUSB"
+#define LOG_TAG "USB_HOST"
 #define _D(fmt, args...)   SLOGD(fmt, ##args)
 #define _E(fmt, args...)   SLOGE(fmt, ##args)
 #define _I(fmt, args...)   SLOGI(fmt, ##args)
diff --git a/include/usb_host.h b/include/usb_host.h
new file mode 100644 (file)
index 0000000..aa1488b
--- /dev/null
@@ -0,0 +1,997 @@
+/*
+ * usb_host.h
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_USB_HOST_H__
+#define __TIZEN_USB_HOST_H__
+
+#include <stdint.h>
+#include <tizen.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @ingroup CAPI_USB_HOST_ENDPOINT_MODULE
+ * @brief Enumeration of an endpoint's direction.
+ * @since_tizen 3.0
+ */
+typedef enum {
+       USB_HOST_DIRECTION_IN,  /**< IN direction */
+       USB_HOST_DIRECTION_OUT, /**< OUT direction */
+} usb_host_endpoint_direction_e;
+
+/**
+ * @ingroup CAPI_USB_HOST_ENDPOINT_MODULE
+ * @brief Enumeration of transfer type.
+ * @since_tizen 3.0
+ */
+typedef enum {
+       USB_HOST_TRANSFER_TYPE_CONTROL,         /**< Control transfer */
+       USB_HOST_TRANSFER_TYPE_ISOCHRONOUS,     /**< Isochronous transfer */
+       USB_HOST_TRANSFER_TYPE_BULK,            /**< Bulk transfer */
+       USB_HOST_TRANSFER_TYPE_INTERRUPT,       /**< Interrupt transfer */
+} usb_host_transfer_type_e;
+
+/**
+ * @ingroup CAPI_USB_HOST_ENDPOINT_MODULE
+ * @brief Enumeration of isochronous endpoint's synchronization type.
+ * @since_tizen 3.0
+ */
+typedef enum {
+       USB_HOST_ISO_SYNC_TYPE_NONE,    /**< No synchronization */
+       USB_HOST_ISO_SYNC_TYPE_ASYNC,   /**< Asynchronous */
+       USB_HOST_ISO_SYNC_TYPE_ADAPTIVE,/**< Adaptive */
+       USB_HOST_ISO_SYNC_TYPE_SYNC,    /**< Synchronous */
+} usb_host_iso_sync_type_e;
+
+/**
+ * @ingroup CAPI_USB_HOST_ENDPOINT_MODULE
+ * @brief Enumeration of an endpoint's usage type.
+ * @since_tizen 3.0
+ */
+typedef enum {
+       USB_HOST_USAGE_TYPE_DATA,       /**< Data endpoint */
+       USB_HOST_USAGE_TYPE_FEEDBACK,   /**< Feedback endpoint */
+       USB_HOST_USAGE_TYPE_IMPLICIT,   /**< Implicit feedback Data endpoint */
+} usb_host_usage_type_e;
+
+
+#ifndef TIZEN_ERROR_USB_HOST
+#define TIZEN_ERROR_USB_HOST -0x03000000
+#endif
+
+/**
+ * @brief Enumeration of error codes reported by USB host API.
+ * @since_tizen 3.0
+ */
+typedef enum {
+       USB_HOST_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */
+       USB_HOST_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR, /**< I/O error */
+       USB_HOST_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
+       USB_HOST_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */
+       USB_HOST_ERROR_NO_SUCH_DEVICE = TIZEN_ERROR_NO_SUCH_DEVICE, /**< No device */
+       USB_HOST_ERROR_NOT_FOUND = TIZEN_ERROR_USB_HOST | 0x01, /**< Entity not found */
+       USB_HOST_ERROR_RESOURCE_BUSY = TIZEN_ERROR_RESOURCE_BUSY, /**< Resource busy */
+       USB_HOST_ERROR_TIMED_OUT = TIZEN_ERROR_TIMED_OUT, /**< Operation timed out */
+       USB_HOST_ERROR_OVERFLOW = TIZEN_ERROR_USB_HOST | 0x02, /**< Overflow */
+       USB_HOST_ERROR_DEVICE_NOT_OPENED = TIZEN_ERROR_USB_HOST | 0x03, /**< Device is not opened */
+       USB_HOST_ERROR_BROKEN_PIPE = TIZEN_ERROR_BROKEN_PIPE, /**< Pipe error */
+       USB_HOST_ERROR_INTERRUPTED_SYS_CALL = TIZEN_ERROR_INTERRUPTED_SYS_CALL, /**< System call interrupted */
+       USB_HOST_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Insufficient memory */
+       USB_HOST_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< Operation not supported */
+       USB_HOST_ERROR_UNKNOWN = TIZEN_ERROR_UNKNOWN, /**< Other error */
+} usb_host_error_e;
+
+/**
+ * @ingroup CAPI_USB_HOST_INIT_MODULE
+ * @brief Context handle to USB host.
+ * @details This structure represents usb_host session.
+ * Using own session allows to use this API independently.
+ * For example calling usb_host_destroy() will not destroy resources
+ * that are being used by another user of the library.
+ *
+ * To create session there is need to call usb_host_create(),
+ * to destroy call usb_host_destroy(). Each session created by usb_host_create()
+ * has to be destroyed using usb_host_destroy()
+ * @since_tizen 3.0
+ */
+typedef struct usb_host_context_s *usb_host_context_h;
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Structure representing USB device.
+ * @details This structure represents USB device found on USB bus.
+ *
+ * This can be obtained by usb_host_get_device_list() or usb_host_device_open_with_vid_pidi().
+ * Some basic operations can be performed on closed device obtained by usb_host_device_list().
+ * To perform any I/O operations the device must be opened by calling usb_host_device_open()
+ * or usb_host_device_open_with_vid_pid().
+ *
+ * @since_tizen 3.0
+ */
+typedef struct usb_host_device_s *usb_host_device_h;
+
+/**
+ * @ingroup CAPI_USB_HOST_CONFIG_MODULE
+ * @brief USB config handle.
+ * @details This type represents USB device configuration. Device can have multiple configurations,
+ * a configuration can have multiple interfaces. This handle can be obtained by
+ * usb_host_device_get_config().
+ * @since_tizen 3.0
+ */
+typedef struct usb_host_config_s *usb_host_config_h;
+
+/**
+ * @ingroup CAPI_USB_HOST_INTERFACE_MODULE
+ * @brief USB interface handle.
+ * @details This type represents USB interface. An interface is a part of configuration and
+ * can have multiple endpoints. This handle can be obtained by usb_host_config_get_interface().
+ * @since_tizen 3.0
+ */
+typedef struct usb_host_interface_s *usb_host_interface_h;
+
+/**
+ * @ingroup CAPI_USB_HOST_ENDPOINT_MODULE
+ * @brief USB endpoint handle.
+ * @details This type represents USB endpoint. This handle can be obtained by
+ * usb_host_interface_get_endpoint().
+ * @since_tizen 3.0
+ */
+typedef struct usb_host_endpoint_s *usb_host_endpoint_h;
+
+/* Library initialization and cleanup */
+
+/**
+ * @ingroup CAPI_USB_HOST_INIT_MODULE
+ * @brief Initializes usb_host context.
+ * @details This function must be called before any other function from this module.
+ * @since_tizen 3.0
+ * @remarks @a ctx should be destroyed by calling usb_host_destroy() when no longer needed.
+ * @param[out] ctx Context pointer
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @post usb_host_destroy() should be called to free resources allocated for ctx by this function.
+ */
+int usb_host_create(usb_host_context_h *ctx);
+
+/**
+ * @ingroup CAPI_USB_HOST_INIT_MODULE
+ * @brief Deinitializes usb_host context.
+ * @details This function must be called after closing all devices
+ * and before application close. It has to be called to clean
+ * the memory used by library.
+ * @since_tizen 3.0
+ * @param[in] ctx Context to deinitialize
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @retval #USB_HOST_ERROR_NONE Success
+ * @pre Context must be initialized by usb_host_create().
+ */
+int usb_host_destroy(usb_host_context_h ctx);
+
+/* Device handling and enumeration */
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Gets USB device list.
+ * @details This function returns list of USB devices attached to system.
+ * To free obtained device list usb_host_free_devices() should be used, this
+ * function can also unref devices. Do not unref device and then open it.
+ *
+ * All devices have reference counter. Functions usb_host_ref_device() and
+ * usb_host_unref_device() are used to ref or unref device. When ref counter
+ * reaches 0 device will be freed.
+ * Devices reached by calling usb_host_get_device_list() have a reference count of
+ * 1, and usb_host_free_devices() can optionally decrease the reference count
+ * on all devices in the list. usb_host_device_open() adds another reference which is
+ * later destroyed by usb_host_device_close().
+ *
+ * @since_tizen 3.0
+ * @param[in] ctx Context handle
+ * @param[out] devs An array of devices
+ * @param[out] length Number of devices
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Operation not supported
+ * @retval #USB_HOST_ERROR_PERMISSION_DENIED Permission denied
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @post @a devs must be freed with usb_host_free_device_list() when no longer needed.
+ */
+int usb_host_get_device_list(usb_host_context_h ctx, usb_host_device_h **devs, int *length);
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Frees devices list.
+ * @details This function needs to be called to free device list. This
+ * function can also unref devices if unref_devices is set to non-zero value.
+ * Do not unref device and then open it.
+ * @since_tizen 3.0
+ * @param[in] devs List of devices
+ * @param[in] unref_devices Set to true to unreference devices, set to false to not unref
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @pre usb_host_get_device_list() must be called before using this function.
+ */
+int usb_host_free_device_list(usb_host_device_h *devs, bool unref_devices);
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Refs a device.
+ * @details Increment ref count of device.
+ * @since_tizen 3.0
+ * @param[in] dev Device to reference
+ * @return 0 on success, error code otherwise
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @retval #USB_HOST_ERROR_NONE Successful
+ */
+int usb_host_ref_device(usb_host_device_h dev);
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Unrefs a device.
+ * @details Decrements ref count of device. If ref count reaches zero,
+ * device will be destroyed.
+ * @since_tizen 3.0
+ * @param[in] dev Device to unreference
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ */
+int usb_host_unref_device(usb_host_device_h dev);
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Opens a device.
+ * @details This function opens a device, which allows performing operations on it
+ * (including transfer operations and strings introspection).
+ * @since_tizen 3.0
+ * @param[in] dev Device to open
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_OUT_OF_MEMORY Memory allocation failure
+ * @retval #USB_HOST_ERROR_NO_SUCH_DEVICE There is no device connected
+ * @retval #USB_HOST_ERROR_PERMISSION_DENIED No proper permission to access device
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Operation not supported
+ * @see usb_host_is_device_opened()
+ */
+int usb_host_device_open(usb_host_device_h dev);
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Closes device.
+ * @details Function should be called before usb_host_destroy().
+ * It destroys reference that was added by usb_host_device_open().
+ * @since_tizen 3.0
+ * @param[in] dev Device that should be closed
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_DEVICE_NOT_OPENED If device is not opened
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @retval #USB_HOST_ERROR_NONE Successful
+ */
+int usb_host_device_close(usb_host_device_h dev);
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Opens device with valid idVendor and idProduct.
+ * @details This function can be used to open device with known idVendor and
+ * idProduct. If two or more devices have same vendor and product id only
+ * first will be opened.
+ * @since_tizen 3.0
+ * @param[in] ctx Context
+ * @param[in] vendor_id idVendor of connected device
+ * @param[in] product_id idProduct of connected device
+ * @param[out] device_handle Opened device handle
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_OUT_OF_MEMORY Insufficient memory
+ * @retval #USB_HOST_ERROR_NO_SUCH_DEVICE No device
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ */
+int usb_host_device_open_with_vid_pid(usb_host_context_h ctx,
+                                 int vendor_id, int product_id, usb_host_device_h *device_handle);
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Gets bus number.
+ * @details Gets device bus number. This is number of the bus
+ * that device is connected to.
+ * @since_tizen 3.0
+ * @param[in] dev Device handle
+ * @param[out] bus_number Device bus number
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_PERMISSION_DENIED Permission denied
+ */
+int usb_host_device_get_bus_number(usb_host_device_h dev, int *bus_number);
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Gets address.
+ * @details Gets device address. This is address of device on the bus
+ * that device is connected to.
+ * @since_tizen 3.0
+ * @param[in] dev Device
+ * @param[out] device_address Device address
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ */
+int usb_host_device_get_address(usb_host_device_h dev, int *device_address);
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Gets list of port numbers.
+ * @details Gets list of all port numbers from a device.
+ * @since_tizen 3.0
+ * @param[in] dev Device
+ * @param[out] port_numbers Array to be filled with port numbers
+ * @param[in] port_numbers_len Max length of array
+ * @param[out] ports_count Number of all ports obtained from device
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @retval #USB_HOST_ERROR_OUT_OF_MEMORY Insufficient memory
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ */
+int usb_host_device_get_port_numbers(usb_host_device_h dev, int *port_numbers, int port_numbers_len, int *ports_count);
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Gets a configuration.
+ * @details Gets a USB configuration from a device.
+ * @since_tizen 3.0
+ * @remarks @a config must be freed with usb_host_config_destroy().
+ * @param[in] dev Device
+ * @param[in] config_index index of configuration to retrieve
+ * @param[out] config Output location for USB configuration
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_NOT_FOUND The configuration does not exist
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @post Returned configuration should be destroyed by usb_host_config_destroy()
+ * when no longer needed.
+ */
+int usb_host_device_get_config(usb_host_device_h dev, int config_index, usb_host_config_h *config);
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Gets an active config.
+ * @details Gets handle to active configuration.
+ * This function will return 0 value in config parameter :if device is unconfigured.
+ * @since_tizen 3.0
+ * @param[in] dev A device
+ * @param[out] config Handle to active configuration
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NO_SUCH_DEVICE the dev has been disconnected
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @post Obtained configuration should be destroyed by usb_host_config_destroy()
+ * when no longer needed.
+ */
+int usb_host_get_active_config(usb_host_device_h dev, usb_host_config_h *config);
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Sets a configuration.
+ * @details Set active configuration for a device.
+ * @since_tizen 3.0
+ * @param[in] configuration Handle to configuration to be activated
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_NOT_FOUND Requested configuration does not exist
+ * @retval #USB_HOST_ERROR_RESOURCE_BUSY Interfaces are currently claimed
+ * @retval #USB_HOST_ERROR_NO_SUCH_DEVICE The device has been disconnected
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @retval #USB_HOST_ERROR_DEVICE_NOT_OPENED The device was not opened
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ */
+int usb_host_set_config(usb_host_config_h configuration);
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Gets USB specification release number.
+ * @details Gets binary-coded decimal USB specification release number.
+ * This value is equal to bcdUSB field of device descriptor. See USB specification
+ * for more info.
+ * @since_tizen 3.0
+ * @param[in] dev A device
+ * @param[out] bcd_usb Bcd release number of USB
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @retval #USB_HOST_ERROR_PERMISSION_DENIED Permission denied
+ */
+int usb_host_device_get_bcd_usb(usb_host_device_h dev, int *bcd_usb);
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Gets device class.
+ * @since_tizen 3.0
+ * @param[in] dev A device
+ * @param[out] device_class Device class
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ */
+int usb_host_device_get_class(usb_host_device_h dev, int *device_class);
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Gets device sub class.
+ * @since_tizen 3.0
+ * @param[in] dev A device
+ * @param[out] subclass Device subclass
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ */
+int usb_host_device_get_sub_class(usb_host_device_h dev, int *subclass);
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Gets device protocol.
+ * @since_tizen 3.0
+ * @param[in] dev A device
+ * @param[out] protocol Device protocol
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ */
+int usb_host_device_get_protocol(usb_host_device_h dev, int *protocol);
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Gets maximum packet size for endpoint 0.
+ * @since_tizen 3.0
+ * @param[in] dev A device
+ * @param[out] max_packet_size Maximum size of single packet
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ */
+int usb_host_device_get_max_packet_size_0(usb_host_device_h dev, int *max_packet_size);
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Gets vendor id.
+ * @since_tizen 3.0
+ * @param[in] dev A device
+ * @param[out] vendor_id Vendor id of @dev
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ */
+int usb_host_device_get_id_vendor(usb_host_device_h dev, int *vendor_id);
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Gets product id.
+ * @since_tizen 3.0
+ * @param[in] dev A device
+ * @param[out] product_id Product id of @a dev
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ */
+int usb_host_device_get_id_product(usb_host_device_h dev, int *product_id);
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Gets device release number in binary-coded decimal.
+ * @since_tizen 3.0
+ * @param[in] dev A device
+ * @param[out] device_bcd Device release number
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ */
+int usb_host_device_get_bcd_device(usb_host_device_h dev, int *device_bcd);
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Gets number of configurations for given device.
+ * @since_tizen 3.0
+ * @param[in] dev A device
+ * @param[out] num_configurations Number of configurations for given device
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ */
+int usb_host_device_get_num_configurations(usb_host_device_h dev, int *num_configurations);
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Checks if device is opened.
+ * @since_tizen 3.0
+ * @param[in] dev A device
+ * @param[out] is_opened True if device is opened, false otherwise
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ */
+int usb_host_is_device_opened(usb_host_device_h dev, bool *is_opened);
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Gets string describing device manufacturer, in ASCII.
+ * @since_tizen 3.0
+ * @param[in] dev A handle to opened device
+ * @param[in/out] length Data buffer size/how much was actually used
+ * @param[out] data Buffer to store string
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_OVERFLOW There was no space in buffer
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @retval #USB_HOST_ERROR_PERMISSION_DENIED Permission denied
+ * @pre dev must point to device opened by usb_host_device_open() or usb_host_device_open_with_vid_pid().
+ */
+int usb_host_device_get_manufacturer_str(usb_host_device_h dev, int *length, unsigned char *data);
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Gets product string of device, in ASCII.
+ * @since_tizen 3.0
+ * @param[in] dev A handle to opened device
+ * @param[in/out] length Data buffer size/how much was actually used
+ * @param[out] data Buffer to store string
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_OVERFLOW There was no space in buffer
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @retval #USB_HOST_ERROR_PERMISSION_DENIED Permission denied
+ * @pre dev must point to device opened by usb_host_device_open() or usb_host_device_open_with_vid_pid().
+ */
+int usb_host_device_get_product_str(usb_host_device_h dev, int *length, unsigned char *data);
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Gets serial number of a device, in ASCII.
+ * @since_tizen 3.0
+ * @param[in] dev A handle to opened device
+ * @param[in/out] length Data buffer size/how much was actually used
+ * @param[out] data Buffer to store string
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_OVERFLOW There was no space in buffer
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @retval #USB_HOST_ERROR_PERMISSION_DENIED Permission denied
+ * @pre dev must point to device opened by usb_host_device_open() or usb_host_device_open_with_vid_pid().
+ */
+int usb_host_device_get_serial_number_str(usb_host_device_h dev, int *length, unsigned char *data);
+
+/**
+ * @ingroup CAPI_USB_HOST_DEV_MODULE
+ * @brief Gets string descriptor.
+ * @details Retrieves a string descriptor in ASCII.
+ * @since_tizen 3.0
+ * @param[in] dev An opened device
+ * @param[in] desc_index Index of descriptor to retrieve
+ * @param[in/out] length Data buffer size/how much was actually used
+ * @param[out] data Out buffer for ASCII string descriptor
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_OVERFLOW There was no space in buffer
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @retval #USB_HOST_ERROR_PERMISSION_DENIED Permission denied
+ * @pre dev must point to device opened by usb_host_device_open() or usb_host_device_open_with_vid_pid().
+ */
+int usb_host_device_get_string_descriptor_ascii(usb_host_device_h dev,
+       int desc_index, int *length, unsigned char *data);
+
+/**
+ * @ingroup CAPI_USB_HOST_CONFIG_MODULE
+ * @brief Gets number of interfaces for given configuration.
+ * @since_tizen 3.0
+ * @param[in] config A configuration
+ * @param[out] num_interfaces Number of interfaces
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ */
+int usb_host_config_get_num_interfaces(usb_host_config_h config, int *num_interfaces);
+
+/**
+ * @ingroup CAPI_USB_HOST_CONFIG_MODULE
+ * @brief Checks if device is self-powered in given configuration.
+ * @since_tizen 3.0
+ * @param[in] config A configuration
+ * @param[out] self_powered True if device is self-powered in given configuration,
+ * false otherwise
+ * @return 0 on success, negative error code otherwise
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ */
+int usb_host_config_is_self_powered(usb_host_config_h config, bool *self_powered);
+
+/**
+ * @ingroup CAPI_USB_HOST_CONFIG_MODULE
+ * @brief Checks if device in given configuration supports remote wakeup.
+ * @since_tizen 3.0
+ * @param[in] config A configuration
+ * @param[out] remote_wakeup True if device supports remote wakeup in given configuration,
+ * false otherwise
+ * @return 0 on success, negative error code otherwise
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval @USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ */
+int usb_host_config_support_remote_wakeup(usb_host_config_h config, bool *remote_wakeup);
+
+/**
+ * @ingroup CAPI_USB_HOST_CONFIG_MODULE
+ * @brief Gets maximum power in given configuration, in mA.
+ * @since_tizen 3.0
+ * @param[in] config A configuration
+ * @param[out] max_power Maximum power, in mA
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ */
+int usb_host_config_get_max_power(usb_host_config_h config, int *max_power);
+
+/**
+ * @ingroup CAPI_USB_HOST_CONFIG_MODULE
+ * @brief Gets string describing a configuration.
+ * @since_tizen 3.0
+ * @param[in] config A configuration
+ * @param[in/out] length Data buffer size/how much was actually used
+ * @param[out] data Buffer to store string
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_OVERFLOW There was no space in buffer
+ * @retval #USB_HOST_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @pre config must be configuration of device opened by usb_host_device_open() or
+ * usb_host_device_open_with_vid_pid()
+ */
+int usb_host_device_get_config_str(usb_host_config_h config, int *length, unsigned char *data);
+
+/**
+ * @ingroup CAPI_USB_HOST_CONFIG_MODULE
+ * @brief Gets an interface from configuration.
+ * @details Gets a USB interface from configuration by its index.
+ * @since_tizen 3.0
+ * @param[in] config Configuration handle
+ * @param[in] interface_index index of interface to retrieve
+ * @param[out] interface Interface handle
+ * @remarks There is no need to destroy the @a interface handle. It is no longer valid
+ * when config is destroyed.
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_NOT_FOUND Configuration does not exist
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @retval #USB_HOST_ERROR_PERMISSION_DENIED Permission denied
+ */
+int usb_host_config_get_interface(usb_host_config_h config, int interface_index, usb_host_interface_h *interface);
+
+/**
+ * @ingroup CAPI_USB_HOST_CONFIG_MODULE
+ * @brief Frees configuration.
+ * @details Frees configuration obtained from usb_host_device_get_config().
+ * @since_tizen 3.0
+ * @param[in] config Configuration to free
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @retval #USB_HOST_ERROR_PERMISSION_DENIED Permission denied
+ * @pre config must be obtained by usb_host_device_get_config().
+ */
+int usb_host_config_destroy(usb_host_config_h config);
+
+/**
+ * @ingroup CAPI_USB_HOST_INTERFACE_MODULE
+ * @brief Claims interface.
+ * @details Claims interface on a device.
+ * To perform I/O operations on interface user has to claim it.
+ * Remember to call usb_host_release_interface() when communication
+ * with the device is finished.
+ * @since_tizen 3.0
+ * @param[in] interface_number The bInterfaceNumber of interface to claim
+ * @param[in] force Set to true to auto detach kernel driver, set to false to not detach it
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_NOT_FOUND Requested interface does not exist
+ * @retval #USB_HOST_ERROR_RESOURCE_BUSY Another program or driver has claimed the
+ * interface
+ * @retval #USB_HOST_ERROR_NO_SUCH_DEVICE Device has been disconnected
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @retval #USB_HOST_ERROR_DEVICE_NOT_OPENED The device was not opened
+  */
+int usb_host_claim_interface(usb_host_interface_h interface, bool force);
+
+/**
+ * @ingroup CAPI_USB_HOST_INTERFACE_MODULE
+ * @brief Releases interface.
+ * @details Releases interface previously claimed by usb_host_claim_interface().
+ * This is a blocking function.
+ * @since_tizen 3.0
+ * @param[in] interface_number The bInterfaceNumber of interface to release
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_NOT_FOUND Interface was not claimed
+ * @retval #USB_HOST_ERROR_NO_SUCH_DEVICE Device has been disconnected
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @retval #USB_HOST_ERROR_DEVICE_NOT_OPENED The device was not opened
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_PERMISSION_DENIED Permission denied
+ */
+int usb_host_release_interface(usb_host_interface_h interface);
+
+/**
+ * @ingroup CAPI_USB_HOST_INTERFACE_MODULE
+ * @brief Gets number of given interface.
+ * @since_tizen 3.0
+ * @param[in] interface An interface
+ * @param[out] number Number of given interface
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ */
+int usb_host_interface_get_number(usb_host_interface_h interface, int *number);
+
+/**
+ * @ingroup CAPI_USB_HOST_INTERFACE_MODULE
+ * @brief Gets number of endpoints in given interface.
+ * @since_tizen 3.0
+ * @param[in] interface An interface
+ * @param[out] num_endpoints Number of endpoints in @a interface
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ */
+int usb_host_interface_get_num_endpoints(usb_host_interface_h interface, int *num_endpoints);
+
+/**
+ * @ingroup CAPI_USB_HOST_INTERFACE_MODULE
+ * @brief Gets an endpoint from interface.
+ * @details Get a USB endpoint from interface by its index.
+ * @since_tizen 3.0
+ * @param[in] interface Interface handle
+ * @param[in] config_index index of endpoint to retrieve
+ * @param[out] ep Endpoint handle
+ * @remarks @a ep handle is no longer valid when config will be destroyed. There is no need to destroy it,
+ * it is done automatically when the configuration is destroyed.
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ */
+int usb_host_interface_get_endpoint(usb_host_interface_h interface, int ep_index,
+               usb_host_endpoint_h *ep);
+
+/**
+ * @ingroup CAPI_USB_HOST_INTERFACE_MODULE
+ * @brief Sets alternative setting for interface.
+ * @since_tizen 3.0
+ * @param[in] interface Interface handle
+ * @param[in] altsetting Index of new alternative setting for given interface
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ */
+int usb_host_interface_set_altsetting(usb_host_interface_h interface, int altsetting);
+
+/**
+ * @ingroup CAPI_USB_HOST_INTERFACE_MODULE
+ * @brief Gets string describing an interface.
+ * @since_tizen 3.0
+ * @param[in] interface An interface
+ * @param[in/out] length Data buffer size/how much was actually used
+ * @param[out] data Buffer to store string
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_OVERFLOW There was no space in buffer
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @pre device which interface is part of must be opened by usb_host_device_open() or
+ * usb_host_device_open_with_vid_pid()
+ */
+int usb_host_interface_get_str(usb_host_interface_h interface, int *length,
+               unsigned char *data);
+
+/**
+ * @ingroup CAPI_USB_HOST_ENDPOINT_MODULE
+ * @brief Gets number of given endpoint.
+ * @since_tizen 3.0
+ * @param[in] ep An endpoint
+ * @param[out] number Number of given endpoint
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ */
+int usb_host_endpoint_get_number(usb_host_endpoint_h ep, int *number);
+
+/**
+ * @ingroup CAPI_USB_HOST_ENDPOINT_MODULE
+ * @brief Gets direction of an endpoint.
+ * @since_tizen 3.0
+ * @param[in] ep An endpoint
+ * @param[out] direction Direction of endpoint (a value from enum #usb_host_endpoint_direction_e)
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ */
+int usb_host_endpoint_get_direction(usb_host_endpoint_h ep, int *direction);
+
+/**
+ * @ingroup CAPI_USB_HOST_ENDPOINT_MODULE
+ * @brief Gets transfer type of given endpoint.
+ * @since_tizen 3.0
+ * @param[in] ep An endpoint
+ * @param[out] transfer_type Transfer type (a value from enum #usb_host_transfer_type_e)
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ */
+int usb_host_endpoint_get_transfer_type(usb_host_endpoint_h ep, int *transfer_type);
+
+/**
+ * @ingroup CAPI_USB_HOST_ENDPOINT_MODULE
+ * @brief Gets synchronization type of given endpoint.
+ * @since_tizen 3.0
+ * @param[in] ep An endpoint
+ * @param[out] synch_type Synch type (a value from enum #usb_host_iso_sync_type_e)
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ */
+int usb_host_endpoint_get_synch_type(usb_host_endpoint_h ep, int *synch_type);
+
+/**
+ * @ingroup CAPI_USB_HOST_ENDPOINT_MODULE
+ * @brief Gets usage type of given endpoint.
+ * @since_tizen 3.0
+ * @param[in] ep An endpoint
+ * @param[out] usage_type Usage type (a value from enum #usb_host_usage_type_e)
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ */
+int usb_host_endpoint_get_usage_type(usb_host_endpoint_h ep, int *usage_type);
+
+/**
+ * @ingroup CAPI_USB_HOST_ENDPOINT_MODULE
+ * @brief Gets max packet size of given endpoint.
+ * @since_tizen 3.0
+ * @param[in] ep An endpoint
+ * @param[out] max_packet_size Max packet size
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ */
+int usb_host_endpoint_get_max_packet_size(usb_host_endpoint_h ep, int *max_packet_size);
+
+/**
+ * @ingroup CAPI_USB_HOST_ENDPOINT_MODULE
+ * @brief Gets interval for polling endpoint for data transfers.
+ * @since_tizen 3.0
+ * @param[in] ep An endpoint
+ * @param[out] interval Interval for polling
+ * @return 0 on success, otherwise a negative error value
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ */
+int usb_host_endpoint_get_interval(usb_host_endpoint_h ep, int *interval);
+
+/* sync IO */
+
+/**
+ * @ingroup CAPI_USB_HOST_SYNCIO_MODULE
+ * @brief Performs USB control transfer.
+ * @since_tizen 3.0
+ * @remarks The wValue, wIndex and wLength fields values should be given in host-endian
+ * byte order.
+ * @param[in] handle Device handle
+ * @param[in] bm_request_type bmRequestType type field for the setup packet
+ * @param[in] b_request bRequest field for the setup packet
+ * @param[in] w_value wValue field for the setup packet
+ * @param[in] w_index wIndex field for the setup packet
+ * @param[in] data Suitably-sized data buffer for either input or output
+ * (depending on direction bits within bmRequestType)
+ * @param[in] w_length wLength field for the setup packet. The data buffer should
+ * be at least this size
+ * @param[in] timeout Timeout (in milliseconds) that this function should wait
+ * before giving up due to no response being received. For an unlimited
+ * timeout, 0 value should be used.
+ * @return  0 on success, negative error code otherwise
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_TIMED_OUT Transfer timed out
+ * @retval #USB_HOST_ERROR_BROKEN_PIPE Control request was not supported by the device
+ * @retval #USB_HOST_ERROR_NO_SUCH_DEVICE The device has been disconnected
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_DEVICE_NOT_OPENED The device was not opened
+ * @retval #USB_HOST_ERROR_OVERFLOW Device offered more data
+ * @pre dev must point to device opened by usb_host_device_open() or usb_host_device_open_with_vid_pid()
+ */
+int usb_host_control_transfer(usb_host_device_h dev,
+       uint8_t bm_request_type, uint8_t b_request, uint16_t w_value, uint16_t w_index,
+       unsigned char *data, uint16_t w_length, unsigned int timeout, int *transfered);
+
+/**
+ * @ingroup CAPI_USB_HOST_SYNCIO_MODULE
+ * @brief Performs transfer on given endpoint.
+ * @details Performs a USB transfer on given endpoint. Direction of transfer is
+ * determined by the endpoint.
+ * @since_tizen 3.0
+ * @param[in] ep Endpoint handle
+ * @param[in] data Suitably-sized data buffer for either input or output
+ * (depending on endpoint)
+ * @param[in] length For writes, the number of bytes from data to be sent, for
+ * reads the maximum number of bytes to receive into the data buffer
+ * @param[out] transferred Output location for the number of bytes actually
+ * transferred
+ * @param[in] timeout Timeout (in milliseconds) that this function should wait
+ * before giving up due to no response being received (for an unlimited
+ * timeout 0 value should be used)
+ * @return 0 on success (and populates @a transferred), negative error code on error
+ * @retval #USB_HOST_ERROR_NONE Successful
+ * @retval #USB_HOST_ERROR_TIMED_OUT Transfer timed out
+ * @retval #USB_HOST_ERROR_BROKEN_PIPE Endpoint halted
+ * @retval #USB_HOST_ERROR_OVERFLOW Device offered more data
+ * @retval #USB_HOST_ERROR_NO_SUCH_DEVICE Device has been disconnected
+ * @retval #USB_HOST_ERROR_INVALID_PARAMETER Invalid parameter was passed
+ * @retval #USB_HOST_ERROR_NOT_SUPPORTED Not supported
+ * @retval #USB_HOST_ERROR_DEVICE_NOT_OPENED The device was not opened
+ * @pre ep must be a valid endpoint received from usb_host_interface_get_endpoint().
+ * @pre ep must be an endpoint of device opened by usb_host_device_open() or
+ * usb_host_device_open_with_vid_pid().
+ */
+int usb_host_transfer(usb_host_endpoint_h ep, unsigned char *data, int length,
+               int *transferred, unsigned int timeout);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_USB_HOST_H__ */
diff --git a/include/usb_host_internal.h b/include/usb_host_internal.h
new file mode 100644 (file)
index 0000000..69fa7b8
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * usb_host_internal.h
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "usb_host.h"
+#include "uref.h"
+#include "common.h"
+#include "log.h"
+#include <libusb-1.0/libusb.h>
+
+#define MAX_NMB_OF_CONFIGS 255
+
+struct usb_host_context_s {
+       libusb_context *lusb_ctx;
+};
+
+struct usb_host_device_s {
+       struct libusb_device_descriptor desc;
+       struct uref ref;
+       libusb_device *lusb_dev;
+       int refcnt;
+
+       struct libusb_device_handle *lusb_dev_handle;
+       /* TODO: replace with bit fields */
+       unsigned char driver_detached[MAX_NMB_OF_CONFIGS];
+};
+
+struct usb_host_transfer_s {
+       struct libusb_transfer *lusb_transfer;
+};
+
+/**
+ * @ingroup CAPI_USB_HOST_DESC_MODULE
+ * @brief usb_host_interface_descriptor_s struct
+ * @details This structure presents standard USB endpoint descriptor.
+ */
+struct usb_host_endpoint_descriptor_s {
+       uint8_t  bLength;
+       uint8_t  bDescriptorType;
+       uint8_t  bEndpointAddress;
+       uint8_t  bmAttributes;
+       uint16_t wMaxPacketSize;
+       uint8_t  bInterval;
+       uint8_t  bRefresh;
+       uint8_t  bSynchAddress;
+};
+
+struct usb_host_endpoint_s {
+       struct usb_host_endpoint_descriptor_s desc;
+       const unsigned char *extra;
+       int extra_length;
+
+       struct usb_host_device_s *dev;
+};
+
+/**
+ * @ingroup CAPI_USB_HOST_DESC_MODULE
+ * @brief usb_host_interface_descriptor_s struct
+ * @details This structure presents standard USB interface descriptor.
+ */
+struct usb_host_interface_descriptor_s {
+       uint8_t  bLength;
+       uint8_t  bDescriptorType;
+       uint8_t  bInterfaceNumber;
+       uint8_t  bAlternateSetting;
+       uint8_t  bNumEndpoints;
+       uint8_t  bInterfaceClass;
+       uint8_t  bInterfaceSubClass;
+       uint8_t  bInterfaceProtocol;
+       uint8_t  iInterface;
+};
+
+struct usb_host_altsetting_s {
+       struct usb_host_interface_descriptor_s desc;
+       int num_endpoints;
+       struct usb_host_endpoint_s *endpoints;
+       const unsigned char *extra;
+       int extra_length;
+
+       struct usb_host_device_s *dev;
+};
+
+struct usb_host_interface_s {
+       int num_altsettings;
+       struct usb_host_altsetting_s *altsettings;
+       int altsetting;
+
+       struct usb_host_device_s *dev;
+};
+
+/**
+ * @ingroup CAPI_USB_HOST_DESC_MODULE
+ * @brief usb_host_config_descriptor_s struct
+ * @details This structure presents standard USB configuration descriptor.
+ */
+struct usb_host_config_descriptor_s {
+       uint8_t  bLength;
+       uint8_t  bDescriptorType;
+       uint16_t wTotalLength;
+       uint8_t  bNumInterfaces;
+       uint8_t  bConfigurationValue;
+       uint8_t  iConfiguration;
+       uint8_t  bmAttributes;
+       uint8_t  MaxPower;
+};
+
+struct usb_host_config_s {
+       struct usb_host_config_descriptor_s desc;
+       int num_interfaces;
+       struct usb_host_interface_s *interfaces;
+       const unsigned char *extra;
+       int extra_length;
+
+       struct usb_host_device_s *dev;
+};
index 580d7877568fe91c1081ec05850df702082376f7..8fb82a99847dc0e6acc26232f31c9f7b662eae4e 100644 (file)
@@ -15,7 +15,9 @@ BuildRequires: zip
 BuildRequires: pkgconfig(dlog)
 BuildRequires: libattr-devel
 BuildRequires: libcap-devel
+%if "%{?_build_tests}" == "1"
 BuildRequires: pkgconfig(cmocka)
+%endif
 BuildRequires: pkgconfig(libsmack)
 BuildRequires: pkgconfig(libsystemd-daemon)
 BuildRequires: pkgconfig(libsystemd-journal)
@@ -23,7 +25,7 @@ BuildRequires: pkgconfig(dbus-1)
 %{?systemd_requires}
 
 %description
-Libhusb is a librarary for raw communication with USB devices.
+Usb-host is a librarary for raw communication with USB devices.
 
 %package devel
 Summary:    RAW USB host API
@@ -34,6 +36,16 @@ Requires:   %{name} = %{version}-%{release}
 Development package for capi-system-usbhost. Contains headers and binaries required for
 compilation of applications which use capi-system-usbhost.
 
+%package target-tests
+Summary:    Test setup for target
+Group:      Development/Libraries
+Requires:   %{name} = %{version}-%{release}
+Requires:   gt
+Requires:   arm-odroidxu3-usb-host-tests-modules
+
+%description target-tests
+Tests to be executed on target
+
 %prep
 %setup -q
 cp %{SOURCE1001} .
@@ -50,7 +62,8 @@ export LDFLAGS="${LDFLAGS} -Wl,--rpath=%{_libdir}"
          -DCMAKE_BUILD_TYPE=%{?build_type:%build_type}%{!?build_type:RELEASE} \
          -DCMAKE_VERBOSE_MAKEFILE=ON \
          -DLIB_INSTALL_DIR=%{_libdir} \
-        -DBUILD_TESTS=1 \
+        -DBUILD_TESTS=%{?_build_tests} \
+        -DBUILD_TARGET_TESTS=1 \
          -DSYSTEMD_DIR=%{_unitdir}
 
 %__make %{?_smp_mflags}
@@ -87,11 +100,10 @@ rm -rf %{buildroot}
 %files devel
 %manifest %{name}.manifest
 %defattr(-,root,root)
-%{_includedir}/libhusb.h
+%{_includedir}/usb_host.h
 %{_libdir}/lib%{name}.so
 %{_libdir}/pkgconfig/%{name}.pc
 
 %{_datadir}/license/%{name}
 
-
 %changelog
diff --git a/src/libhusb.c b/src/libhusb.c
deleted file mode 100644 (file)
index b905cb7..0000000
+++ /dev/null
@@ -1,1129 +0,0 @@
-/*
- * libhusb.c
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <libusb-1.0/libusb.h>
-#include <libhusb.h>
-#include <assert.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/queue.h>
-
-#include "libhusb.h"
-#include "uref.h"
-#include "common.h"
-#include "log.h"
-
-#include "libhusb_internal.h"
-
-static inline struct libhusb_device *to_libhusb_device(struct uref *_uref)
-{
-       return container_of(_uref, struct libhusb_device, ref);
-}
-
-static int translate_error(int error_code)
-{
-       switch (error_code) {
-       case LIBUSB_ERROR_IO:
-               return LIBHUSB_ERROR_IO;
-       case LIBUSB_ERROR_INVALID_PARAM:
-               return LIBHUSB_ERROR_INVALID_PARAM;
-       case LIBUSB_ERROR_ACCESS:
-               return LIBHUSB_ERROR_ACCESS;
-       case LIBUSB_ERROR_NO_DEVICE:
-               return LIBHUSB_ERROR_NO_DEVICE;
-       case LIBUSB_ERROR_NOT_FOUND:
-               return LIBHUSB_ERROR_NOT_FOUND;
-       case LIBUSB_ERROR_BUSY:
-               return LIBHUSB_ERROR_BUSY;
-       case LIBUSB_ERROR_TIMEOUT:
-               return LIBHUSB_ERROR_TIMEOUT;
-       case LIBUSB_ERROR_OVERFLOW:
-               return LIBHUSB_ERROR_OVERFLOW;
-       case LIBUSB_ERROR_PIPE:
-               return LIBHUSB_ERROR_PIPE;
-       case LIBUSB_ERROR_INTERRUPTED:
-               return LIBHUSB_ERROR_INTERRUPTED;
-       case LIBUSB_ERROR_NO_MEM:
-               return LIBHUSB_ERROR_NO_MEM;
-       case LIBUSB_ERROR_NOT_SUPPORTED:
-               return LIBHUSB_ERROR_NOT_SUPPORTED;
-       case LIBUSB_ERROR_OTHER:
-               return LIBHUSB_ERROR_OTHER;
-       case LIBUSB_TRANSFER_ERROR:
-               return LIBHUSB_TRANSFER_ERROR;
-       case LIBUSB_TRANSFER_TIMED_OUT:
-               return LIBHUSB_TRANSFER_TIMED_OUT;
-       case LIBUSB_TRANSFER_CANCELLED:
-               return LIBHUSB_TRANSFER_CANCELLED;
-       case LIBUSB_TRANSFER_STALL:
-               return LIBHUSB_TRANSFER_STALL;
-       case LIBUSB_TRANSFER_NO_DEVICE:
-               return LIBHUSB_TRANSFER_NO_DEVICE;
-       case LIBUSB_TRANSFER_OVERFLOW:
-               return LIBHUSB_TRANSFER_OVERFLOW;
-
-       case 0:
-               return LIBHUSB_SUCCESS;
-       default:
-               return LIBHUSB_ERROR_OTHER;
-       }
-}
-
-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) {
-               _E("malloc() failed");
-               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;
-       int count = 10;
-       struct libhusb_context *_ctx;
-
-       assert(ctx);
-
-       _ctx = malloc(sizeof(*_ctx));
-       if (!_ctx) {
-               _E("malloc() failed");
-               goto out;
-       }
-
-       do {
-               ret = libusb_init(&(_ctx->lusb_ctx));
-               count--;
-       } while (ret == LIBUSB_ERROR_OTHER && count > 0);
-
-       if (ret < 0) {
-               _E("Failed to init libusb (%d)", ret);
-               goto free_ctx;
-       }
-
-       *ctx = _ctx;
-
-       return ret;
-
-free_ctx:
-       free(_ctx);
-       ret = translate_error(ret);
-out:
-       return ret;
-}
-
-void libhusb_exit(libhusb_context *context)
-{
-       assert(context);
-
-       libusb_exit(context->lusb_ctx);
-
-       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) {
-               _E("malloc() failed");
-               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);
-               _E("Failed to open device using libusb_open (%d)", 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) {
-               _E("malloc() failed");
-               goto out;
-       }
-
-       ldev_handle = libusb_open_device_with_vid_pid(ctx->lusb_ctx,
-                                                     vendor_id, product_id);
-       if (ldev_handle == NULL) {
-               _E("Failed to open usb device with vid and pid");
-               goto free_handle;
-       }
-
-       handle->lusb_dev_handle = ldev_handle;
-
-       ldev = libusb_get_device(ldev_handle);
-       if (!ldev) {
-               _E("Failed to get device");
-               goto close_handle;
-       }
-
-       dev = alloc_device(ldev);
-       if (!dev) {
-               _E("Failed to allocate memory for a device");
-               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);
-
-       return libusb_get_bus_number(dev->lusb_dev);
-}
-
-uint8_t libhusb_get_address(libhusb_device *dev)
-{
-       uint8_t device_address;
-
-       assert(dev);
-
-       device_address = libusb_get_device_address(dev->lusb_dev);
-
-       return device_address;
-}
-
-int libhusb_get_port_numbers(libhusb_device *dev, uint8_t* port_numbers, int port_numbers_len)
-{
-       /* As per the USB 3.0 specs, the current maximum limit for the depth is 7 */
-       uint8_t p_numbers[8];
-       int ret = 0;
-       int i;
-
-       if (port_numbers_len <= 0)
-               return LIBHUSB_ERROR_INVALID_PARAM;
-
-       assert(dev);
-
-       ret = libusb_get_port_numbers(dev->lusb_dev, p_numbers, port_numbers_len);
-
-       for (i = 0; i < ret; i++)
-               port_numbers[i] = p_numbers[i];
-
-       return ret;
-}
-
-ssize_t libhusb_get_devices(libhusb_context *context, libhusb_device ***devs)
-{
-       ssize_t len;
-       int i = 0;
-       int ret = LIBHUSB_ERROR_NO_MEM;
-       libusb_device **lusb_list = NULL;
-       struct libhusb_device *rdevice;
-       struct libhusb_device **list;
-
-       assert(context);
-       assert(devs);
-
-
-       len = libusb_get_device_list(context->lusb_ctx, &lusb_list);
-       if (len < 0) {
-               ret = translate_error(len);
-               _E("Failed to get device list(%d)", ret);
-               goto out;
-       }
-
-       list = calloc(len + 1, sizeof(*list));
-       if (!list) {
-               _E("calloc() failed");
-               goto free_lusb_list;
-       }
-
-       list[len] = NULL;
-       for (i = 0; i < len; i++) {
-               rdevice = alloc_device(lusb_list[i]);
-               if (!rdevice) {
-                       _E("Failed to allocate memory for a device");
-                       goto free_dev_list;
-               }
-
-               list[i] = rdevice;
-       }
-
-       *devs = list;
-
-       libusb_free_device_list(lusb_list, 1);
-
-       return len;
-
-free_dev_list:
-       while (--i <= 0)
-               libhusb_unref_device(list[i]);
-       free(list);
-free_lusb_list:
-       libusb_free_device_list(lusb_list, 1);
-out:
-       return ret;
-}
-
-libhusb_device *libhusb_ref_device(libhusb_device *dev)
-{
-       uref_get(&dev->ref);
-       return dev;
-}
-
-void libhusb_unref_device(libhusb_device *dev)
-{
-       uref_put(&dev->ref);
-}
-
-void libhusb_free_devices(libhusb_device **list, int unref_devices)
-{
-       int i = 0;
-
-       if (!list)
-               return;
-
-       for (i = 0; list[i] != NULL; i++)
-               if (unref_devices)
-                       libhusb_unref_device(list[i]);
-
-       free(list);
-}
-
-int libhusb_get_max_packet_size(libhusb_device *dev, uint8_t endpoint)
-{
-       int ret;
-
-       assert(dev);
-
-       ret = libusb_get_max_iso_packet_size(dev->lusb_dev, endpoint);
-       if (ret < 0) {
-               ret = translate_error(ret);
-               _E("Failed to get max iso packet size(%d)", ret);
-       }
-
-       return ret;
-}
-
-int libhusb_get_active_config(libhusb_device_handle *handle, int *config)
-{
-       int ret;
-
-       assert(handle);
-
-       ret = libusb_get_configuration(handle->lusb_dev_handle, config);
-       if (ret < 0) {
-               ret = translate_error(ret);
-               _E("Failed to get configuration(%d)", ret);
-       }
-
-       return ret;
-}
-
-int libhusb_set_config(libhusb_device_handle *handle, int configuration)
-{
-       int ret;
-
-       assert(handle);
-
-       ret = libusb_set_configuration(handle->lusb_dev_handle, configuration);
-       if (ret < 0) {
-               ret = translate_error(ret);
-               _E("Failed to set configuration(%d)", ret);
-       }
-
-       return ret;
-}
-
-int libhusb_claim_interface(libhusb_device_handle *handle, int interface_number,
-                           int force)
-{
-       int ret = LIBHUSB_ERROR_INVALID_PARAM;
-       int driver_detached = 0;
-
-       assert(handle);
-
-       if (interface_number < 0 || interface_number > MAX_NMB_OF_CONFIGS) {
-               _E("Invalid parameters");
-               goto out;
-       }
-
-       if (!force)
-               goto claim_interface;
-
-       /*
-        * If force param has been set let's check if kernel driver is active
-        * and detach it if necessary
-        */
-       ret = libusb_kernel_driver_active(handle->lusb_dev_handle,
-                                         interface_number);
-       if (ret < 0) {
-               ret = translate_error(ret);
-               _E("Failed to activate kernel driver (%d)", ret);
-               goto out;
-       } else if (ret == 1) {
-               ret = libusb_detach_kernel_driver(handle->lusb_dev_handle,
-                                                 interface_number);
-               if (ret < 0) {
-                       ret = translate_error(ret);
-                       _E("Failed to detach kernel driver(%d)", ret);
-                       goto out;
-               }
-
-               driver_detached = 1;
-       }
-
-claim_interface:
-       ret = libusb_claim_interface(handle->lusb_dev_handle, interface_number);
-       if (ret < 0) {
-               ret = translate_error(ret);
-               _E("Failed to claim interface (%d)", ret);
-               goto claim_failed;
-       }
-
-       handle->driver_detached[interface_number] = 1;
-
-       return 0;
-
-claim_failed:
-       if (driver_detached)
-               libusb_attach_kernel_driver(handle->lusb_dev_handle,
-                                           interface_number);
-out:
-       return ret;
-}
-
-int libhusb_release_interface(libhusb_device_handle *handle, int interface_number)
-{
-       int ret = LIBHUSB_ERROR_INVALID_PARAM;
-
-       assert(handle);
-
-       if (interface_number < 0 || interface_number > MAX_NMB_OF_CONFIGS) {
-               _E("Invalid parameters");
-               goto out;
-       }
-
-       ret = libusb_release_interface(handle->lusb_dev_handle,
-                                      interface_number);
-       if (ret != 0) {
-               ret = translate_error(ret);
-               _E("Failed to release interface(%d)", ret);
-               goto out;
-       }
-
-       if (handle->driver_detached[interface_number]) {
-               /*
-                * yeah we should check error code but there is no good method
-                * of handling it so for now lets just silently ignore it
-                */
-               libusb_attach_kernel_driver(handle->lusb_dev_handle,
-                                           interface_number);
-               handle->driver_detached[interface_number] = 0;
-       }
-
-out:
-       return ret;
-}
-
-int libhusb_clear_halt(libhusb_device_handle *handle, uint8_t endpoint)
-{
-       int ret;
-
-       assert(handle);
-
-       ret = libusb_clear_halt(handle->lusb_dev_handle, endpoint);
-       if (ret < 0) {
-               ret = translate_error(ret);
-               _E("Failed to clear halt (%d)", ret);
-       }
-
-       return ret;
-}
-
-int libhusb_reset_device(libhusb_device_handle *handle)
-{
-       int ret;
-
-       assert(handle);
-
-       ret = libusb_reset_device(handle->lusb_dev_handle);
-       if (ret < 0) {
-               ret = translate_error(ret);
-               _E("Failed to reset device (%d)", ret);
-       }
-
-       return ret;
-}
-
-int libhusb_kernel_driver_active(libhusb_device_handle *handle, int interface_number)
-{
-       int ret;
-
-       assert(handle);
-
-       ret = libusb_kernel_driver_active(handle->lusb_dev_handle, interface_number);
-       if (ret < 0) {
-               ret = translate_error(ret);
-               _E("Failed to activate kernel driver");
-       }
-
-       return ret;
-}
-
-int libhusb_detach_kernel_driver(libhusb_device_handle *handle, int interface_number)
-{
-       int ret;
-
-       assert(handle);
-
-       ret = libusb_detach_kernel_driver(handle->lusb_dev_handle, interface_number);
-       if (ret < 0) {
-               ret = translate_error(ret);
-               _E("Failed to detach kernel driver (%d)", ret);
-       }
-
-       return ret;
-}
-
-int libhusb_attach_kernel_driver(libhusb_device_handle *handle, int interface_number)
-{
-       int ret;
-
-       assert(handle);
-
-       ret = libusb_attach_kernel_driver(handle->lusb_dev_handle, interface_number);
-       if (ret < 0) {
-               ret = translate_error(ret);
-               _E("Failed to attach kernel driver(%d)", ret);
-       }
-
-       return ret;
-}
-
-int libhusb_get_device_descriptor(libhusb_device *dev, struct libhusb_device_descriptor *desc)
-{
-       int descriptor;
-
-       assert(dev);
-
-       descriptor = libusb_get_device_descriptor(dev->lusb_dev,
-                                                (struct libusb_device_descriptor *)desc);
-
-       if (descriptor < 0) {
-               descriptor = translate_error(descriptor);
-               _E("Failed to get device descriptor(%d)", descriptor);
-       }
-
-       return descriptor;
-}
-
-static void free_ep_desc(struct libhusb_endpoint_descriptor *ep_desc)
-{
-       free((void *)ep_desc->extra);
-}
-
-static void free_interface_desc(struct libhusb_interface_descriptor *int_desc)
-{
-       int i;
-
-       free((void *)int_desc->extra);
-
-       for (i = 0; i < int_desc->bNumEndpoints; ++i)
-               free_ep_desc(int_desc->endpoint + i);
-       free(int_desc->endpoint);
-}
-
-static void free_interface(struct libhusb_interface *interface)
-{
-       int i;
-
-       for (i = 0; i < interface->num_altsetting; ++i)
-               free_interface_desc(interface->altsetting + i);
-       free(interface->altsetting);
-}
-
-void libhusb_free_config_descriptor(struct libhusb_cfg_descriptor *config)
-{
-       int i;
-
-       free((void *)config->extra);
-
-       for (i = 0; i < config->bNumInterfaces; ++i)
-               free_interface(config->interface + i);
-       free(config->interface);
-
-       free(config);
-}
-
-static int dump_extra(const unsigned char *src, int src_len,
-                     const unsigned char **dest, int *dest_len)
-{
-       int ret = LIBHUSB_ERROR_NO_MEM;
-       unsigned char *extra = NULL;
-       int extra_length = 0;
-
-       if (src_len > 0) {
-               extra_length = src_len;
-               extra = malloc(extra_length);
-               if (!extra) {
-                       _E("malloc() failed");
-                       goto out;
-               }
-
-               memcpy(extra, src, extra_length);
-       }
-
-       *dest = extra;
-       *dest_len = extra_length;
-       ret = 0;
-out:
-       return ret;
-}
-
-static int dump_ep_desc(struct libhusb_endpoint_descriptor *dest,
-                         const struct libusb_endpoint_descriptor *src)
-{
-       int ret = LIBHUSB_ERROR_NO_MEM;
-
-#define COPY_FIELD(field) (dest->field = src->field)
-       COPY_FIELD(bLength);
-       COPY_FIELD(bDescriptorType);
-       COPY_FIELD(bEndpointAddress);
-       COPY_FIELD(bmAttributes);
-       COPY_FIELD(wMaxPacketSize);
-       COPY_FIELD(bInterval);
-       COPY_FIELD(bRefresh);
-       COPY_FIELD(bSynchAddress);
-#undef COPY_FIELD
-
-       ret = dump_extra(src->extra, src->extra_length,
-                        &(dest->extra), &(dest->extra_length));
-
-       return ret;
-}
-
-static int dump_interface_desc(struct libhusb_interface_descriptor *dest,
-                         const struct libusb_interface_descriptor *src)
-{
-       int i;
-       int ret = LIBHUSB_ERROR_NO_MEM;
-       struct libhusb_endpoint_descriptor *eps;
-
-#define COPY_FIELD(field) (dest->field = src->field)
-       COPY_FIELD(bLength);
-       COPY_FIELD(bDescriptorType);
-       COPY_FIELD(bInterfaceNumber);
-       COPY_FIELD(bAlternateSetting);
-       COPY_FIELD(bNumEndpoints);
-       COPY_FIELD(bInterfaceClass);
-       COPY_FIELD(bInterfaceSubClass);
-       COPY_FIELD(bInterfaceProtocol);
-       COPY_FIELD(iInterface);
-#undef COPY_FIELD
-
-       eps = calloc(dest->bNumEndpoints, sizeof(*eps));
-       if (!eps) {
-               _E("calloc() failed");
-               goto out;
-       }
-
-       for (i = 0; i < dest->bNumEndpoints; ++i) {
-               ret = dump_ep_desc(eps + i, src->endpoint + i);
-               if (ret != 0) {
-                       _E("dump_ep_desc() failed (%d)", ret);
-                       goto free_eps;
-               }
-       }
-
-       ret = dump_extra(src->extra, src->extra_length,
-                        &(dest->extra), &(dest->extra_length));
-       if (ret) {
-               _E("dump_extra() failed (%d)", ret);
-               goto free_eps;
-       }
-
-       dest->endpoint = eps;
-
-       return 0;
-
-free_eps:
-       while (--i >= 0)
-               free_ep_desc(eps + i);
-       free(eps);
-out:
-       return ret;
-}
-
-static int dump_interface(struct libhusb_interface *dest,
-                         const struct libusb_interface *src)
-{
-       int i;
-       int ret = LIBHUSB_ERROR_NO_MEM;
-       struct libhusb_interface_descriptor *int_descs;
-
-       dest->num_altsetting = src->num_altsetting;
-       int_descs = calloc(dest->num_altsetting, sizeof(*int_descs));
-       if (!int_descs) {
-               _E("calloc() failed");
-               goto out;
-       }
-
-       for (i = 0; i < dest->num_altsetting; ++i) {
-               ret = dump_interface_desc(int_descs + i, src->altsetting + i);
-               if (ret != 0) {
-                       _E("dump_interface_desc() failed (%d)", ret);
-                       goto free_int_desc;
-               }
-       }
-
-       dest->altsetting = int_descs;
-
-       return 0;
-
-free_int_desc:
-       while (--i <= 0)
-               free_interface_desc(int_descs + i);
-       free(int_descs);
-out:
-       return ret;
-}
-
-static int dump_config_desc(struct libhusb_cfg_descriptor *dest,
-                           const struct libusb_config_descriptor *src)
-{
-       int ret = LIBHUSB_ERROR_NO_MEM;
-       int i;
-       struct libhusb_interface *interfaces;
-
-#define COPY_FIELD(field) (dest->field = src->field)
-       COPY_FIELD(bLength);
-       COPY_FIELD(bDescriptorType);
-       COPY_FIELD(wTotalLength);
-       COPY_FIELD(bNumInterfaces);
-       COPY_FIELD(bConfigurationValue);
-       COPY_FIELD(iConfiguration);
-       COPY_FIELD(bmAttributes);
-       COPY_FIELD(MaxPower);
-#undef COPY_FIELD
-
-       interfaces = calloc(dest->bNumInterfaces, sizeof(*interfaces));
-       if (!interfaces) {
-               _E("calloc() failed");
-               goto out;
-       }
-
-       for (i = 0; i < dest->bNumInterfaces; ++i) {
-               ret = dump_interface(interfaces + i, src->interface + i);
-               if (ret != 0) {
-                       _E("dump_interface() failed");
-                       goto free_interfaces;
-               }
-       }
-
-       ret = dump_extra(src->extra, src->extra_length,
-                        &(dest->extra), &(dest->extra_length));
-       if (ret) {
-               _E("dump_extra() failed");
-               goto free_interfaces;
-       }
-
-       dest->interface = interfaces;
-
-       return 0;
-
-free_interfaces:
-       while (--i >= 0)
-               free_interface(interfaces + i);
-       free(interfaces);
-out:
-       return ret;
-}
-
-int libhusb_get_config_descriptor(libhusb_device *dev, uint8_t config_index,
-                                 struct libhusb_cfg_descriptor **config)
-{
-       int ret;
-       struct libusb_config_descriptor *lcfg_desc;
-       struct libhusb_cfg_descriptor *cfg_desc;
-
-       ret = libusb_get_config_descriptor(dev->lusb_dev,
-                                          config_index, &lcfg_desc);
-       if (ret < 0) {
-               ret = translate_error(ret);
-               _E("Failed to get configuration descriptor (%d)", ret);
-               goto out;
-       }
-
-       cfg_desc = malloc(sizeof(*cfg_desc));
-       if (!cfg_desc) {
-               _E("malloc() failed");
-               ret = LIBHUSB_ERROR_NO_MEM;
-               goto free_lcfg_desc;
-       }
-
-       ret = dump_config_desc(cfg_desc, lcfg_desc);
-       if (ret != 0) {
-               _E("dump_config_desc() failed");
-               free(cfg_desc);
-       }
-
-       *config = cfg_desc;
-
-free_lcfg_desc:
-       libusb_free_config_descriptor(lcfg_desc);
-out:
-       return ret;
-}
-
-int libhusb_get_string_descriptor_ascii(libhusb_device_handle *handle,
-       uint8_t desc_index, unsigned char *data, int length)
-{
-       int ret;
-
-       assert(handle);
-
-       ret = libusb_get_string_descriptor_ascii(handle->lusb_dev_handle, desc_index, data, length);
-       if (ret < 0) {
-               ret = translate_error(ret);
-               _E("Failed to get descriptor(%d)", ret);
-       }
-
-       return ret;
-}
-
-int libhusb_control_transfer(libhusb_device_handle *handle, uint8_t request_type,
-                            uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
-                            unsigned char *data, uint16_t wLength, unsigned int timeout)
-{
-       int ret;
-
-       assert(handle);
-
-       ret = libusb_control_transfer(handle->lusb_dev_handle, request_type, bRequest,
-                                      wValue, wIndex, data, wLength, timeout);
-       if (ret < 0) {
-               ret = translate_error(ret);
-               _E("Control transfer failed(%d)", ret);
-       }
-
-       return ret;
-}
-
-int libhusb_bulk_transfer(libhusb_device_handle *handle, uint8_t endpoint,
-                         unsigned char *data, int length, int *transferred,
-                         unsigned int timeout)
-{
-       int ret;
-
-       assert(handle);
-
-       ret = libusb_bulk_transfer(handle->lusb_dev_handle, endpoint, data, length,
-                                  transferred, timeout);
-       if (ret < 0) {
-               ret = translate_error(ret);
-               _E("Bulk transfer failed (%d)", ret);
-       }
-
-       return ret;
-}
-
-int libhusb_interrupt_transfer(libhusb_device_handle *handle,
-       uint8_t endpoint, unsigned char *data, int length,
-       int *transferred, unsigned int timeout)
-{
-       int ret;
-
-       assert(handle);
-
-       ret = libusb_interrupt_transfer(handle->lusb_dev_handle, endpoint, data, length,
-                                       transferred, timeout);
-       if (ret < 0) {
-               ret = translate_error(ret);
-               _E("Interrupt transfer failed (%d)", ret);
-       }
-
-       return ret;
-}
-
-struct async_transfer_data {
-       libhusb_transfer_cb_fn cb;
-       void *user_data;
-};
-
-static void generic_transfer_cb(struct libusb_transfer *transfer)
-{
-       struct async_transfer_data *data;
-
-       data = transfer->user_data;
-       data->cb(translate_error(transfer->status), transfer->buffer, transfer->actual_length, data->user_data);
-}
-
-int libhusb_create_transfer(libhusb_transfer **transfer, int iso_packets)
-{
-       libhusb_transfer *rtransfer;
-
-       assert(transfer);
-
-       rtransfer = malloc(sizeof(*rtransfer));
-       if (!rtransfer) {
-               _E("Failed to alloc transfer structure");
-               return LIBHUSB_ERROR_NO_MEM;
-       }
-
-       rtransfer->lusb_transfer = libusb_alloc_transfer(iso_packets);
-       rtransfer->lusb_transfer->user_data = NULL;
-       *transfer = rtransfer;
-
-       return 0;
-}
-
-int libhusb_submit_transfer(libhusb_transfer *transfer)
-{
-       int ret;
-
-       ret = libusb_submit_transfer(transfer->lusb_transfer);
-       if (ret < 0) {
-               _E("Failed to submit async transfer: %d", ret);
-               ret = translate_error(ret);
-       }
-
-       return ret;
-}
-
-int libhusb_cancel_transfer(libhusb_transfer *transfer)
-{
-       int ret;
-
-       ret = libusb_cancel_transfer(transfer->lusb_transfer);
-       if (ret < 0) {
-               _E("Failed to cancel async transfer: %d", ret);
-               ret = translate_error(ret);
-       }
-
-       return ret;
-}
-
-void libhusb_destroy_transfer(libhusb_transfer *transfer)
-{
-       libusb_free_transfer(transfer->lusb_transfer);
-       free(transfer->lusb_transfer->user_data);
-       free(transfer);
-}
-
-void libhusb_fill_control_setup(unsigned char *buffer, uint8_t bmRequestType,
-               uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength)
-{
-       assert(buffer);
-
-       libusb_fill_control_setup(buffer, bmRequestType, bRequest, wValue, wIndex, wLength);
-}
-
-int libhusb_fill_interrupt_transfer(libhusb_transfer *transfer, libhusb_device_handle *handle,
-       libhusb_transfer_cb_fn callback, uint8_t endpoint, unsigned char *buffer, int length,
-       void *user_data, unsigned int timeout)
-{
-       struct async_transfer_data *data;
-       assert(transfer);
-       assert(transfer->lsusb_transfer);
-       assert(handle);
-
-       data = malloc(sizeof(*data));
-       if (!data) {
-               _E("malloc failed");
-               return LIBHUSB_ERROR_NO_MEM;
-       }
-
-       data->cb = callback;
-       data->user_data = user_data;
-
-       /* it's either NULL, or was allocated by library */
-       free(transfer->lusb_transfer->user_data);
-       libusb_fill_interrupt_transfer(transfer->lusb_transfer, handle->lusb_dev_handle, endpoint, buffer, length, generic_transfer_cb, data, timeout);
-
-       return 0;
-}
-
-int libhusb_fill_bulk_transfer(libhusb_transfer *transfer, libhusb_device_handle *handle,
-       libhusb_transfer_cb_fn callback, uint8_t endpoint, unsigned char *buffer, int length,
-       void *user_data, unsigned int timeout)
-{
-       struct async_transfer_data *data;
-       assert(transfer);
-       assert(transfer->lsusb_transfer);
-       assert(handle);
-
-       data = malloc(sizeof(*data));
-       if (!data) {
-               _E("malloc failed");
-               return LIBHUSB_ERROR_NO_MEM;
-       }
-
-       data->cb = callback;
-       data->user_data = user_data;
-
-       /* it's either NULL, or was allocated by library */
-       free(transfer->lusb_transfer->user_data);
-       libusb_fill_bulk_transfer(transfer->lusb_transfer, handle->lusb_dev_handle, endpoint, buffer, length, generic_transfer_cb, data, timeout);
-
-       return 0;
-}
-
-int libhusb_fill_control_transfer(libhusb_transfer *transfer, libhusb_device_handle *handle,
-       libhusb_transfer_cb_fn callback, unsigned char *buffer, void *user_data, unsigned int timeout)
-{
-       struct async_transfer_data *data;
-       assert(transfer);
-       assert(transfer->lsusb_transfer);
-       assert(handle);
-
-       data = malloc(sizeof(*data));
-       if (!data) {
-               _E("malloc failed");
-               return LIBHUSB_ERROR_NO_MEM;
-       }
-
-       data->cb = callback;
-       data->user_data = user_data;
-
-       /* it's either NULL, or was allocated by library */
-       free(transfer->lusb_transfer->user_data);
-       libusb_fill_control_transfer(transfer->lusb_transfer, handle->lusb_dev_handle, buffer, generic_transfer_cb, data, timeout);
-
-       return 0;
-}
-
-int libhusb_handle_events(libhusb_context *ctx, int *completed)
-{
-       int ret;
-
-       ret = libusb_handle_events_completed(ctx->lusb_ctx, completed);
-       return translate_error(ret);
-}
-
-const char *libhusb_error_name(int error_code)
-{
-       switch (error_code) {
-       case LIBHUSB_ERROR_IO:
-               return "LIBHUSB_ERROR_IO";
-       case LIBHUSB_ERROR_INVALID_PARAM:
-               return "LIBHUSB_ERROR_INVALID_PARAM";
-       case LIBHUSB_ERROR_ACCESS:
-               return "LIBHUSB_ERROR_ACCESS";
-       case LIBHUSB_ERROR_NO_DEVICE:
-               return "LIBHUSB_ERROR_NO_DEVICE";
-       case LIBHUSB_ERROR_NOT_FOUND:
-               return "LIBHUSB_ERROR_NOT_FOUND";
-       case LIBHUSB_ERROR_BUSY:
-               return "LIBHUSB_ERROR_BUSY";
-       case LIBHUSB_ERROR_TIMEOUT:
-               return "LIBHUSB_ERROR_TIMEOUT";
-       case LIBHUSB_ERROR_OVERFLOW:
-               return "LIBHUSB_ERROR_OVERFLOW";
-       case LIBHUSB_ERROR_PIPE:
-               return "LIBHUSB_ERROR_PIPE";
-       case LIBHUSB_ERROR_INTERRUPTED:
-               return "LIBHUSB_ERROR_INTERRUPTED";
-       case LIBHUSB_ERROR_NO_MEM:
-               return "LIBHUSB_ERROR_NO_MEM";
-       case LIBHUSB_ERROR_NOT_SUPPORTED:
-               return "LIBHUSB_ERROR_NOT_SUPPORTED";
-       case LIBHUSB_ERROR_OTHER:
-               return "LIBHUSB_ERROR_OTHER";
-       case LIBHUSB_TRANSFER_ERROR:
-               return "LIBHUSB_TRANSFER_ERROR";
-       case LIBHUSB_TRANSFER_TIMED_OUT:
-               return "LIBHUSB_TRANSFER_TIMED_OUT";
-       case LIBHUSB_TRANSFER_CANCELLED:
-               return "LIBHUSB_TRANSFER_CANCELLED";
-       case LIBHUSB_TRANSFER_STALL:
-               return "LIBHUSB_TRANSFER_STALL";
-       case LIBHUSB_TRANSFER_NO_DEVICE:
-               return "LIBHUSB_TRANSFER_NO_DEVICE";
-       case LIBHUSB_TRANSFER_OVERFLOW:
-               return "LIBHUSB_TRANSFER_OVERFLOW";
-
-       case 0:
-               return "LIBHUSB_SUCCESS / LIBHUSB_TRANSFER_COMPLETED";
-       default:
-               return "LIBHUSB_ERROR_OTHER";
-       }
-}
-
diff --git a/src/usb_host.c b/src/usb_host.c
new file mode 100644 (file)
index 0000000..e5e836f
--- /dev/null
@@ -0,0 +1,1392 @@
+/*
+ * usb_host.c
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <libusb-1.0/libusb.h>
+#include <linux/usb/ch9.h>
+#include <usb_host.h>
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/queue.h>
+
+#include "usb_host.h"
+#include "uref.h"
+#include "common.h"
+#include "log.h"
+
+#include "usb_host_internal.h"
+
+static inline struct usb_host_device_s *to_usb_host_device(struct uref *_uref)
+{
+       return container_of(_uref, struct usb_host_device_s, ref);
+}
+
+static int translate_error(int error_code)
+{
+       switch (error_code) {
+       case LIBUSB_ERROR_IO:
+               return USB_HOST_ERROR_IO_ERROR;
+       case LIBUSB_ERROR_INVALID_PARAM:
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       case LIBUSB_ERROR_ACCESS:
+               return USB_HOST_ERROR_PERMISSION_DENIED;
+       case LIBUSB_ERROR_NO_DEVICE:
+               return USB_HOST_ERROR_NO_SUCH_DEVICE;
+       case LIBUSB_ERROR_NOT_FOUND:
+               return USB_HOST_ERROR_NOT_FOUND;
+       case LIBUSB_ERROR_BUSY:
+               return USB_HOST_ERROR_RESOURCE_BUSY;
+       case LIBUSB_ERROR_TIMEOUT:
+               return USB_HOST_ERROR_TIMED_OUT;
+       case LIBUSB_ERROR_OVERFLOW:
+               return USB_HOST_ERROR_OUT_OF_MEMORY;
+       case LIBUSB_ERROR_PIPE:
+               return USB_HOST_ERROR_BROKEN_PIPE;
+       case LIBUSB_ERROR_INTERRUPTED:
+               return USB_HOST_ERROR_INTERRUPTED_SYS_CALL;
+       case LIBUSB_ERROR_NO_MEM:
+               return USB_HOST_ERROR_OUT_OF_MEMORY;
+       case LIBUSB_ERROR_NOT_SUPPORTED:
+               return USB_HOST_ERROR_NOT_SUPPORTED;
+       case LIBUSB_TRANSFER_ERROR:
+       case LIBUSB_TRANSFER_TIMED_OUT:
+       case LIBUSB_TRANSFER_CANCELLED:
+       case LIBUSB_TRANSFER_STALL:
+       case LIBUSB_TRANSFER_NO_DEVICE:
+       case LIBUSB_TRANSFER_OVERFLOW:
+       case LIBUSB_ERROR_OTHER:
+               return TIZEN_ERROR_UNKNOWN;
+
+       case 0:
+               return USB_HOST_ERROR_NONE;
+       default:
+               return TIZEN_ERROR_UNKNOWN;
+       }
+}
+
+static void free_device(struct uref *uref)
+{
+       struct usb_host_device_s *dev = to_usb_host_device(uref);
+
+       libusb_unref_device(dev->lusb_dev);
+       free(dev);
+}
+
+static struct usb_host_device_s *alloc_device(libusb_device *lusb_dev)
+{
+       struct usb_host_device_s *dev;
+       int ret;
+
+       dev = calloc(1, sizeof(*dev));
+       if (!dev) {
+               _E("malloc() failed");
+               goto out;
+       }
+
+       uref_init(&dev->ref, free_device);
+
+       libusb_ref_device(lusb_dev);
+       dev->lusb_dev = lusb_dev;
+
+       ret = libusb_get_device_descriptor(lusb_dev, &dev->desc);
+       if (ret < 0) {
+               _E("could not get device descriptor");
+               libusb_unref_device(lusb_dev);
+               free(dev);
+               return NULL;
+       }
+
+out:
+       return dev;
+}
+
+static void free_ep(struct usb_host_endpoint_s *ep)
+{
+       free((void *)ep->extra);
+}
+
+static void free_altsetting(struct usb_host_altsetting_s *alt)
+{
+       int i;
+
+       free((void *)alt->extra);
+
+       for (i = 0; i < alt->desc.bNumEndpoints; ++i)
+               free_ep(alt->endpoints + i);
+       free(alt->endpoints);
+}
+
+static void free_interface(struct usb_host_interface_s *interface)
+{
+       int i;
+
+       for (i = 0; i < interface->num_altsettings; ++i)
+               free_altsetting(interface->altsettings + i);
+       free(interface->altsettings);
+}
+
+static int dump_extra(const unsigned char *src, int src_len,
+                     const unsigned char **dest, int *dest_len)
+{
+       int ret = USB_HOST_ERROR_OUT_OF_MEMORY;
+       unsigned char *extra = NULL;
+       int extra_length = 0;
+
+       if (src_len > 0) {
+               extra_length = src_len;
+               extra = malloc(extra_length);
+               if (!extra) {
+                       _E("malloc() failed");
+                       goto out;
+               }
+
+               memcpy(extra, src, extra_length);
+       }
+
+       *dest = extra;
+       *dest_len = extra_length;
+       ret = 0;
+out:
+       return ret;
+}
+
+static int dump_ep_desc(struct usb_host_endpoint_s *dest,
+                         const struct libusb_endpoint_descriptor *src,
+                         struct usb_host_device_s *dev)
+{
+       int ret = USB_HOST_ERROR_OUT_OF_MEMORY;
+
+#define COPY_FIELD(field) (dest->desc.field = src->field)
+       COPY_FIELD(bLength);
+       COPY_FIELD(bDescriptorType);
+       COPY_FIELD(bEndpointAddress);
+       COPY_FIELD(bmAttributes);
+       COPY_FIELD(wMaxPacketSize);
+       COPY_FIELD(bInterval);
+       COPY_FIELD(bRefresh);
+       COPY_FIELD(bSynchAddress);
+#undef COPY_FIELD
+
+       dest->dev = dev;
+
+       ret = dump_extra(src->extra, src->extra_length,
+                        &(dest->extra), &(dest->extra_length));
+
+       return ret;
+}
+
+static int dump_altsetting(struct usb_host_altsetting_s *dest,
+                         const struct libusb_interface_descriptor *src,
+                         struct usb_host_device_s *dev)
+{
+       int i;
+       int ret = USB_HOST_ERROR_OUT_OF_MEMORY;
+       struct usb_host_endpoint_s *eps;
+
+#define COPY_FIELD(field) (dest->desc.field = src->field)
+       COPY_FIELD(bLength);
+       COPY_FIELD(bDescriptorType);
+       COPY_FIELD(bInterfaceNumber);
+       COPY_FIELD(bAlternateSetting);
+       COPY_FIELD(bNumEndpoints);
+       COPY_FIELD(bInterfaceClass);
+       COPY_FIELD(bInterfaceSubClass);
+       COPY_FIELD(bInterfaceProtocol);
+       COPY_FIELD(iInterface);
+#undef COPY_FIELD
+
+       dest->dev = dev;
+
+       dest->num_endpoints = dest->desc.bNumEndpoints;
+       eps = calloc(dest->desc.bNumEndpoints, sizeof(*eps));
+       if (!eps) {
+               _E("calloc() failed");
+               goto out;
+       }
+
+       for (i = 0; i < dest->desc.bNumEndpoints; ++i) {
+               ret = dump_ep_desc(eps + i, src->endpoint + i, dev);
+               if (ret != 0) {
+                       _E("dump_ep_desc() failed (%d)", ret);
+                       goto free_eps;
+               }
+       }
+
+       ret = dump_extra(src->extra, src->extra_length,
+                        &(dest->extra), &(dest->extra_length));
+       if (ret) {
+               _E("dump_extra() failed (%d)", ret);
+               goto free_eps;
+       }
+
+       dest->endpoints = eps;
+
+       return 0;
+
+free_eps:
+       while (--i >= 0)
+               free_ep(eps + i);
+       free(eps);
+out:
+       return ret;
+}
+
+static int dump_interface(struct usb_host_interface_s *dest,
+                         const struct libusb_interface *src,
+                         struct usb_host_device_s *dev)
+{
+       int i;
+       int ret = USB_HOST_ERROR_OUT_OF_MEMORY;
+       struct usb_host_altsetting_s *alts;
+
+       dest->num_altsettings = src->num_altsetting;
+       alts = calloc(dest->num_altsettings, sizeof(*alts));
+       if (!alts) {
+               _E("calloc() failed");
+               goto out;
+       }
+
+       dest->dev = dev;
+
+       for (i = 0; i < dest->num_altsettings; ++i) {
+               ret = dump_altsetting(alts + i, src->altsetting + i, dev);
+               if (ret != 0) {
+                       _E("dump_interface_desc() failed (%d)", ret);
+                       goto free_alts;
+               }
+       }
+
+       dest->altsettings = alts;
+       dest->altsetting = 0;
+
+       return 0;
+
+free_alts:
+       while (--i >= 0)
+               free_altsetting(alts + i);
+       free(alts);
+out:
+       return ret;
+}
+
+static int dump_config_desc(struct usb_host_config_s *dest,
+                           const struct libusb_config_descriptor *src,
+                           struct usb_host_device_s *dev)
+{
+       int ret = USB_HOST_ERROR_OUT_OF_MEMORY;
+       int i;
+       struct usb_host_interface_s *interfaces;
+
+#define COPY_FIELD(field) (dest->desc.field = src->field)
+       COPY_FIELD(bLength);
+       COPY_FIELD(bDescriptorType);
+       COPY_FIELD(wTotalLength);
+       COPY_FIELD(bNumInterfaces);
+       COPY_FIELD(bConfigurationValue);
+       COPY_FIELD(iConfiguration);
+       COPY_FIELD(bmAttributes);
+       COPY_FIELD(MaxPower);
+#undef COPY_FIELD
+
+       dest->dev = dev;
+
+       dest->num_interfaces = dest->desc.bNumInterfaces;
+       interfaces = calloc(dest->desc.bNumInterfaces, sizeof(*interfaces));
+       if (!interfaces) {
+               _E("calloc() failed");
+               goto out;
+       }
+
+       for (i = 0; i < dest->desc.bNumInterfaces; ++i) {
+               ret = dump_interface(interfaces + i, src->interface + i, dev);
+               if (ret != 0) {
+                       _E("dump_interface() failed");
+                       goto free_interfaces;
+               }
+       }
+
+       ret = dump_extra(src->extra, src->extra_length,
+                        &(dest->extra), &(dest->extra_length));
+       if (ret) {
+               _E("dump_extra() failed");
+               goto free_interfaces;
+       }
+
+       dest->interfaces = interfaces;
+
+       return 0;
+
+free_interfaces:
+       while (--i >= 0)
+               free_interface(interfaces + i);
+       free(interfaces);
+out:
+       return ret;
+}
+
+int usb_host_create(usb_host_context_h *ctx)
+{
+       int ret = USB_HOST_ERROR_OUT_OF_MEMORY;
+       int count = 10;
+       struct usb_host_context_s *_ctx;
+
+       if (!ctx) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       _ctx = malloc(sizeof(*_ctx));
+       if (!_ctx) {
+               _E("malloc() failed");
+               goto out;
+       }
+
+       do {
+               ret = libusb_init(&(_ctx->lusb_ctx));
+               count--;
+       } while (ret == LIBUSB_ERROR_OTHER && count > 0);
+
+       if (ret < 0) {
+               _E("Failed to init libusb (%d)", ret);
+               goto free_ctx;
+       }
+
+       *ctx = _ctx;
+
+       return USB_HOST_ERROR_NONE;
+
+free_ctx:
+       free(_ctx);
+       ret = translate_error(ret);
+out:
+       return ret;
+}
+
+int usb_host_destroy(usb_host_context_h context)
+{
+       if (!context) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       libusb_exit(context->lusb_ctx);
+
+       free(context);
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_device_open(usb_host_device_h dev)
+{
+       int ret = USB_HOST_ERROR_OUT_OF_MEMORY;
+
+       if (!dev) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       ret = libusb_open(dev->lusb_dev, &(dev->lusb_dev_handle));
+       if (ret < 0) {
+               ret = translate_error(ret);
+               _E("Failed to open device using libusb_open (%d)", ret);
+       }
+
+       return ret;
+}
+
+int usb_host_device_close(usb_host_device_h dev)
+{
+       if (!dev) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       if (dev->lusb_dev_handle == NULL) {
+               _E("Device is not opened");
+               return USB_HOST_ERROR_DEVICE_NOT_OPENED;
+       }
+
+       libusb_close(dev->lusb_dev_handle);
+       dev->lusb_dev_handle = NULL;
+
+       return 0;
+}
+
+int usb_host_device_open_with_vid_pid(usb_host_context_h ctx,
+                                 int vendor_id, int product_id, usb_host_device_h *device_handle)
+{
+       int r = USB_HOST_ERROR_INVALID_PARAMETER;
+       struct usb_host_device_s *dev;
+       libusb_device_handle *ldev_handle;
+       libusb_device *ldev;
+
+       if (!ctx || !device_handle) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       ldev_handle = libusb_open_device_with_vid_pid(ctx->lusb_ctx,
+                                                     vendor_id, product_id);
+       if (ldev_handle == NULL) {
+               _E("Failed to open usb device with vid and pid");
+               r = USB_HOST_ERROR_NO_SUCH_DEVICE;
+               goto out;
+       }
+
+       ldev = libusb_get_device(ldev_handle);
+       if (!ldev) {
+               _E("Failed to get device");
+               r = USB_HOST_ERROR_NO_SUCH_DEVICE;
+               goto close_handle;
+       }
+
+       dev = alloc_device(ldev);
+       if (!dev) {
+               _E("Failed to allocate memory for a device");
+               r = USB_HOST_ERROR_OUT_OF_MEMORY;
+               goto close_handle;
+       }
+
+       dev->lusb_dev_handle = ldev_handle;
+
+       *device_handle = dev;
+       return USB_HOST_ERROR_NONE;
+
+close_handle:
+       libusb_close(ldev_handle);
+out:
+       _E("Failed to open device with given parameters");
+       return r;
+}
+
+int usb_host_device_get_bus_number(usb_host_device_h dev, int *bus_number)
+{
+       if (!dev || !bus_number) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       *bus_number = libusb_get_bus_number(dev->lusb_dev);
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_device_get_address(usb_host_device_h dev, int *device_address)
+{
+
+       if (!dev || !device_address) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       *device_address = libusb_get_device_address(dev->lusb_dev);
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_device_get_port_numbers(usb_host_device_h dev, int *port_numbers, int port_numbers_len, int *ports_count)
+{
+       /* As per the USB 3.0 specs, the current maximum limit for the depth is 7 */
+       uint8_t p_numbers[8];
+       int ret = 0;
+       int i;
+
+       if (port_numbers_len <= 0) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       if (!dev || !port_numbers) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+       ret = libusb_get_port_numbers(dev->lusb_dev, p_numbers, port_numbers_len);
+
+       for (i = 0; i < ret; i++)
+               port_numbers[i] = p_numbers[i];
+
+       *ports_count = ret;
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_get_device_list(usb_host_context_h context, usb_host_device_h **devs, int *length)
+{
+       ssize_t len;
+       int i = 0;
+       int ret = USB_HOST_ERROR_OUT_OF_MEMORY;
+       libusb_device **lusb_list = NULL;
+       struct usb_host_device_s *rdevice;
+       struct usb_host_device_s **list;
+
+       if (!context || !devs || !length) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       len = libusb_get_device_list(context->lusb_ctx, &lusb_list);
+       if (len < 0) {
+               ret = translate_error(len);
+               _E("Failed to get device list(%d)", ret);
+               goto out;
+       }
+
+       list = calloc(len + 1, sizeof(*list));
+       if (!list) {
+               _E("calloc() failed");
+               goto free_lusb_list;
+       }
+
+       list[len] = NULL;
+       for (i = 0; i < len; i++) {
+               rdevice = alloc_device(lusb_list[i]);
+               if (!rdevice) {
+                       _E("Failed to allocate memory for a device");
+                       goto free_dev_list;
+               }
+
+               list[i] = rdevice;
+       }
+
+       *devs = list;
+
+       libusb_free_device_list(lusb_list, 1);
+       *length = len;
+       return USB_HOST_ERROR_NONE;
+
+free_dev_list:
+       while (--i >= 0)
+               usb_host_unref_device(list[i]);
+       free(list);
+free_lusb_list:
+       libusb_free_device_list(lusb_list, 1);
+out:
+       return ret;
+}
+
+int usb_host_ref_device(usb_host_device_h dev)
+{
+       if (!dev) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       uref_get(&dev->ref);
+
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_unref_device(usb_host_device_h dev)
+{
+       if (!dev) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+       uref_put(&dev->ref);
+
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_free_device_list(usb_host_device_h *devs, bool unref_devices)
+{
+       int i = 0;
+       int ret;
+
+       if (!devs) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       if (unref_devices)
+               for (i = 0; devs[i] != NULL; i++) {
+                       ret = usb_host_unref_device(devs[i]);
+                       if (ret < 0)
+                               return ret;
+               }
+
+       free(devs);
+
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_get_active_config(usb_host_device_h dev, usb_host_config_h *config)
+{
+       int ret;
+       int cfg_nmb;
+       struct libusb_config_descriptor *lcfg_desc;
+       struct usb_host_config_s *cfg;
+
+       if (!dev || !config) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       ret = libusb_get_configuration(dev->lusb_dev_handle, &cfg_nmb);
+       if (ret < 0) {
+               ret = translate_error(ret);
+               _E("Failed to get configuration(%d)", ret);
+               goto out;
+       }
+
+       ret = libusb_get_config_descriptor_by_value(dev->lusb_dev, cfg_nmb, &lcfg_desc);
+       if (ret < 0) {
+               ret = translate_error(ret);
+               _E("Failed to get configuration descriptor (%d)", ret);
+               goto out;
+       }
+
+       cfg = malloc(sizeof(*cfg));
+       if (!cfg) {
+               _E("malloc() failed");
+               ret = USB_HOST_ERROR_OUT_OF_MEMORY;
+               goto free_lcfg_desc;
+       }
+
+       ret = dump_config_desc(cfg, lcfg_desc, dev);
+       if (ret != 0) {
+               _E("dump_config_desc() failed");
+               free(cfg);
+       }
+
+       *config = cfg;
+
+free_lcfg_desc:
+       libusb_free_config_descriptor(lcfg_desc);
+out:
+       return ret;
+}
+
+int usb_host_set_config(usb_host_config_h configuration)
+{
+       int ret;
+       struct usb_host_device_s *dev;
+
+       if (!configuration) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       dev = configuration->dev;
+
+       if (!dev->lusb_dev_handle) {
+               _E("Device not opened");
+               return USB_HOST_ERROR_DEVICE_NOT_OPENED;
+       }
+
+       ret = libusb_set_configuration(dev->lusb_dev_handle, configuration->desc.bConfigurationValue);
+       if (ret < 0) {
+               ret = translate_error(ret);
+               _E("Failed to set configuration(%d)", ret);
+       }
+
+       return ret;
+}
+
+int usb_host_claim_interface(usb_host_interface_h interface, bool force)
+{
+       int ret = USB_HOST_ERROR_INVALID_PARAMETER;
+       int driver_detached = 0;
+       int interface_number;
+       struct libusb_device_handle *lusb_dev_handle;
+
+       if (!interface) {
+               _E("Invalid parameter");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       interface_number = interface->altsettings[interface->altsetting].desc.bInterfaceNumber;
+       lusb_dev_handle = interface->dev->lusb_dev_handle;
+
+       if (!lusb_dev_handle) {
+               _E("Device not opened");
+               return USB_HOST_ERROR_DEVICE_NOT_OPENED;
+       }
+
+       if (!force)
+               goto claim_interface;
+
+       /*
+        * If force param has been set let's check if kernel driver is active
+        * and detach it if necessary
+        */
+       ret = libusb_kernel_driver_active(lusb_dev_handle,
+                                         interface_number);
+       if (ret < 0) {
+               ret = translate_error(ret);
+               _E("Failed to activate kernel driver (%d)", ret);
+               goto out;
+       } else if (ret == 1) {
+               ret = libusb_detach_kernel_driver(lusb_dev_handle,
+                                                 interface_number);
+               if (ret < 0) {
+                       ret = translate_error(ret);
+                       _E("Failed to detach kernel driver(%d)", ret);
+                       goto out;
+               }
+
+               driver_detached = 1;
+       }
+
+claim_interface:
+       ret = libusb_claim_interface(lusb_dev_handle, interface_number);
+       if (ret < 0) {
+               ret = translate_error(ret);
+               _E("Failed to claim interface (%d)", ret);
+               goto claim_failed;
+       }
+
+       interface->dev->driver_detached[interface_number] = 1;
+
+       return 0;
+
+claim_failed:
+       if (driver_detached)
+               libusb_attach_kernel_driver(lusb_dev_handle,
+                                           interface_number);
+out:
+       return ret;
+}
+
+int usb_host_release_interface(usb_host_interface_h interface)
+{
+       int ret = USB_HOST_ERROR_INVALID_PARAMETER;
+       int interface_number;
+       struct libusb_device_handle *lusb_dev_handle;
+
+       if (!interface) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       lusb_dev_handle = interface->dev->lusb_dev_handle;
+       interface_number = interface->altsettings[interface->altsetting].desc.bInterfaceNumber;
+
+       if (!lusb_dev_handle) {
+               _E("Device not opened");
+               return USB_HOST_ERROR_DEVICE_NOT_OPENED;
+       }
+
+       ret = libusb_release_interface(lusb_dev_handle, interface_number);
+       if (ret != 0) {
+               ret = translate_error(ret);
+               _E("Failed to release interface(%d)", ret);
+               goto out;
+       }
+
+       if (interface->dev->driver_detached[interface_number]) {
+               /*
+                * yeah we should check error code but there is no good method
+                * of handling it so for now lets just silently ignore it
+                */
+               libusb_attach_kernel_driver(interface->dev->lusb_dev_handle,
+                                           interface_number);
+               interface->dev->driver_detached[interface_number] = 0;
+       }
+
+out:
+       return ret;
+}
+
+int usb_host_device_get_bcd_usb(usb_host_device_h dev, int *bcd_usb)
+{
+       if (!dev || !bcd_usb) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+       *bcd_usb = dev->desc.bcdUSB;
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_device_get_class(usb_host_device_h dev, int *device_class)
+{
+       if (!dev || !device_class) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       *device_class = dev->desc.bDeviceClass;
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_device_get_sub_class(usb_host_device_h dev, int *subclass)
+{
+       if (!dev || !subclass) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       *subclass = dev->desc.bDeviceSubClass;
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_device_get_protocol(usb_host_device_h dev, int *protocol)
+{
+       if (!dev || !protocol) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       *protocol = dev->desc.bDeviceProtocol;
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_device_get_max_packet_size_0(usb_host_device_h dev, int *max_packet_size)
+{
+       if (!dev || !max_packet_size) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       *max_packet_size = dev->desc.bMaxPacketSize0;
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_device_get_id_vendor(usb_host_device_h dev, int *vendor_id)
+{
+       if (!dev || !vendor_id) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       *vendor_id = dev->desc.idVendor;
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_device_get_id_product(usb_host_device_h dev, int *product_id)
+{
+       if (!dev || !product_id) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       *product_id = dev->desc.idProduct;
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_device_get_bcd_device(usb_host_device_h dev, int *device_bcd)
+{
+       if (!dev || !device_bcd) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       *device_bcd = dev->desc.bcdDevice;
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_device_get_num_configurations(usb_host_device_h dev, int *num_configurations)
+{
+       if (!dev || !num_configurations) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+       *num_configurations = dev->desc.bNumConfigurations;
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_is_device_opened(usb_host_device_h dev, bool *is_opened)
+{
+       if (!dev || !is_opened) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       *is_opened = !!dev->lusb_dev_handle;
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_device_get_manufacturer_str(usb_host_device_h dev, int *length, unsigned char *data)
+{
+       if (!dev || !data) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       return usb_host_device_get_string_descriptor_ascii(dev,
+                       dev->desc.iManufacturer, length, data);
+}
+
+int usb_host_device_get_product_str(usb_host_device_h dev, int *length, unsigned char *data)
+{
+       if (!dev || !data) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       return  usb_host_device_get_string_descriptor_ascii(dev,
+                       dev->desc.iProduct, length, data);
+}
+
+int usb_host_device_get_serial_number_str(usb_host_device_h dev, int *length, unsigned char *data)
+{
+       if (!dev || !data) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       return usb_host_device_get_string_descriptor_ascii(dev,
+                       dev->desc.iSerialNumber, length, data);
+}
+
+int usb_host_config_get_num_interfaces(usb_host_config_h config, int *num_interfaces)
+{
+       if (!config || !num_interfaces) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+       *num_interfaces = config->desc.bNumInterfaces;
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_config_is_self_powered(usb_host_config_h config, bool *self_powered)
+{
+       if (!config || !self_powered) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       *self_powered = config->desc.bmAttributes & (1 << 6);
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_config_support_remote_wakeup(usb_host_config_h config, bool *remote_wakeup)
+{
+       if (!config || !remote_wakeup) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       *remote_wakeup = config->desc.bmAttributes & (1 << 5);
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_config_get_max_power(usb_host_config_h config, int *max_power)
+{
+       int speed;
+
+       if (!config || !max_power) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       speed = libusb_get_device_speed(config->dev->lusb_dev);
+
+       if (speed == LIBUSB_SPEED_SUPER)
+               *max_power = 8 * config->desc.MaxPower;
+       else
+               *max_power = 2 * config->desc.MaxPower;
+
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_device_get_config_str(usb_host_config_h config, int *length, unsigned char *data)
+{
+       if (!config || !data) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       return usb_host_device_get_string_descriptor_ascii(config->dev,
+                       config->desc.iConfiguration, length, data);
+}
+
+int usb_host_interface_get_number(usb_host_interface_h interface, int *number)
+{
+       if (!interface || !number) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       *number = interface->altsettings[interface->altsetting].desc.bInterfaceNumber;
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_interface_get_num_endpoints(usb_host_interface_h interface, int *num_endpoints)
+{
+       if (!interface || !num_endpoints) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       *num_endpoints = interface->altsettings[interface->altsetting].desc.bNumEndpoints;
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_interface_get_str(usb_host_interface_h interface, int *length,
+               unsigned char *data)
+{
+       if (!interface || !data) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       return usb_host_device_get_string_descriptor_ascii(interface->dev,
+                       interface->altsettings[interface->altsetting].desc.iInterface, length, data);
+}
+
+int usb_host_endpoint_get_number(usb_host_endpoint_h ep, int *number)
+{
+       if (!ep || !number) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+       *number = ep->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_endpoint_get_direction(usb_host_endpoint_h ep, int* direction)
+{
+       if (!ep || !direction) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       *direction = (ep->desc.bEndpointAddress & USB_ENDPOINT_DIR_MASK) ?
+               USB_HOST_DIRECTION_IN : USB_HOST_DIRECTION_OUT;
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_endpoint_get_transfer_type(usb_host_endpoint_h ep, int *transfer_type)
+{
+       if (!ep || !transfer_type) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       int type = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+
+       switch (type) {
+       case USB_ENDPOINT_XFER_CONTROL:
+               *transfer_type = USB_HOST_TRANSFER_TYPE_CONTROL;
+               break;
+       case USB_ENDPOINT_XFER_ISOC:
+               *transfer_type = USB_HOST_TRANSFER_TYPE_ISOCHRONOUS;
+               break;
+       case USB_ENDPOINT_XFER_BULK:
+               *transfer_type = USB_HOST_TRANSFER_TYPE_BULK;
+               break;
+       case USB_ENDPOINT_XFER_INT:
+               *transfer_type = USB_HOST_TRANSFER_TYPE_INTERRUPT;
+               break;
+       default:
+               return USB_HOST_ERROR_NOT_SUPPORTED;
+       }
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_endpoint_get_synch_type(usb_host_endpoint_h ep, int *synch_type)
+{
+       if (!ep || !synch_type) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       int type = ep->desc.bmAttributes & USB_ENDPOINT_SYNCTYPE;
+
+       switch (type) {
+       case USB_ENDPOINT_SYNC_NONE:
+               *synch_type = USB_HOST_ISO_SYNC_TYPE_NONE;
+               break;
+       case USB_ENDPOINT_SYNC_ASYNC:
+               *synch_type = USB_HOST_ISO_SYNC_TYPE_ASYNC;
+               break;
+       case USB_ENDPOINT_SYNC_ADAPTIVE:
+               *synch_type = USB_HOST_ISO_SYNC_TYPE_ADAPTIVE;
+               break;
+       case USB_ENDPOINT_SYNC_SYNC:
+               *synch_type = USB_HOST_ISO_SYNC_TYPE_SYNC;
+               break;
+       default:
+               return USB_HOST_ERROR_NOT_SUPPORTED;
+       }
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_endpoint_get_usage_type(usb_host_endpoint_h ep, int *usage_type)
+{
+       if (!ep || !usage_type) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+       int type = ep->desc.bmAttributes & USB_ENDPOINT_USAGE_MASK;
+
+       switch (type) {
+       case USB_ENDPOINT_USAGE_DATA:
+               *usage_type = USB_HOST_USAGE_TYPE_DATA;
+               break;
+       case USB_ENDPOINT_USAGE_FEEDBACK:
+               *usage_type = USB_HOST_USAGE_TYPE_FEEDBACK;
+               break;
+       case USB_ENDPOINT_USAGE_IMPLICIT_FB:
+               *usage_type = USB_HOST_USAGE_TYPE_IMPLICIT;
+               break;
+       default:
+               return USB_HOST_ERROR_NOT_SUPPORTED;
+       }
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_endpoint_get_max_packet_size(usb_host_endpoint_h ep, int *max_packet_size)
+{
+       if (!ep || !max_packet_size) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       *max_packet_size = ep->desc.wMaxPacketSize;
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_endpoint_get_interval(usb_host_endpoint_h ep, int *interval)
+{
+       if (!ep || !interval) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       *interval = ep->desc.bInterval;
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_config_destroy(usb_host_config_h config)
+{
+       int i;
+
+       if (!config) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       free((void *)config->extra);
+
+       for (i = 0; i < config->desc.bNumInterfaces; ++i)
+               free_interface(config->interfaces + i);
+       free(config->interfaces);
+
+       free(config);
+
+       return 0;
+}
+
+int usb_host_interface_get_endpoint(usb_host_interface_h interface, int ep_index,
+               usb_host_endpoint_h *ep)
+{
+
+       if (!interface || !ep || ep_index >= interface->altsettings[interface->altsetting].num_endpoints) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       *ep = &interface->altsettings[interface->altsetting].endpoints[ep_index];
+       return 0;
+}
+
+int usb_host_interface_set_altsetting(usb_host_interface_h interface, int altsetting)
+{
+       if (!interface || altsetting < 0 || altsetting >= interface->num_altsettings) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+       interface->altsetting = altsetting;
+       return 0;
+}
+
+int usb_host_config_get_interface(usb_host_config_h config, int interface_index, usb_host_interface_h *interface)
+{
+       if (!interface || !config || interface_index < 0 || interface_index >= config->num_interfaces) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       *interface = &config->interfaces[interface_index];
+       return 0;
+}
+
+int usb_host_device_get_config(usb_host_device_h dev, int config_index, usb_host_config_h *config)
+{
+       if (!dev || !config) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       int ret;
+       struct libusb_config_descriptor *lcfg_desc;
+       struct usb_host_config_s *cfg;
+
+       ret = libusb_get_config_descriptor(dev->lusb_dev,
+                                          config_index, &lcfg_desc);
+       if (ret < 0) {
+               ret = translate_error(ret);
+               _E("Failed to get configuration descriptor (%d)", ret);
+               goto out;
+       }
+
+       cfg = malloc(sizeof(*cfg));
+       if (!cfg) {
+               _E("malloc() failed");
+               ret = USB_HOST_ERROR_OUT_OF_MEMORY;
+               goto free_lcfg_desc;
+       }
+
+       ret = dump_config_desc(cfg, lcfg_desc, dev);
+       if (ret != 0) {
+               _E("dump_config_desc() failed");
+               free(cfg);
+       }
+
+       *config = cfg;
+
+free_lcfg_desc:
+       libusb_free_config_descriptor(lcfg_desc);
+out:
+       return ret;
+}
+
+int usb_host_device_get_string_descriptor_ascii(usb_host_device_h dev,
+       int desc_index, int *length, unsigned char *data)
+{
+       int ret;
+
+       if (!dev || !data || !length) {
+               _E("Invalid parameter was passed");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       if (dev->lusb_dev_handle == NULL) {
+               _E("Device is not opened");
+               return USB_HOST_ERROR_DEVICE_NOT_OPENED;
+       }
+
+       ret = libusb_get_string_descriptor_ascii(dev->lusb_dev_handle, desc_index, data, *length);
+       if (ret < 0) {
+               ret = translate_error(ret);
+               _E("Failed to get descriptor(%d)", ret);
+               return ret;
+       }
+
+       *length = ret;
+       return USB_HOST_ERROR_NONE;
+}
+
+int usb_host_control_transfer(usb_host_device_h dev, uint8_t bmRequestType,
+                            uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
+                            unsigned char *data, uint16_t wLength, unsigned int timeout, int *transfered)
+{
+       int ret;
+
+       if (!dev || !data || !transfered) {
+               _E("Invalid parameter");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       if (!dev->lusb_dev_handle) {
+               _E("Device is not opened");
+               return USB_HOST_ERROR_DEVICE_NOT_OPENED;
+       }
+
+       ret = libusb_control_transfer(dev->lusb_dev_handle, bmRequestType, bRequest,
+                                      wValue, wIndex, data, wLength, timeout);
+       if (ret < 0) {
+               ret = translate_error(ret);
+               _E("Control transfer failed(%d)", ret);
+               return ret;
+       }
+
+       *transfered = ret;
+
+       return USB_HOST_ERROR_NONE;
+}
+
+static int usb_host_bulk_transfer(usb_host_device_h dev, uint8_t endpoint,
+                         unsigned char *data, int length, int *transferred,
+                         unsigned int timeout)
+{
+       int ret;
+
+       if (!dev || !data || !transferred) {
+               _E("Invalid parameter");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       if (!dev->lusb_dev_handle) {
+               _E("Device not opened");
+               return USB_HOST_ERROR_DEVICE_NOT_OPENED;
+       }
+
+       ret = libusb_bulk_transfer(dev->lusb_dev_handle, endpoint, data, length,
+                                  transferred, timeout);
+       if (ret < 0) {
+               ret = translate_error(ret);
+               _E("Bulk transfer failed (%d)", ret);
+               return ret;
+       }
+
+       return USB_HOST_ERROR_NONE;
+}
+
+static int usb_host_interrupt_transfer(usb_host_device_h dev,
+       uint8_t endpoint, unsigned char *data, int length,
+       int *transferred, unsigned int timeout)
+{
+       int ret;
+
+       if (!dev || !data || !transferred) {
+               _E("Invalid parameter");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       if (!dev->lusb_dev_handle) {
+               _E("Device not opened");
+               return USB_HOST_ERROR_DEVICE_NOT_OPENED;
+       }
+
+       ret = libusb_interrupt_transfer(dev->lusb_dev_handle, endpoint, data, length,
+                                       transferred, timeout);
+       if (ret < 0) {
+               ret = translate_error(ret);
+               _E("Interrupt transfer failed (%d)", ret);
+               return ret;
+       }
+
+       return USB_HOST_ERROR_NONE;
+}
+
+static int usb_host_get_ep_type(usb_host_endpoint_h ep)
+{
+       return ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+}
+
+int usb_host_transfer(usb_host_endpoint_h ep, unsigned char *data, int length,
+               int *transferred, unsigned int timeout)
+{
+       int type;
+
+       if (!ep) {
+               _E("Inavlid parameter");
+               return USB_HOST_ERROR_INVALID_PARAMETER;
+       }
+
+       type = usb_host_get_ep_type(ep);
+
+       switch (type) {
+       case USB_ENDPOINT_XFER_BULK:
+               return usb_host_bulk_transfer(ep->dev, ep->desc.bEndpointAddress, data,
+                               length, transferred, timeout);
+       case USB_ENDPOINT_XFER_INT:
+               return usb_host_interrupt_transfer(ep->dev, ep->desc.bEndpointAddress, data,
+                               length, transferred, timeout);
+       default:
+               return USB_HOST_ERROR_NOT_SUPPORTED;
+       }
+}
diff --git a/tests/libhusb-test.c b/tests/libhusb-test.c
deleted file mode 100644 (file)
index 19a1ed1..0000000
+++ /dev/null
@@ -1,992 +0,0 @@
-/*
- * libhusb-test.c
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <errno.h>
-#include <setjmp.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <cmocka.h>
-#include <time.h>
-
-#include "libhusb.h"
-#include "libhusb_internal.h"
-#include <libusb-1.0/libusb.h>
-#include "uref.h"
-
-/* assertions and checks */
-
-/**
- * @brief Initialize library context and check results
- */
-static int setup_libhusb_context(void **state)
-{
-       int ret;
-       libhusb_context *ctx;
-       libusb_context *lusb_ctx;
-
-       expect_any(libusb_init, ctx);
-       will_return(libusb_init, lusb_ctx);
-       will_return(libusb_init, LIBUSB_SUCCESS);
-
-       ret = libhusb_init(&ctx);
-
-       assert_return_code(ret, 0);
-       assert_ptr_equal(ctx->lusb_ctx, lusb_ctx);
-
-       *state = (void *)ctx;
-
-       return 0;
-}
-
-static int teardown_libhusb_context(void **state)
-{
-       libhusb_context *ctx;
-
-       ctx = (libhusb_context *)(*state);
-       expect_any(libusb_exit, ctx);
-       libhusb_exit(ctx);
-
-       return 0;
-}
-
-static int setup_libhusb_device(void **state)
-{
-       libhusb_device *dev;
-
-       dev = malloc(sizeof(libhusb_device));
-       /* TODO fill this with something? */
-
-       *state = dev;
-
-       return 0;
-}
-
-static int setup_libhusb_dev_handle(void **state)
-{
-       libhusb_device_handle *dev;
-
-       dev = malloc(sizeof(libhusb_device_handle));
-       /* TODO fill this with something? */
-
-       *state = dev;
-
-       return 0;
-}
-
-/**
- * @brief Just free the memory
- */
-static int teardown_free(void **state)
-{
-       free(*state);
-
-       return 0;
-}
-
-/**
- * @brief Test if initialization works fine
- */
-static void test_init(void **state)
-{
-       libhusb_context *ctx;
-
-       ctx = (libhusb_context *)(*state);
-       assert_non_null(ctx);
-}
-
-static void test_open(void **state)
-{
-       libhusb_context *ctx;
-       libusb_device_handle *lusb_handle;
-       libhusb_device_handle *handle;
-       libhusb_device device;
-
-       ctx = (libhusb_context *)(*state);
-       assert_non_null(ctx);
-
-       expect_value(libusb_open, dev, device.lusb_dev);
-       expect_any(libusb_open, handle);
-       will_return(libusb_open, lusb_handle);
-       will_return(libusb_open, 0);
-
-       handle = libhusb_open(&device);
-
-       assert_non_null(handle);
-       assert_ptr_equal(handle->device, &device);
-       assert_ptr_equal(handle->lusb_dev_handle, lusb_handle);
-}
-
-/*
- * A pair of functions required for uref,
- * to which libhusb_close relegates some work
- * and expects to find inside a libhusb_device,
- * so we cannot use a mock instance.
- *
- * No libhusb function returns a libhusb_device,
- * so we need to manually instantiate one.
- */
-static inline struct libhusb_device *to_libhusb_device(struct uref *_uref)
-{
-       return container_of(_uref, struct libhusb_device, ref);
-}
-
-static void free_device(struct uref *uref)
-{
-       struct libhusb_device *dev = to_libhusb_device(uref);
-
-       libusb_unref_device(dev->lusb_dev);
-       free(dev);
-}
-
-static void test_close(void **state)
-{
-       libhusb_device_handle *handle;
-
-       handle = (libhusb_device_handle *) (*state);
-       assert_non_null(handle);
-
-       handle->device = malloc (sizeof (libhusb_device));
-       uref_init(&handle->device->ref, free_device);
-
-       expect_value (libusb_close, dev_handle, handle->lusb_dev_handle);
-
-       libhusb_close (handle);
-}
-
-static void test_get_device(void **state)
-{
-       libhusb_device_handle handle;
-       libhusb_device *device;
-
-       device = libhusb_get_device(&handle);
-       assert_ptr_equal(handle.device, device);
-}
-
-static void test_get_devices(void **state)
-{
-       int n = 7, i, ret;
-       libhusb_context *ctx;
-       libhusb_device **devs;
-
-       libusb_device *lusb_devs[n];
-       for (i = 0; i < n; ++i)
-               lusb_devs[i] = (libusb_device *) rand();
-
-       ctx = (libhusb_context *)(*state);
-       assert_non_null(ctx);
-
-       will_return(libusb_get_device_list, n);
-       for (i = 0; i < n; ++i) {
-               expect_any(libusb_ref_device, dev);
-               will_return(libusb_get_device_list, lusb_devs[i]);
-       }
-
-       ret = libhusb_get_devices(ctx, &devs);
-
-       assert_int_equal(ret, n);
-       for (i = 0; i < n; ++i)
-               assert_ptr_equal(devs[i]->lusb_dev, lusb_devs[i]);
-
-       libhusb_free_devices(devs, 0);
-}
-
-static void test_get_max_packet_size(void **state)
-{
-       libhusb_device *device;
-       int ep = 7, ret, expected;
-
-       device = (libhusb_device *)(*state);
-       assert_non_null(device);
-       expected = rand();
-
-       expect_value(libusb_get_max_iso_packet_size, dev, device->lusb_dev);
-       expect_value(libusb_get_max_iso_packet_size, endpoint, ep);
-       will_return(libusb_get_max_iso_packet_size, expected);
-
-       ret = libhusb_get_max_packet_size(device, ep);
-
-       assert_int_equal(ret, expected);
-}
-
-static void test_get_bus_number(void **state)
-{
-       libhusb_device *device;
-       uint8_t expected, ret;
-
-       expected = rand();
-       device = (libhusb_device *)(*state);
-       assert_non_null(device);
-
-       expect_value(libusb_get_bus_number, dev, device->lusb_dev);
-       will_return(libusb_get_bus_number, expected);
-
-       ret = libhusb_get_bus_number(device);
-
-       assert_int_equal(ret, expected);
-}
-
-static void test_get_address(void **state)
-{
-       libhusb_device *device;
-       uint8_t expected, ret;
-
-       expected = rand();
-       device = (libhusb_device *)(*state);
-       assert_non_null(device);
-
-       expect_value(libusb_get_device_address, dev, device->lusb_dev);
-       will_return(libusb_get_device_address, expected);
-
-       ret = libhusb_get_address(device);
-
-       assert_int_equal(ret, expected);
-}
-
-static void test_get_port_numbers(void **state)
-{
-       libhusb_device *device;
-       uint8_t p_numbers[8];
-       int ret, p_num_len;
-
-       /* As per the USB 3.0 specs, the current maximum limit for the depth is 7 */
-       p_num_len = 8;
-       device = (libhusb_device *)(*state);
-       assert_non_null(device);
-
-       expect_value(libusb_get_port_numbers, dev, device->lusb_dev);
-       expect_value(libusb_get_port_numbers, port_numbers_len, p_num_len);
-       will_return(libusb_get_port_numbers, p_num_len -1);
-       will_return(libusb_get_port_numbers, 0);
-
-       ret = libhusb_get_port_numbers(device, p_numbers, p_num_len);
-
-       assert_return_code(ret, 0);
-}
-
-static void test_get_device_descriptor(void **state)
-{
-       libhusb_device *device;
-       struct libhusb_device_descriptor descriptor;
-       int ret;
-
-       device = (libhusb_device *)(*state);
-
-       expect_value(libusb_get_device_descriptor, dev, device->lusb_dev);
-       expect_value(libusb_get_device_descriptor, desc, &descriptor);
-       will_return(libusb_get_device_descriptor, 0);
-
-       ret = libhusb_get_device_descriptor(device, &descriptor);
-
-       assert_return_code(ret, 0);
-}
-
-static void test_get_active_config(void **state)
-{
-       libhusb_device_handle *handle;
-       int conf, expected, ret;
-
-       handle = (libhusb_device_handle *)(*state);
-       expected = rand();
-
-       expect_value(libusb_get_configuration, dev, handle->lusb_dev_handle);
-       will_return(libusb_get_configuration, expected);
-       will_return(libusb_get_configuration, 0);
-
-       ret = libhusb_get_active_config(handle, &conf);
-
-       assert_return_code(ret, 0);
-       assert_int_equal(conf, expected);
-}
-
-static void test_open_device_vid_pid(void **state)
-{
-       libhusb_device_handle *handle;
-       libhusb_context *ctx;
-       libusb_device_handle *lusb_dev_handle;
-       libusb_device *lusb_device;
-       uint16_t vid, pid;
-
-       vid = (uint16_t)rand();
-       pid = (uint16_t)rand();
-       lusb_dev_handle = (libusb_device_handle *)rand();
-       lusb_device = (libusb_device *)rand();
-
-       ctx = (libhusb_context *)(*state);
-       assert_non_null(ctx);
-
-       expect_value(libusb_open_device_with_vid_pid, ctx, ctx->lusb_ctx);
-       expect_value(libusb_open_device_with_vid_pid, vendor_id, vid);
-       expect_value(libusb_open_device_with_vid_pid, product_id, pid);
-       will_return(libusb_open_device_with_vid_pid, lusb_dev_handle);
-       will_return(libusb_get_device, lusb_device);
-       expect_any(libusb_ref_device, dev);
-
-       handle = libhusb_device_open_with_vid_pid(ctx, vid, pid);
-
-       assert_non_null(handle);
-       assert_ptr_equal(handle->lusb_dev_handle, lusb_dev_handle);
-       assert_non_null(handle->device);
-       assert_ptr_equal(handle->device->lusb_dev, lusb_device);
-
-       expect_value (libusb_close, dev_handle, handle->lusb_dev_handle);
-       libhusb_close(handle);
-}
-
-static void test_set_config(void **state)
-{
-       libhusb_device_handle *handle;
-       int config, ret;
-
-       config = rand();
-       handle = (libhusb_device_handle *)(*state);
-       assert_non_null(handle);
-
-       expect_value(libusb_set_configuration, dev, handle->lusb_dev_handle);
-       expect_value(libusb_set_configuration, configuration, config);
-       will_return(libusb_set_configuration, 0);
-
-       ret = libhusb_set_config(handle, config);
-
-       assert_return_code(ret, 0);
-}
-
-static void test_claim_interface_simple(void **state)
-{
-       libhusb_device_handle *handle;
-       int interface_nmb, ret;
-
-       interface_nmb = 0;
-       handle = (libhusb_device_handle *)(*state);
-       assert_non_null(handle);
-
-       expect_value(libusb_claim_interface, dev, handle->lusb_dev_handle);
-       expect_value(libusb_claim_interface, interface_number, interface_nmb);
-       will_return(libusb_claim_interface, 0);
-
-       ret = libhusb_claim_interface(handle, interface_nmb, 0);
-
-       assert_return_code(ret, 0);
-       assert_int_equal(handle->driver_detached[interface_nmb], 1);
-}
-
-static void test_claim_interface_invalid(void **state)
-{
-       libhusb_device_handle *handle;
-       int interface_nmb, ret;
-
-       handle = (libhusb_device_handle *)(*state);
-       assert_non_null(handle);
-
-       interface_nmb = MAX_NMB_OF_CONFIGS + 1;
-
-       ret = libhusb_claim_interface(handle, interface_nmb, 0);
-       assert_int_equal(ret, LIBHUSB_ERROR_INVALID_PARAM);
-
-       interface_nmb = -1;
-
-       ret = libhusb_claim_interface(handle, interface_nmb, 0);
-       assert_int_equal(ret, LIBHUSB_ERROR_INVALID_PARAM);
-}
-
-static void test_release_interface_simple(void **state)
-{
-       libhusb_device_handle *handle;
-       int interface_nmb, ret;
-
-       interface_nmb = rand() % MAX_NMB_OF_CONFIGS;
-       handle = (libhusb_device_handle *)(*state);
-       assert_non_null(handle);
-       handle->driver_detached[interface_nmb] = 0;
-
-       expect_value(libusb_release_interface, dev, handle->lusb_dev_handle);
-       expect_value(libusb_release_interface, interface_number, interface_nmb);
-       will_return(libusb_release_interface, 0);
-
-       ret = libhusb_release_interface(handle, interface_nmb);
-
-       assert_return_code(ret, 0);
-}
-
-static void test_release_interface_attachment(void **state)
-{
-       libhusb_device_handle *handle;
-       int interface_nmb, ret;
-
-       interface_nmb = rand() % MAX_NMB_OF_CONFIGS;
-       handle = (libhusb_device_handle *)(*state);
-       assert_non_null(handle);
-       handle->driver_detached[interface_nmb] = 1;
-
-       expect_value(libusb_release_interface, dev, handle->lusb_dev_handle);
-       expect_value(libusb_release_interface, interface_number, interface_nmb);
-       will_return(libusb_release_interface, 0);
-
-       expect_value(libusb_attach_kernel_driver, dev, handle->lusb_dev_handle);
-       expect_value(libusb_attach_kernel_driver, interface_number, interface_nmb);
-       will_return(libusb_attach_kernel_driver, 0);
-
-       ret = libhusb_release_interface(handle, interface_nmb);
-
-       assert_return_code(ret, 0);
-       assert_int_equal(0, handle->driver_detached[interface_nmb]);
-}
-
-static void test_release_interface_invalid(void **state)
-{
-       libhusb_device_handle *handle;
-       int interface_nmb, ret;
-
-       handle = (libhusb_device_handle *)(*state);
-       assert_non_null(handle);
-
-       interface_nmb = MAX_NMB_OF_CONFIGS + 1;
-
-       ret = libhusb_release_interface(handle, interface_nmb);
-       assert_int_equal(ret, LIBHUSB_ERROR_INVALID_PARAM);
-
-       interface_nmb = -1;
-
-       ret = libhusb_release_interface(handle, interface_nmb);
-       assert_int_equal(ret, LIBHUSB_ERROR_INVALID_PARAM);
-}
-
-static void test_clear_halt(void **state)
-{
-       libhusb_device_handle *handle;
-       uint8_t ep, ret;
-
-       ep = rand();
-       handle = (libhusb_device_handle *)(*state);
-       assert_non_null(handle);
-
-       expect_value(libusb_clear_halt, dev, handle->lusb_dev_handle);
-       expect_value(libusb_clear_halt, endpoint, ep);
-       will_return(libusb_clear_halt, 0);
-
-       ret = libhusb_clear_halt(handle, ep);
-
-       assert_return_code(ret, 0);
-}
-
-static void test_reset_device(void **state)
-{
-       libhusb_device_handle *handle;
-       int ret;
-
-       handle = (libhusb_device_handle *)(*state);
-       assert_non_null(handle);
-
-       expect_value(libusb_reset_device, dev, handle->lusb_dev_handle);
-       will_return(libusb_reset_device, 0);
-
-       ret = libhusb_reset_device(handle);
-
-       assert_return_code(ret, 0);
-}
-
-static void test_kernel_driver_active(void **state)
-{
-       libhusb_device_handle *handle;
-       int ret,iface;
-
-       iface = rand();
-       handle = (libhusb_device_handle *)(*state);
-       assert_non_null(handle);
-
-       expect_value(libusb_kernel_driver_active, dev, handle->lusb_dev_handle);
-       expect_value(libusb_kernel_driver_active, interface_number, iface);
-       will_return(libusb_kernel_driver_active, 0);
-
-       ret = libhusb_kernel_driver_active(handle, iface);
-
-       assert_return_code(ret, 0);
-}
-
-static void test_detach_kernel_driver(void **state)
-{
-       libhusb_device_handle *handle;
-       int ret,iface;
-
-       iface = rand();
-       handle = (libhusb_device_handle *)(*state);
-       assert_non_null(handle);
-
-       expect_value(libusb_detach_kernel_driver, dev, handle->lusb_dev_handle);
-       expect_value(libusb_detach_kernel_driver, interface_number, iface);
-       will_return(libusb_detach_kernel_driver, 0);
-
-       ret = libhusb_detach_kernel_driver(handle, iface);
-
-       assert_return_code(ret, 0);
-}
-
-static void test_attach_kernel_driver(void **state)
-{
-       libhusb_device_handle *handle;
-       int ret,iface;
-
-       iface = rand();
-       handle = (libhusb_device_handle *)(*state);
-       assert_non_null(handle);
-
-       expect_value(libusb_attach_kernel_driver, dev, handle->lusb_dev_handle);
-       expect_value(libusb_attach_kernel_driver, interface_number, iface);
-       will_return(libusb_attach_kernel_driver, 0);
-
-       ret = libhusb_attach_kernel_driver(handle, iface);
-
-       assert_return_code(ret, 0);
-}
-
-static void test_control_transfer(void **state)
-{
-       uint8_t request_type, bRequest;
-       uint16_t wValue, wIndex, wLength;
-       unsigned char *data;
-       unsigned int timeout;
-       int ret;
-       libhusb_device_handle *handle;
-
-       handle = (libhusb_device_handle *)(*state);
-       assert_non_null(handle);
-
-#define EXPECT_VAL(val) expect_value(libusb_control_transfer, val, val);
-       EXPECT_VAL(request_type);
-       EXPECT_VAL(bRequest);
-       EXPECT_VAL(wValue);
-       EXPECT_VAL(wIndex);
-       EXPECT_VAL(data);
-       EXPECT_VAL(wLength);
-       EXPECT_VAL(timeout);
-#undef EXPECT_VAL
-       expect_value(libusb_control_transfer, dev_handle, handle->lusb_dev_handle);
-       will_return(libusb_control_transfer, 0);
-
-       ret =  libhusb_control_transfer(handle, request_type, bRequest, wValue,
-                       wIndex, data, wLength, timeout);
-
-       assert_return_code(ret, 0);
-}
-
-static void test_bulk_transfer_length_check(void **state)
-{
-       uint8_t endpoint;
-       unsigned char *data;
-       int length;
-       int transferred;
-       unsigned int timeout;
-       int ret;
-       libhusb_device_handle *handle;
-
-       length = rand();
-       handle = (libhusb_device_handle *)(*state);
-       assert_non_null(handle);
-
-#define EXPECT_VAL(val) expect_value(libusb_bulk_transfer, val, val);
-       EXPECT_VAL(endpoint);
-       EXPECT_VAL(data);
-       EXPECT_VAL(length);
-       EXPECT_VAL(timeout);
-#undef EXPECT_VAL
-       expect_value(libusb_bulk_transfer, dev_handle, handle->lusb_dev_handle);
-       will_return(libusb_bulk_transfer, length);
-       will_return(libusb_bulk_transfer, 0);
-
-       ret = libhusb_bulk_transfer(handle, endpoint, data, length, &transferred, timeout);
-
-       assert_int_equal(transferred, length);
-       assert_return_code(ret, 0);
-}
-
-static void test_bulk_transfer_simple(void **state)
-{
-       uint8_t endpoint;
-       unsigned char *data;
-       int length;
-       int transferred;
-       unsigned int timeout;
-       int ret;
-       libhusb_device_handle *handle;
-
-       handle = (libhusb_device_handle *)(*state);
-       assert_non_null(handle);
-
-#define EXPECT_VAL(val) expect_value(libusb_bulk_transfer, val, val);
-       EXPECT_VAL(endpoint);
-       EXPECT_VAL(data);
-       EXPECT_VAL(length);
-       EXPECT_VAL(timeout);
-#undef EXPECT_VAL
-       expect_value(libusb_bulk_transfer, dev_handle, handle->lusb_dev_handle);
-       will_return(libusb_bulk_transfer, rand());
-       will_return(libusb_bulk_transfer, 0);
-
-       ret = libhusb_bulk_transfer(handle, endpoint, data, length, &transferred, timeout);
-
-       assert_return_code(ret, 0);
-}
-
-static void test_interrupt_transfer_length_check(void **state)
-{
-       uint8_t endpoint;
-       unsigned char *data;
-       int length;
-       int transferred;
-       unsigned int timeout;
-       int ret;
-       libhusb_device_handle *handle;
-
-       length = rand();
-       handle = (libhusb_device_handle *)(*state);
-       assert_non_null(handle);
-
-#define EXPECT_VAL(val) expect_value(libusb_interrupt_transfer, val, val);
-       EXPECT_VAL(endpoint);
-       EXPECT_VAL(data);
-       EXPECT_VAL(length);
-       EXPECT_VAL(timeout);
-#undef EXPECT_VAL
-       expect_value(libusb_interrupt_transfer, dev_handle, handle->lusb_dev_handle);
-       will_return(libusb_interrupt_transfer, length);
-       will_return(libusb_interrupt_transfer, 0);
-
-       ret = libhusb_interrupt_transfer(handle, endpoint, data, length, &transferred, timeout);
-
-       assert_int_equal(transferred, length);
-       assert_return_code(ret, 0);
-}
-
-static void test_interrupt_transfer_simple(void **state)
-{
-       uint8_t endpoint;
-       unsigned char *data;
-       int length;
-       int transferred;
-       unsigned int timeout;
-       int ret;
-       libhusb_device_handle *handle;
-
-       handle = (libhusb_device_handle *)(*state);
-       assert_non_null(handle);
-
-#define EXPECT_VAL(val) expect_value(libusb_interrupt_transfer, val, val);
-       EXPECT_VAL(endpoint);
-       EXPECT_VAL(data);
-       EXPECT_VAL(length);
-       EXPECT_VAL(timeout);
-#undef EXPECT_VAL
-       expect_value(libusb_interrupt_transfer, dev_handle, handle->lusb_dev_handle);
-       will_return(libusb_interrupt_transfer, rand());
-       will_return(libusb_interrupt_transfer, 0);
-
-       ret = libhusb_interrupt_transfer(handle, endpoint, data, length, &transferred, timeout);
-
-       assert_return_code(ret, 0);
-}
-
-static void test_get_string_descriptor_ascii(void **state)
-{
-       libhusb_device_handle *handle;
-       uint8_t desc_index;
-       unsigned char data [16];
-       int length, ret;
-       const char * testString = "TestString";
-
-       handle = (libhusb_device_handle *)(*state);
-       assert_non_null(handle);
-
-       expect_value(libusb_get_string_descriptor_ascii, dev, handle->lusb_dev_handle);
-       expect_value(libusb_get_string_descriptor_ascii, desc_index, desc_index);
-       expect_value(libusb_get_string_descriptor_ascii, length, length);
-       will_return(libusb_get_string_descriptor_ascii, cast_ptr_to_largest_integral_type(testString));
-       will_return(libusb_get_string_descriptor_ascii, 0);
-
-       ret = libhusb_get_string_descriptor_ascii(handle, desc_index, data, length);
-
-       assert_return_code(ret, 0);
-       assert_string_equal(data, testString);
-}
-
-static void test_config_descriptor(void **state)
-{
-       libhusb_cfg_descriptor *config;
-       libhusb_device *dev;
-       uint8_t config_index;
-       int ret, interfaces;
-
-       config_index = rand();
-       interfaces = rand() % 6 + 1; // not too large, n^4 objects are created
-       dev = (libhusb_device *)(*state);
-       assert_non_null(dev);
-
-       will_return(libusb_get_config_descriptor, interfaces);
-
-       ret = libhusb_get_config_descriptor(dev, config_index, &config);
-
-       assert_return_code(ret, 0);
-
-       libhusb_free_config_descriptor(config);
-}
-
-static void transfer_cb(int status, unsigned char *buffer, int len, void *user_data)
-{
-       fail_msg("This function should never be called directly, libusb does it for us");
-}
-
-static void init_transfer(struct libusb_transfer *lusb_transfer,
-               struct libhusb_transfer **transfer, libusb_device_handle *handle)
-{
-       int ret;
-       struct libusb_transfer *ret_transfer;
-
-       ret_transfer = malloc(sizeof(struct libusb_transfer));
-
-       expect_value(libusb_alloc_transfer, iso_packets, 0);
-       will_return(libusb_alloc_transfer, ret_transfer);
-       ret = libhusb_create_transfer(transfer, 0);
-       assert_return_code(ret, 0);
-
-       lusb_transfer->endpoint = rand();
-       lusb_transfer->length = rand();
-       lusb_transfer->timeout = rand();
-       lusb_transfer->dev_handle = handle;
-       lusb_transfer->status = 0;
-       lusb_transfer->actual_length = rand();
-       lusb_transfer->num_iso_packets = 0;
-}
-
-static void test_fill_interrupt_transfer(void **state)
-{
-       struct libusb_transfer lusb_transfer;
-       libhusb_transfer *transfer;
-       libhusb_device_handle *dev_handle;
-
-       dev_handle = (libhusb_device_handle *)(*state);
-
-       init_transfer(&lusb_transfer, &transfer, dev_handle->lusb_dev_handle);
-
-       /* libusb fill functions are inline, we don't mock them, just check the result */
-       libhusb_fill_interrupt_transfer(transfer, dev_handle, transfer_cb, lusb_transfer.endpoint,
-               lusb_transfer.buffer, lusb_transfer.length, NULL, lusb_transfer.timeout);
-       assert_ptr_equal(transfer->lusb_transfer->dev_handle, dev_handle->lusb_dev_handle);
-       assert_int_equal(transfer->lusb_transfer->endpoint, lusb_transfer.endpoint);
-       assert_int_equal(transfer->lusb_transfer->length, lusb_transfer.length);
-       assert_int_equal(transfer->lusb_transfer->timeout, lusb_transfer.timeout);
-       assert_int_equal(transfer->lusb_transfer->type, LIBUSB_TRANSFER_TYPE_INTERRUPT);
-}
-
-static void test_fill_bulk_transfer(void **state)
-{
-       struct libusb_transfer lusb_transfer;
-       libhusb_transfer *transfer;
-       libhusb_device_handle *dev_handle;
-
-       dev_handle = (libhusb_device_handle *)(*state);
-
-       init_transfer(&lusb_transfer, &transfer, dev_handle->lusb_dev_handle);
-
-       /* libusb fill functions are inline, we don't mock them, just check the result */
-       libhusb_fill_bulk_transfer(transfer, dev_handle, transfer_cb, lusb_transfer.endpoint,
-                       lusb_transfer.buffer, lusb_transfer.length, NULL, lusb_transfer.timeout);
-       assert_ptr_equal(transfer->lusb_transfer->dev_handle, dev_handle->lusb_dev_handle);
-       assert_int_equal(transfer->lusb_transfer->endpoint, lusb_transfer.endpoint);
-       assert_int_equal(transfer->lusb_transfer->length, lusb_transfer.length);
-       assert_int_equal(transfer->lusb_transfer->timeout, lusb_transfer.timeout);
-       assert_int_equal(transfer->lusb_transfer->type, LIBUSB_TRANSFER_TYPE_BULK);
-}
-
-static void test_fill_control_transfer(void **state)
-{
-       libhusb_transfer *transfer;
-       libhusb_device_handle *dev_handle;
-       struct libusb_transfer lusb_transfer;
-       int timeout;
-       uint8_t bmRequestType, bRequest;
-       uint16_t wValue, wIndex, wLength;
-       char buffer[16];
-       int ret;
-
-       dev_handle = (libhusb_device_handle *)(*state);
-
-       expect_value(libusb_alloc_transfer, iso_packets, 0);
-       will_return(libusb_alloc_transfer, &lusb_transfer);
-       ret = libhusb_create_transfer(&transfer, 0);
-       assert_return_code(ret, 0);
-
-       timeout = rand();
-       bmRequestType = rand();
-       bRequest = rand();
-       wValue = rand();
-       wIndex = rand();
-       wLength = rand();
-
-       libhusb_fill_control_setup(buffer, bmRequestType, bRequest, wValue, wIndex, wLength);
-       libhusb_fill_control_transfer(transfer, dev_handle, transfer_cb, buffer, NULL, timeout);
-
-       assert_ptr_equal(transfer->lusb_transfer->dev_handle, dev_handle->lusb_dev_handle);
-       assert_ptr_equal(transfer->lusb_transfer->buffer, buffer);
-       assert_int_equal(transfer->lusb_transfer->length, wLength + 8);
-       assert_int_equal(transfer->lusb_transfer->timeout, timeout);
-       assert_int_equal(transfer->lusb_transfer->type, LIBUSB_TRANSFER_TYPE_CONTROL);
-}
-
-static void test_destroy_transfer(void **state)
-{
-       libhusb_device_handle *dev_handle;
-       libhusb_transfer *transfer = NULL;
-       struct libusb_transfer lusb_transfer;
-       int ret;
-
-       dev_handle = (libhusb_device_handle *)(*state);
-
-       expect_value(libusb_alloc_transfer, iso_packets, 0);
-       will_return(libusb_alloc_transfer, &lusb_transfer);
-       ret = libhusb_create_transfer(&transfer, 0);
-
-       expect_value(libusb_free_transfer, transfer, &lusb_transfer);
-       libhusb_destroy_transfer(transfer);
-}
-
-static void test_submit_transfer(void **state)
-{
-       libhusb_device_handle *dev_handle = NULL;
-       libhusb_transfer *transfer= NULL;
-       struct libusb_transfer lusb_transfer;
-       int ret;
-
-       dev_handle = (libhusb_device_handle *)(*state);
-
-       expect_any(libusb_alloc_transfer, iso_packets);
-       will_return(libusb_alloc_transfer, &lusb_transfer);
-       ret = libhusb_create_transfer(&transfer, 0);
-
-       expect_value(libusb_submit_transfer, transfer, &lusb_transfer);
-       will_return(libusb_submit_transfer, 0);
-       ret = libhusb_submit_transfer(transfer);
-       assert_return_code(ret, 0);
-
-       expect_any(libusb_free_transfer, transfer);
-       libhusb_destroy_transfer(transfer);
-}
-
-static void test_cancel_transfer(void **state)
-{
-       libhusb_device_handle *dev_handle = NULL;
-       libhusb_transfer *transfer= NULL;
-       struct libusb_transfer lusb_transfer;
-       int ret;
-
-       dev_handle = (libhusb_device_handle *)(*state);
-
-       expect_any(libusb_alloc_transfer, iso_packets);
-       will_return(libusb_alloc_transfer, &lusb_transfer);
-       ret = libhusb_create_transfer(&transfer, 0);
-
-       expect_any(libusb_submit_transfer, transfer);
-       will_return(libusb_submit_transfer, 0);
-       ret = libhusb_submit_transfer(transfer);
-
-       expect_value(libusb_cancel_transfer, transfer, &lusb_transfer);
-       will_return(libusb_cancel_transfer, 0);
-       ret = libhusb_cancel_transfer(transfer);
-       assert_return_code(ret, 0);
-
-       expect_any(libusb_free_transfer, transfer);
-       libhusb_destroy_transfer(transfer);
-}
-
-static void test_handle_events(void **state)
-{
-       libhusb_context *ctx;
-       int completed;
-       int ret;
-
-       ctx = (libhusb_device_handle *)(*state);
-
-       expect_value(libusb_handle_events_completed, ctx, ctx->lusb_ctx);
-       expect_value(libusb_handle_events_completed, completed, &completed);
-       will_return(libusb_handle_events_completed, 0);
-       ret = libhusb_handle_events(ctx, &completed);
-       assert_return_code(ret, 0);
-}
-
-/* Custom macro for defining test with given name and fixed teardown function */
-#define HUSB_TEST(func, setup, teardown) \
-       cmocka_unit_test_setup_teardown(func, setup, teardown)
-#define HUSB_TEST_CTX(func) \
-       cmocka_unit_test_setup_teardown(func, setup_libhusb_context, teardown_libhusb_context)
-#define HUSB_TEST_DEVICE(func) \
-       cmocka_unit_test_setup_teardown(func, setup_libhusb_device, teardown_free)
-#define HUSB_TEST_DEV_HANDLE(func) \
-       cmocka_unit_test_setup_teardown(func, setup_libhusb_dev_handle, teardown_free)
-#define HUSB_TEST_NOSETUP(func) \
-       cmocka_unit_test(func)
-#define HUSB_TEST_NO_TEARDOWN(func, setup) \
-       cmocka_unit_test_setup (func, setup)
-
-static struct CMUnitTest tests[] = {
-
-               /**
-                * @some_test
-                * TODO: documentation
-                */
-               HUSB_TEST_CTX(test_init),
-               HUSB_TEST_CTX(test_open),
-               HUSB_TEST_NO_TEARDOWN(test_close, setup_libhusb_dev_handle), // the tested function does the teardown
-               HUSB_TEST_NOSETUP(test_get_device),
-               HUSB_TEST_CTX(test_get_devices),
-               HUSB_TEST_DEVICE(test_get_max_packet_size),
-               HUSB_TEST_DEVICE(test_get_bus_number),
-               HUSB_TEST_DEVICE(test_get_address),
-               HUSB_TEST_DEVICE(test_get_port_numbers),
-               HUSB_TEST_DEVICE(test_get_device_descriptor),
-               HUSB_TEST_DEV_HANDLE(test_get_active_config),
-               HUSB_TEST_CTX(test_open_device_vid_pid),
-               HUSB_TEST_DEV_HANDLE(test_set_config),
-               HUSB_TEST_DEV_HANDLE(test_claim_interface_simple),
-               HUSB_TEST_DEV_HANDLE(test_claim_interface_invalid),
-               HUSB_TEST_DEV_HANDLE(test_control_transfer),
-               HUSB_TEST_DEV_HANDLE(test_bulk_transfer_simple),
-               HUSB_TEST_DEV_HANDLE(test_bulk_transfer_length_check),
-               HUSB_TEST_DEV_HANDLE(test_release_interface_simple),
-               HUSB_TEST_DEV_HANDLE(test_release_interface_attachment),
-               HUSB_TEST_DEV_HANDLE(test_release_interface_invalid),
-               HUSB_TEST_DEV_HANDLE(test_interrupt_transfer_simple),
-               HUSB_TEST_DEV_HANDLE(test_interrupt_transfer_length_check),
-               HUSB_TEST_DEV_HANDLE(test_clear_halt),
-               HUSB_TEST_DEV_HANDLE(test_reset_device),
-               HUSB_TEST_DEV_HANDLE(test_kernel_driver_active),
-               HUSB_TEST_DEV_HANDLE(test_detach_kernel_driver),
-               HUSB_TEST_DEV_HANDLE(test_attach_kernel_driver),
-               HUSB_TEST_DEV_HANDLE(test_get_string_descriptor_ascii),
-               HUSB_TEST_DEVICE(test_config_descriptor),
-               HUSB_TEST_DEV_HANDLE(test_submit_transfer),
-               HUSB_TEST_DEV_HANDLE(test_destroy_transfer),
-               HUSB_TEST_DEV_HANDLE(test_cancel_transfer),
-               HUSB_TEST_DEV_HANDLE(test_fill_bulk_transfer),
-               HUSB_TEST_DEV_HANDLE(test_fill_interrupt_transfer),
-               HUSB_TEST_DEV_HANDLE(test_fill_control_transfer),
-               HUSB_TEST_CTX(test_handle_events),
-};
-
-
-int main(int argc, char **argv)
-{
-       srand(time(NULL));
-       return cmocka_run_group_tests(tests, NULL, NULL);
-}
diff --git a/tests/libusb-wrap.c b/tests/libusb-wrap.c
deleted file mode 100644 (file)
index 615a0e7..0000000
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * libhusb-test.c
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <libusb-1.0/libusb.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <setjmp.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <cmocka.h>
-#include <string.h>
-#include <stddef.h>
-#include <dlfcn.h>
-
-int libusb_init(libusb_context **ctx)
-{
-       check_expected(ctx);
-       *ctx = mock_ptr_type(libusb_context *);
-
-       return mock_type(int);
-}
-
-libusb_device_handle * libusb_open_device_with_vid_pid(libusb_context *ctx, uint16_t vendor_id, uint16_t product_id)
-{
-       libusb_device_handle *handle;
-
-       check_expected(ctx);
-       check_expected(vendor_id);
-       check_expected(product_id);
-
-       return mock_ptr_type(libusb_device_handle *);
-}
-
-void libusb_exit(libusb_context *ctx)
-{
-       check_expected(ctx);
-}
-
-void libusb_set_debug(libusb_context *ctx, int level)
-{
-}
-
-const struct libusb_version * libusb_get_version(void)
-{
-       return NULL;
-}
-
-int libusb_has_capability(uint32_t capability)
-{
-       return 0;
-}
-
-const char * libusb_error_name(int errcode)
-{
-       return NULL;
-}
-
-ssize_t libusb_get_device_list(libusb_context *ctx,
-       libusb_device ***list)
-{
-       int n, i;
-       libusb_device **rlist;
-
-       n = mock_type(int);
-       rlist = calloc(sizeof(libusb_device *), n);
-       for (i = 0; i < n; ++i) {
-               rlist[i] = mock_ptr_type(libusb_device *);
-       }
-
-       *list = rlist;
-       return n;
-}
-
-void libusb_free_device_list(libusb_device **list,
-       int unref_devices)
-{
-       free(list);
-}
-
-libusb_device * libusb_ref_device(libusb_device *dev)
-{
-       check_expected(dev);
-       return dev;
-}
-
-void libusb_unref_device(libusb_device *dev)
-{
-}
-
-int libusb_get_configuration(libusb_device_handle *dev,
-       int *config)
-{
-       check_expected(dev);
-       *config = mock_type(int);
-       return mock_type(int);
-}
-
-int libusb_get_device_descriptor(libusb_device *dev,
-       struct libusb_device_descriptor *desc)
-{
-       check_expected(dev);
-       check_expected(desc);
-       return mock_type(int);
-}
-
-int libusb_get_active_config_descriptor(libusb_device *dev,
-       struct libusb_config_descriptor **config)
-{
-       return 0;
-}
-
-static int deallocate_config_descriptor (struct libusb_config_descriptor *c,
-       int i, int j, int temp)
-{
-       while (i > 0)
-       {
-               --i;
-               while (j > 0)
-               {
-                       --j;
-                       free (c->interface[i].altsetting[j].endpoint);
-               }
-               j = temp;
-               free (c->interface[i].altsetting);
-       }
-       free (c->interface);
-       free (c);
-
-       return LIBUSB_ERROR_NO_MEM;
-}
-
-int libusb_get_config_descriptor(libusb_device *dev,
-       uint8_t config_index, struct libusb_config_descriptor **config)
-{
-       int i, j, k, temp;
-
-       struct libusb_interface *iface;
-       struct libusb_interface_descriptor *desc;
-       struct libusb_endpoint_descriptor *ep;
-
-       struct libusb_config_descriptor *c = malloc (sizeof (*c));
-       if (!c) return LIBUSB_ERROR_NO_MEM;
-
-       temp = mock_type(int);
-
-       c->bNumInterfaces = temp;
-       c->interface = malloc(temp * sizeof(*iface));
-       if (!c->interface)
-       {
-               free (c);
-               return LIBUSB_ERROR_NO_MEM;
-       }
-
-       c->extra_length = 0;
-       for (i = 0; i < temp; ++i)
-       {
-               iface = c->interface + i;
-               iface->num_altsetting = temp;
-               iface->altsetting = malloc(temp * sizeof(*desc));
-               if (!iface->altsetting) return deallocate_config_descriptor (c, i, j, temp);
-               for (j = 0; j < temp; ++j)
-               {
-                       desc = iface->altsetting + j;
-                       desc->bNumEndpoints = temp;
-                       desc->endpoint = malloc(temp * sizeof(*ep));
-                       if (!desc->endpoint) return deallocate_config_descriptor (c, i, j, temp);
-                       desc->extra_length = 0;
-                       for (k = 0; k < temp; ++k)
-                       {
-                               ep = desc->endpoint + k;
-                               ep->extra_length = 0;
-                       }
-               }
-               j = 0;
-       }
-
-       *config = c;
-
-       return 0;
-}
-
-int libusb_get_config_descriptor_by_value(libusb_device *dev,
-       uint8_t bConfigurationValue, struct libusb_config_descriptor **config)
-{
-       return 0;
-}
-
-void libusb_free_config_descriptor(
-       struct libusb_config_descriptor *config)
-{
-}
-
-uint8_t libusb_get_bus_number(libusb_device *dev)
-{
-       check_expected(dev);
-       return mock_type(uint8_t);
-}
-
-uint8_t libusb_get_device_address(libusb_device *dev)
-{
-       check_expected(dev);
-       return mock_type(uint8_t);
-}
-
-int libusb_get_port_numbers(libusb_device *dev,
-               uint8_t* port_numbers, int port_numbers_len)
-{
-       check_expected(dev);
-       *port_numbers = mock_type(uint8_t);
-       check_expected(port_numbers_len);
-
-       return mock_type(int);
-}
-
-int libusb_get_device_speed(libusb_device *dev)
-{
-       return 0;
-}
-
-int libusb_get_max_packet_size(libusb_device *dev,
-       unsigned char endpoint)
-{
-       return 0;
-}
-
-int libusb_get_max_iso_packet_size(libusb_device *dev,
-       unsigned char endpoint)
-{
-       check_expected(dev);
-       check_expected(endpoint);
-       return mock_type(int);
-}
-
-int libusb_open(libusb_device *dev, libusb_device_handle **handle)
-{
-       check_expected(dev);
-       check_expected(handle);
-       *handle = mock_ptr_type(libusb_device_handle *);
-       return mock_type(int);
-}
-
-void libusb_close(libusb_device_handle *dev_handle)
-{
-       check_expected (dev_handle);
-}
-
-libusb_device * libusb_get_device(libusb_device_handle *dev_handle)
-{
-       return mock_ptr_type(libusb_device *);
-}
-
-int libusb_set_configuration(libusb_device_handle *dev,
-       int configuration)
-{
-       check_expected(dev);
-       check_expected(configuration);
-       return mock_type(int);
-}
-
-int libusb_claim_interface(libusb_device_handle *dev,
-       int interface_number)
-{
-       check_expected(dev);
-       check_expected(interface_number);
-       return mock_type(int);
-}
-
-int libusb_release_interface(libusb_device_handle *dev,
-       int interface_number)
-{
-       check_expected(dev);
-       check_expected(interface_number);
-       return mock_type(int);
-}
-
-int libusb_set_interface_alt_setting(libusb_device_handle *dev,
-       int interface_number, int alternate_setting)
-{
-       return 0;
-}
-
-int libusb_clear_halt(libusb_device_handle *dev,
-       unsigned char endpoint)
-{
-       check_expected(dev);
-       check_expected(endpoint);
-       return mock_type(int);
-}
-
-int libusb_reset_device(libusb_device_handle *dev)
-{
-       check_expected(dev);
-       return mock_type(int);
-}
-
-int libusb_kernel_driver_active(libusb_device_handle *dev,
-       int interface_number)
-{
-       check_expected(dev);
-       check_expected(interface_number);
-       return mock_type(int);
-}
-
-int libusb_detach_kernel_driver(libusb_device_handle *dev,
-       int interface_number)
-{
-       check_expected(dev);
-       check_expected(interface_number);
-       return mock_type(int);
-}
-
-int libusb_attach_kernel_driver(libusb_device_handle *dev,
-       int interface_number)
-{
-       check_expected(dev);
-       check_expected(interface_number);
-       return mock_type(int);
-}
-
-int libusb_control_transfer(libusb_device_handle *dev_handle,
-       uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
-       unsigned char *data, uint16_t wLength, unsigned int timeout)
-{
-       check_expected(dev_handle);
-       check_expected(request_type);
-       check_expected(bRequest);
-       check_expected(wValue);
-       check_expected(wIndex);
-       check_expected(data);
-       check_expected(wLength);
-       check_expected(timeout);
-
-       return mock_type(int);
-}
-
-int libusb_bulk_transfer(libusb_device_handle *dev_handle,
-       uint8_t endpoint, unsigned char *data, int length,
-       int *transferred, unsigned int timeout)
-{
-       check_expected(dev_handle);
-       check_expected(endpoint);
-       check_expected(data);
-       check_expected(length);
-       check_expected(timeout);
-
-       *transferred = mock_type(int);
-
-       return mock_type(int);
-}
-
-int libusb_interrupt_transfer(libusb_device_handle *dev_handle,
-       uint8_t endpoint, unsigned char *data, int length,
-       int *transferred, unsigned int timeout)
-{
-       check_expected(dev_handle);
-       check_expected(endpoint);
-       check_expected(data);
-       check_expected(length);
-       check_expected(timeout);
-
-       *transferred = mock_type(int);
-
-       return mock_type(int);
-}
-
-int libusb_get_string_descriptor_ascii(libusb_device_handle *dev,
-       uint8_t desc_index, unsigned char *data, int length)
-{
-       check_expected(dev);
-       check_expected(desc_index);
-       check_expected(length);
-
-       strcpy (data, mock_ptr_type(unsigned char *));
-       return mock_type(int);
-}
-
-struct libusb_transfer *libusb_alloc_transfer(int iso_packets)
-{
-       check_expected(iso_packets);
-       return mock_ptr_type(struct libusb_transfer *);
-}
-
-void libusb_free_transfer(struct libusb_transfer *transfer)
-{
-       check_expected(transfer);
-}
-
-int libusb_submit_transfer(struct libusb_transfer *transfer)
-{
-       check_expected(transfer);
-       return mock_type(int);
-}
-
-int libusb_cancel_transfer(struct libusb_transfer *transfer)
-{
-       check_expected(transfer);
-       return mock_type(int);
-}
-
-int libusb_handle_events_completed(libusb_context *ctx, int *completed)
-{
-       check_expected(ctx);
-       check_expected(completed);
-       return mock_type(int);
-}
diff --git a/tests/libusb_wrap.c b/tests/libusb_wrap.c
new file mode 100644 (file)
index 0000000..d437753
--- /dev/null
@@ -0,0 +1,421 @@
+/*
+ * libusb_wrap.c
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libusb-1.0/libusb.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <setjmp.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <cmocka.h>
+#include <string.h>
+#include <stddef.h>
+#include <dlfcn.h>
+
+int libusb_init(libusb_context **ctx)
+{
+       check_expected(ctx);
+       *ctx = mock_ptr_type(libusb_context *);
+
+       return mock_type(int);
+}
+
+libusb_device_handle * libusb_open_device_with_vid_pid(libusb_context *ctx, uint16_t vendor_id, uint16_t product_id)
+{
+       libusb_device_handle *handle;
+
+       check_expected(ctx);
+       check_expected(vendor_id);
+       check_expected(product_id);
+
+       return mock_ptr_type(libusb_device_handle *);
+}
+
+void libusb_exit(libusb_context *ctx)
+{
+       check_expected(ctx);
+}
+
+void libusb_set_debug(libusb_context *ctx, int level)
+{
+}
+
+const struct libusb_version * libusb_get_version(void)
+{
+       return NULL;
+}
+
+int libusb_has_capability(uint32_t capability)
+{
+       return 0;
+}
+
+const char * libusb_error_name(int errcode)
+{
+       return NULL;
+}
+
+ssize_t libusb_get_device_list(libusb_context *ctx,
+       libusb_device ***list)
+{
+       int n, i;
+       libusb_device **rlist;
+
+       n = mock_type(int);
+       rlist = calloc(sizeof(libusb_device *), n);
+       for (i = 0; i < n; ++i) {
+               rlist[i] = mock_ptr_type(libusb_device *);
+       }
+
+       *list = rlist;
+       return n;
+}
+
+void libusb_free_device_list(libusb_device **list,
+       int unref_devices)
+{
+       free(list);
+}
+
+libusb_device * libusb_ref_device(libusb_device *dev)
+{
+       check_expected(dev);
+       return dev;
+}
+
+void libusb_unref_device(libusb_device *dev)
+{
+}
+
+int libusb_get_configuration(libusb_device_handle *dev,
+       int *config)
+{
+       check_expected(dev);
+       *config = mock_type(int);
+       return mock_type(int);
+}
+
+int libusb_get_device_descriptor(libusb_device *dev,
+       struct libusb_device_descriptor *desc)
+{
+       check_expected(dev);
+       check_expected(desc);
+       return mock_type(int);
+}
+
+int libusb_get_active_config_descriptor(libusb_device *dev,
+       struct libusb_config_descriptor **config)
+{
+       return 0;
+}
+
+static int deallocate_config_descriptor (struct libusb_config_descriptor *c,
+       int i, int j, int temp)
+{
+       while (i > 0)
+       {
+               --i;
+               while (j > 0)
+               {
+                       --j;
+                       free (c->interface[i].altsetting[j].endpoint);
+               }
+               j = temp;
+               free (c->interface[i].altsetting);
+       }
+       free (c->interface);
+       free (c);
+
+       return LIBUSB_ERROR_NO_MEM;
+}
+
+int libusb_get_config_descriptor(libusb_device *dev,
+       uint8_t config_index, struct libusb_config_descriptor **config)
+{
+       int i, j, k, temp;
+
+       struct libusb_interface *iface;
+       struct libusb_interface_descriptor *desc;
+       struct libusb_endpoint_descriptor *ep;
+
+       struct libusb_config_descriptor *c = malloc (sizeof (*c));
+       if (!c) return LIBUSB_ERROR_NO_MEM;
+
+       temp = mock_type(int);
+
+       c->bNumInterfaces = temp;
+       c->interface = malloc(temp * sizeof(*iface));
+       if (!c->interface)
+       {
+               free (c);
+               return LIBUSB_ERROR_NO_MEM;
+       }
+
+       c->extra_length = 0;
+       for (i = 0; i < temp; ++i)
+       {
+               iface = c->interface + i;
+               iface->num_altsetting = temp;
+               iface->altsetting = malloc(temp * sizeof(*desc));
+               if (!iface->altsetting) return deallocate_config_descriptor (c, i, j, temp);
+               for (j = 0; j < temp; ++j)
+               {
+                       desc = iface->altsetting + j;
+                       desc->bNumEndpoints = temp;
+                       desc->endpoint = malloc(temp * sizeof(*ep));
+                       if (!desc->endpoint) return deallocate_config_descriptor (c, i, j, temp);
+                       desc->extra_length = 0;
+                       for (k = 0; k < temp; ++k)
+                       {
+                               ep = desc->endpoint + k;
+                               ep->extra_length = 0;
+                       }
+               }
+               j = 0;
+       }
+
+       *config = c;
+
+       return 0;
+}
+
+int libusb_get_config_descriptor_by_value(libusb_device *dev,
+       uint8_t bConfigurationValue, struct libusb_config_descriptor **config)
+{
+       check_expected(dev);
+       *config = mock_ptr_type(struct libusb_config_descriptor *);
+       return mock_type(int);
+}
+
+void libusb_free_config_descriptor(
+       struct libusb_config_descriptor *config)
+{
+}
+
+uint8_t libusb_get_bus_number(libusb_device *dev)
+{
+       check_expected(dev);
+       return mock_type(uint8_t);
+}
+
+uint8_t libusb_get_device_address(libusb_device *dev)
+{
+       check_expected(dev);
+       return mock_type(uint8_t);
+}
+
+int libusb_get_port_numbers(libusb_device *dev,
+               uint8_t* port_numbers, int port_numbers_len)
+{
+       check_expected(dev);
+       *port_numbers = mock_type(uint8_t);
+       check_expected(port_numbers_len);
+
+       return mock_type(int);
+}
+
+int libusb_get_device_speed(libusb_device *dev)
+{
+       return 0;
+}
+
+int libusb_get_max_packet_size(libusb_device *dev,
+       unsigned char endpoint)
+{
+       return 0;
+}
+
+int libusb_get_max_iso_packet_size(libusb_device *dev,
+       unsigned char endpoint)
+{
+       check_expected(dev);
+       check_expected(endpoint);
+       return mock_type(int);
+}
+
+int libusb_open(libusb_device *dev, libusb_device_handle **handle)
+{
+       check_expected(dev);
+       check_expected(handle);
+       *handle = mock_ptr_type(libusb_device_handle *);
+       return mock_type(int);
+}
+
+void libusb_close(libusb_device_handle *dev_handle)
+{
+       check_expected (dev_handle);
+}
+
+libusb_device * libusb_get_device(libusb_device_handle *dev_handle)
+{
+       return mock_ptr_type(libusb_device *);
+}
+
+int libusb_set_configuration(libusb_device_handle *dev,
+       int configuration)
+{
+       check_expected(dev);
+       check_expected(configuration);
+       return mock_type(int);
+}
+
+int libusb_claim_interface(libusb_device_handle *dev,
+       int interface_number)
+{
+       check_expected(dev);
+       check_expected(interface_number);
+       return mock_type(int);
+}
+
+int libusb_release_interface(libusb_device_handle *dev,
+       int interface_number)
+{
+       check_expected(dev);
+       check_expected(interface_number);
+       return mock_type(int);
+}
+
+int libusb_set_interface_alt_setting(libusb_device_handle *dev,
+       int interface_number, int alternate_setting)
+{
+       return 0;
+}
+
+int libusb_clear_halt(libusb_device_handle *dev,
+       unsigned char endpoint)
+{
+       check_expected(dev);
+       check_expected(endpoint);
+       return mock_type(int);
+}
+
+int libusb_reset_device(libusb_device_handle *dev)
+{
+       check_expected(dev);
+       return mock_type(int);
+}
+
+int libusb_kernel_driver_active(libusb_device_handle *dev,
+       int interface_number)
+{
+       check_expected(dev);
+       check_expected(interface_number);
+       return mock_type(int);
+}
+
+int libusb_detach_kernel_driver(libusb_device_handle *dev,
+       int interface_number)
+{
+       check_expected(dev);
+       check_expected(interface_number);
+       return mock_type(int);
+}
+
+int libusb_attach_kernel_driver(libusb_device_handle *dev,
+       int interface_number)
+{
+       check_expected(dev);
+       check_expected(interface_number);
+       return mock_type(int);
+}
+
+int libusb_control_transfer(libusb_device_handle *dev_handle,
+       uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
+       unsigned char *data, uint16_t wLength, unsigned int timeout)
+{
+       check_expected(dev_handle);
+       check_expected(request_type);
+       check_expected(bRequest);
+       check_expected(wValue);
+       check_expected(wIndex);
+       check_expected(data);
+       check_expected(wLength);
+       check_expected(timeout);
+
+       return mock_type(int);
+}
+
+int libusb_bulk_transfer(libusb_device_handle *dev_handle,
+       uint8_t endpoint, unsigned char *data, int length,
+       int *transferred, unsigned int timeout)
+{
+       check_expected(dev_handle);
+       check_expected(endpoint);
+       check_expected(data);
+       check_expected(length);
+       check_expected(timeout);
+
+       *transferred = mock_type(int);
+
+       return mock_type(int);
+}
+
+int libusb_interrupt_transfer(libusb_device_handle *dev_handle,
+       uint8_t endpoint, unsigned char *data, int length,
+       int *transferred, unsigned int timeout)
+{
+       check_expected(dev_handle);
+       check_expected(endpoint);
+       check_expected(data);
+       check_expected(length);
+       check_expected(timeout);
+
+       *transferred = mock_type(int);
+
+       return mock_type(int);
+}
+
+int libusb_get_string_descriptor_ascii(libusb_device_handle *dev,
+       uint8_t desc_index, unsigned char *data, int length)
+{
+       check_expected(dev);
+       check_expected(desc_index);
+       check_expected(length);
+
+       strcpy (data, mock_ptr_type(unsigned char *));
+       return mock_type(int);
+}
+
+struct libusb_transfer *libusb_alloc_transfer(int iso_packets)
+{
+       check_expected(iso_packets);
+       return mock_ptr_type(struct libusb_transfer *);
+}
+
+void libusb_free_transfer(struct libusb_transfer *transfer)
+{
+       check_expected(transfer);
+}
+
+int libusb_submit_transfer(struct libusb_transfer *transfer)
+{
+       check_expected(transfer);
+       return mock_type(int);
+}
+
+int libusb_cancel_transfer(struct libusb_transfer *transfer)
+{
+       check_expected(transfer);
+       return mock_type(int);
+}
+
+int libusb_handle_events_completed(libusb_context *ctx, int *completed)
+{
+       check_expected(ctx);
+       check_expected(completed);
+       return mock_type(int);
+}
diff --git a/tests/usb_host_test.c b/tests/usb_host_test.c
new file mode 100644 (file)
index 0000000..39d906f
--- /dev/null
@@ -0,0 +1,736 @@
+/*
+ * usb_host-test.c
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <linux/usb/ch9.h>
+#include <setjmp.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <cmocka.h>
+#include <time.h>
+
+#include "usb_host.h"
+#include "usb_host_internal.h"
+#include <libusb-1.0/libusb.h>
+#include "uref.h"
+
+/* assertions and checks */
+
+/**
+ * @brief Initialize library context and check results
+ */
+static int setup_usb_host_context(void **state)
+{
+       int ret;
+       usb_host_context_h ctx;
+       libusb_context *lusb_ctx;
+
+       expect_any(libusb_init, ctx);
+       will_return(libusb_init, lusb_ctx);
+       will_return(libusb_init, LIBUSB_SUCCESS);
+
+       ret = usb_host_create(&ctx);
+
+       assert_return_code(ret, 0);
+       assert_ptr_equal(ctx->lusb_ctx, lusb_ctx);
+
+       *state = (void *)ctx;
+
+       return 0;
+}
+
+static int teardown_usb_host_context(void **state)
+{
+       usb_host_context_h ctx;
+
+       ctx = (usb_host_context_h )(*state);
+       expect_any(libusb_exit, ctx);
+       usb_host_destroy(ctx);
+
+       return 0;
+}
+
+static int setup_usb_host_device(void **state)
+{
+       usb_host_device_h dev;
+
+       dev = malloc(sizeof(*dev));
+       /* TODO fill this with something? */
+
+       dev->lusb_dev = rand();
+       dev->lusb_dev_handle = rand();
+
+       *state = dev;
+
+       return 0;
+}
+
+/**
+ * @brief Just free the memory
+ */
+static int teardown_free(void **state)
+{
+       free(*state);
+
+       return 0;
+}
+
+/**
+ * @brief Test if initialization works fine
+ */
+static void test_init(void **state)
+{
+       usb_host_context_h ctx;
+
+       ctx = (usb_host_context_h )(*state);
+       assert_non_null(ctx);
+}
+
+static void test_open(void **state)
+{
+       usb_host_context_h ctx;
+       libusb_device_handle *lusb_handle;
+       struct usb_host_device_s device;
+       int ret;
+
+       ctx = (usb_host_context_h )(*state);
+       assert_non_null(ctx);
+
+       expect_value(libusb_open, dev, device.lusb_dev);
+       expect_any(libusb_open, handle);
+       will_return(libusb_open, lusb_handle);
+       will_return(libusb_open, 0);
+
+       ret = usb_host_device_open(&device);
+
+       assert_return_code(ret, 0);
+       assert_ptr_equal(device.lusb_dev_handle, lusb_handle);
+}
+
+/*
+ * A pair of functions required for uref,
+ * to which usb_host_device_close relegates some work
+ * and expects to find inside a usb_host_device_s,
+ * so we cannot use a mock instance.
+ *
+ * No usb_host function returns a usb_host_device_s,
+ * so we need to manually instantiate one.
+ */
+static inline usb_host_device_h to_usb_host_device(struct uref *_uref)
+{
+       return container_of(_uref, struct usb_host_device_s, ref);
+}
+
+static void free_device(struct uref *uref)
+{
+       usb_host_device_h dev = to_usb_host_device(uref);
+
+       libusb_unref_device(dev->lusb_dev);
+       free(dev);
+}
+
+static void test_close(void **state)
+{
+       usb_host_device_h handle;
+
+       handle = (usb_host_device_h ) (*state);
+       assert_non_null(handle);
+
+       handle->lusb_dev_handle = rand();
+
+       expect_value (libusb_close, dev_handle, handle->lusb_dev_handle);
+       usb_host_device_close (handle);
+}
+
+static void test_get_devices(void **state)
+{
+       int n = 7, i, ret;
+       usb_host_context_h ctx;
+       usb_host_device_h *devs;
+
+       libusb_device *lusb_devs[n];
+       for (i = 0; i < n; ++i)
+               lusb_devs[i] = (libusb_device *) rand();
+
+       ctx = (usb_host_context_h )(*state);
+       assert_non_null(ctx);
+
+       will_return(libusb_get_device_list, n);
+       for (i = 0; i < n; ++i) {
+               expect_any(libusb_ref_device, dev);
+               will_return(libusb_get_device_list, lusb_devs[i]);
+
+               expect_value(libusb_get_device_descriptor, dev, lusb_devs[i]);
+               expect_any(libusb_get_device_descriptor, desc);
+               will_return(libusb_get_device_descriptor, 0);
+       }
+
+       ret = usb_host_get_device_list(ctx, &devs);
+
+       assert_int_equal(ret, n);
+       for (i = 0; i < n; ++i)
+               assert_ptr_equal(devs[i]->lusb_dev, lusb_devs[i]);
+
+       usb_host_free_device_list(devs, 0);
+}
+
+static void test_get_bus_number(void **state)
+{
+       usb_host_device_h device;
+       uint8_t expected, ret;
+
+       expected = rand();
+       device = (usb_host_device_h )(*state);
+       assert_non_null(device);
+
+       expect_value(libusb_get_bus_number, dev, device->lusb_dev);
+       will_return(libusb_get_bus_number, expected);
+
+       ret = usb_host_device_get_bus_number(device);
+
+       assert_int_equal(ret, expected);
+}
+
+static void test_get_address(void **state)
+{
+       usb_host_device_h device;
+       uint8_t expected, ret;
+
+       expected = rand();
+       device = (usb_host_device_h )(*state);
+       assert_non_null(device);
+
+       expect_value(libusb_get_device_address, dev, device->lusb_dev);
+       will_return(libusb_get_device_address, expected);
+
+       ret = usb_host_device_get_address(device);
+
+       assert_int_equal(ret, expected);
+}
+
+static void test_get_port_numbers(void **state)
+{
+       usb_host_device_h device;
+       uint8_t p_numbers[8];
+       int ret, p_num_len;
+
+       /* As per the USB 3.0 specs, the current maximum limit for the depth is 7 */
+       p_num_len = 8;
+       device = (usb_host_device_h )(*state);
+       assert_non_null(device);
+
+       expect_value(libusb_get_port_numbers, dev, device->lusb_dev);
+       expect_value(libusb_get_port_numbers, port_numbers_len, p_num_len);
+       will_return(libusb_get_port_numbers, p_num_len -1);
+       will_return(libusb_get_port_numbers, 0);
+
+       ret = usb_host_device_get_port_numbers(device, p_numbers, p_num_len);
+
+       assert_return_code(ret, 0);
+}
+
+static void test_get_active_config(void **state)
+{
+       usb_host_device_h handle;
+       int expected, ret;
+       struct usb_host_config_s *conf;
+       struct libusb_config_descriptor desc;
+
+       handle = (usb_host_device_h )(*state);
+       expected = rand();
+
+       desc.bNumInterfaces = 0;
+       desc.bConfigurationValue = expected;
+
+       expect_value(libusb_get_configuration, dev, handle->lusb_dev_handle);
+       will_return(libusb_get_configuration, expected);
+       will_return(libusb_get_configuration, 0);
+
+       expect_value(libusb_get_config_descriptor_by_value, dev, handle->lusb_dev);
+       will_return(libusb_get_config_descriptor_by_value, &desc);
+       will_return(libusb_get_config_descriptor_by_value, 0);
+
+       ret = usb_host_get_active_config(handle, &conf);
+
+       assert_return_code(ret, 0);
+}
+
+static void test_open_device_vid_pid(void **state)
+{
+       usb_host_device_h handle;
+       usb_host_context_h ctx;
+       libusb_device_handle *lusb_dev_handle;
+       libusb_device *lusb_device;
+       uint16_t vid, pid;
+
+       vid = (uint16_t)rand();
+       pid = (uint16_t)rand();
+       lusb_dev_handle = (libusb_device_handle *)rand();
+       lusb_device = (libusb_device *)rand();
+
+       ctx = (usb_host_context_h )(*state);
+       assert_non_null(ctx);
+
+       expect_value(libusb_open_device_with_vid_pid, ctx, ctx->lusb_ctx);
+       expect_value(libusb_open_device_with_vid_pid, vendor_id, vid);
+       expect_value(libusb_open_device_with_vid_pid, product_id, pid);
+       will_return(libusb_open_device_with_vid_pid, lusb_dev_handle);
+       will_return(libusb_get_device, lusb_device);
+       expect_any(libusb_ref_device, dev);
+       expect_value(libusb_get_device_descriptor, dev, lusb_device);
+       expect_any(libusb_get_device_descriptor, desc);
+       will_return(libusb_get_device_descriptor, 0);
+
+       handle = usb_host_open_device_with_vid_pid(ctx, vid, pid);
+
+       assert_non_null(handle);
+       assert_ptr_equal(handle->lusb_dev_handle, lusb_dev_handle);
+       assert_ptr_equal(handle->lusb_dev, lusb_device);
+
+       expect_value (libusb_close, dev_handle, handle->lusb_dev_handle);
+       usb_host_device_close(handle);
+}
+
+static void test_set_config(void **state)
+{
+       usb_host_device_h handle;
+       struct usb_host_config_s config;
+       uint8_t cfg_nmb;
+       int ret;
+
+       cfg_nmb = rand();
+       handle = (usb_host_device_h )(*state);
+       assert_non_null(handle);
+
+       config.desc.bConfigurationValue = cfg_nmb;
+       config.dev = handle;
+
+       expect_value(libusb_set_configuration, dev, handle->lusb_dev_handle);
+       expect_value(libusb_set_configuration, configuration, cfg_nmb);
+       will_return(libusb_set_configuration, 0);
+
+       ret = usb_host_set_config(&config);
+
+       assert_return_code(ret, 0);
+}
+
+static void test_claim_interface_simple(void **state)
+{
+       usb_host_device_h handle;
+       struct usb_host_interface_s interface;
+       int ret;
+
+       handle = (usb_host_device_h )(*state);
+       assert_non_null(handle);
+
+       interface.num_altsettings = 1;
+       interface.altsettings = calloc(sizeof(*interface.altsettings), 1);
+       interface.altsetting = 0;
+
+       interface.dev = handle;
+       interface.altsettings[0].desc.bInterfaceNumber = 0;
+
+       expect_value(libusb_claim_interface, dev, handle->lusb_dev_handle);
+       expect_value(libusb_claim_interface, interface_number, interface.altsettings[0].desc.bInterfaceNumber);
+       will_return(libusb_claim_interface, 0);
+
+       ret = usb_host_claim_interface(&interface, 0);
+
+       assert_return_code(ret, 0);
+
+       free(interface.altsettings);
+}
+
+static void test_release_interface_simple(void **state)
+{
+       usb_host_device_h handle;
+       int interface_nmb, ret;
+       struct usb_host_interface_s interface;
+
+       interface_nmb = rand() % MAX_NMB_OF_CONFIGS;
+       handle = (usb_host_device_h )(*state);
+       assert_non_null(handle);
+       handle->driver_detached[interface_nmb] = 0;
+
+       interface.num_altsettings = 1;
+       interface.altsettings = calloc(sizeof(*interface.altsettings), 1);
+       interface.altsettings[0].desc.bInterfaceNumber = interface_nmb;
+       interface.altsetting = 0;
+
+       interface.dev = handle;
+
+       expect_value(libusb_release_interface, dev, handle->lusb_dev_handle);
+       expect_value(libusb_release_interface, interface_number, interface_nmb);
+       will_return(libusb_release_interface, 0);
+
+       ret = usb_host_release_interface(&interface);
+
+       assert_return_code(ret, 0);
+
+       free(interface.altsettings);
+}
+
+static void test_release_interface_attachment(void **state)
+{
+       usb_host_device_h handle;
+       int interface_nmb, ret;
+       struct usb_host_interface_s interface;
+
+       interface_nmb = rand() % MAX_NMB_OF_CONFIGS;
+       handle = (usb_host_device_h )(*state);
+       assert_non_null(handle);
+       handle->driver_detached[interface_nmb] = 1;
+
+       interface.num_altsettings = 1;
+       interface.altsettings = calloc(sizeof(*interface.altsettings), 1);
+       interface.altsettings[0].desc.bInterfaceNumber = interface_nmb;
+       interface.altsetting = 0;
+
+       interface.dev = handle;
+
+       expect_value(libusb_release_interface, dev, handle->lusb_dev_handle);
+       expect_value(libusb_release_interface, interface_number, interface_nmb);
+       will_return(libusb_release_interface, 0);
+
+       expect_value(libusb_attach_kernel_driver, dev, handle->lusb_dev_handle);
+       expect_value(libusb_attach_kernel_driver, interface_number, interface_nmb);
+       will_return(libusb_attach_kernel_driver, 0);
+
+       ret = usb_host_release_interface(&interface);
+
+       assert_return_code(ret, 0);
+       assert_int_equal(0, handle->driver_detached[interface_nmb]);
+
+       free(interface.altsettings);
+}
+
+static void test_control_transfer(void **state)
+{
+       uint8_t request_type, bRequest;
+       uint16_t wValue, wIndex, wLength;
+       unsigned char *data;
+       unsigned int timeout;
+       int ret;
+       usb_host_device_h handle;
+
+       handle = (usb_host_device_h )(*state);
+       assert_non_null(handle);
+
+#define EXPECT_VAL(val) expect_value(libusb_control_transfer, val, val);
+       EXPECT_VAL(request_type);
+       EXPECT_VAL(bRequest);
+       EXPECT_VAL(wValue);
+       EXPECT_VAL(wIndex);
+       EXPECT_VAL(data);
+       EXPECT_VAL(wLength);
+       EXPECT_VAL(timeout);
+#undef EXPECT_VAL
+       expect_value(libusb_control_transfer, dev_handle, handle->lusb_dev_handle);
+       will_return(libusb_control_transfer, 0);
+
+       ret =  usb_host_control_transfer(handle, request_type, bRequest, wValue,
+                       wIndex, data, wLength, timeout);
+
+       assert_return_code(ret, 0);
+}
+
+static void test_bulk_transfer_length_check(void **state)
+{
+       uint8_t endpoint;
+       unsigned char *data;
+       int length;
+       int transferred;
+       unsigned int timeout;
+       int ret;
+       usb_host_device_h handle;
+       struct usb_host_endpoint_s ep;
+
+       length = rand();
+       handle = (usb_host_device_h )(*state);
+       assert_non_null(handle);
+
+       ep.desc.bmAttributes = USB_ENDPOINT_XFER_BULK;
+       ep.desc.bEndpointAddress = endpoint;
+       ep.dev = handle;
+
+#define EXPECT_VAL(val) expect_value(libusb_bulk_transfer, val, val);
+       EXPECT_VAL(endpoint);
+       EXPECT_VAL(data);
+       EXPECT_VAL(length);
+       EXPECT_VAL(timeout);
+#undef EXPECT_VAL
+       expect_value(libusb_bulk_transfer, dev_handle, handle->lusb_dev_handle);
+       will_return(libusb_bulk_transfer, length);
+       will_return(libusb_bulk_transfer, 0);
+
+       ret = usb_host_transfer(&ep, data, length, &transferred, timeout);
+
+       assert_int_equal(transferred, length);
+       assert_return_code(ret, 0);
+}
+
+static void test_bulk_transfer_simple(void **state)
+{
+       uint8_t endpoint;
+       unsigned char *data;
+       int length;
+       int transferred;
+       unsigned int timeout;
+       int ret;
+       usb_host_device_h handle;
+       struct usb_host_endpoint_s ep;
+
+       handle = (usb_host_device_h )(*state);
+       assert_non_null(handle);
+
+       ep.desc.bmAttributes = USB_ENDPOINT_XFER_BULK;
+       ep.desc.bEndpointAddress = endpoint;
+       ep.dev = handle;
+
+#define EXPECT_VAL(val) expect_value(libusb_bulk_transfer, val, val);
+       EXPECT_VAL(endpoint);
+       EXPECT_VAL(data);
+       EXPECT_VAL(length);
+       EXPECT_VAL(timeout);
+#undef EXPECT_VAL
+       expect_value(libusb_bulk_transfer, dev_handle, handle->lusb_dev_handle);
+       will_return(libusb_bulk_transfer, rand());
+       will_return(libusb_bulk_transfer, 0);
+
+       ret = usb_host_transfer(&ep, data, length, &transferred, timeout);
+
+       assert_return_code(ret, 0);
+}
+
+static void test_interrupt_transfer_length_check(void **state)
+{
+       uint8_t endpoint;
+       unsigned char *data;
+       int length;
+       int transferred;
+       unsigned int timeout;
+       int ret;
+       usb_host_device_h handle;
+       struct usb_host_endpoint_s ep;
+
+       length = rand();
+       handle = (usb_host_device_h )(*state);
+       assert_non_null(handle);
+
+       ep.desc.bmAttributes = USB_ENDPOINT_XFER_INT;
+       ep.desc.bEndpointAddress = endpoint;
+       ep.dev = handle;
+
+#define EXPECT_VAL(val) expect_value(libusb_interrupt_transfer, val, val);
+       EXPECT_VAL(endpoint);
+       EXPECT_VAL(data);
+       EXPECT_VAL(length);
+       EXPECT_VAL(timeout);
+#undef EXPECT_VAL
+       expect_value(libusb_interrupt_transfer, dev_handle, handle->lusb_dev_handle);
+       will_return(libusb_interrupt_transfer, length);
+       will_return(libusb_interrupt_transfer, 0);
+
+       ret = usb_host_transfer(&ep, data, length, &transferred, timeout);
+
+       assert_int_equal(transferred, length);
+       assert_return_code(ret, 0);
+}
+
+static void test_interrupt_transfer_simple(void **state)
+{
+       uint8_t endpoint;
+       unsigned char *data;
+       int length;
+       int transferred;
+       unsigned int timeout;
+       int ret;
+       usb_host_device_h handle;
+       struct usb_host_endpoint_s ep;
+
+       handle = (usb_host_device_h )(*state);
+       assert_non_null(handle);
+
+       ep.desc.bmAttributes = USB_ENDPOINT_XFER_INT;
+       ep.desc.bEndpointAddress = endpoint;
+       ep.dev = handle;
+
+#define EXPECT_VAL(val) expect_value(libusb_interrupt_transfer, val, val);
+       EXPECT_VAL(endpoint);
+       EXPECT_VAL(data);
+       EXPECT_VAL(length);
+       EXPECT_VAL(timeout);
+#undef EXPECT_VAL
+       expect_value(libusb_interrupt_transfer, dev_handle, handle->lusb_dev_handle);
+       will_return(libusb_interrupt_transfer, rand());
+       will_return(libusb_interrupt_transfer, 0);
+
+       ret = usb_host_transfer(&ep, data, length, &transferred, timeout);
+
+       assert_return_code(ret, 0);
+}
+
+static void test_get_string_descriptor_ascii(void **state)
+{
+       usb_host_device_h handle;
+       uint8_t desc_index;
+       unsigned char data [16];
+       int length, ret;
+       const char * testString = "TestString";
+
+       handle = (usb_host_device_h )(*state);
+       assert_non_null(handle);
+
+       expect_value(libusb_get_string_descriptor_ascii, dev, handle->lusb_dev_handle);
+       expect_value(libusb_get_string_descriptor_ascii, desc_index, desc_index);
+       expect_value(libusb_get_string_descriptor_ascii, length, length);
+       will_return(libusb_get_string_descriptor_ascii, cast_ptr_to_largest_integral_type(testString));
+       will_return(libusb_get_string_descriptor_ascii, 0);
+
+       ret = usb_host_get_string_descriptor_ascii(handle, desc_index, length, data);
+
+       assert_return_code(ret, 0);
+       assert_string_equal(data, testString);
+}
+
+static void test_get_config(void **state)
+{
+       usb_host_config_h config;
+       usb_host_device_h dev;
+       uint8_t config_index;
+       int ret, interfaces;
+
+       config_index = rand();
+       interfaces = rand() % 6 + 1; // not too large, n^4 objects are created
+       dev = (usb_host_device_h )(*state);
+       assert_non_null(dev);
+
+       will_return(libusb_get_config_descriptor, interfaces);
+
+       ret = usb_host_device_get_config(dev, config_index, &config);
+
+       assert_return_code(ret, 0);
+
+       usb_host_free_config(config);
+}
+
+/* Custom macro for defining test with given name and fixed teardown function */
+#define HUSB_TEST(func, setup, teardown) \
+       cmocka_unit_test_setup_teardown(func, setup, teardown)
+#define HUSB_TEST_CTX(func) \
+       cmocka_unit_test_setup_teardown(func, setup_usb_host_context, teardown_usb_host_context)
+#define HUSB_TEST_DEVICE(func) \
+       cmocka_unit_test_setup_teardown(func, setup_usb_host_device, teardown_free)
+#define HUSB_TEST_NOSETUP(func) \
+       cmocka_unit_test(func)
+#define HUSB_TEST_NO_TEARDOWN(func, setup) \
+       cmocka_unit_test_setup (func, setup)
+
+static struct CMUnitTest tests[] = {
+
+               /**
+                * @some_test
+                */
+               /**
+                * @brief Check if library is initailized correctly
+                */
+               HUSB_TEST_CTX(test_init),
+               /**
+                * @brief check if devices are opened correctly
+                */
+               HUSB_TEST_CTX(test_open),
+               /**
+                * @brief Check if devices are closed correctly
+                */
+               HUSB_TEST_DEVICE(test_close), // the tested function does the teardown
+               /**
+                * @brief check if list of devices is retrieved correctly
+                */
+               HUSB_TEST_CTX(test_get_devices),
+               /**
+                * @brief Check if bus number is retrieved correctly
+                */
+               HUSB_TEST_DEVICE(test_get_bus_number),
+               /**
+                * @brief check if address is retrieved correctly
+                */
+               HUSB_TEST_DEVICE(test_get_address),
+               /**
+                * @brief check if port numbers are retrieved correctly
+                */
+               HUSB_TEST_DEVICE(test_get_port_numbers),
+               /**
+                * @brief Check if active configuration is retrieved correctly
+                */
+               HUSB_TEST_DEVICE(test_get_active_config),
+               /**
+                * @brief Check if device is opened correctly by usb_host_open_device_with_vid_pid() function
+                */
+               HUSB_TEST_CTX(test_open_device_vid_pid),
+               /**
+                * @brief Check if configuration is set correctly
+                */
+               HUSB_TEST_DEVICE(test_set_config),
+               /**
+                * @brief Check if interfaces are claimed correctly
+                */
+               HUSB_TEST_DEVICE(test_claim_interface_simple),
+               /**
+                * @brief Check if control transfer works as exepected
+                */
+               HUSB_TEST_DEVICE(test_control_transfer),
+               /**
+                * @brief Check if bulk transfer works as expected
+                */
+               HUSB_TEST_DEVICE(test_bulk_transfer_simple),
+               /**
+                * @brief Check if bulk transfer fill length field with proper value
+                */
+               HUSB_TEST_DEVICE(test_bulk_transfer_length_check),
+               /**
+                * @brief Check if interfaces are released correctly
+                */
+               HUSB_TEST_DEVICE(test_release_interface_simple),
+               /**
+                * @brief Check if drivers are reattached afrer releasing interface
+                */
+               HUSB_TEST_DEVICE(test_release_interface_attachment),
+               /**
+                * @brief Check if interrupt transfer works as expected
+                */
+               HUSB_TEST_DEVICE(test_interrupt_transfer_simple),
+               /**
+                * @brief Check if interrupt transfer fill length field with proper value
+                */
+               HUSB_TEST_DEVICE(test_interrupt_transfer_length_check),
+               /**
+                * @brief Check if string descriptor getter returns correct data
+                */
+               HUSB_TEST_DEVICE(test_get_string_descriptor_ascii),
+               /**
+                * @brief Check if configuration object is retrieved correctly
+                */
+               HUSB_TEST_DEVICE(test_get_config),
+};
+
+
+int main(int argc, char **argv)
+{
+       srand(time(NULL));
+       return cmocka_run_group_tests(tests, NULL, NULL);
+}