# OpenUSB Developers Guide

### lei_chen

# Preface

> This document's purpose is to explain the API for OpenUSB and how to use it to make a USB aware application.

> Any suggestions, corrections and comments regarding this document can be sent to the author: Lei Chen or the libusb developers mailing list. Any bugs or new feature requirements of OpenUSB, please report to libusb developers mailing list

# I. Introduction

# Chapter 1. Overview

This documentation will give an overview of how the OpenUSB external API works and relates to USB. libusb 1.0 API has been discussed and agreed by users and developers in libusb developers mailing list . The API defined in this version is stablized and will not probably be changed in the near future.

OpenUSB or libopenusb is one of the implementation of libusb 1.0 API. It fully comply with libusb 1.0 API. In documents hereafter, OpenUSB and libusb may be used mutually, except when it's neccesary to explicitly clarify.

This documentation assumes that you have a good understanding of USB and how it works.

OpenUSB supports USB v1.1 and v2.0.

The USB 1.1 and 2.0 specification can be found at http://www.usb.org/.

# Chapter 2. Current OS support

- Linux (2.2, 2.4 and on)

- Solaris (OpenSolaris,Solaris Nevada)

# Chapter 3. Differences from libusb v0.1.x

There are many differences from libusb v0.1, all intended to make the API cleaner and support more commonly requested features. These include:

- Completely redesigned enumeration scheme. New APIs are presented to search and manage bus and device. New APIs also have the ability to notify application about dynamic enents, like device attaching/removing.

- Cleaned up API. New APIs are more concise and universal.

- Multi-thread support. This is one of the most significant changes of libusb1.0/OpenUSB APIs. The new APIs are MT-safe and can satisfy requirements of mutli-thread applications.

- Asynchronous support. In v0.1, all functions were synchronous. While this was the most common usage, there are cases where an asynchronous interface was desirable. The API now supports asynchronous versions of most functions where it makes sense.

- More transfer types. libusb v0.1 only supported control and bulk, and control didn't support any endpoints other than the default control pipe. libusb v1.0/OpenUSB now supports all 4 types of transfers (control, bulk, interrupt and isochronous) on all endpoints.

- Normalization of return types. All functions return >= 0 on success or < 0 on error now. The error number and meaning of an error code are unified across platforms.

- OpenUSB is broken into two part,frontend and backend. The frontend is common on all platforms and exports libusb 1.0/OpenUSB APIs to application. The backend is OS specific part, which is the engine behind frontend on different platforms and not visible to application. There's a defined internal interface between frontend and backend. Backend developers can easily implement a new backend for a platform by this interface.

- To make libusb1.0/OpenUSB backward compatible with libusb 0.1.x. An emulation layer is implemented in OpenUSB. Thus, existing applications based on libusb 0.1 do not need any change. All functions in libusb 1.0/OpenUSB API have openusb_ prefix. There's no possible name conflict between libusb 1.0/OpenUSB and libusb 0.1.x. New application can choose to use features of libusb 1.0/OpenUSB or 0.1.x on a single OpenUSB library.

# II. API

This is the external API for applications to use.

The API is relatively lean and designed to have close analogies to the USB specification.

# Chapter 4. Timeouts

Timeout's are always specified in milliseconds.

# Chapter 5. Data Types

Openusb tries to use standard C types wherever possible to avoid complicating things. Where standard C types are insufficient, libopenusb uses abstracted types to ensure portability and forward compatibility.

# III. Functions

# Chapter 6. Core

These functions comprise the core of Openusb. They are used by all applications that utilize libopenusb.

# `openusb_init, openusb_fini`

## Name

`openusb_init, openusb_fini` -- Initialize or destroy a libopenusb instance

## Synopsis

``int32_t openusb_init`(uint32_t flags , openusb_handle_t *handle );`

``void openusb_fini`(openusb_handle_t handle );`

## Parameters

`flags` - Not used in this release. Reserved.

`handle` - Application should pass a valid address and upon successful initialization of openusb_init, a openusb_handle will be returned in it. This hanlde will be used by all operations related with openusb instances.

## Description

Just like the name implies, the `openusb_init()` initialize a openusb instance and sets up some internal structures for that openusb instance. This function MUST be called before any other openusb functions. It will load OS dependent backend and call initialization function of that backend. It also scans for busses and devices on the system. Application should call `openusb_fini()` to destroy a openusb instance when it finishes. `openusb_fini()` will destroy internal structures associated with this instance. All handles associated with this instance become invalid after the call to `openusb_fini()`.

## Return Value

Upon successful initialization of a openusb instance, the `openusb_init()` function will return OPENUSB_SUCCESS. Otherwise, a failure will be returned.

OPENUSB_PLATFORM_FAILURE -- Unspecified kernel/driver failure.

OPENUSB_BADARG -- An invalid argument is passed in. handle is invalid

OPENUSB_NO_RESOURCES -- Memory allocation failure.

## See Also

# `openusb_set_debug`

## Name

`openusb_set_debug` -- Set debug information

## Synopsis

``void openusb_set_debug`(openusb_handle_t *handle , uint32_t level , uint32_t flags , openusb_debug_callback_t callback );`

## Parameters

`handle` - An openusb instance handle, obtained in `openusb_init`.

`level` - Not used. Reserved.

`flags` - Not used in this release. Reserved.

`callback` - Application supplied debug routine.

## Description

Application can call `openusb_set_debug()` to enable tracing of openusb with increasing level of detail. callback is application defined debug function. If it is NULL, the library embedded debug function is used and debug messages, if any and debug level set properly, will go to stderr.

