Global Namespace

// typedefs

typedef struct libusb_context libusb_context;
typedef struct libusb_device libusb_device;
typedef struct libusb_device_handle libusb_device_handle;
typedef void (*libusb_transfer_cb_fn)(struct libusb_transfer *transfer);

typedef void (*libusb_pollfd_added_cb)(
    int fd,
    short events,
    void *user_data
    );

typedef void (*libusb_pollfd_removed_cb)(
    int fd,
    void *user_data
    );

typedef int libusb_hotplug_callback_handle;

typedef int (*libusb_hotplug_callback_fn)(
    libusb_context *ctx,
    libusb_device *device,
    libusb_hotplug_event event,
    void *user_data
    );

// enums

enum libusb_bos_type;
enum libusb_capability;
enum libusb_class_code;
enum libusb_descriptor_type;
enum libusb_endpoint_direction;
enum libusb_error;
enum libusb_hotplug_event;
enum libusb_hotplug_flag;
enum libusb_iso_sync_type;
enum libusb_iso_usage_type;
enum libusb_log_level;
enum libusb_request_recipient;
enum libusb_request_type;
enum libusb_speed;
enum libusb_ss_usb_device_capability_attributes;
enum libusb_standard_request;
enum libusb_supported_speed;
enum libusb_transfer_flags;
enum libusb_transfer_status;
enum libusb_transfer_type;
enum libusb_usb_2_0_extension_attributes;

// structs

struct libusb_bos_descriptor;
struct libusb_bos_dev_capability_descriptor;
struct libusb_config_descriptor;
struct libusb_container_id_descriptor;
struct libusb_control_setup;
struct libusb_device_descriptor;
struct libusb_endpoint_descriptor;
struct libusb_interface;
struct libusb_interface_descriptor;
struct libusb_iso_packet_descriptor;
struct libusb_pollfd;
struct libusb_ss_endpoint_companion_descriptor;
struct libusb_ss_usb_device_capability_descriptor;
struct libusb_transfer;
struct libusb_usb_2_0_extension_descriptor;
struct libusb_version;

// global variables

struct libusb_context* usbi_default_context = NULL;
static const struct libusb_version libusb_version_internal =    { LIBUSB_MAJOR, LIBUSB_MINOR, LIBUSB_MICRO, LIBUSB_NANO,      LIBUSB_RC, "http://libusb.info" };
static int default_context_refcnt = 0;
static usbi_mutex_static_t default_context_lock = USBI_MUTEX_INITIALIZER;
static struct timeval timestamp_origin = { 0, 0 };
usbi_mutex_static_t active_contexts_lock = USBI_MUTEX_INITIALIZER;
struct list_head active_contexts_list;
static size_t usbi_locale = 0;
static const char* usbi_locale_supported[] = { "en", "nl", "fr", "ru" };
static const char* usbi_localized_errors[ARRAYSIZE(usbi_locale_supported)][LIBUSB_ERROR_COUNT];

// global functions

static
struct discovered_devs*
discovered_devs_alloc(void);

static
void
discovered_devs_free(struct discovered_devs* discdevs);

struct discovered_devs*
discovered_devs_append(
    struct discovered_devs* discdevs,
    struct libusb_device* dev
);

struct libusb_device*
usbi_alloc_device(
    struct libusb_context* ctx,
    unsigned long session_id
);

void
usbi_connect_device(struct libusb_device* dev);

void
usbi_disconnect_device(struct libusb_device* dev);

int
usbi_sanitize_device(struct libusb_device* dev);

struct libusb_device*
usbi_get_device_by_session_id(
    struct libusb_context* ctx,
    unsigned long session_id
);

ssize_t
libusb_get_device_list(
    libusb_context* ctx,
    libusb_device*** list
);

void
libusb_free_device_list(
    libusb_device** list,
    int unref_devices
);

uint8_t
libusb_get_bus_number(libusb_device* dev);

uint8_t
libusb_get_port_number(libusb_device* dev);

int
libusb_get_port_numbers(
    libusb_device* dev,
    uint8_t* port_numbers,
    int port_numbers_len
);

int
libusb_get_port_path(
    libusb_context* ctx,
    libusb_device* dev,
    uint8_t* port_numbers,
    uint8_t port_numbers_len
);

libusb_device*
libusb_get_parent(libusb_device* dev);

uint8_t
libusb_get_device_address(libusb_device* dev);

int
libusb_get_device_speed(libusb_device* dev);

