cscope.*
ncscope.*
-#
-# ignore doxygen documentation
-#
-doc/
-
#
#ignode build directory
#
IF(BUILD_SHARED_LIBS)
SET(HOST_CAPI_SRCS
- src/libhusb.c
+ src/usb_host.c
)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
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})
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})
--- /dev/null
+/*
+ * 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__ */
# 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
#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);
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;
}
Source1001: %{name}.manifest
BuildRequires: cmake
BuildRequires: pkgconfig(capi-system-usbhost)
+BuildRequires: pkgconfig(capi-base-common)
Requires(post): /sbin/ldconfig
Requires(postun): /sbin/ldconfig
#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");
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;
}
* 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>
}
#endif
-#endif /* LIBHUSB_COMMON_H */
+#endif /* USB_HOST_COMMON_H */
+++ /dev/null
-/*
- * 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 */
+++ /dev/null
-/*
- * 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;
-};
/*
- * libhusb
+ * usb_host
*
* Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
*
#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)
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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;
+};
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)
%{?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
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} .
-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}
%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
+++ /dev/null
-/*
- * 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";
- }
-}
-
--- /dev/null
+/*
+ * 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;
+ }
+}
+++ /dev/null
-/*
- * 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);
-}
+++ /dev/null
-/*
- * 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);
-}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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);
+}