This operation will override the `USB_DEBUG` environment variable, if set.

## Return Value

None

## See Also

`openusb_init, openusb_fini`

# `openusb_set_event_callback, openusb_coldplug_callbacks_done`

## Name

`openusb_set_event_callback, openusb_coldplug_callbacks_done` -- Set event callbacks or Waiting for coldplug events completion

## Synopsis

``int32_t openusb_set_event_callback`(openusb_handle_t handle , openusb_event_t type , openusb_event_callback_t callback , void *arg );`

``void openusb_coldplug_callbacks_done`(openusb_handle_t handle);`

## Parameters

`handle` - An openusb instance handle, obtained in `openusb_init`.

`type` - Event type.

`callback` - Pointer to callback function.

`arg` - Arguments passed to `callback`

## Description

Application can call `openusb_set_event_callback()` to register with openusb for events and corresponding callbacks. When these events occur, the `callback` will be called with `arg`, if any, as the parameter.

The supported events type:

              typedef enum openusb_event {
                    USB_ATTACH = 0,     /* attachment of device */
                    USB_REMOVE,         /* detachment of device */
                    USB_SUSPEND,        /* device suspend */
                    USB_RESUME,         /* device resume */
                    USB_HC_ATTACH,      /* host controller attachment */
                    USB_HC_REMOVE,      /* host controller detachment */
                    USB_COLDPLUG_COMPLETED, /* first scan of device completed */
              } openusb_event_t;

openusb_event_callback_t has this prototype:

              typedef void    (*openusb_event_callback_t)(openusb_handle_t handle,
                  openusb_devid_t devid, openusb_event_t event, void *arg);

Application can call openusb_coldplug_callbacks_done() to block execution until end of coldplug events.

## Return Value

`openusb_set_event_callback` returns 0 if succeed. Otherwise, a openusb error will be returned.

OPENUSB_SUCCESS - Callback was successfully set.

OPENUSB_BADARG - Invalid arguments, either invalid type or callback.

OPENUSB_INVALID_HANDLE - Invalid handle.

OPENUSB_NO_RESOURCES - Memory allocation failure.

## See Also

`openusb_init, openusb_fini`

# `openusb_set_default_timeout`

## Name

`openusb_set_default_timeout` -- Set default timeout for USB transfer

## Synopsis

``int32_t openusb_set_default_timeout`(openusb_handle_t handle , openusb_transfer_type_t type , uint32_t timeout );`

## Parameters

`handle` - An openusb instance handle, obtained in `openusb_init`.

`type` - Transfer type.

`timeout` - Timeout value, in millisecond unit.

## Description

Application can call `openusb_set_default_timeout()` to set default timeout for individual transfer type. `timeout` = 0 represents infinite timeout value. OpenUSB supported transfer types are:

              typedef enum openusb_transfer_type {
                USB_TYPE_ALL = 0,
                USB_TYPE_CONTROL,
                USB_TYPE_INTERRUPT,
                USB_TYPE_BULK,
                USB_TYPE_ISOCHRONOUS,
              } openusb_transfer_type_t;

## Return Value

OPENUSB_SUCCESS - New timeout was successfully set.

OPENUSB_INVALID_HANDLE - Invalid openusb handle.

OPENUSB_BADARG - Invalid argument. Type is not a valid transfer type.

## See Also

`openusb_init, openusb_fini`

# Chapter 7. Bus and Device Operations

This group of functions deal with the bus and device. Bus operations allows application to scan busses on a system. Device operations allows application to search for specific device, open and close those devices as well standard USB operations like setting the configuration, alternate settings, clearing halts and resetting the device. It also provides OS level operations such as claiming and releasing interfaces.

# `openusb_get_busid_list, openusb_free_busid_list`

## Name

`openusb_get_busid_list, openusb_free_busid_list` -- Return all busids in the system, Free returned busids

## Synopsis

``uint32_t openusb_get_busid_list`(openusb_handle_t handle , openusb_busid_t **busids , uint32_t *num_busids );`

``void openusb_free_busid_list`(openusb_busid_t * busids);`

## Parameters

`handle` - An openusb instance handle, obtained in `openusb_init`.

`busids` - Pointer to address of the busid list.

`num_busids` - Number of bus ids in the list.

## Description

`openusb_get_busid_list()` returns all the ids of busses in a system. The busids are used by other openusb functions to search and match specific devices that an application will operate on. `openusb_free_busid_list()` frees the busids returned in `openusb_get_busid_list()`.

## Return Value

`openusb_get_busid_list` may have the following return values,

OPENUSB_SUCCESS - Callback was successfully set.

OPENUSB_BADARG - Invalid argument. busids or num_busids is NULL. Or, (*busids) is NOT null, otherwise it will cause memory leak..

OPENUSB_INVALID_HANDLE - Invalid handle.

OPENUSB_NULL_LIST - The busids list is empty.

OPENUSB_NO_RESOURCES - Memory allocation failure.

## See Also

`openusb_init, openusb_fini`

# `openusb_get_devids_by_bus, openusb_get_devids_by_vendor, openusb_get_devids_by_class, openusb_free_devid_list`

## Name

`openusb_get_devids_by_bus, openusb_get_devids_by_vendor, openusb_get_devids_by_class, openusb_free_devid_list` -- Return all devids matching a pattern, Free returned devids

## Synopsis

``uint32_t openusb_get_devids_by_bus`(openusb_handle_t handle , openusb_busid_t busid , openusb_devid_t **devids , uint32_t *num_devids );`