static
const struct libusb_endpoint_descriptor*
find_endpoint(
    struct libusb_config_descriptor* config,
    unsigned char endpoint
);

int
libusb_get_max_packet_size(
    libusb_device* dev,
    unsigned char endpoint
);

int
libusb_get_max_iso_packet_size(
    libusb_device* dev,
    unsigned char endpoint
);

libusb_device*
libusb_ref_device(libusb_device* dev);

void
libusb_unref_device(libusb_device* dev);

int
usbi_signal_event(struct libusb_context* ctx);

int
usbi_clear_event(struct libusb_context* ctx);

int
libusb_open(
    libusb_device* dev,
    libusb_device_handle** dev_handle
);

libusb_device_handle*
libusb_open_device_with_vid_pid(
    libusb_context* ctx,
    uint16_t vendor_id,
    uint16_t product_id
);

static
void
do_close(
    struct libusb_context* ctx,
    struct libusb_device_handle* dev_handle
);

void
libusb_close(libusb_device_handle* dev_handle);

libusb_device*
libusb_get_device(libusb_device_handle* dev_handle);

int
libusb_get_configuration(
    libusb_device_handle* dev_handle,
    int* config
);

int
libusb_set_configuration(
    libusb_device_handle* dev_handle,
    int configuration
);

int
libusb_claim_interface(
    libusb_device_handle* dev_handle,
    int interface_number
);

int
libusb_release_interface(
    libusb_device_handle* dev_handle,
    int interface_number
);

int
libusb_set_interface_alt_setting(
    libusb_device_handle* dev_handle,
    int interface_number,
    int alternate_setting
);

int
libusb_clear_halt(
    libusb_device_handle* dev_handle,
    unsigned char endpoint
);

int
libusb_reset_device(libusb_device_handle* dev_handle);

int
libusb_alloc_streams(
    libusb_device_handle* dev_handle,
    uint32_t num_streams,
    unsigned char* endpoints,
    int num_endpoints
);

int
libusb_free_streams(
    libusb_device_handle* dev_handle,
    unsigned char* endpoints,
    int num_endpoints
);

unsigned char*
libusb_dev_mem_alloc(
    libusb_device_handle* dev_handle,
    size_t length
);

int
libusb_dev_mem_free(
    libusb_device_handle* dev_handle,
    unsigned char* buffer,
    size_t length
);

int
libusb_kernel_driver_active(
    libusb_device_handle* dev_handle,
    int interface_number
);

int
libusb_detach_kernel_driver(
    libusb_device_handle* dev_handle,
    int interface_number
);

int
libusb_attach_kernel_driver(
    libusb_device_handle* dev_handle,
    int interface_number
);

int
libusb_set_auto_detach_kernel_driver(
    libusb_device_handle* dev_handle,
    int enable
);

void
libusb_set_debug(
    libusb_context* ctx,
    int level
);

int
libusb_init(libusb_context** context);

void
libusb_exit(struct libusb_context* ctx);

int
libusb_has_capability(uint32_t capability);

static
void
usbi_log_str(
    struct libusb_context* ctx,
    enum libusb_log_level level,
    const char* str
);

void
usbi_log_v(
    struct libusb_context* ctx,
    enum libusb_log_level level,
    const char* function,
    const char* format,
    va_list args
);

void
usbi_log(
    struct libusb_context* ctx,
    enum libusb_log_level level,
    const char* function,
    const char* format,
    ...
);

const char*
libusb_error_name(int error_code);

const struct libusb_version*
libusb_get_version(void);

int
usbi_parse_descriptor(
    const unsigned char* source,
    const char* descriptor,
    void* dest,
    int host_endian
);

static
void
clear_endpoint(struct libusb_endpoint_descriptor* endpoint);

static
int
parse_endpoint(
    struct libusb_context* ctx,
    struct libusb_endpoint_descriptor* endpoint,
    unsigned char* buffer,
    int size,
    int host_endian
);

static
void
clear_interface(struct libusb_interface* usb_interface);

static
int
parse_interface(
    libusb_context* ctx,
    struct libusb_interface* usb_interface,
    unsigned char* buffer,
    int size,
    int host_endian
);

static
void
clear_configuration(struct libusb_config_descriptor* config);

static
int
parse_configuration(
    struct libusb_context* ctx,
    struct libusb_config_descriptor* config,
    unsigned char* buffer,
    int size,
    int host_endian
);