``uint32_t openusb_get_devids_by_vendor`(openusb_handle_t handle , int32_t vendor , int32_t product , openusb_devid_t **devids , uint32_t *num_devids );`

``uint32_t openusb_get_devids_by_class`(openusb_handle_t handle , int16_t devclass, int16_t subclass, int16_t protocol, openusb_devid_t **devids , uint32_t *num_devids );`

``void openusb_free_devid_list`(openusb_devid_t * devids);`

## Parameters

`handle` - Libusb handle returned in openusb_init().

`busid` - Which bus (0 for all busses).

`devids` - Pointer to address of the devid list, allocated by openusb.

`num_devids` - Number of device ids by this search/match.

`vendor` - Vendor ID (0 - 0xFFFF, -1 for all).

`product` - Product ID (0 - 0xFFFF, -1 for all).

`class` - Class (0 - 0xFF, -1 for all).

`subclass` - Subclass (0 - 0xFF, -1 for all).

`protocol` - Protocol (0 - 0xFF, -1 for all).

## Description

These functions are used to get/free device IDs of those devices that an application is interested in. Application depends on these devids to do any other operation on a device. For example, when application wants to transfer data to a device, it has to specify the devid got here to call corresponding openusb functions to open.

`openusb_get_devids_by_bus()` returns all the ids of devices on a bus. If `busid` is 0, it will return all `devids` in the system. The returned devids are stored in `devids`. The number of devids is in `num_devids` .

`openusb_get_devids_by_vendor()` returns all devids of devices that match specific VID and PID. If `vendor` = -1, it will match any vendor's device. If `product` = -1, it will match any devices of a vendor. If both are -1, it will match any devices of any vendor.

`openusb_get_devids_by_class()` returns all devids of devices that match specific `class, subclass or protocol`. This function first uses application supplied class, subclass and protocol to match their counterpart in Device Descriptor of a device. If they don't match, then this function will try to match class, subclass and protocol to their counterparts in invidual Interface Descriptors of a device. If an argument is -1, it means to match any class, subclass or protocol.

`openusb_free_devid_list()` frees `devids` returned in above interfaces.

## Return Value

openusb_get_devids_by_bus(), openusb_get_devids_by_vendor(), openusb_get_devids_by_class() may have the following return values:

OPENUSB_SUCCESS - Success.

OPENUSB_NO_RESOURCES - Memory allocation failure.

OPENUSB_BADARG - Invalid argument. devids or num_devids is NULL; busid is invalid; vendor or product is out of range; class, subclass or product is out of range.

OPENUSB_NULL_LIST - The devids list is empty.

OPENUSB_INVALID_HANDLE - Libusb handle is invalid.

## See Also

`openusb_init, openusb_fini`

# `openusb_get_device_data,openusb_free_device_data`

## Name

`openusb_get_device_data,openusb_free_device_data` -- Get a device's data, Free the device data

## Synopsis

``int32_t openusb_get_device_data`(openusb_handle_t handle , openusb_devid_t devid , uint32_t flags , openusb_dev_data_t **data);`

``void openusb_free_device_data`(openusb_dev_data_t *data);`

## Parameters

`handle` - Libusb handle.

`devid` - Device's devid.

`flags` - Reserved.

`data` - Data returned by openusb of type openusb_dev_data_t

## Description

`openusb_get_device_data()` will return data of the specified device. Application doesn't have to open the device before calling this function.The data is stored in the openusb_dev_data_t structure, which has such members:

                openusb_busid_t          busid; /* busid of the bus this device is on */
                openusb_devid_t          devid; /* devid of this device */

                /* bus address of the bus the device is on */
                uint8_t                 bus_address;

                /* parent device id, 0 for root-hub */
                openusb_devid_t          pdevid;

                /* parent port the device is connected to */
                uint8_t                 pport;

                /* number of ports on the device, 0 for non-hub device */
                uint8_t                 nports;

                /* descriptive path such as /dev/bus/usb/xxx */
                char                    *sys_path;

                /* topological path such as 1.2.1 */
                char                    *bus_path;

                usb_device_desc_t       dev_desc; /* device descriptor */
                usb_config_desc_t       cfg_desc; /* configuration descriptors */

                /* raw configuration desc cloud */
                uint8_t                 *raw_cfg_desc;

                /* string descriptors with the first langid */
                usb_string_desc_t       *manufacturer;
                usb_string_desc_t       *product;
                usb_string_desc_t       *serialnumber;

                /* max transfer size for each request, 0 if not supported */
                uint32_t                ctrl_max_xfer_size;
                uint32_t                intr_max_xfer_size;
                uint32_t                bulk_max_xfer_size;
                uint32_t                isoc_max_xfer_size;

Application should call `openusb_free_device_data` to free memory space allocated in `openusb_get_device_data`.

## Return Value

`openusb_get_device_data()` may have such return values:

OPENUSB_SUCCESS - Success.

OPENUSB_NO_RESOURCES - Memory allocation failure.

OPENUSB_UNKNOWN_DEVICE - Can't find the device specified by `devid`.

OPENUSB_PARSE_ERROR - Libusb fails to get device, configuration or string descriptors of this device.

OPENUSB_INVALID_HANDLE - Libusb handle is invalid.

## See Also

`openusb_init, openusb_fini`

# `openusb_open_device,openusb_close_device`

## Name

`openusb_open_device,openusb_close_device` -- Open/Close a device

## Synopsis

``int32_t openusb_open_device`(openusb_handle_t handle , openusb_devid_t devid , uint32_t flags , openusb_dev_handle_t *dev);`

``int32_t openusb_close_device`(openusb_dev_handle_t dev);`

## Parameters

`handle` - Libusb handle.

`devid` - Device's devid.

`flags` - Initialization flag.

`dev` - Device handle

## Description

`openusb_open_device` prepares a device and sets up internal data structures for use by openusb. `openusb_close_device` returns the opened device to its original state.

Application must call `openusb_open_device()` to open a device before it can do any USB transfers on that device. The open `flags` can be:

               USB_INIT_DEFAULT		default behavior

               USB_INIT_FAIL_FAST		fail if not immediately available

               USB_INIT_REVERSIBLE	try platform dependent things that are
                                        guaranteed to be reversed on close

               USB_INIT_NON_REVERSIBLE	try advanced platform dependent things that may
                                        not be guaranteed to be reversible on close

Upon successful open of a device, the device handle is returned in `dev`. All device associated operations will use this handle.

`openusb_close_device()` will destroy some internal data structures associated with the device handle `dev`.

## Return Value

OPENUSB_SUCCESS - Success.

OPENUSB_NO_RESOURCES - Memory allocation failure.

OPENUSB_UNKNOWN_DEVICE - Can't find the device specified by `devid`.

OPENUSB_SYS_FUNC_FAILURE - System function fails.

OPENUSB_INVALID_HANDLE - Libusb `handle` is invalid.

OPENUSB_PLATFORM_FAILURE - Unspecified kernel/driver failure.

OPENUSB_IO_* - USB host controller errors

## See Also

`openusb_init, openusb_fini`

# `openusb_get_devid`

## Name

`openusb_get_devid` -- Extract device ID from a device handle

## Synopsis

``int32_t openusb_get_devid`(openusb_dev_handle_t dev, openusb_devid_t * devid);`

## Parameters

`dev` - Device handle.

`devid` - Address stored the returned devid value.

## Description

`openusb_get_devid()` gets the device ID of which the device handle is dev.

## Return Value

`openusb_get_devid()` returns 0 on success. Otherwise, a openusb error is returned.

OPENUSB_SUCCESS - No errors.

OPENUSB_UNKNOWN_DEVICE - Device handle `dev` is not valid

OPENUSB_BADARG - `Devid` address is not valid

## See Also

# `openusb_get_lib_handle`

## Name

`openusb_get_lib_handle` -- Extract openusb handle from a device handle

## Synopsis

``int32_t openusb_get_lib_handle`(openusb_dev_handle_t dev, openusb_handle_t * lib_handle);`

## Parameters

`dev` - Device handle.

`lib_handle` - Address to store returned openusb handle

## Description

`openusb_get_lib_handle()` gets the openusb handle of the device whose device handle is `dev`.

## Return Value

`openusb_get_devid()` returns 0 on success. Otherwise, a openusb error is returned.

OPENUSB_SUCCESS - No errors.

OPENUSB_UNKNOWN_DEVICE - Device handle `dev`is not valid.

OPENUSB_BADARG - `lib_handle` is an invalid address

## See Also

# `openusb_get_max_xfer_size`

## Name

`openusb_get_max_xfer_size` -- Get the maximum data transfer size per request based on the bus and type

## Synopsis

``int32_t openusb_get_max_xfer_size`(openusb_handle_t handle, openusb_busid_t bus, openusb_transfer_type_t type, uint32_t * bytes);`

## Parameters

`handle` - Libusb handle.

`bus` - Bus ID.

`type` - Transfer type.

`bytes` - Max allowed size.

## Description

`openusb_get_max_xfer_size()` gets the maximum transfer size that can be specified in openusb_request based on the which bus the target device is on and the desired transfer type. The size value is returned in `bytes`.

## Return Value

`openusb_get_max_xfer_size()` returns OPENUSB_SUCCESS on success. Otherwise, a openusb error is returned.

OPENUSB_SUCCESS - No errors.

OPENUSB_INVALID_HANDLE - Invalid openusb handle.

OPENUSB_UNKNOWN_DEVICE - Bus id`bus` is not valid

OPENUSB_BADARG - `type` is not valid or `bytes` is NULL.

OPENUSB_NOT_SUPPORTED - Operation is not supported.

## See Also

# `openusb_get_configuration, openusb_set_configuration`

## Name

`openusb_get_configuration, openusb_set_configuration` -- Get the current bConfigurationValue of a device, Set a device's bConfigurationValue

## Synopsis

``int32_t openusb_get_configuration`(openusb_dev_handle_t dev, uint8_t* cfg);`

``int32_topenusb_set_configuration`(openusb_dev_handle_t dev, uint8_t cfg);`

## Parameters

`dev` - Device handle.

`cfg` - Configuration value.

## Description

`openusb_get_configuration()` gets the current active configuration value of the device specified by dev. The bConfigurationValue is returned in `cfg`.

`openusb_set_configuration`() sets a device's bConfigurationValue to `cfg`.

## Return Value

`openusb_get_configuration`() or `openusb_set_configuration`() returns 0 on success. Otherwise, a openusb error is returned.

OPENUSB_SUCCESS No errors.

OPENUSB_BADARG `cfg` is an invalid address for openusb_get_configuration(), or not a valid bConfigurationValue for openusb_set_configuration()

OPENUSB_UNKNOWN_DEVICE Device handle is not valid

## See Also

# `openusb_claim_interface, openusb_release_interface, openusb_is_interface_claimed`