static
int
raw_desc_to_config(
    struct libusb_context* ctx,
    unsigned char* buf,
    int size,
    int host_endian,
    struct libusb_config_descriptor** config
);

int
usbi_device_cache_descriptor(libusb_device* dev);

int
libusb_get_device_descriptor(
    libusb_device* dev,
    struct libusb_device_descriptor* desc
);

int
libusb_get_active_config_descriptor(
    libusb_device* dev,
    struct libusb_config_descriptor** config
);

int
libusb_get_config_descriptor(
    libusb_device* dev,
    uint8_t config_index,
    struct libusb_config_descriptor** config
);

int
usbi_get_config_index_by_value(
    struct libusb_device* dev,
    uint8_t bConfigurationValue,
    int* idx
);

int
libusb_get_config_descriptor_by_value(
    libusb_device* dev,
    uint8_t bConfigurationValue,
    struct libusb_config_descriptor** config
);

void
libusb_free_config_descriptor(struct libusb_config_descriptor* config);

int
libusb_get_ss_endpoint_companion_descriptor(
    struct libusb_context* ctx,
    const struct libusb_endpoint_descriptor* endpoint,
    struct libusb_ss_endpoint_companion_descriptor** ep_comp
);

void
libusb_free_ss_endpoint_companion_descriptor(struct libusb_ss_endpoint_companion_descriptor* ep_comp);

static
int
parse_bos(
    struct libusb_context* ctx,
    struct libusb_bos_descriptor** bos,
    unsigned char* buffer,
    int size,
    int host_endian
);

int
libusb_get_bos_descriptor(
    libusb_device_handle* dev_handle,
    struct libusb_bos_descriptor** bos
);

void
libusb_free_bos_descriptor(struct libusb_bos_descriptor* bos);

int
libusb_get_usb_2_0_extension_descriptor(
    struct libusb_context* ctx,
    struct libusb_bos_dev_capability_descriptor* dev_cap,
    struct libusb_usb_2_0_extension_descriptor** usb_2_0_extension
);

void
libusb_free_usb_2_0_extension_descriptor(struct libusb_usb_2_0_extension_descriptor* usb_2_0_extension);

int
libusb_get_ss_usb_device_capability_descriptor(
    struct libusb_context* ctx,
    struct libusb_bos_dev_capability_descriptor* dev_cap,
    struct libusb_ss_usb_device_capability_descriptor** ss_usb_device_cap
);

void
libusb_free_ss_usb_device_capability_descriptor(struct libusb_ss_usb_device_capability_descriptor* ss_usb_device_cap);

int
libusb_get_container_id_descriptor(
    struct libusb_context* ctx,
    struct libusb_bos_dev_capability_descriptor* dev_cap,
    struct libusb_container_id_descriptor** container_id
);

void
libusb_free_container_id_descriptor(struct libusb_container_id_descriptor* container_id);

int
libusb_get_string_descriptor_ascii(
    libusb_device_handle* dev_handle,
    uint8_t desc_index,
    unsigned char* data,
    int length
);

static
int
usbi_hotplug_match_cb(
    struct libusb_context* ctx,
    struct libusb_device* dev,
    libusb_hotplug_event event,
    struct libusb_hotplug_callback* hotplug_cb
);

void
usbi_hotplug_match(
    struct libusb_context* ctx,
    struct libusb_device* dev,
    libusb_hotplug_event event
);

void
usbi_hotplug_notification(
    struct libusb_context* ctx,
    struct libusb_device* dev,
    libusb_hotplug_event event
);

int
libusb_hotplug_register_callback(
    libusb_context* ctx,
    libusb_hotplug_event events,
    libusb_hotplug_flag flags,
    int vendor_id,
    int product_id,
    int dev_class,
    libusb_hotplug_callback_fn cb_fn,
    void* user_data,
    libusb_hotplug_callback_handle* callback_handle
);

void
libusb_hotplug_deregister_callback(
    libusb_context* ctx,
    libusb_hotplug_callback_handle callback_handle
);

void
usbi_hotplug_deregister_all(struct libusb_context* ctx);

int
usbi_io_init(struct libusb_context* ctx);

void
usbi_io_exit(struct libusb_context* ctx);

static
int
calculate_timeout(struct usbi_transfer* transfer);

struct libusb_transfer*
libusb_alloc_transfer(int iso_packets);

void
libusb_free_transfer(struct libusb_transfer* transfer);

static
int
arm_timerfd_for_next_timeout(struct libusb_context* ctx);