## Name

`openusb_claim_interface, openusb_release_interface, openusb_is_interface_claimed` -- Claim interface exclusively, Release an interface, Check if an interface has been claimed

## Synopsis

``int32_t openusb_claim_interface`(openusb_dev_handle_t dev, uint8_t ifc, openusb_init_flag_t flags);`

``int32_topenusb_release_interface`(openusb_dev_handle_t dev, uint8_t ifc);`

``int32_topenusb_is_interface_claimed`(openusb_dev_handle_t dev, uint8_t ifc);`

## Parameters

`dev` - Device handle.

`ifc` - Interface number.

`flags` - Claiming flags.

## Description

`openusb_claim_interface()` claims an interface of device `dev`. See `openusb_open_device` for the meaning of `flags`. Application must call `openusb_claim_interface`() before it further operates on an interface.

`openusb_release_interface`() releases a claimed interface `ifc`.

`openusb_is_interface_claimed` returns if the interface `ifc` has been claimed.

## Return Value

`openusb_claim_interface`() or `openusb_release_interface`() returns 0 on success. `openusb_is_interface_claimed` returns 0 if not claimed and 1 if already claimed. Otherwise, a openusb error is returned.

OPENUSB_SUCCESS No errors.

OPENUSB_BADARG `ifc` is not valid.

OPENUSB_UNKNOWN_DEVICE Device handle is not valid

OPENUSB_BUSY The interface `ifc` has already been claimed.

## See Also

`openusb_open_device,openusb_close_device`

# `openusb_get_altsetting,openusb_set_altsetting`

## Name

`openusb_get_altsetting,openusb_set_altsetting` -- Get alternate setting number, Set alternate setting

## Synopsis

``int32_t openusb_get_altsetting`(openusb_dev_handle_t dev, uint8_t ifc, openusb_init_flag_t* alt);`

``int32_topenusb_set_altsetting`(openusb_dev_handle_t dev, uint8_t ifc, uint8_t alt);`

## Parameters

`dev` - Device handle.

`ifc` - Interface number.

`alt` - Alternate setting number

## Description

`openusb_get_altsetting()` get the current alternate setting number of interface `ifc`. The alternate number is returned in `alt`.

`openusb_set_altsetting()` sets the active alternate setting of the interface `ifc`. Application should call this function to set proper alternate setting of an interface before doing data transfer on endpoints in that setting.

## Return Value

`openusb_get_altsetting`(), `openusb_set_altsetting`() returns 0 on success. Otherwise, a openusb error is returned.

OPENUSB_SUCCESS No errors.

OPENUSB_BADARG `ifc` or `alt` is not valid.

OPENUSB_UNKNOWN_DEVICE Device handle is not valid

OPENUSB_PLATFORM_FAILURE Unspecified kernel/driver failure

OPENUSB_BUSY The interface `ifc` has already been claimed.

## See Also

`openusb_claim_interface, openusb_release_interface, openusb_is_interface_claimed`

# `openusb_reset`

## Name

`openusb_reset` -- Reset device

## Synopsis

``int32_t openusb_reset`(openusb_dev_handle_t dev);`

## Parameters

`dev` - Device handle.

## Description

`openusb_reset()` resets a device by resetting its port. The full reset of a device is not guaranteed.

## Return Value

`openusb_get_devid()` returns 0 on success. Otherwise, a openusb error is returned.

OPENUSB_SUCCESS No errors.

OPENUSB_UNKNOWN_DEVICE Device handle is not valid

OPENUSB_NOT_SUPPORTED Device reset is not supported.

OPENUSB_IO_* USB host controller errors

## See Also

# Chapter 8. Device Descriptor Parsers

This group of functions are helpers to get and parse kinds of USB descriptors.

# `openusb_get_raw_desc, openusb_free_raw_desc, openusb_parse_device_desc, openusb_parse_config_desc, openusb_parse_interface_desc, openusb_parse_endpoint_desc`

## Name

`openusb_get_raw_desc, openusb_free_raw_desc, openusb_parse_device_desc, openusb_parse_config_desc, openusb_parse_interface_desc, openusb_parse_endpoint_desc` -- Get/Free raw device descriptors; Get cooked Device, Configuration, Interface, Endpoint descriptors

## Synopsis

``int32_t openusb_get_raw_desc`(openusb_handle_t handle, openusb_devid_t devid, uint8_t type, uint8_t descidx, uint16_t langid, uint8_t **buffer, uint16_t *buflen);`

``int32_t openusb_parse_device_desc`(openusb_handle_t handle, openusb_devid_t devid, uint8_t *buffer, uint16_t buflen, usb_device_desc_t *devdesc);`

``int32_t openusb_parse_config_desc`(openusb_handle_t handle, openusb_devid_t devid, uint8_t *buffer, uint16_t buflen, uint8_t cfgidx, usb_config_desc_t *cfgdesc);`

``int32_t openusb_parse_interface_desc`(openusb_handle_t handle, openusb_devid_t devid, uint8_t *buffer, uint16_t buflen, uint8_t cfgidx, uint8_t ifcidx, uint8_t alt, usb_interface_desc_t *ifcdesc);`

``int32_t openusb_parse_endpoint_desc`(openusb_handle_t handle, openusb_devid_t devid, uint8_t *buffer, uint16_t buflen, uint8_t cfgidx, uint8_t ifcidx, uint8_t alt, uint8_t eptidx, usb_endpoint_desc_t *eptdesc);`

``void openusb_free_raw_desc`(uint8_t *buffer);`

## Parameters

`handle` Libusb handle.

`devid` Device's devid.

`type` Descriptor type.

`descidx` Index for config/string descriptor, zero for others

`langid` Language ID for string descriptor, zero for others

`buffer` Data buffer of raw descriptors data.

`buflen` Length of raw descriptors.

`devdesc` Pointer to device descriptor.

`cfgidx` Configuration descriptor index.

`cfgdesc` Pointer to configuration descriptor.

`ifcidx` Interface index.

`alt` Alternate setting number.

`ifcdesc` Pointer to interface descriptor.

`eptidx` Endpoint index.

`eptdesc` Pointer to endpoint descriptor.

## Description

`openusb_get_raw_desc()` will return raw descriptors of `type, descidx and langid` which an application specifies on calling this function. The raw descriptor is returned in `buffer` and length of it is in `buflen`.

Application should call `openusb_free_raw_desc()` to free descriptor memory if it has called `openusb_get_raw_desc()`.

`openusb_parse_device_desc()` returns the cooked device descriptors of the specified `devid`.

`openusb_parse_config_desc()` returns the cooked configuration descriptor of specified `devid` and `cfgidx`.

`openusb_parse_interface_desc()` returns the cooked interface descriptor of number alt alternate setting of interface `ifcidx` in configuration `cfgidx`.

`openusb_parse_endpoint_desc()` returns an endpoint's descriptor of which is in alternate setting `alt` of interface `ifcidx` in configuration `cfgidx`.

For `openusb_parse_device_desc(), openusb_parse_config_desc(), openusb_parse_interface_desc() and openusb_parse_endpoint_desc()`, application can use the raw descriptor buffer got through `openusb_get_raw_desc()`. If application pass a NULL buffer pointer, these four openusb functions will call `openusb_get_raw_desc()` internally and return the cooked descriptors.

## Return Values

OPENUSB_SUCCESS Success.

OPENUSB_UNKNOWN_DEVICE Can't find the device specified by devid.

OPENUSB_INVALID_HANDLE Invalid openusb handle.

OPENUSB_NO_RESOURCES Memory allocation failure.

OPENUSB_PARSE_ERROR Fail to parse descriptors.

OPENUSB_PLATFORM_FAILURE Kernel/driver failure.

OPENUSB_BADARG Invalid arguments. devdesc, cfgdesc, ifcdesc or eptdesc is NULL. buflen is invalid if buffer is not NULL.

## See Also

# `openusb_parse_data`

## Name

`openusb_parse_data` -- Unpack arbitrary little endian raw data

## Synopsis

``void openusb_parse_data`(char *format, uint8_t *data, uint32_t datalen, void *structure, uint32_t structlen, uint32_t *count);`

## Parameters

`format` A character string indicating the format that application requires. Character 'b' represents one byte, 'w' for word and 'd' for dword(4 bytes). Specially, character '.' indicates skipping one byte of source data.

`data` Little endian raw data that will be parsed.

`datalen` Length of data.

`structure` Address of the returned structure where the unpacked data will be stored

`structlen` Length of structure.

`count` Number of bytes parsed.

## Description

`openusb_parse_data()` can parse little endian raw data and convert it to structured data. It's basically used to parse USB descriptors.

For exampe, to parse a descriptor such as:

        	struct test_descr {
        		uint8_t		a;
        		uint16_t	b;
        		uint8_t		c;
        		uint32_t	d;
        	};

The application would call:

            	rv = openusb_parse_data("bwbd", buffer, sizeof (buffer), (void *)&descr,
        		sizeof (descr), &count);

## Return Value

OPENUSB_SUCCESS - Parse data successfully.

OPENUSB_PARSE_ERROR - Error happened during parsing.

OPENUSB_BADARG - Invalid argument. `Format, data, structure or count` is NULL pointer.

## See Also

# Chapter 9. USB Data Transfer

Functions in this group are used to transfer USB data. OpenUSB implements transfer APIs, including synchronous and asynchronous, defined in openusb 1.0 interface. The synchronous means when such API is used, it will block until a transfer request is accomplished or timeout. The asynchronous means such interface will returns immediately no matter success or failure. Application can use callback mechanism or other openusb 1.0 interface to check asynchronous request.

# `openusb_xfer_wait, openusb_xfer_aio`

## Name

`openusb_xfer_wait, openusb_xfer_aio` -- Issue synchronous I/O request, Issue asynchronous I/O request

## Synopsis

``int32_t openusb_xfer_wait`(openusb_request_handle_t handle);`

``int32_topenusb_xfer_aio`(openusb_request_handle_t handle);`

## Parameters

`handle` - Pointer to request handle.

Elements in openusb_request_handle structure:

        	   openusb_dev_handle_t     dev; /* device handle */
        	   uint8_t                 interface;      /* ignored for ep0 */
        	   uint8_t                 endpoint;
        	   openusb_transfer_type_t  type; /* transfer type */

        	   union openusb_request {
        	       openusb_ctrl_request_t   *ctrl;
        	       openusb_intr_request_t   *intr;
        	       openusb_bulk_request_t   *bulk;
        	       openusb_isoc_request_t   *isoc;
        	   } req;

        	   int32_t (*cb)(struct openusb_request_handle *handle); /* callback of this request */
        	   void    *arg;   /* additional arg for callback */

## Description

`openusb_xfer_wait()` can be called by application to do synchronous USB transfers. Alternately, application can call `openusb_xfer_aio()` to do asynchronous USB transfer.