static
int
add_to_flying_list(struct usbi_transfer* transfer);

static
int
remove_from_flying_list(struct usbi_transfer* transfer);

int
libusb_submit_transfer(struct libusb_transfer* transfer);

int
libusb_cancel_transfer(struct libusb_transfer* transfer);

void
libusb_transfer_set_stream_id(
    struct libusb_transfer* transfer,
    uint32_t stream_id
);

uint32_t
libusb_transfer_get_stream_id(struct libusb_transfer* transfer);

int
usbi_handle_transfer_completion(
    struct usbi_transfer* itransfer,
    enum libusb_transfer_status status
);

int
usbi_handle_transfer_cancellation(struct usbi_transfer* transfer);

void
usbi_signal_transfer_completion(struct usbi_transfer* transfer);

int
libusb_try_lock_events(libusb_context* ctx);

void
libusb_lock_events(libusb_context* ctx);

void
libusb_unlock_events(libusb_context* ctx);

int
libusb_event_handling_ok(libusb_context* ctx);

int
libusb_event_handler_active(libusb_context* ctx);

void
libusb_interrupt_event_handler(libusb_context* ctx);

void
libusb_lock_event_waiters(libusb_context* ctx);

void
libusb_unlock_event_waiters(libusb_context* ctx);

int
libusb_wait_for_event(
    libusb_context* ctx,
    struct timeval* tv
);

static
void
handle_timeout(struct usbi_transfer* itransfer);

static
int
handle_timeouts_locked(struct libusb_context* ctx);

static
int
handle_timeouts(struct libusb_context* ctx);

static
int
handle_events(
    struct libusb_context* ctx,
    struct timeval* tv
);

static
int
get_next_timeout(
    libusb_context* ctx,
    struct timeval* tv,
    struct timeval* out
);

int
libusb_handle_events_timeout_completed(
    libusb_context* ctx,
    struct timeval* tv,
    int* completed
);

int
libusb_handle_events_timeout(
    libusb_context* ctx,
    struct timeval* tv
);

int
libusb_handle_events(libusb_context* ctx);

int
libusb_handle_events_completed(
    libusb_context* ctx,
    int* completed
);

int
libusb_handle_events_locked(
    libusb_context* ctx,
    struct timeval* tv
);

int
libusb_pollfds_handle_timeouts(libusb_context* ctx);

int
libusb_get_next_timeout(
    libusb_context* ctx,
    struct timeval* tv
);

void
libusb_set_pollfd_notifiers(
    libusb_context* ctx,
    libusb_pollfd_added_cb added_cb,
    libusb_pollfd_removed_cb removed_cb,
    void* user_data
);

static
void
usbi_fd_notification(struct libusb_context* ctx);

int
usbi_add_pollfd(
    struct libusb_context* ctx,
    int fd,
    short events
);

void
usbi_remove_pollfd(
    struct libusb_context* ctx,
    int fd
);

const struct libusb_pollfd**
libusb_get_pollfds(libusb_context* ctx);

void
libusb_free_pollfds(const struct libusb_pollfd** pollfds);

void
usbi_handle_disconnect(struct libusb_device_handle* dev_handle);

static
uint16_t
libusb_cpu_to_le16(const uint16_t x);

int
libusb_setlocale(const char* locale);

const char*
libusb_strerror(enum libusb_error errcode);

static
unsigned char*
libusb_control_transfer_get_data(struct libusb_transfer* transfer);

static
struct libusb_control_setup*
libusb_control_transfer_get_setup(struct libusb_transfer* transfer);

static
void
libusb_fill_control_setup(
    unsigned char* buffer,
    uint8_t bmRequestType,
    uint8_t bRequest,
    uint16_t wValue,
    uint16_t wIndex,
    uint16_t wLength
);

static
void
libusb_fill_control_transfer(
    struct libusb_transfer* transfer,
    libusb_device_handle* dev_handle,
    unsigned char* buffer,
    libusb_transfer_cb_fn callback,
    void* user_data,
    unsigned int timeout
);

static
void
libusb_fill_bulk_transfer(
    struct libusb_transfer* transfer,
    libusb_device_handle* dev_handle,
    unsigned char endpoint,
    unsigned char* buffer,
    int length,
    libusb_transfer_cb_fn callback,
    void* user_data,
    unsigned int timeout
);