For both functions, application should allocate a request handle and fill required parameters in it. When application calls `openusb_xfer_wait()`, they don't have to set request callback. For `openusb_xfer_aio()`, if application wants to use `openusb_wait()` or `openusb_poll()` to get completed request, it must not set callback `cb` in the request handle. (In implementation of OpenUSB, if `cb` is not NULL, it will be called immediately after this request is accomplished. Otherwise, the completed request is put on a list for application to retrieve by using `openusb_wait/openusb_poll` )

## Return Value

`openusb_xfer_wait`(), `openusb_xfer_aio`() returns 0 on success. Otherwise, a openusb error is returned. NOTE, when an error happens, it just means submission of this request fails. The data status should be checked in `result` of individual request type.

OPENUSB_SUCCESS - No errors.

OPENUSB_BADARG - `handle` or elements in `handle` is not valid.

OPENUSB_UNKNOWN_DEVICE - Device handle `dev` is not valid.

OPENUSB_PLATFORM_FAILURE - Unspecified kernel/driver failure.

OPENUSB_NO_RESOURCES - Memory allocation failure.

OPENUSB_IO_* - USB host controller errors.

## See Also

`openusb_wait, openusb_poll`

# `openusb_ctrl_xfer, openusb_intr_xfer, openusb_bulk_xfer, openusb_isoc_xfer`

## Name

`openusb_ctrl_xfer, openusb_intr_xfer, openusb_bulk_xfer, openusb_isoc_xfer` -- Issue synchronous Control, Interrupt, Bulk, Isochronous request

## Synopsis

``int32_t openusb_ctrl_xfer`(openusb_dev_handle_t dev, uint8_t ifc, uint8_t ept, openusb_ctrl_request_t *ctrl);`

``int32_t openusb_intr_xfer`(openusb_dev_handle_t dev, uint8_t ifc, uint8_t ept, openusb_intr_request_t *intr);`

``int32_t openusb_bulk_xfer`(openusb_dev_handle_t dev, uint8_t ifc, uint8_t ept, openusb_bulk_request_t *bulk);`

``int32_t openusb_isoc_xfer`(openusb_dev_handle_t dev, uint8_t ifc, uint8_t ept, openusb_isoc_request_t *isoc);`

## Parameters

`dev` - Device handle.

`ifc` - Interface number.

`ept` - Endpoint number.

`ctrl` - Control request set by application.

`intr` - Interrupt request set by application.

`bulk` - Bulk request set by application.

`isoc` - Isochronous request set by application.

## Description

`openusb_ctrl_xfer()` is used to do synchronous USB CONTROL transfers. Application should allocate and fill a openusb_ctrl_request:

            struct openusb_ctrl_request {
        	    struct openusb_ctrl_setup {
        		    uint8_t         bmRequestType;
        		    uint8_t         bRequest;
        		    uint16_t        wValue;
        		    uint16_t        wIndex;

        		    /* wLength set automatically based on length */
        	    } setup;

        	    uint8_t                 *payload;
        	    uint32_t                length; /* platform endian */
        	    uint32_t                timeout;
        	    uint32_t                flags;
        	    openusb_request_result_t result;
        	    struct openusb_ctrl_request      *next;
            }

`openusb_intr_xfer()` is used to do synchronous USB INTERRUPT transfers. Application should allocate and fill a openusb_intr_request:

            struct openusb_intr_request {
            	uint16_t                interval;       /* may not work on some OS */
            	uint8_t                 *payload;
            	uint32_t                length;
            	uint32_t                timeout;
            	uint32_t                flags;
            	openusb_request_result_t result;
            	struct openusb_intr_request      *next;
            }

`openusb_bulk_xfer()` is used to do synchronous USB BULK transfers. Application should allocate and fill a openusb_bulk_request:

            struct openusb_bulk_request {
        	    uint8_t                 *payload;
        	    uint32_t                length;
        	    uint32_t                timeout;
        	    uint32_t                flags;
        	    openusb_request_result_t result;
        	    struct openusb_bulk_request      *next;
            }

`openusb_isoc_xfer()` is used to do synchronous USB ISOCHRONOUS transfers. Application should allocate and fill a openusb_isoc_request:

            typedef struct openusb_isoc_pkts {
        	    uint32_t                num_packets;
        	    struct openusb_isoc_packet {
        		    uint8_t         *payload;
        		    uint32_t        length;
        	    } *packets;
            } openusb_isoc_pkts_t;

            struct openusb_isoc_request {
        	    uint32_t                start_frame;
        	    uint32_t                flags;
        	    openusb_isoc_pkts_t      pkts;

        	    /* pointer to isoc result array */
        	    openusb_request_result_t *isoc_results;

        	    /* overall isoc transfer completion status */
        	    int32_t                 isoc_status;

        	    struct openusb_isoc_request      *next;
            }

For `openusb_ctrl_xfer, openusb_intr_xfer and openusb_bulk_xfer`, the request status is returned in `openusb_request_result`. Application may get transfer status and length of its last request. For `openusb_isoc_xfer()`, every packet in the isoc request has a corresponding `result`, application can check individual packet status from the `isoc_results`. Application must allocate enough number of `isoc_results` for openusb to fill the status.

openusb_request_result_t has the following elements:

        	   int32_t                 status;
        	   uint32_t                transferred_bytes;

## Return Value

`openusb_ctrl_xfer`, `openusb_intr_xfer, openusb_bulk_xfer and openusb_isoc_xfer` () returns 0 on success. Otherwise, a openusb error is returned. NOTE, when there's no error, it just means submission of this request succeed. Even if these functions didn't return failure, the data transfer may still have error and such kind of failure is reflected in in `result` of individual request.

OPENUSB_SUCCESS No errors.

OPENUSB_BADARG `handle` or elements in `handle` is not valid.

OPENUSB_UNKNOWN_DEVICE Device handle `dev` is not valid

OPENUSB_PLATFORM_FAILURE Unspecified kernel/driver failure

OPENUSB_NO_RESOURCES Memory allocation failure

OPENUSB_IO_* USB host controller errors

## See Also

# `openusb_abort`

## Name

`openusb_abort` -- Abort previous I/O request

## Synopsis

``int32_t openusb_abort`(openusb_request_handle_t handle);`

## Parameters

`handle` - Request handle.

## Description

`openusb_abort()` is used to abort an I/O request submitted previously by `openusb_xfer_wait/openusb_xfer_aio`.

## Return Value

`openusb_abort` returns 0 on success. Otherwise, a openusb error is returned.

OPENUSB_SUCCESS No errors.

OPENUSB_INVALID_HANDLE `handle` is not valid.

OPENUSB_NO_RESOURCES Memory allocation failure.

OPENUSB_IO_* USB host controller errors.

## See Also

# `openusb_wait, openusb_poll`

## Name

`openusb_wait, openusb_poll` -- Wait for I/O request completion, Poll completion status of I/O request

## Synopsis

``int32_t openusb_wait`(uint32_t num_reqs, openusb_request_handle_t* handles, openusb_request_handle_t* handle);`

``int32_topenusb_poll`(uint32_t num_reqs, openusb_request_handle_t* handles, openusb_request_handle_t* handle);`

## Parameters

`num_reqs` Number of requests to wait/poll.

`handles` Array of request handles to wait/poll.

`handle` Completed request handle.

## Description

`openusb_wait()` can be called to wait for completion on `num_reqs` of request handles. If one request was completed, `openusb_wait` will return its handle in `handle`. Otherwise, `openusb_wait` will block until one request gets completed.

`openusb_poll()` is different from `openusb_wait`. It checks if any request in `handles` has been completed. If there's one, `openusb_poll` will return this request's handle in `handle`. Otherwise, it returns immediately with `handle` set to NULL. No block at all.

For both functions, caller should allocate an array of `num_reqs` elements for `handles` and set every element to the request handles to be checked.

If application has set callback in request when submitting it in `openusb_xfer_aio` , it should NOT call the above functions to wait/poll that request.

## Return Value

`openusb_wait`(), `openusb_poll`() returns 0 on success. Otherwise, a openusb error is returned.

OPENUSB_SUCCESS No errors.

OPENUSB_BADARG `handles` or `handle` is not valid. Either they are NULL or some member of request is invalid.

OPENUSB_UNKNOWN_DEVICE Can't find the device specified in request.

OPENUSB_PLATFORM_FAILURE Unspecified kernel/driver failure

OPENUSB_NO_RESOURCES Memory allocation failure

OPENUSB_IO_* USB host controller errors

## See Also

# `openusb_start, openusb_stop`

## Name

`openusb_start, openusb_stop` -- Start multi-xfer mode I/O; Stop multi-xfer mode I/O

## Synopsis

``int32_t openusb_start`(openusb_multi_request_handle_t handle);`

``int32_topenusb_stop`(openusb_multi_request_handle_t handle);`

## Parameters

`handle` Pointer to multi-xfer request handle.

## Description

These two functions are to be implemented by OpenUSB.

## Return Value

TBD

## See Also

# Chapter 10. Helper Utilities

Some handy functions.

# `openusb_strerror`

## Name

`openusb_strerror` -- Return english text corresponding to an error code

## Synopsis

``const char *openusb_strerror`(int32_t error );`

## Parameters

`error` - Error code.

## Description

`openusb_strerror()` returns a string of English text representing an error code `error`

## Return Value

A none NULL pointer to string

## See Also

# `openusb_cpu_to_le16,openusb_cpu_to_le32`

## Name

`openusb_cpu_to_le16,openusb_cpu_to_le32` -- Convert data from CPU endianess to Little Endian

## Synopsis

``uint16_t openusb_cpu_to_le16`(uint16_t data );`

``uint32_t openusb_cpu_to_le32`(uint32_t data );`

## Parameters

`data` - To be converted data.

## Description

`openusb_cpu_to_le16()` converts one word (2bytes) of data from byte order in CPU endian to Little Endian.

`openusb_cpu_to_le32` converts a Dword(4bytes) data from CPU byte order to little endian order.

## Return Value

The return value is converted data.

## See Also

# `openusb_le16_to_cpu,openusb_le32_to_cpu`

## Name

`openusb_le16_to_cpu,openusb_le32_to_cpu` -- Convert data from little endian to CPU byte order.

## Synopsis

``uint16_t openusb_le16_to_cpu`(uint16_t data );`

``uint32_t openusb_le32_to_cpu`(uint32_t data );`

## Parameters

`data` - To be converted data.

## Description

`openusb_le16_to_cpu()` converts one Word (2bytes) of data from little endian order to CPU byte order.

`openusb_cpu_to_le32` converts a Dword(4bytes) data from little endian order to CPU order.

## Return Value

The return value is converted data.

## See Also

# IV. Examples

This section is to provide some sample codes to demonstrate how to use OpenUSB interfaces.

To be provided

# Chapter 11. Other Applications

Another source of examples can be gleaned from other applications.

- TBD

- TBD