static
void
libusb_fill_bulk_stream_transfer(
    struct libusb_transfer* transfer,
    libusb_device_handle* dev_handle,
    unsigned char endpoint,
    uint32_t stream_id,
    unsigned char* buffer,
    int length,
    libusb_transfer_cb_fn callback,
    void* user_data,
    unsigned int timeout
);

static
void
libusb_fill_interrupt_transfer(
    struct libusb_transfer* transfer,
    libusb_device_handle* dev_handle,
    unsigned char endpoint,
    unsigned char* buffer,
    int length,
    libusb_transfer_cb_fn callback,
    void* user_data,
    unsigned int timeout
);

static
void
libusb_fill_iso_transfer(
    struct libusb_transfer* transfer,
    libusb_device_handle* dev_handle,
    unsigned char endpoint,
    unsigned char* buffer,
    int length,
    int num_iso_packets,
    libusb_transfer_cb_fn callback,
    void* user_data,
    unsigned int timeout
);

static
void
libusb_set_iso_packet_lengths(
    struct libusb_transfer* transfer,
    unsigned int length
);

static
unsigned char*
libusb_get_iso_packet_buffer(
    struct libusb_transfer* transfer,
    unsigned int packet
);

static
unsigned char*
libusb_get_iso_packet_buffer_simple(
    struct libusb_transfer* transfer,
    unsigned int packet
);

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
);

int
libusb_bulk_transfer(
    libusb_device_handle* dev_handle,
    unsigned char endpoint,
    unsigned char* data,
    int length,
    int* actual_length,
    unsigned int timeout
);

int
libusb_interrupt_transfer(
    libusb_device_handle* dev_handle,
    unsigned char endpoint,
    unsigned char* data,
    int length,
    int* actual_length,
    unsigned int timeout
);

static
int
libusb_get_descriptor(
    libusb_device_handle* dev_handle,
    uint8_t desc_type,
    uint8_t desc_index,
    unsigned char* data,
    int length
);

static
int
libusb_get_string_descriptor(
    libusb_device_handle* dev_handle,
    uint8_t desc_index,
    uint16_t langid,
    unsigned char* data,
    int length
);

static
void
sync_transfer_cb(struct libusb_transfer* transfer);

static
void
sync_transfer_wait_for_completion(struct libusb_transfer* transfer);

static
int
do_sync_bulk_transfer(
    struct libusb_device_handle* dev_handle,
    unsigned char endpoint,
    unsigned char* buffer,
    int length,
    int* transferred,
    unsigned int timeout,
    unsigned char type
);

// macros

#define CONFIG_DESC_LENGTH
#define DESC_HEADER_LENGTH
#define DEVICE_DESC_LENGTH
#define DISCOVERED_DEVICES_SIZE_STEP
#define ENDPOINT_AUDIO_DESC_LENGTH
#define ENDPOINT_DESC_LENGTH
#define INTERFACE_DESC_LENGTH
#define LIBUSBX_API_VERSION
#define LIBUSB_API_VERSION
#define LIBUSB_BT_CONTAINER_ID_SIZE
#define LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE
#define LIBUSB_BT_USB_2_0_EXTENSION_SIZE
#define LIBUSB_CALL
#define LIBUSB_CONTROL_SETUP_SIZE
#define LIBUSB_DEPRECATED_FOR(f)
#define LIBUSB_DT_BOS_MAX_SIZE
#define LIBUSB_DT_BOS_SIZE
#define LIBUSB_DT_CONFIG_SIZE
#define LIBUSB_DT_DEVICE_CAPABILITY_SIZE
#define LIBUSB_DT_DEVICE_SIZE
#define LIBUSB_DT_ENDPOINT_AUDIO_SIZE
#define LIBUSB_DT_ENDPOINT_SIZE
#define LIBUSB_DT_HUB_NONVAR_SIZE
#define LIBUSB_DT_INTERFACE_SIZE
#define LIBUSB_DT_SS_ENDPOINT_COMPANION_SIZE
#define LIBUSB_ENDPOINT_ADDRESS_MASK
#define LIBUSB_ENDPOINT_DIR_MASK
#define LIBUSB_ERROR_COUNT
#define LIBUSB_HOTPLUG_MATCH_ANY
#define LIBUSB_ISO_SYNC_TYPE_MASK
#define LIBUSB_ISO_USAGE_TYPE_MASK
#define LIBUSB_MICRO
#define LIBUSB_MINOR
#define LIBUSB_NANO
#define LIBUSB_RC
#define LIBUSB_TRANSFER_TYPE_MASK
#define libusb_le16_to_cpu