From 33e08312f272c863f062fffe53ea4a4ce94e6e26 Mon Sep 17 00:00:00 2001 From: Jingkui Wang Date: Fri, 2 Nov 2018 00:27:48 -0700 Subject: usb_util: Create libusb wrapper This wrapper will be part of usb emulation backend. BUG=chromium:831850 TEST=local build Change-Id: I084b15201941e4c16c4e3ff9b967e55db09db567 Reviewed-on: https://chromium-review.googlesource.com/1124870 Commit-Ready: Jingkui Wang Tested-by: Jingkui Wang Reviewed-by: Jingkui Wang --- usb_util/Cargo.toml | 11 + usb_util/build.rs | 11 + usb_util/src/bindings.rs | 4627 +++++++++++++++++++++++++++++++++++++ usb_util/src/config_descriptor.rs | 32 + usb_util/src/device_handle.rs | 129 ++ usb_util/src/error.rs | 85 + usb_util/src/lib.rs | 19 + usb_util/src/libusb_context.rs | 156 ++ usb_util/src/libusb_device.rs | 109 + usb_util/src/types.rs | 198 ++ 10 files changed, 5377 insertions(+) create mode 100644 usb_util/Cargo.toml create mode 100644 usb_util/build.rs create mode 100644 usb_util/src/bindings.rs create mode 100644 usb_util/src/config_descriptor.rs create mode 100644 usb_util/src/device_handle.rs create mode 100644 usb_util/src/error.rs create mode 100644 usb_util/src/lib.rs create mode 100644 usb_util/src/libusb_context.rs create mode 100644 usb_util/src/libusb_device.rs create mode 100644 usb_util/src/types.rs (limited to 'usb_util') diff --git a/usb_util/Cargo.toml b/usb_util/Cargo.toml new file mode 100644 index 0000000..a0984a2 --- /dev/null +++ b/usb_util/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "usb_util" +version = "0.1.0" +authors = ["The Chromium OS Authors"] +build = "build.rs" + +[dependencies] +data_model = { path = "../data_model" } + +[build-dependencies] +pkg-config = "=0.3.11" diff --git a/usb_util/build.rs b/usb_util/build.rs new file mode 100644 index 0000000..ee6ab30 --- /dev/null +++ b/usb_util/build.rs @@ -0,0 +1,11 @@ +// Copyright 2018 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +extern crate pkg_config; +use std::env; + +fn main() { + env::set_var("PKG_CONFIG_ALLOW_CROSS", "1"); + pkg_config::probe_library("libusb-1.0").unwrap(); +} diff --git a/usb_util/src/bindings.rs b/usb_util/src/bindings.rs new file mode 100644 index 0000000..d24bf03 --- /dev/null +++ b/usb_util/src/bindings.rs @@ -0,0 +1,4627 @@ +/* automatically generated by rust-bindgen */ + +#[repr(C)] +#[derive(Default)] +pub struct __IncompleteArrayField(::std::marker::PhantomData); +impl __IncompleteArrayField { + #[inline] + pub fn new() -> Self { + __IncompleteArrayField(::std::marker::PhantomData) + } + #[inline] + pub unsafe fn as_ptr(&self) -> *const T { + ::std::mem::transmute(self) + } + #[inline] + pub unsafe fn as_mut_ptr(&mut self) -> *mut T { + ::std::mem::transmute(self) + } + #[inline] + pub unsafe fn as_slice(&self, len: usize) -> &[T] { + ::std::slice::from_raw_parts(self.as_ptr(), len) + } + #[inline] + pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] { + ::std::slice::from_raw_parts_mut(self.as_mut_ptr(), len) + } +} +impl ::std::fmt::Debug for __IncompleteArrayField { + fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fmt.write_str("__IncompleteArrayField") + } +} +impl ::std::clone::Clone for __IncompleteArrayField { + #[inline] + fn clone(&self) -> Self { + Self::new() + } +} +impl ::std::marker::Copy for __IncompleteArrayField {} +pub const _STDINT_H: u32 = 1; +pub const _FEATURES_H: u32 = 1; +pub const _DEFAULT_SOURCE: u32 = 1; +pub const __USE_ISOC11: u32 = 1; +pub const __USE_ISOC99: u32 = 1; +pub const __USE_ISOC95: u32 = 1; +pub const __USE_POSIX_IMPLICITLY: u32 = 1; +pub const _POSIX_SOURCE: u32 = 1; +pub const _POSIX_C_SOURCE: u32 = 200809; +pub const __USE_POSIX: u32 = 1; +pub const __USE_POSIX2: u32 = 1; +pub const __USE_POSIX199309: u32 = 1; +pub const __USE_POSIX199506: u32 = 1; +pub const __USE_XOPEN2K: u32 = 1; +pub const __USE_XOPEN2K8: u32 = 1; +pub const _ATFILE_SOURCE: u32 = 1; +pub const __USE_MISC: u32 = 1; +pub const __USE_ATFILE: u32 = 1; +pub const __USE_FORTIFY_LEVEL: u32 = 0; +pub const _STDC_PREDEF_H: u32 = 1; +pub const __STDC_IEC_559__: u32 = 1; +pub const __STDC_IEC_559_COMPLEX__: u32 = 1; +pub const __STDC_ISO_10646__: u32 = 201605; +pub const __STDC_NO_THREADS__: u32 = 1; +pub const __GNU_LIBRARY__: u32 = 6; +pub const __GLIBC__: u32 = 2; +pub const __GLIBC_MINOR__: u32 = 24; +pub const _SYS_CDEFS_H: u32 = 1; +pub const __WORDSIZE: u32 = 64; +pub const __WORDSIZE_TIME64_COMPAT32: u32 = 1; +pub const __SYSCALL_WORDSIZE: u32 = 64; +pub const _BITS_WCHAR_H: u32 = 1; +pub const INT8_MIN: i32 = -128; +pub const INT16_MIN: i32 = -32768; +pub const INT32_MIN: i32 = -2147483648; +pub const INT8_MAX: u32 = 127; +pub const INT16_MAX: u32 = 32767; +pub const INT32_MAX: u32 = 2147483647; +pub const UINT8_MAX: u32 = 255; +pub const UINT16_MAX: u32 = 65535; +pub const UINT32_MAX: u32 = 4294967295; +pub const INT_LEAST8_MIN: i32 = -128; +pub const INT_LEAST16_MIN: i32 = -32768; +pub const INT_LEAST32_MIN: i32 = -2147483648; +pub const INT_LEAST8_MAX: u32 = 127; +pub const INT_LEAST16_MAX: u32 = 32767; +pub const INT_LEAST32_MAX: u32 = 2147483647; +pub const UINT_LEAST8_MAX: u32 = 255; +pub const UINT_LEAST16_MAX: u32 = 65535; +pub const UINT_LEAST32_MAX: u32 = 4294967295; +pub const INT_FAST8_MIN: i32 = -128; +pub const INT_FAST16_MIN: i64 = -9223372036854775808; +pub const INT_FAST32_MIN: i64 = -9223372036854775808; +pub const INT_FAST8_MAX: u32 = 127; +pub const INT_FAST16_MAX: u64 = 9223372036854775807; +pub const INT_FAST32_MAX: u64 = 9223372036854775807; +pub const UINT_FAST8_MAX: u32 = 255; +pub const UINT_FAST16_MAX: i32 = -1; +pub const UINT_FAST32_MAX: i32 = -1; +pub const INTPTR_MIN: i64 = -9223372036854775808; +pub const INTPTR_MAX: u64 = 9223372036854775807; +pub const UINTPTR_MAX: i32 = -1; +pub const PTRDIFF_MIN: i64 = -9223372036854775808; +pub const PTRDIFF_MAX: u64 = 9223372036854775807; +pub const SIG_ATOMIC_MIN: i32 = -2147483648; +pub const SIG_ATOMIC_MAX: u32 = 2147483647; +pub const SIZE_MAX: i32 = -1; +pub const WINT_MIN: u32 = 0; +pub const WINT_MAX: u32 = 4294967295; +pub const _SYS_TYPES_H: u32 = 1; +pub const _BITS_TYPES_H: u32 = 1; +pub const _BITS_TYPESIZES_H: u32 = 1; +pub const __OFF_T_MATCHES_OFF64_T: u32 = 1; +pub const __INO_T_MATCHES_INO64_T: u32 = 1; +pub const __FD_SETSIZE: u32 = 1024; +pub const __clock_t_defined: u32 = 1; +pub const __time_t_defined: u32 = 1; +pub const __clockid_t_defined: u32 = 1; +pub const __timer_t_defined: u32 = 1; +pub const __BIT_TYPES_DEFINED__: u32 = 1; +pub const _ENDIAN_H: u32 = 1; +pub const __LITTLE_ENDIAN: u32 = 1234; +pub const __BIG_ENDIAN: u32 = 4321; +pub const __PDP_ENDIAN: u32 = 3412; +pub const __BYTE_ORDER: u32 = 1234; +pub const __FLOAT_WORD_ORDER: u32 = 1234; +pub const LITTLE_ENDIAN: u32 = 1234; +pub const BIG_ENDIAN: u32 = 4321; +pub const PDP_ENDIAN: u32 = 3412; +pub const BYTE_ORDER: u32 = 1234; +pub const _BITS_BYTESWAP_H: u32 = 1; +pub const _SYS_SELECT_H: u32 = 1; +pub const __FD_ZERO_STOS: &'static [u8; 6usize] = b"stosq\0"; +pub const _SIGSET_H_types: u32 = 1; +pub const __timespec_defined: u32 = 1; +pub const _STRUCT_TIMEVAL: u32 = 1; +pub const FD_SETSIZE: u32 = 1024; +pub const _SYS_SYSMACROS_H: u32 = 1; +pub const _BITS_PTHREADTYPES_H: u32 = 1; +pub const __SIZEOF_PTHREAD_ATTR_T: u32 = 56; +pub const __SIZEOF_PTHREAD_MUTEX_T: u32 = 40; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: u32 = 4; +pub const __SIZEOF_PTHREAD_COND_T: u32 = 48; +pub const __SIZEOF_PTHREAD_CONDATTR_T: u32 = 4; +pub const __SIZEOF_PTHREAD_RWLOCK_T: u32 = 56; +pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: u32 = 8; +pub const __SIZEOF_PTHREAD_BARRIER_T: u32 = 32; +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: u32 = 4; +pub const __have_pthread_attr_t: u32 = 1; +pub const __PTHREAD_MUTEX_HAVE_PREV: u32 = 1; +pub const __PTHREAD_RWLOCK_INT_FLAGS_SHARED: u32 = 1; +pub const _SYS_TIME_H: u32 = 1; +pub const _TIME_H: u32 = 1; +pub const _BITS_TIME_H: u32 = 1; +pub const CLOCK_REALTIME: u32 = 0; +pub const CLOCK_MONOTONIC: u32 = 1; +pub const CLOCK_PROCESS_CPUTIME_ID: u32 = 2; +pub const CLOCK_THREAD_CPUTIME_ID: u32 = 3; +pub const CLOCK_MONOTONIC_RAW: u32 = 4; +pub const CLOCK_REALTIME_COARSE: u32 = 5; +pub const CLOCK_MONOTONIC_COARSE: u32 = 6; +pub const CLOCK_BOOTTIME: u32 = 7; +pub const CLOCK_REALTIME_ALARM: u32 = 8; +pub const CLOCK_BOOTTIME_ALARM: u32 = 9; +pub const CLOCK_TAI: u32 = 11; +pub const TIMER_ABSTIME: u32 = 1; +pub const TIME_UTC: u32 = 1; +pub const _XLOCALE_H: u32 = 1; +pub const _LIBC_LIMITS_H_: u32 = 1; +pub const MB_LEN_MAX: u32 = 16; +pub const _BITS_POSIX1_LIM_H: u32 = 1; +pub const _POSIX_AIO_LISTIO_MAX: u32 = 2; +pub const _POSIX_AIO_MAX: u32 = 1; +pub const _POSIX_ARG_MAX: u32 = 4096; +pub const _POSIX_CHILD_MAX: u32 = 25; +pub const _POSIX_DELAYTIMER_MAX: u32 = 32; +pub const _POSIX_HOST_NAME_MAX: u32 = 255; +pub const _POSIX_LINK_MAX: u32 = 8; +pub const _POSIX_LOGIN_NAME_MAX: u32 = 9; +pub const _POSIX_MAX_CANON: u32 = 255; +pub const _POSIX_MAX_INPUT: u32 = 255; +pub const _POSIX_MQ_OPEN_MAX: u32 = 8; +pub const _POSIX_MQ_PRIO_MAX: u32 = 32; +pub const _POSIX_NAME_MAX: u32 = 14; +pub const _POSIX_NGROUPS_MAX: u32 = 8; +pub const _POSIX_OPEN_MAX: u32 = 20; +pub const _POSIX_PATH_MAX: u32 = 256; +pub const _POSIX_PIPE_BUF: u32 = 512; +pub const _POSIX_RE_DUP_MAX: u32 = 255; +pub const _POSIX_RTSIG_MAX: u32 = 8; +pub const _POSIX_SEM_NSEMS_MAX: u32 = 256; +pub const _POSIX_SEM_VALUE_MAX: u32 = 32767; +pub const _POSIX_SIGQUEUE_MAX: u32 = 32; +pub const _POSIX_SSIZE_MAX: u32 = 32767; +pub const _POSIX_STREAM_MAX: u32 = 8; +pub const _POSIX_SYMLINK_MAX: u32 = 255; +pub const _POSIX_SYMLOOP_MAX: u32 = 8; +pub const _POSIX_TIMER_MAX: u32 = 32; +pub const _POSIX_TTY_NAME_MAX: u32 = 9; +pub const _POSIX_TZNAME_MAX: u32 = 6; +pub const _POSIX_CLOCKRES_MIN: u32 = 20000000; +pub const NR_OPEN: u32 = 1024; +pub const NGROUPS_MAX: u32 = 65536; +pub const ARG_MAX: u32 = 131072; +pub const LINK_MAX: u32 = 127; +pub const MAX_CANON: u32 = 255; +pub const MAX_INPUT: u32 = 255; +pub const NAME_MAX: u32 = 255; +pub const PATH_MAX: u32 = 4096; +pub const PIPE_BUF: u32 = 4096; +pub const XATTR_NAME_MAX: u32 = 255; +pub const XATTR_SIZE_MAX: u32 = 65536; +pub const XATTR_LIST_MAX: u32 = 65536; +pub const RTSIG_MAX: u32 = 32; +pub const _POSIX_THREAD_KEYS_MAX: u32 = 128; +pub const PTHREAD_KEYS_MAX: u32 = 1024; +pub const _POSIX_THREAD_DESTRUCTOR_ITERATIONS: u32 = 4; +pub const PTHREAD_DESTRUCTOR_ITERATIONS: u32 = 4; +pub const _POSIX_THREAD_THREADS_MAX: u32 = 64; +pub const AIO_PRIO_DELTA_MAX: u32 = 20; +pub const PTHREAD_STACK_MIN: u32 = 16384; +pub const DELAYTIMER_MAX: u32 = 2147483647; +pub const TTY_NAME_MAX: u32 = 32; +pub const LOGIN_NAME_MAX: u32 = 256; +pub const HOST_NAME_MAX: u32 = 64; +pub const MQ_PRIO_MAX: u32 = 32768; +pub const SEM_VALUE_MAX: u32 = 2147483647; +pub const _BITS_POSIX2_LIM_H: u32 = 1; +pub const _POSIX2_BC_BASE_MAX: u32 = 99; +pub const _POSIX2_BC_DIM_MAX: u32 = 2048; +pub const _POSIX2_BC_SCALE_MAX: u32 = 99; +pub const _POSIX2_BC_STRING_MAX: u32 = 1000; +pub const _POSIX2_COLL_WEIGHTS_MAX: u32 = 2; +pub const _POSIX2_EXPR_NEST_MAX: u32 = 32; +pub const _POSIX2_LINE_MAX: u32 = 2048; +pub const _POSIX2_RE_DUP_MAX: u32 = 255; +pub const _POSIX2_CHARCLASS_NAME_MAX: u32 = 14; +pub const BC_BASE_MAX: u32 = 99; +pub const BC_DIM_MAX: u32 = 2048; +pub const BC_SCALE_MAX: u32 = 99; +pub const BC_STRING_MAX: u32 = 1000; +pub const COLL_WEIGHTS_MAX: u32 = 255; +pub const EXPR_NEST_MAX: u32 = 32; +pub const LINE_MAX: u32 = 2048; +pub const CHARCLASS_NAME_MAX: u32 = 2048; +pub const RE_DUP_MAX: u32 = 32767; +pub const LIBUSB_API_VERSION: u32 = 16777477; +pub const LIBUSBX_API_VERSION: u32 = 16777477; +pub const LIBUSB_DT_DEVICE_SIZE: u32 = 18; +pub const LIBUSB_DT_CONFIG_SIZE: u32 = 9; +pub const LIBUSB_DT_INTERFACE_SIZE: u32 = 9; +pub const LIBUSB_DT_ENDPOINT_SIZE: u32 = 7; +pub const LIBUSB_DT_ENDPOINT_AUDIO_SIZE: u32 = 9; +pub const LIBUSB_DT_HUB_NONVAR_SIZE: u32 = 7; +pub const LIBUSB_DT_SS_ENDPOINT_COMPANION_SIZE: u32 = 6; +pub const LIBUSB_DT_BOS_SIZE: u32 = 5; +pub const LIBUSB_DT_DEVICE_CAPABILITY_SIZE: u32 = 3; +pub const LIBUSB_BT_USB_2_0_EXTENSION_SIZE: u32 = 7; +pub const LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE: u32 = 10; +pub const LIBUSB_BT_CONTAINER_ID_SIZE: u32 = 20; +pub const LIBUSB_DT_BOS_MAX_SIZE: u32 = 42; +pub const LIBUSB_ENDPOINT_ADDRESS_MASK: u32 = 15; +pub const LIBUSB_ENDPOINT_DIR_MASK: u32 = 128; +pub const LIBUSB_TRANSFER_TYPE_MASK: u32 = 3; +pub const LIBUSB_ISO_SYNC_TYPE_MASK: u32 = 12; +pub const LIBUSB_ISO_USAGE_TYPE_MASK: u32 = 48; +pub const LIBUSB_ERROR_COUNT: u32 = 14; +pub const LIBUSB_HOTPLUG_MATCH_ANY: i32 = -1; +pub type int_least8_t = ::std::os::raw::c_schar; +pub type int_least16_t = ::std::os::raw::c_short; +pub type int_least32_t = ::std::os::raw::c_int; +pub type int_least64_t = ::std::os::raw::c_long; +pub type uint_least8_t = ::std::os::raw::c_uchar; +pub type uint_least16_t = ::std::os::raw::c_ushort; +pub type uint_least32_t = ::std::os::raw::c_uint; +pub type uint_least64_t = ::std::os::raw::c_ulong; +pub type int_fast8_t = ::std::os::raw::c_schar; +pub type int_fast16_t = ::std::os::raw::c_long; +pub type int_fast32_t = ::std::os::raw::c_long; +pub type int_fast64_t = ::std::os::raw::c_long; +pub type uint_fast8_t = ::std::os::raw::c_uchar; +pub type uint_fast16_t = ::std::os::raw::c_ulong; +pub type uint_fast32_t = ::std::os::raw::c_ulong; +pub type uint_fast64_t = ::std::os::raw::c_ulong; +pub type intmax_t = ::std::os::raw::c_long; +pub type uintmax_t = ::std::os::raw::c_ulong; +pub type __u_char = ::std::os::raw::c_uchar; +pub type __u_short = ::std::os::raw::c_ushort; +pub type __u_int = ::std::os::raw::c_uint; +pub type __u_long = ::std::os::raw::c_ulong; +pub type __int8_t = ::std::os::raw::c_schar; +pub type __uint8_t = ::std::os::raw::c_uchar; +pub type __int16_t = ::std::os::raw::c_short; +pub type __uint16_t = ::std::os::raw::c_ushort; +pub type __int32_t = ::std::os::raw::c_int; +pub type __uint32_t = ::std::os::raw::c_uint; +pub type __int64_t = ::std::os::raw::c_long; +pub type __uint64_t = ::std::os::raw::c_ulong; +pub type __quad_t = ::std::os::raw::c_long; +pub type __u_quad_t = ::std::os::raw::c_ulong; +pub type __dev_t = ::std::os::raw::c_ulong; +pub type __uid_t = ::std::os::raw::c_uint; +pub type __gid_t = ::std::os::raw::c_uint; +pub type __ino_t = ::std::os::raw::c_ulong; +pub type __ino64_t = ::std::os::raw::c_ulong; +pub type __mode_t = ::std::os::raw::c_uint; +pub type __nlink_t = ::std::os::raw::c_ulong; +pub type __off_t = ::std::os::raw::c_long; +pub type __off64_t = ::std::os::raw::c_long; +pub type __pid_t = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __fsid_t { + pub __val: [::std::os::raw::c_int; 2usize], +} +#[test] +fn bindgen_test_layout___fsid_t() { + assert_eq!( + ::std::mem::size_of::<__fsid_t>(), + 8usize, + concat!("Size of: ", stringify!(__fsid_t)) + ); + assert_eq!( + ::std::mem::align_of::<__fsid_t>(), + 4usize, + concat!("Alignment of ", stringify!(__fsid_t)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__fsid_t>())).__val as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__fsid_t), + "::", + stringify!(__val) + ) + ); +} +pub type __clock_t = ::std::os::raw::c_long; +pub type __rlim_t = ::std::os::raw::c_ulong; +pub type __rlim64_t = ::std::os::raw::c_ulong; +pub type __id_t = ::std::os::raw::c_uint; +pub type __time_t = ::std::os::raw::c_long; +pub type __useconds_t = ::std::os::raw::c_uint; +pub type __suseconds_t = ::std::os::raw::c_long; +pub type __daddr_t = ::std::os::raw::c_int; +pub type __key_t = ::std::os::raw::c_int; +pub type __clockid_t = ::std::os::raw::c_int; +pub type __timer_t = *mut ::std::os::raw::c_void; +pub type __blksize_t = ::std::os::raw::c_long; +pub type __blkcnt_t = ::std::os::raw::c_long; +pub type __blkcnt64_t = ::std::os::raw::c_long; +pub type __fsblkcnt_t = ::std::os::raw::c_ulong; +pub type __fsblkcnt64_t = ::std::os::raw::c_ulong; +pub type __fsfilcnt_t = ::std::os::raw::c_ulong; +pub type __fsfilcnt64_t = ::std::os::raw::c_ulong; +pub type __fsword_t = ::std::os::raw::c_long; +pub type __ssize_t = ::std::os::raw::c_long; +pub type __syscall_slong_t = ::std::os::raw::c_long; +pub type __syscall_ulong_t = ::std::os::raw::c_ulong; +pub type __loff_t = __off64_t; +pub type __qaddr_t = *mut __quad_t; +pub type __caddr_t = *mut ::std::os::raw::c_char; +pub type __intptr_t = ::std::os::raw::c_long; +pub type __socklen_t = ::std::os::raw::c_uint; +pub type u_char = __u_char; +pub type u_short = __u_short; +pub type u_int = __u_int; +pub type u_long = __u_long; +pub type quad_t = __quad_t; +pub type u_quad_t = __u_quad_t; +pub type fsid_t = __fsid_t; +pub type loff_t = __loff_t; +pub type ino_t = __ino_t; +pub type dev_t = __dev_t; +pub type gid_t = __gid_t; +pub type mode_t = __mode_t; +pub type nlink_t = __nlink_t; +pub type uid_t = __uid_t; +pub type off_t = __off_t; +pub type pid_t = __pid_t; +pub type id_t = __id_t; +pub type daddr_t = __daddr_t; +pub type caddr_t = __caddr_t; +pub type key_t = __key_t; +pub type clock_t = __clock_t; +pub type time_t = __time_t; +pub type clockid_t = __clockid_t; +pub type timer_t = __timer_t; +pub type ulong = ::std::os::raw::c_ulong; +pub type ushort = ::std::os::raw::c_ushort; +pub type uint = ::std::os::raw::c_uint; +pub type u_int8_t = ::std::os::raw::c_uchar; +pub type u_int16_t = ::std::os::raw::c_ushort; +pub type u_int32_t = ::std::os::raw::c_uint; +pub type u_int64_t = ::std::os::raw::c_ulong; +pub type register_t = ::std::os::raw::c_long; +pub type __sig_atomic_t = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __sigset_t { + pub __val: [::std::os::raw::c_ulong; 16usize], +} +#[test] +fn bindgen_test_layout___sigset_t() { + assert_eq!( + ::std::mem::size_of::<__sigset_t>(), + 128usize, + concat!("Size of: ", stringify!(__sigset_t)) + ); + assert_eq!( + ::std::mem::align_of::<__sigset_t>(), + 8usize, + concat!("Alignment of ", stringify!(__sigset_t)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__sigset_t>())).__val as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__sigset_t), + "::", + stringify!(__val) + ) + ); +} +pub type sigset_t = __sigset_t; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct timespec { + pub tv_sec: __time_t, + pub tv_nsec: __syscall_slong_t, +} +#[test] +fn bindgen_test_layout_timespec() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(timespec)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(timespec)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tv_sec as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(timespec), + "::", + stringify!(tv_sec) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tv_nsec as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(timespec), + "::", + stringify!(tv_nsec) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct timeval { + pub tv_sec: __time_t, + pub tv_usec: __suseconds_t, +} +#[test] +fn bindgen_test_layout_timeval() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(timeval)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(timeval)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tv_sec as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(timeval), + "::", + stringify!(tv_sec) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tv_usec as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(timeval), + "::", + stringify!(tv_usec) + ) + ); +} +pub type suseconds_t = __suseconds_t; +pub type __fd_mask = ::std::os::raw::c_long; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct fd_set { + pub __fds_bits: [__fd_mask; 16usize], +} +#[test] +fn bindgen_test_layout_fd_set() { + assert_eq!( + ::std::mem::size_of::(), + 128usize, + concat!("Size of: ", stringify!(fd_set)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(fd_set)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).__fds_bits as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(fd_set), + "::", + stringify!(__fds_bits) + ) + ); +} +pub type fd_mask = __fd_mask; +extern "C" { + pub fn select( + __nfds: ::std::os::raw::c_int, + __readfds: *mut fd_set, + __writefds: *mut fd_set, + __exceptfds: *mut fd_set, + __timeout: *mut timeval, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn pselect( + __nfds: ::std::os::raw::c_int, + __readfds: *mut fd_set, + __writefds: *mut fd_set, + __exceptfds: *mut fd_set, + __timeout: *const timespec, + __sigmask: *const __sigset_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn gnu_dev_major(__dev: ::std::os::raw::c_ulonglong) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn gnu_dev_minor(__dev: ::std::os::raw::c_ulonglong) -> ::std::os::raw::c_uint; +} +extern "C" { + pub fn gnu_dev_makedev( + __major: ::std::os::raw::c_uint, + __minor: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_ulonglong; +} +pub type blksize_t = __blksize_t; +pub type blkcnt_t = __blkcnt_t; +pub type fsblkcnt_t = __fsblkcnt_t; +pub type fsfilcnt_t = __fsfilcnt_t; +pub type pthread_t = ::std::os::raw::c_ulong; +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_attr_t { + pub __size: [::std::os::raw::c_char; 56usize], + pub __align: ::std::os::raw::c_long, + _bindgen_union_align: [u64; 7usize], +} +#[test] +fn bindgen_test_layout_pthread_attr_t() { + assert_eq!( + ::std::mem::size_of::(), + 56usize, + concat!("Size of: ", stringify!(pthread_attr_t)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(pthread_attr_t)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).__size as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_attr_t), + "::", + stringify!(__size) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).__align as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_attr_t), + "::", + stringify!(__align) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __pthread_internal_list { + pub __prev: *mut __pthread_internal_list, + pub __next: *mut __pthread_internal_list, +} +#[test] +fn bindgen_test_layout___pthread_internal_list() { + assert_eq!( + ::std::mem::size_of::<__pthread_internal_list>(), + 16usize, + concat!("Size of: ", stringify!(__pthread_internal_list)) + ); + assert_eq!( + ::std::mem::align_of::<__pthread_internal_list>(), + 8usize, + concat!("Alignment of ", stringify!(__pthread_internal_list)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__pthread_internal_list>())).__prev as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__pthread_internal_list), + "::", + stringify!(__prev) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__pthread_internal_list>())).__next as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(__pthread_internal_list), + "::", + stringify!(__next) + ) + ); +} +pub type __pthread_list_t = __pthread_internal_list; +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_mutex_t { + pub __data: pthread_mutex_t___pthread_mutex_s, + pub __size: [::std::os::raw::c_char; 40usize], + pub __align: ::std::os::raw::c_long, + _bindgen_union_align: [u64; 5usize], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct pthread_mutex_t___pthread_mutex_s { + pub __lock: ::std::os::raw::c_int, + pub __count: ::std::os::raw::c_uint, + pub __owner: ::std::os::raw::c_int, + pub __nusers: ::std::os::raw::c_uint, + pub __kind: ::std::os::raw::c_int, + pub __spins: ::std::os::raw::c_short, + pub __elision: ::std::os::raw::c_short, + pub __list: __pthread_list_t, +} +#[test] +fn bindgen_test_layout_pthread_mutex_t___pthread_mutex_s() { + assert_eq!( + ::std::mem::size_of::(), + 40usize, + concat!("Size of: ", stringify!(pthread_mutex_t___pthread_mutex_s)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!( + "Alignment of ", + stringify!(pthread_mutex_t___pthread_mutex_s) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__lock as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_mutex_t___pthread_mutex_s), + "::", + stringify!(__lock) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__count as *const _ + as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(pthread_mutex_t___pthread_mutex_s), + "::", + stringify!(__count) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__owner as *const _ + as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(pthread_mutex_t___pthread_mutex_s), + "::", + stringify!(__owner) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__nusers as *const _ + as usize + }, + 12usize, + concat!( + "Offset of field: ", + stringify!(pthread_mutex_t___pthread_mutex_s), + "::", + stringify!(__nusers) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__kind as *const _ + as usize + }, + 16usize, + concat!( + "Offset of field: ", + stringify!(pthread_mutex_t___pthread_mutex_s), + "::", + stringify!(__kind) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__spins as *const _ + as usize + }, + 20usize, + concat!( + "Offset of field: ", + stringify!(pthread_mutex_t___pthread_mutex_s), + "::", + stringify!(__spins) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__elision as *const _ + as usize + }, + 22usize, + concat!( + "Offset of field: ", + stringify!(pthread_mutex_t___pthread_mutex_s), + "::", + stringify!(__elision) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__list as *const _ + as usize + }, + 24usize, + concat!( + "Offset of field: ", + stringify!(pthread_mutex_t___pthread_mutex_s), + "::", + stringify!(__list) + ) + ); +} +#[test] +fn bindgen_test_layout_pthread_mutex_t() { + assert_eq!( + ::std::mem::size_of::(), + 40usize, + concat!("Size of: ", stringify!(pthread_mutex_t)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(pthread_mutex_t)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).__data as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_mutex_t), + "::", + stringify!(__data) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).__size as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_mutex_t), + "::", + stringify!(__size) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).__align as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_mutex_t), + "::", + stringify!(__align) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_mutexattr_t { + pub __size: [::std::os::raw::c_char; 4usize], + pub __align: ::std::os::raw::c_int, + _bindgen_union_align: u32, +} +#[test] +fn bindgen_test_layout_pthread_mutexattr_t() { + assert_eq!( + ::std::mem::size_of::(), + 4usize, + concat!("Size of: ", stringify!(pthread_mutexattr_t)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(pthread_mutexattr_t)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).__size as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_mutexattr_t), + "::", + stringify!(__size) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).__align as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_mutexattr_t), + "::", + stringify!(__align) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_cond_t { + pub __data: pthread_cond_t__bindgen_ty_1, + pub __size: [::std::os::raw::c_char; 48usize], + pub __align: ::std::os::raw::c_longlong, + _bindgen_union_align: [u64; 6usize], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct pthread_cond_t__bindgen_ty_1 { + pub __lock: ::std::os::raw::c_int, + pub __futex: ::std::os::raw::c_uint, + pub __total_seq: ::std::os::raw::c_ulonglong, + pub __wakeup_seq: ::std::os::raw::c_ulonglong, + pub __woken_seq: ::std::os::raw::c_ulonglong, + pub __mutex: *mut ::std::os::raw::c_void, + pub __nwaiters: ::std::os::raw::c_uint, + pub __broadcast_seq: ::std::os::raw::c_uint, +} +#[test] +fn bindgen_test_layout_pthread_cond_t__bindgen_ty_1() { + assert_eq!( + ::std::mem::size_of::(), + 48usize, + concat!("Size of: ", stringify!(pthread_cond_t__bindgen_ty_1)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(pthread_cond_t__bindgen_ty_1)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__lock as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_cond_t__bindgen_ty_1), + "::", + stringify!(__lock) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__futex as *const _ as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(pthread_cond_t__bindgen_ty_1), + "::", + stringify!(__futex) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__total_seq as *const _ + as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(pthread_cond_t__bindgen_ty_1), + "::", + stringify!(__total_seq) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__wakeup_seq as *const _ + as usize + }, + 16usize, + concat!( + "Offset of field: ", + stringify!(pthread_cond_t__bindgen_ty_1), + "::", + stringify!(__wakeup_seq) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__woken_seq as *const _ + as usize + }, + 24usize, + concat!( + "Offset of field: ", + stringify!(pthread_cond_t__bindgen_ty_1), + "::", + stringify!(__woken_seq) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__mutex as *const _ as usize + }, + 32usize, + concat!( + "Offset of field: ", + stringify!(pthread_cond_t__bindgen_ty_1), + "::", + stringify!(__mutex) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__nwaiters as *const _ as usize + }, + 40usize, + concat!( + "Offset of field: ", + stringify!(pthread_cond_t__bindgen_ty_1), + "::", + stringify!(__nwaiters) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__broadcast_seq as *const _ + as usize + }, + 44usize, + concat!( + "Offset of field: ", + stringify!(pthread_cond_t__bindgen_ty_1), + "::", + stringify!(__broadcast_seq) + ) + ); +} +#[test] +fn bindgen_test_layout_pthread_cond_t() { + assert_eq!( + ::std::mem::size_of::(), + 48usize, + concat!("Size of: ", stringify!(pthread_cond_t)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(pthread_cond_t)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).__data as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_cond_t), + "::", + stringify!(__data) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).__size as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_cond_t), + "::", + stringify!(__size) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).__align as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_cond_t), + "::", + stringify!(__align) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_condattr_t { + pub __size: [::std::os::raw::c_char; 4usize], + pub __align: ::std::os::raw::c_int, + _bindgen_union_align: u32, +} +#[test] +fn bindgen_test_layout_pthread_condattr_t() { + assert_eq!( + ::std::mem::size_of::(), + 4usize, + concat!("Size of: ", stringify!(pthread_condattr_t)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(pthread_condattr_t)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).__size as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_condattr_t), + "::", + stringify!(__size) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).__align as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_condattr_t), + "::", + stringify!(__align) + ) + ); +} +pub type pthread_key_t = ::std::os::raw::c_uint; +pub type pthread_once_t = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_rwlock_t { + pub __data: pthread_rwlock_t__bindgen_ty_1, + pub __size: [::std::os::raw::c_char; 56usize], + pub __align: ::std::os::raw::c_long, + _bindgen_union_align: [u64; 7usize], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct pthread_rwlock_t__bindgen_ty_1 { + pub __lock: ::std::os::raw::c_int, + pub __nr_readers: ::std::os::raw::c_uint, + pub __readers_wakeup: ::std::os::raw::c_uint, + pub __writer_wakeup: ::std::os::raw::c_uint, + pub __nr_readers_queued: ::std::os::raw::c_uint, + pub __nr_writers_queued: ::std::os::raw::c_uint, + pub __writer: ::std::os::raw::c_int, + pub __shared: ::std::os::raw::c_int, + pub __rwelision: ::std::os::raw::c_schar, + pub __pad1: [::std::os::raw::c_uchar; 7usize], + pub __pad2: ::std::os::raw::c_ulong, + pub __flags: ::std::os::raw::c_uint, +} +#[test] +fn bindgen_test_layout_pthread_rwlock_t__bindgen_ty_1() { + assert_eq!( + ::std::mem::size_of::(), + 56usize, + concat!("Size of: ", stringify!(pthread_rwlock_t__bindgen_ty_1)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(pthread_rwlock_t__bindgen_ty_1)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__lock as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_rwlock_t__bindgen_ty_1), + "::", + stringify!(__lock) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__nr_readers as *const _ + as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(pthread_rwlock_t__bindgen_ty_1), + "::", + stringify!(__nr_readers) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__readers_wakeup as *const _ + as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(pthread_rwlock_t__bindgen_ty_1), + "::", + stringify!(__readers_wakeup) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__writer_wakeup as *const _ + as usize + }, + 12usize, + concat!( + "Offset of field: ", + stringify!(pthread_rwlock_t__bindgen_ty_1), + "::", + stringify!(__writer_wakeup) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__nr_readers_queued + as *const _ as usize + }, + 16usize, + concat!( + "Offset of field: ", + stringify!(pthread_rwlock_t__bindgen_ty_1), + "::", + stringify!(__nr_readers_queued) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__nr_writers_queued + as *const _ as usize + }, + 20usize, + concat!( + "Offset of field: ", + stringify!(pthread_rwlock_t__bindgen_ty_1), + "::", + stringify!(__nr_writers_queued) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__writer as *const _ as usize + }, + 24usize, + concat!( + "Offset of field: ", + stringify!(pthread_rwlock_t__bindgen_ty_1), + "::", + stringify!(__writer) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__shared as *const _ as usize + }, + 28usize, + concat!( + "Offset of field: ", + stringify!(pthread_rwlock_t__bindgen_ty_1), + "::", + stringify!(__shared) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__rwelision as *const _ + as usize + }, + 32usize, + concat!( + "Offset of field: ", + stringify!(pthread_rwlock_t__bindgen_ty_1), + "::", + stringify!(__rwelision) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__pad1 as *const _ as usize + }, + 33usize, + concat!( + "Offset of field: ", + stringify!(pthread_rwlock_t__bindgen_ty_1), + "::", + stringify!(__pad1) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__pad2 as *const _ as usize + }, + 40usize, + concat!( + "Offset of field: ", + stringify!(pthread_rwlock_t__bindgen_ty_1), + "::", + stringify!(__pad2) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).__flags as *const _ as usize + }, + 48usize, + concat!( + "Offset of field: ", + stringify!(pthread_rwlock_t__bindgen_ty_1), + "::", + stringify!(__flags) + ) + ); +} +#[test] +fn bindgen_test_layout_pthread_rwlock_t() { + assert_eq!( + ::std::mem::size_of::(), + 56usize, + concat!("Size of: ", stringify!(pthread_rwlock_t)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(pthread_rwlock_t)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).__data as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_rwlock_t), + "::", + stringify!(__data) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).__size as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_rwlock_t), + "::", + stringify!(__size) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).__align as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_rwlock_t), + "::", + stringify!(__align) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_rwlockattr_t { + pub __size: [::std::os::raw::c_char; 8usize], + pub __align: ::std::os::raw::c_long, + _bindgen_union_align: u64, +} +#[test] +fn bindgen_test_layout_pthread_rwlockattr_t() { + assert_eq!( + ::std::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(pthread_rwlockattr_t)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(pthread_rwlockattr_t)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).__size as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_rwlockattr_t), + "::", + stringify!(__size) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).__align as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_rwlockattr_t), + "::", + stringify!(__align) + ) + ); +} +pub type pthread_spinlock_t = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_barrier_t { + pub __size: [::std::os::raw::c_char; 32usize], + pub __align: ::std::os::raw::c_long, + _bindgen_union_align: [u64; 4usize], +} +#[test] +fn bindgen_test_layout_pthread_barrier_t() { + assert_eq!( + ::std::mem::size_of::(), + 32usize, + concat!("Size of: ", stringify!(pthread_barrier_t)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(pthread_barrier_t)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).__size as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_barrier_t), + "::", + stringify!(__size) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).__align as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_barrier_t), + "::", + stringify!(__align) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_barrierattr_t { + pub __size: [::std::os::raw::c_char; 4usize], + pub __align: ::std::os::raw::c_int, + _bindgen_union_align: u32, +} +#[test] +fn bindgen_test_layout_pthread_barrierattr_t() { + assert_eq!( + ::std::mem::size_of::(), + 4usize, + concat!("Size of: ", stringify!(pthread_barrierattr_t)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(pthread_barrierattr_t)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).__size as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_barrierattr_t), + "::", + stringify!(__size) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).__align as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_barrierattr_t), + "::", + stringify!(__align) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct timezone { + pub tz_minuteswest: ::std::os::raw::c_int, + pub tz_dsttime: ::std::os::raw::c_int, +} +#[test] +fn bindgen_test_layout_timezone() { + assert_eq!( + ::std::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(timezone)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(timezone)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tz_minuteswest as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(timezone), + "::", + stringify!(tz_minuteswest) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tz_dsttime as *const _ as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(timezone), + "::", + stringify!(tz_dsttime) + ) + ); +} +pub type __timezone_ptr_t = *mut timezone; +extern "C" { + pub fn gettimeofday(__tv: *mut timeval, __tz: __timezone_ptr_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn settimeofday(__tv: *const timeval, __tz: *const timezone) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn adjtime(__delta: *const timeval, __olddelta: *mut timeval) -> ::std::os::raw::c_int; +} +pub const ITIMER_REAL: __itimer_which = 0; +pub const ITIMER_VIRTUAL: __itimer_which = 1; +pub const ITIMER_PROF: __itimer_which = 2; +pub type __itimer_which = u32; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct itimerval { + pub it_interval: timeval, + pub it_value: timeval, +} +#[test] +fn bindgen_test_layout_itimerval() { + assert_eq!( + ::std::mem::size_of::(), + 32usize, + concat!("Size of: ", stringify!(itimerval)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(itimerval)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).it_interval as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(itimerval), + "::", + stringify!(it_interval) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).it_value as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(itimerval), + "::", + stringify!(it_value) + ) + ); +} +pub type __itimer_which_t = ::std::os::raw::c_int; +extern "C" { + pub fn getitimer(__which: __itimer_which_t, __value: *mut itimerval) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn setitimer( + __which: __itimer_which_t, + __new: *const itimerval, + __old: *mut itimerval, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn utimes( + __file: *const ::std::os::raw::c_char, + __tvp: *const timeval, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn lutimes( + __file: *const ::std::os::raw::c_char, + __tvp: *const timeval, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn futimes(__fd: ::std::os::raw::c_int, __tvp: *const timeval) -> ::std::os::raw::c_int; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct tm { + pub tm_sec: ::std::os::raw::c_int, + pub tm_min: ::std::os::raw::c_int, + pub tm_hour: ::std::os::raw::c_int, + pub tm_mday: ::std::os::raw::c_int, + pub tm_mon: ::std::os::raw::c_int, + pub tm_year: ::std::os::raw::c_int, + pub tm_wday: ::std::os::raw::c_int, + pub tm_yday: ::std::os::raw::c_int, + pub tm_isdst: ::std::os::raw::c_int, + pub tm_gmtoff: ::std::os::raw::c_long, + pub tm_zone: *const ::std::os::raw::c_char, +} +#[test] +fn bindgen_test_layout_tm() { + assert_eq!( + ::std::mem::size_of::(), + 56usize, + concat!("Size of: ", stringify!(tm)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(tm)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tm_sec as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(tm), + "::", + stringify!(tm_sec) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tm_min as *const _ as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(tm), + "::", + stringify!(tm_min) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tm_hour as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(tm), + "::", + stringify!(tm_hour) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tm_mday as *const _ as usize }, + 12usize, + concat!( + "Offset of field: ", + stringify!(tm), + "::", + stringify!(tm_mday) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tm_mon as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(tm), + "::", + stringify!(tm_mon) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tm_year as *const _ as usize }, + 20usize, + concat!( + "Offset of field: ", + stringify!(tm), + "::", + stringify!(tm_year) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tm_wday as *const _ as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(tm), + "::", + stringify!(tm_wday) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tm_yday as *const _ as usize }, + 28usize, + concat!( + "Offset of field: ", + stringify!(tm), + "::", + stringify!(tm_yday) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tm_isdst as *const _ as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(tm), + "::", + stringify!(tm_isdst) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tm_gmtoff as *const _ as usize }, + 40usize, + concat!( + "Offset of field: ", + stringify!(tm), + "::", + stringify!(tm_gmtoff) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).tm_zone as *const _ as usize }, + 48usize, + concat!( + "Offset of field: ", + stringify!(tm), + "::", + stringify!(tm_zone) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct itimerspec { + pub it_interval: timespec, + pub it_value: timespec, +} +#[test] +fn bindgen_test_layout_itimerspec() { + assert_eq!( + ::std::mem::size_of::(), + 32usize, + concat!("Size of: ", stringify!(itimerspec)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(itimerspec)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).it_interval as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(itimerspec), + "::", + stringify!(it_interval) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).it_value as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(itimerspec), + "::", + stringify!(it_value) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct sigevent { + _unused: [u8; 0], +} +extern "C" { + pub fn clock() -> clock_t; +} +extern "C" { + pub fn time(__timer: *mut time_t) -> time_t; +} +extern "C" { + pub fn difftime(__time1: time_t, __time0: time_t) -> f64; +} +extern "C" { + pub fn mktime(__tp: *mut tm) -> time_t; +} +extern "C" { + pub fn strftime( + __s: *mut ::std::os::raw::c_char, + __maxsize: usize, + __format: *const ::std::os::raw::c_char, + __tp: *const tm, + ) -> usize; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __locale_struct { + pub __locales: [*mut __locale_data; 13usize], + pub __ctype_b: *const ::std::os::raw::c_ushort, + pub __ctype_tolower: *const ::std::os::raw::c_int, + pub __ctype_toupper: *const ::std::os::raw::c_int, + pub __names: [*const ::std::os::raw::c_char; 13usize], +} +#[test] +fn bindgen_test_layout___locale_struct() { + assert_eq!( + ::std::mem::size_of::<__locale_struct>(), + 232usize, + concat!("Size of: ", stringify!(__locale_struct)) + ); + assert_eq!( + ::std::mem::align_of::<__locale_struct>(), + 8usize, + concat!("Alignment of ", stringify!(__locale_struct)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__locale_struct>())).__locales as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__locale_struct), + "::", + stringify!(__locales) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__locale_struct>())).__ctype_b as *const _ as usize }, + 104usize, + concat!( + "Offset of field: ", + stringify!(__locale_struct), + "::", + stringify!(__ctype_b) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__locale_struct>())).__ctype_tolower as *const _ as usize }, + 112usize, + concat!( + "Offset of field: ", + stringify!(__locale_struct), + "::", + stringify!(__ctype_tolower) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__locale_struct>())).__ctype_toupper as *const _ as usize }, + 120usize, + concat!( + "Offset of field: ", + stringify!(__locale_struct), + "::", + stringify!(__ctype_toupper) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__locale_struct>())).__names as *const _ as usize }, + 128usize, + concat!( + "Offset of field: ", + stringify!(__locale_struct), + "::", + stringify!(__names) + ) + ); +} +pub type __locale_t = *mut __locale_struct; +pub type locale_t = __locale_t; +extern "C" { + pub fn strftime_l( + __s: *mut ::std::os::raw::c_char, + __maxsize: usize, + __format: *const ::std::os::raw::c_char, + __tp: *const tm, + __loc: __locale_t, + ) -> usize; +} +extern "C" { + pub fn gmtime(__timer: *const time_t) -> *mut tm; +} +extern "C" { + pub fn localtime(__timer: *const time_t) -> *mut tm; +} +extern "C" { + pub fn gmtime_r(__timer: *const time_t, __tp: *mut tm) -> *mut tm; +} +extern "C" { + pub fn localtime_r(__timer: *const time_t, __tp: *mut tm) -> *mut tm; +} +extern "C" { + pub fn asctime(__tp: *const tm) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn ctime(__timer: *const time_t) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn asctime_r( + __tp: *const tm, + __buf: *mut ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn ctime_r( + __timer: *const time_t, + __buf: *mut ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + #[link_name = "\u{1}__tzname"] + pub static mut __tzname: [*mut ::std::os::raw::c_char; 2usize]; +} +extern "C" { + #[link_name = "\u{1}__daylight"] + pub static mut __daylight: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}__timezone"] + pub static mut __timezone: ::std::os::raw::c_long; +} +extern "C" { + #[link_name = "\u{1}tzname"] + pub static mut tzname: [*mut ::std::os::raw::c_char; 2usize]; +} +extern "C" { + pub fn tzset(); +} +extern "C" { + #[link_name = "\u{1}daylight"] + pub static mut daylight: ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}timezone"] + pub static mut timezone: ::std::os::raw::c_long; +} +extern "C" { + pub fn stime(__when: *const time_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn timegm(__tp: *mut tm) -> time_t; +} +extern "C" { + pub fn timelocal(__tp: *mut tm) -> time_t; +} +extern "C" { + pub fn dysize(__year: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn nanosleep( + __requested_time: *const timespec, + __remaining: *mut timespec, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clock_getres(__clock_id: clockid_t, __res: *mut timespec) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clock_gettime(__clock_id: clockid_t, __tp: *mut timespec) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clock_settime(__clock_id: clockid_t, __tp: *const timespec) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clock_nanosleep( + __clock_id: clockid_t, + __flags: ::std::os::raw::c_int, + __req: *const timespec, + __rem: *mut timespec, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clock_getcpuclockid(__pid: pid_t, __clock_id: *mut clockid_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn timer_create( + __clock_id: clockid_t, + __evp: *mut sigevent, + __timerid: *mut timer_t, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn timer_delete(__timerid: timer_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn timer_settime( + __timerid: timer_t, + __flags: ::std::os::raw::c_int, + __value: *const itimerspec, + __ovalue: *mut itimerspec, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn timer_gettime(__timerid: timer_t, __value: *mut itimerspec) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn timer_getoverrun(__timerid: timer_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn timespec_get( + __ts: *mut timespec, + __base: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +/// In the context of a \ref libusb_device_descriptor "device descriptor", +/// this bDeviceClass value indicates that each interface specifies its +/// own class information and all interfaces operate independently. +pub const LIBUSB_CLASS_PER_INTERFACE: libusb_class_code = 0; +/// Audio class +pub const LIBUSB_CLASS_AUDIO: libusb_class_code = 1; +/// Communications class +pub const LIBUSB_CLASS_COMM: libusb_class_code = 2; +/// Human Interface Device class +pub const LIBUSB_CLASS_HID: libusb_class_code = 3; +/// Physical +pub const LIBUSB_CLASS_PHYSICAL: libusb_class_code = 5; +/// Printer class +pub const LIBUSB_CLASS_PRINTER: libusb_class_code = 7; +/// Image class +pub const LIBUSB_CLASS_PTP: libusb_class_code = 6; +/// Image class +pub const LIBUSB_CLASS_IMAGE: libusb_class_code = 6; +/// Mass storage class +pub const LIBUSB_CLASS_MASS_STORAGE: libusb_class_code = 8; +/// Hub class +pub const LIBUSB_CLASS_HUB: libusb_class_code = 9; +/// Data class +pub const LIBUSB_CLASS_DATA: libusb_class_code = 10; +/// Smart Card +pub const LIBUSB_CLASS_SMART_CARD: libusb_class_code = 11; +/// Content Security +pub const LIBUSB_CLASS_CONTENT_SECURITY: libusb_class_code = 13; +/// Video +pub const LIBUSB_CLASS_VIDEO: libusb_class_code = 14; +/// Personal Healthcare +pub const LIBUSB_CLASS_PERSONAL_HEALTHCARE: libusb_class_code = 15; +/// Diagnostic Device +pub const LIBUSB_CLASS_DIAGNOSTIC_DEVICE: libusb_class_code = 220; +/// Wireless class +pub const LIBUSB_CLASS_WIRELESS: libusb_class_code = 224; +/// Application class +pub const LIBUSB_CLASS_APPLICATION: libusb_class_code = 254; +/// Class is vendor-specific +pub const LIBUSB_CLASS_VENDOR_SPEC: libusb_class_code = 255; +/// \ingroup libusb_desc +/// Device and/or Interface Class codes +pub type libusb_class_code = u32; +/// Device descriptor. See libusb_device_descriptor. +pub const LIBUSB_DT_DEVICE: libusb_descriptor_type = 1; +/// Configuration descriptor. See libusb_config_descriptor. +pub const LIBUSB_DT_CONFIG: libusb_descriptor_type = 2; +/// String descriptor +pub const LIBUSB_DT_STRING: libusb_descriptor_type = 3; +/// Interface descriptor. See libusb_interface_descriptor. +pub const LIBUSB_DT_INTERFACE: libusb_descriptor_type = 4; +/// Endpoint descriptor. See libusb_endpoint_descriptor. +pub const LIBUSB_DT_ENDPOINT: libusb_descriptor_type = 5; +/// BOS descriptor +pub const LIBUSB_DT_BOS: libusb_descriptor_type = 15; +/// Device Capability descriptor +pub const LIBUSB_DT_DEVICE_CAPABILITY: libusb_descriptor_type = 16; +/// HID descriptor +pub const LIBUSB_DT_HID: libusb_descriptor_type = 33; +/// HID report descriptor +pub const LIBUSB_DT_REPORT: libusb_descriptor_type = 34; +/// Physical descriptor +pub const LIBUSB_DT_PHYSICAL: libusb_descriptor_type = 35; +/// Hub descriptor +pub const LIBUSB_DT_HUB: libusb_descriptor_type = 41; +/// SuperSpeed Hub descriptor +pub const LIBUSB_DT_SUPERSPEED_HUB: libusb_descriptor_type = 42; +/// SuperSpeed Endpoint Companion descriptor +pub const LIBUSB_DT_SS_ENDPOINT_COMPANION: libusb_descriptor_type = 48; +/// \ingroup libusb_desc +/// Descriptor types as defined by the USB specification. +pub type libusb_descriptor_type = u32; +/// In: device-to-host +pub const LIBUSB_ENDPOINT_IN: libusb_endpoint_direction = 128; +/// Out: host-to-device +pub const LIBUSB_ENDPOINT_OUT: libusb_endpoint_direction = 0; +/// \ingroup libusb_desc +/// Endpoint direction. Values for bit 7 of the +/// \ref libusb_endpoint_descriptor::bEndpointAddress "endpoint address" scheme. +pub type libusb_endpoint_direction = u32; +/// Control endpoint +pub const LIBUSB_TRANSFER_TYPE_CONTROL: libusb_transfer_type = 0; +/// Isochronous endpoint +pub const LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: libusb_transfer_type = 1; +/// Bulk endpoint +pub const LIBUSB_TRANSFER_TYPE_BULK: libusb_transfer_type = 2; +/// Interrupt endpoint +pub const LIBUSB_TRANSFER_TYPE_INTERRUPT: libusb_transfer_type = 3; +/// Stream endpoint +pub const LIBUSB_TRANSFER_TYPE_BULK_STREAM: libusb_transfer_type = 4; +/// \ingroup libusb_desc +/// Endpoint transfer type. Values for bits 0:1 of the +/// \ref libusb_endpoint_descriptor::bmAttributes "endpoint attributes" field. +pub type libusb_transfer_type = u32; +/// Request status of the specific recipient +pub const LIBUSB_REQUEST_GET_STATUS: libusb_standard_request = 0; +/// Clear or disable a specific feature +pub const LIBUSB_REQUEST_CLEAR_FEATURE: libusb_standard_request = 1; +/// Set or enable a specific feature +pub const LIBUSB_REQUEST_SET_FEATURE: libusb_standard_request = 3; +/// Set device address for all future accesses +pub const LIBUSB_REQUEST_SET_ADDRESS: libusb_standard_request = 5; +/// Get the specified descriptor +pub const LIBUSB_REQUEST_GET_DESCRIPTOR: libusb_standard_request = 6; +/// Used to update existing descriptors or add new descriptors +pub const LIBUSB_REQUEST_SET_DESCRIPTOR: libusb_standard_request = 7; +/// Get the current device configuration value +pub const LIBUSB_REQUEST_GET_CONFIGURATION: libusb_standard_request = 8; +/// Set device configuration +pub const LIBUSB_REQUEST_SET_CONFIGURATION: libusb_standard_request = 9; +/// Return the selected alternate setting for the specified interface +pub const LIBUSB_REQUEST_GET_INTERFACE: libusb_standard_request = 10; +/// Select an alternate interface for the specified interface +pub const LIBUSB_REQUEST_SET_INTERFACE: libusb_standard_request = 11; +/// Set then report an endpoint's synchronization frame +pub const LIBUSB_REQUEST_SYNCH_FRAME: libusb_standard_request = 12; +/// Sets both the U1 and U2 Exit Latency +pub const LIBUSB_REQUEST_SET_SEL: libusb_standard_request = 48; +/// Delay from the time a host transmits a packet to the time it is +/// received by the device. +pub const LIBUSB_SET_ISOCH_DELAY: libusb_standard_request = 49; +/// \ingroup libusb_misc +/// Standard requests, as defined in table 9-5 of the USB 3.0 specifications +pub type libusb_standard_request = u32; +/// Standard +pub const LIBUSB_REQUEST_TYPE_STANDARD: libusb_request_type = 0; +/// Class +pub const LIBUSB_REQUEST_TYPE_CLASS: libusb_request_type = 32; +/// Vendor +pub const LIBUSB_REQUEST_TYPE_VENDOR: libusb_request_type = 64; +/// Reserved +pub const LIBUSB_REQUEST_TYPE_RESERVED: libusb_request_type = 96; +/// \ingroup libusb_misc +/// Request type bits of the +/// \ref libusb_control_setup::bmRequestType "bmRequestType" field in control +/// transfers. +pub type libusb_request_type = u32; +/// Device +pub const LIBUSB_RECIPIENT_DEVICE: libusb_request_recipient = 0; +/// Interface +pub const LIBUSB_RECIPIENT_INTERFACE: libusb_request_recipient = 1; +/// Endpoint +pub const LIBUSB_RECIPIENT_ENDPOINT: libusb_request_recipient = 2; +/// Other +pub const LIBUSB_RECIPIENT_OTHER: libusb_request_recipient = 3; +/// \ingroup libusb_misc +/// Recipient bits of the +/// \ref libusb_control_setup::bmRequestType "bmRequestType" field in control +/// transfers. Values 4 through 31 are reserved. +pub type libusb_request_recipient = u32; +/// No synchronization +pub const LIBUSB_ISO_SYNC_TYPE_NONE: libusb_iso_sync_type = 0; +/// Asynchronous +pub const LIBUSB_ISO_SYNC_TYPE_ASYNC: libusb_iso_sync_type = 1; +/// Adaptive +pub const LIBUSB_ISO_SYNC_TYPE_ADAPTIVE: libusb_iso_sync_type = 2; +/// Synchronous +pub const LIBUSB_ISO_SYNC_TYPE_SYNC: libusb_iso_sync_type = 3; +/// \ingroup libusb_desc +/// Synchronization type for isochronous endpoints. Values for bits 2:3 of the +/// \ref libusb_endpoint_descriptor::bmAttributes "bmAttributes" field in +/// libusb_endpoint_descriptor. +pub type libusb_iso_sync_type = u32; +/// Data endpoint +pub const LIBUSB_ISO_USAGE_TYPE_DATA: libusb_iso_usage_type = 0; +/// Feedback endpoint +pub const LIBUSB_ISO_USAGE_TYPE_FEEDBACK: libusb_iso_usage_type = 1; +/// Implicit feedback Data endpoint +pub const LIBUSB_ISO_USAGE_TYPE_IMPLICIT: libusb_iso_usage_type = 2; +/// \ingroup libusb_desc +/// Usage type for isochronous endpoints. Values for bits 4:5 of the +/// \ref libusb_endpoint_descriptor::bmAttributes "bmAttributes" field in +/// libusb_endpoint_descriptor. +pub type libusb_iso_usage_type = u32; +/// \ingroup libusb_desc +/// A structure representing the standard USB device descriptor. This +/// descriptor is documented in section 9.6.1 of the USB 3.0 specification. +/// All multiple-byte fields are represented in host-endian format. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct libusb_device_descriptor { + /// Size of this descriptor (in bytes) + pub bLength: u8, + /// Descriptor type. Will have value + /// \ref libusb_descriptor_type::LIBUSB_DT_DEVICE LIBUSB_DT_DEVICE in this + /// context. + pub bDescriptorType: u8, + /// USB specification release number in binary-coded decimal. A value of + /// 0x0200 indicates USB 2.0, 0x0110 indicates USB 1.1, etc. + pub bcdUSB: u16, + /// USB-IF class code for the device. See \ref libusb_class_code. + pub bDeviceClass: u8, + /// USB-IF subclass code for the device, qualified by the bDeviceClass + /// value + pub bDeviceSubClass: u8, + /// USB-IF protocol code for the device, qualified by the bDeviceClass and + /// bDeviceSubClass values + pub bDeviceProtocol: u8, + /// Maximum packet size for endpoint 0 + pub bMaxPacketSize0: u8, + /// USB-IF vendor ID + pub idVendor: u16, + /// USB-IF product ID + pub idProduct: u16, + /// Device release number in binary-coded decimal + pub bcdDevice: u16, + /// Index of string descriptor describing manufacturer + pub iManufacturer: u8, + /// Index of string descriptor describing product + pub iProduct: u8, + /// Index of string descriptor containing device serial number + pub iSerialNumber: u8, + /// Number of possible configurations + pub bNumConfigurations: u8, +} +#[test] +fn bindgen_test_layout_libusb_device_descriptor() { + assert_eq!( + ::std::mem::size_of::(), + 18usize, + concat!("Size of: ", stringify!(libusb_device_descriptor)) + ); + assert_eq!( + ::std::mem::align_of::(), + 2usize, + concat!("Alignment of ", stringify!(libusb_device_descriptor)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bLength as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(libusb_device_descriptor), + "::", + stringify!(bLength) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bDescriptorType as *const _ + as usize + }, + 1usize, + concat!( + "Offset of field: ", + stringify!(libusb_device_descriptor), + "::", + stringify!(bDescriptorType) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).bcdUSB as *const _ as usize }, + 2usize, + concat!( + "Offset of field: ", + stringify!(libusb_device_descriptor), + "::", + stringify!(bcdUSB) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bDeviceClass as *const _ as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(libusb_device_descriptor), + "::", + stringify!(bDeviceClass) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bDeviceSubClass as *const _ + as usize + }, + 5usize, + concat!( + "Offset of field: ", + stringify!(libusb_device_descriptor), + "::", + stringify!(bDeviceSubClass) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bDeviceProtocol as *const _ + as usize + }, + 6usize, + concat!( + "Offset of field: ", + stringify!(libusb_device_descriptor), + "::", + stringify!(bDeviceProtocol) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bMaxPacketSize0 as *const _ + as usize + }, + 7usize, + concat!( + "Offset of field: ", + stringify!(libusb_device_descriptor), + "::", + stringify!(bMaxPacketSize0) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).idVendor as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(libusb_device_descriptor), + "::", + stringify!(idVendor) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).idProduct as *const _ as usize + }, + 10usize, + concat!( + "Offset of field: ", + stringify!(libusb_device_descriptor), + "::", + stringify!(idProduct) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bcdDevice as *const _ as usize + }, + 12usize, + concat!( + "Offset of field: ", + stringify!(libusb_device_descriptor), + "::", + stringify!(bcdDevice) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).iManufacturer as *const _ as usize + }, + 14usize, + concat!( + "Offset of field: ", + stringify!(libusb_device_descriptor), + "::", + stringify!(iManufacturer) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).iProduct as *const _ as usize + }, + 15usize, + concat!( + "Offset of field: ", + stringify!(libusb_device_descriptor), + "::", + stringify!(iProduct) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).iSerialNumber as *const _ as usize + }, + 16usize, + concat!( + "Offset of field: ", + stringify!(libusb_device_descriptor), + "::", + stringify!(iSerialNumber) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bNumConfigurations as *const _ + as usize + }, + 17usize, + concat!( + "Offset of field: ", + stringify!(libusb_device_descriptor), + "::", + stringify!(bNumConfigurations) + ) + ); +} +/// \ingroup libusb_desc +/// A structure representing the standard USB endpoint descriptor. This +/// descriptor is documented in section 9.6.6 of the USB 3.0 specification. +/// All multiple-byte fields are represented in host-endian format. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct libusb_endpoint_descriptor { + /// Size of this descriptor (in bytes) + pub bLength: u8, + /// Descriptor type. Will have value + /// \ref libusb_descriptor_type::LIBUSB_DT_ENDPOINT LIBUSB_DT_ENDPOINT in + /// this context. + pub bDescriptorType: u8, + /// The address of the endpoint described by this descriptor. Bits 0:3 are + /// the endpoint number. Bits 4:6 are reserved. Bit 7 indicates direction, + /// see \ref libusb_endpoint_direction. + pub bEndpointAddress: u8, + /// Attributes which apply to the endpoint when it is configured using + /// the bConfigurationValue. Bits 0:1 determine the transfer type and + /// correspond to \ref libusb_transfer_type. Bits 2:3 are only used for + /// isochronous endpoints and correspond to \ref libusb_iso_sync_type. + /// Bits 4:5 are also only used for isochronous endpoints and correspond to + /// \ref libusb_iso_usage_type. Bits 6:7 are reserved. + pub bmAttributes: u8, + /// Maximum packet size this endpoint is capable of sending/receiving. + pub wMaxPacketSize: u16, + /// Interval for polling endpoint for data transfers. + pub bInterval: u8, + /// For audio devices only: the rate at which synchronization feedback + /// is provided. + pub bRefresh: u8, + /// For audio devices only: the address if the synch endpoint + pub bSynchAddress: u8, + /// Extra descriptors. If libusb encounters unknown endpoint descriptors, + /// it will store them here, should you wish to parse them. + pub extra: *const ::std::os::raw::c_uchar, + /// Length of the extra descriptors, in bytes. + pub extra_length: ::std::os::raw::c_int, +} +#[test] +fn bindgen_test_layout_libusb_endpoint_descriptor() { + assert_eq!( + ::std::mem::size_of::(), + 32usize, + concat!("Size of: ", stringify!(libusb_endpoint_descriptor)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(libusb_endpoint_descriptor)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bLength as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(libusb_endpoint_descriptor), + "::", + stringify!(bLength) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bDescriptorType as *const _ + as usize + }, + 1usize, + concat!( + "Offset of field: ", + stringify!(libusb_endpoint_descriptor), + "::", + stringify!(bDescriptorType) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bEndpointAddress as *const _ + as usize + }, + 2usize, + concat!( + "Offset of field: ", + stringify!(libusb_endpoint_descriptor), + "::", + stringify!(bEndpointAddress) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bmAttributes as *const _ as usize + }, + 3usize, + concat!( + "Offset of field: ", + stringify!(libusb_endpoint_descriptor), + "::", + stringify!(bmAttributes) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).wMaxPacketSize as *const _ + as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(libusb_endpoint_descriptor), + "::", + stringify!(wMaxPacketSize) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bInterval as *const _ as usize + }, + 6usize, + concat!( + "Offset of field: ", + stringify!(libusb_endpoint_descriptor), + "::", + stringify!(bInterval) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bRefresh as *const _ as usize + }, + 7usize, + concat!( + "Offset of field: ", + stringify!(libusb_endpoint_descriptor), + "::", + stringify!(bRefresh) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bSynchAddress as *const _ + as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(libusb_endpoint_descriptor), + "::", + stringify!(bSynchAddress) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).extra as *const _ as usize + }, + 16usize, + concat!( + "Offset of field: ", + stringify!(libusb_endpoint_descriptor), + "::", + stringify!(extra) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).extra_length as *const _ as usize + }, + 24usize, + concat!( + "Offset of field: ", + stringify!(libusb_endpoint_descriptor), + "::", + stringify!(extra_length) + ) + ); +} +/// \ingroup libusb_desc +/// A structure representing the standard USB interface descriptor. This +/// descriptor is documented in section 9.6.5 of the USB 3.0 specification. +/// All multiple-byte fields are represented in host-endian format. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct libusb_interface_descriptor { + /// Size of this descriptor (in bytes) + pub bLength: u8, + /// Descriptor type. Will have value + /// \ref libusb_descriptor_type::LIBUSB_DT_INTERFACE LIBUSB_DT_INTERFACE + /// in this context. + pub bDescriptorType: u8, + /// Number of this interface + pub bInterfaceNumber: u8, + /// Value used to select this alternate setting for this interface + pub bAlternateSetting: u8, + /// Number of endpoints used by this interface (excluding the control + /// endpoint). + pub bNumEndpoints: u8, + /// USB-IF class code for this interface. See \ref libusb_class_code. + pub bInterfaceClass: u8, + /// USB-IF subclass code for this interface, qualified by the + /// bInterfaceClass value + pub bInterfaceSubClass: u8, + /// USB-IF protocol code for this interface, qualified by the + /// bInterfaceClass and bInterfaceSubClass values + pub bInterfaceProtocol: u8, + /// Index of string descriptor describing this interface + pub iInterface: u8, + /// Array of endpoint descriptors. This length of this array is determined + /// by the bNumEndpoints field. + pub endpoint: *const libusb_endpoint_descriptor, + /// Extra descriptors. If libusb encounters unknown interface descriptors, + /// it will store them here, should you wish to parse them. + pub extra: *const ::std::os::raw::c_uchar, + /// Length of the extra descriptors, in bytes. + pub extra_length: ::std::os::raw::c_int, +} +#[test] +fn bindgen_test_layout_libusb_interface_descriptor() { + assert_eq!( + ::std::mem::size_of::(), + 40usize, + concat!("Size of: ", stringify!(libusb_interface_descriptor)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(libusb_interface_descriptor)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bLength as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(libusb_interface_descriptor), + "::", + stringify!(bLength) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bDescriptorType as *const _ + as usize + }, + 1usize, + concat!( + "Offset of field: ", + stringify!(libusb_interface_descriptor), + "::", + stringify!(bDescriptorType) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bInterfaceNumber as *const _ + as usize + }, + 2usize, + concat!( + "Offset of field: ", + stringify!(libusb_interface_descriptor), + "::", + stringify!(bInterfaceNumber) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bAlternateSetting as *const _ + as usize + }, + 3usize, + concat!( + "Offset of field: ", + stringify!(libusb_interface_descriptor), + "::", + stringify!(bAlternateSetting) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bNumEndpoints as *const _ + as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(libusb_interface_descriptor), + "::", + stringify!(bNumEndpoints) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bInterfaceClass as *const _ + as usize + }, + 5usize, + concat!( + "Offset of field: ", + stringify!(libusb_interface_descriptor), + "::", + stringify!(bInterfaceClass) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bInterfaceSubClass as *const _ + as usize + }, + 6usize, + concat!( + "Offset of field: ", + stringify!(libusb_interface_descriptor), + "::", + stringify!(bInterfaceSubClass) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bInterfaceProtocol as *const _ + as usize + }, + 7usize, + concat!( + "Offset of field: ", + stringify!(libusb_interface_descriptor), + "::", + stringify!(bInterfaceProtocol) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).iInterface as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(libusb_interface_descriptor), + "::", + stringify!(iInterface) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).endpoint as *const _ as usize + }, + 16usize, + concat!( + "Offset of field: ", + stringify!(libusb_interface_descriptor), + "::", + stringify!(endpoint) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).extra as *const _ as usize + }, + 24usize, + concat!( + "Offset of field: ", + stringify!(libusb_interface_descriptor), + "::", + stringify!(extra) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).extra_length as *const _ + as usize + }, + 32usize, + concat!( + "Offset of field: ", + stringify!(libusb_interface_descriptor), + "::", + stringify!(extra_length) + ) + ); +} +/// \ingroup libusb_desc +/// A collection of alternate settings for a particular USB interface. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct libusb_interface { + /// Array of interface descriptors. The length of this array is determined + /// by the num_altsetting field. + pub altsetting: *const libusb_interface_descriptor, + /// The number of alternate settings that belong to this interface + pub num_altsetting: ::std::os::raw::c_int, +} +#[test] +fn bindgen_test_layout_libusb_interface() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(libusb_interface)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(libusb_interface)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).altsetting as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(libusb_interface), + "::", + stringify!(altsetting) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).num_altsetting as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(libusb_interface), + "::", + stringify!(num_altsetting) + ) + ); +} +/// \ingroup libusb_desc +/// A structure representing the standard USB configuration descriptor. This +/// descriptor is documented in section 9.6.3 of the USB 3.0 specification. +/// All multiple-byte fields are represented in host-endian format. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct libusb_config_descriptor { + /// Size of this descriptor (in bytes) + pub bLength: u8, + /// Descriptor type. Will have value + /// \ref libusb_descriptor_type::LIBUSB_DT_CONFIG LIBUSB_DT_CONFIG + /// in this context. + pub bDescriptorType: u8, + /// Total length of data returned for this configuration + pub wTotalLength: u16, + /// Number of interfaces supported by this configuration + pub bNumInterfaces: u8, + /// Identifier value for this configuration + pub bConfigurationValue: u8, + /// Index of string descriptor describing this configuration + pub iConfiguration: u8, + /// Configuration characteristics + pub bmAttributes: u8, + /// Maximum power consumption of the USB device from this bus in this + /// configuration when the device is fully operation. Expressed in units + /// of 2 mA when the device is operating in high-speed mode and in units + /// of 8 mA when the device is operating in super-speed mode. + pub MaxPower: u8, + /// Array of interfaces supported by this configuration. The length of + /// this array is determined by the bNumInterfaces field. + pub interface: *const libusb_interface, + /// Extra descriptors. If libusb encounters unknown configuration + /// descriptors, it will store them here, should you wish to parse them. + pub extra: *const ::std::os::raw::c_uchar, + /// Length of the extra descriptors, in bytes. + pub extra_length: ::std::os::raw::c_int, +} +#[test] +fn bindgen_test_layout_libusb_config_descriptor() { + assert_eq!( + ::std::mem::size_of::(), + 40usize, + concat!("Size of: ", stringify!(libusb_config_descriptor)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(libusb_config_descriptor)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bLength as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(libusb_config_descriptor), + "::", + stringify!(bLength) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bDescriptorType as *const _ + as usize + }, + 1usize, + concat!( + "Offset of field: ", + stringify!(libusb_config_descriptor), + "::", + stringify!(bDescriptorType) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).wTotalLength as *const _ as usize + }, + 2usize, + concat!( + "Offset of field: ", + stringify!(libusb_config_descriptor), + "::", + stringify!(wTotalLength) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bNumInterfaces as *const _ as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(libusb_config_descriptor), + "::", + stringify!(bNumInterfaces) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bConfigurationValue as *const _ + as usize + }, + 5usize, + concat!( + "Offset of field: ", + stringify!(libusb_config_descriptor), + "::", + stringify!(bConfigurationValue) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).iConfiguration as *const _ as usize + }, + 6usize, + concat!( + "Offset of field: ", + stringify!(libusb_config_descriptor), + "::", + stringify!(iConfiguration) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bmAttributes as *const _ as usize + }, + 7usize, + concat!( + "Offset of field: ", + stringify!(libusb_config_descriptor), + "::", + stringify!(bmAttributes) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).MaxPower as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(libusb_config_descriptor), + "::", + stringify!(MaxPower) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).interface as *const _ as usize + }, + 16usize, + concat!( + "Offset of field: ", + stringify!(libusb_config_descriptor), + "::", + stringify!(interface) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).extra as *const _ as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(libusb_config_descriptor), + "::", + stringify!(extra) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).extra_length as *const _ as usize + }, + 32usize, + concat!( + "Offset of field: ", + stringify!(libusb_config_descriptor), + "::", + stringify!(extra_length) + ) + ); +} +/// \ingroup libusb_desc +/// A structure representing the superspeed endpoint companion +/// descriptor. This descriptor is documented in section 9.6.7 of +/// the USB 3.0 specification. All multiple-byte fields are represented in +/// host-endian format. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct libusb_ss_endpoint_companion_descriptor { + /// Size of this descriptor (in bytes) + pub bLength: u8, + /// Descriptor type. Will have value + /// \ref libusb_descriptor_type::LIBUSB_DT_SS_ENDPOINT_COMPANION in + /// this context. + pub bDescriptorType: u8, + /// The maximum number of packets the endpoint can send or + /// receive as part of a burst. + pub bMaxBurst: u8, + /// In bulk EP: bits 4:0 represents the maximum number of + /// streams the EP supports. In isochronous EP: bits 1:0 + /// represents the Mult - a zero based value that determines + /// the maximum number of packets within a service interval + pub bmAttributes: u8, + /// The total number of bytes this EP will transfer every + /// service interval. valid only for periodic EPs. + pub wBytesPerInterval: u16, +} +#[test] +fn bindgen_test_layout_libusb_ss_endpoint_companion_descriptor() { + assert_eq!( + ::std::mem::size_of::(), + 6usize, + concat!( + "Size of: ", + stringify!(libusb_ss_endpoint_companion_descriptor) + ) + ); + assert_eq!( + ::std::mem::align_of::(), + 2usize, + concat!( + "Alignment of ", + stringify!(libusb_ss_endpoint_companion_descriptor) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bLength as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(libusb_ss_endpoint_companion_descriptor), + "::", + stringify!(bLength) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bDescriptorType + as *const _ as usize + }, + 1usize, + concat!( + "Offset of field: ", + stringify!(libusb_ss_endpoint_companion_descriptor), + "::", + stringify!(bDescriptorType) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bMaxBurst + as *const _ as usize + }, + 2usize, + concat!( + "Offset of field: ", + stringify!(libusb_ss_endpoint_companion_descriptor), + "::", + stringify!(bMaxBurst) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bmAttributes + as *const _ as usize + }, + 3usize, + concat!( + "Offset of field: ", + stringify!(libusb_ss_endpoint_companion_descriptor), + "::", + stringify!(bmAttributes) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).wBytesPerInterval + as *const _ as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(libusb_ss_endpoint_companion_descriptor), + "::", + stringify!(wBytesPerInterval) + ) + ); +} +/// \ingroup libusb_desc +/// A generic representation of a BOS Device Capability descriptor. It is +/// advised to check bDevCapabilityType and call the matching +/// libusb_get_*_descriptor function to get a structure fully matching the type. +#[repr(C)] +#[derive(Debug)] +pub struct libusb_bos_dev_capability_descriptor { + /// Size of this descriptor (in bytes) + pub bLength: u8, + /// Descriptor type. Will have value + /// \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY + /// LIBUSB_DT_DEVICE_CAPABILITY in this context. + pub bDescriptorType: u8, + /// Device Capability type + pub bDevCapabilityType: u8, + /// Device Capability data (bLength - 3 bytes) + pub dev_capability_data: __IncompleteArrayField, +} +#[test] +fn bindgen_test_layout_libusb_bos_dev_capability_descriptor() { + assert_eq!( + ::std::mem::size_of::(), + 3usize, + concat!( + "Size of: ", + stringify!(libusb_bos_dev_capability_descriptor) + ) + ); + assert_eq!( + ::std::mem::align_of::(), + 1usize, + concat!( + "Alignment of ", + stringify!(libusb_bos_dev_capability_descriptor) + ) + ); +} +/// \ingroup libusb_desc +/// A structure representing the Binary Device Object Store (BOS) descriptor. +/// This descriptor is documented in section 9.6.2 of the USB 3.0 specification. +/// All multiple-byte fields are represented in host-endian format. +#[repr(C)] +#[derive(Debug)] +pub struct libusb_bos_descriptor { + /// Size of this descriptor (in bytes) + pub bLength: u8, + /// Descriptor type. Will have value + /// \ref libusb_descriptor_type::LIBUSB_DT_BOS LIBUSB_DT_BOS + /// in this context. + pub bDescriptorType: u8, + /// Length of this descriptor and all of its sub descriptors + pub wTotalLength: u16, + /// The number of separate device capability descriptors in + /// the BOS + pub bNumDeviceCaps: u8, + /// bNumDeviceCap Device Capability Descriptors + pub dev_capability: __IncompleteArrayField<*mut libusb_bos_dev_capability_descriptor>, + pub __bindgen_align: [u64; 0usize], +} +#[test] +fn bindgen_test_layout_libusb_bos_descriptor() { + assert_eq!( + ::std::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(libusb_bos_descriptor)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(libusb_bos_descriptor)) + ); +} +/// \ingroup libusb_desc +/// A structure representing the USB 2.0 Extension descriptor +/// This descriptor is documented in section 9.6.2.1 of the USB 3.0 specification. +/// All multiple-byte fields are represented in host-endian format. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct libusb_usb_2_0_extension_descriptor { + /// Size of this descriptor (in bytes) + pub bLength: u8, + /// Descriptor type. Will have value + /// \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY + /// LIBUSB_DT_DEVICE_CAPABILITY in this context. + pub bDescriptorType: u8, + /// Capability type. Will have value + /// \ref libusb_capability_type::LIBUSB_BT_USB_2_0_EXTENSION + /// LIBUSB_BT_USB_2_0_EXTENSION in this context. + pub bDevCapabilityType: u8, + /// Bitmap encoding of supported device level features. + /// A value of one in a bit location indicates a feature is + /// supported; a value of zero indicates it is not supported. + /// See \ref libusb_usb_2_0_extension_attributes. + pub bmAttributes: u32, +} +#[test] +fn bindgen_test_layout_libusb_usb_2_0_extension_descriptor() { + assert_eq!( + ::std::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(libusb_usb_2_0_extension_descriptor)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!( + "Alignment of ", + stringify!(libusb_usb_2_0_extension_descriptor) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bLength as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(libusb_usb_2_0_extension_descriptor), + "::", + stringify!(bLength) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bDescriptorType + as *const _ as usize + }, + 1usize, + concat!( + "Offset of field: ", + stringify!(libusb_usb_2_0_extension_descriptor), + "::", + stringify!(bDescriptorType) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bDevCapabilityType + as *const _ as usize + }, + 2usize, + concat!( + "Offset of field: ", + stringify!(libusb_usb_2_0_extension_descriptor), + "::", + stringify!(bDevCapabilityType) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bmAttributes as *const _ + as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(libusb_usb_2_0_extension_descriptor), + "::", + stringify!(bmAttributes) + ) + ); +} +/// \ingroup libusb_desc +/// A structure representing the SuperSpeed USB Device Capability descriptor +/// This descriptor is documented in section 9.6.2.2 of the USB 3.0 specification. +/// All multiple-byte fields are represented in host-endian format. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct libusb_ss_usb_device_capability_descriptor { + /// Size of this descriptor (in bytes) + pub bLength: u8, + /// Descriptor type. Will have value + /// \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY + /// LIBUSB_DT_DEVICE_CAPABILITY in this context. + pub bDescriptorType: u8, + /// Capability type. Will have value + /// \ref libusb_capability_type::LIBUSB_BT_SS_USB_DEVICE_CAPABILITY + /// LIBUSB_BT_SS_USB_DEVICE_CAPABILITY in this context. + pub bDevCapabilityType: u8, + /// Bitmap encoding of supported device level features. + /// A value of one in a bit location indicates a feature is + /// supported; a value of zero indicates it is not supported. + /// See \ref libusb_ss_usb_device_capability_attributes. + pub bmAttributes: u8, + /// Bitmap encoding of the speed supported by this device when + /// operating in SuperSpeed mode. See \ref libusb_supported_speed. + pub wSpeedSupported: u16, + /// The lowest speed at which all the functionality supported + /// by the device is available to the user. For example if the + /// device supports all its functionality when connected at + /// full speed and above then it sets this value to 1. + pub bFunctionalitySupport: u8, + /// U1 Device Exit Latency. + pub bU1DevExitLat: u8, + /// U2 Device Exit Latency. + pub bU2DevExitLat: u16, +} +#[test] +fn bindgen_test_layout_libusb_ss_usb_device_capability_descriptor() { + assert_eq!( + ::std::mem::size_of::(), + 10usize, + concat!( + "Size of: ", + stringify!(libusb_ss_usb_device_capability_descriptor) + ) + ); + assert_eq!( + ::std::mem::align_of::(), + 2usize, + concat!( + "Alignment of ", + stringify!(libusb_ss_usb_device_capability_descriptor) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bLength + as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(libusb_ss_usb_device_capability_descriptor), + "::", + stringify!(bLength) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bDescriptorType + as *const _ as usize + }, + 1usize, + concat!( + "Offset of field: ", + stringify!(libusb_ss_usb_device_capability_descriptor), + "::", + stringify!(bDescriptorType) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())) + .bDevCapabilityType as *const _ as usize + }, + 2usize, + concat!( + "Offset of field: ", + stringify!(libusb_ss_usb_device_capability_descriptor), + "::", + stringify!(bDevCapabilityType) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bmAttributes + as *const _ as usize + }, + 3usize, + concat!( + "Offset of field: ", + stringify!(libusb_ss_usb_device_capability_descriptor), + "::", + stringify!(bmAttributes) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).wSpeedSupported + as *const _ as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(libusb_ss_usb_device_capability_descriptor), + "::", + stringify!(wSpeedSupported) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())) + .bFunctionalitySupport as *const _ as usize + }, + 6usize, + concat!( + "Offset of field: ", + stringify!(libusb_ss_usb_device_capability_descriptor), + "::", + stringify!(bFunctionalitySupport) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bU1DevExitLat + as *const _ as usize + }, + 7usize, + concat!( + "Offset of field: ", + stringify!(libusb_ss_usb_device_capability_descriptor), + "::", + stringify!(bU1DevExitLat) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bU2DevExitLat + as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(libusb_ss_usb_device_capability_descriptor), + "::", + stringify!(bU2DevExitLat) + ) + ); +} +/// \ingroup libusb_desc +/// A structure representing the Container ID descriptor. +/// This descriptor is documented in section 9.6.2.3 of the USB 3.0 specification. +/// All multiple-byte fields, except UUIDs, are represented in host-endian format. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct libusb_container_id_descriptor { + /// Size of this descriptor (in bytes) + pub bLength: u8, + /// Descriptor type. Will have value + /// \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY + /// LIBUSB_DT_DEVICE_CAPABILITY in this context. + pub bDescriptorType: u8, + /// Capability type. Will have value + /// \ref libusb_capability_type::LIBUSB_BT_CONTAINER_ID + /// LIBUSB_BT_CONTAINER_ID in this context. + pub bDevCapabilityType: u8, + /// Reserved field + pub bReserved: u8, + /// 128 bit UUID + pub ContainerID: [u8; 16usize], +} +#[test] +fn bindgen_test_layout_libusb_container_id_descriptor() { + assert_eq!( + ::std::mem::size_of::(), + 20usize, + concat!("Size of: ", stringify!(libusb_container_id_descriptor)) + ); + assert_eq!( + ::std::mem::align_of::(), + 1usize, + concat!("Alignment of ", stringify!(libusb_container_id_descriptor)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bLength as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(libusb_container_id_descriptor), + "::", + stringify!(bLength) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bDescriptorType as *const _ + as usize + }, + 1usize, + concat!( + "Offset of field: ", + stringify!(libusb_container_id_descriptor), + "::", + stringify!(bDescriptorType) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bDevCapabilityType + as *const _ as usize + }, + 2usize, + concat!( + "Offset of field: ", + stringify!(libusb_container_id_descriptor), + "::", + stringify!(bDevCapabilityType) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bReserved as *const _ + as usize + }, + 3usize, + concat!( + "Offset of field: ", + stringify!(libusb_container_id_descriptor), + "::", + stringify!(bReserved) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).ContainerID as *const _ + as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(libusb_container_id_descriptor), + "::", + stringify!(ContainerID) + ) + ); +} +/// \ingroup libusb_asyncio +/// Setup packet for control transfers. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct libusb_control_setup { + /// Request type. Bits 0:4 determine recipient, see + /// \ref libusb_request_recipient. Bits 5:6 determine type, see + /// \ref libusb_request_type. Bit 7 determines data transfer direction, see + /// \ref libusb_endpoint_direction. + pub bmRequestType: u8, + /// Request. If the type bits of bmRequestType are equal to + /// \ref libusb_request_type::LIBUSB_REQUEST_TYPE_STANDARD + /// "LIBUSB_REQUEST_TYPE_STANDARD" then this field refers to + /// \ref libusb_standard_request. For other cases, use of this field is + /// application-specific. + pub bRequest: u8, + /// Value. Varies according to request + pub wValue: u16, + /// Index. Varies according to request, typically used to pass an index + /// or offset + pub wIndex: u16, + /// Number of bytes to transfer + pub wLength: u16, +} +#[test] +fn bindgen_test_layout_libusb_control_setup() { + assert_eq!( + ::std::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(libusb_control_setup)) + ); + assert_eq!( + ::std::mem::align_of::(), + 2usize, + concat!("Alignment of ", stringify!(libusb_control_setup)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).bmRequestType as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(libusb_control_setup), + "::", + stringify!(bmRequestType) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).bRequest as *const _ as usize }, + 1usize, + concat!( + "Offset of field: ", + stringify!(libusb_control_setup), + "::", + stringify!(bRequest) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).wValue as *const _ as usize }, + 2usize, + concat!( + "Offset of field: ", + stringify!(libusb_control_setup), + "::", + stringify!(wValue) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).wIndex as *const _ as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(libusb_control_setup), + "::", + stringify!(wIndex) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).wLength as *const _ as usize }, + 6usize, + concat!( + "Offset of field: ", + stringify!(libusb_control_setup), + "::", + stringify!(wLength) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct libusb_context { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct libusb_device { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct libusb_device_handle { + _unused: [u8; 0], +} +/// \ingroup libusb_lib +/// Structure providing the version of the libusb runtime +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct libusb_version { + /// Library major version. + pub major: u16, + /// Library minor version. + pub minor: u16, + /// Library micro version. + pub micro: u16, + /// Library nano version. + pub nano: u16, + /// Library release candidate suffix string, e.g. "-rc4". + pub rc: *const ::std::os::raw::c_char, + /// For ABI compatibility only. + pub describe: *const ::std::os::raw::c_char, +} +#[test] +fn bindgen_test_layout_libusb_version() { + assert_eq!( + ::std::mem::size_of::(), + 24usize, + concat!("Size of: ", stringify!(libusb_version)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(libusb_version)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).major as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(libusb_version), + "::", + stringify!(major) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).minor as *const _ as usize }, + 2usize, + concat!( + "Offset of field: ", + stringify!(libusb_version), + "::", + stringify!(minor) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).micro as *const _ as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(libusb_version), + "::", + stringify!(micro) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).nano as *const _ as usize }, + 6usize, + concat!( + "Offset of field: ", + stringify!(libusb_version), + "::", + stringify!(nano) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).rc as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(libusb_version), + "::", + stringify!(rc) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).describe as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(libusb_version), + "::", + stringify!(describe) + ) + ); +} +/// The OS doesn't report or know the device speed. +pub const LIBUSB_SPEED_UNKNOWN: libusb_speed = 0; +/// The device is operating at low speed (1.5MBit/s). +pub const LIBUSB_SPEED_LOW: libusb_speed = 1; +/// The device is operating at full speed (12MBit/s). +pub const LIBUSB_SPEED_FULL: libusb_speed = 2; +/// The device is operating at high speed (480MBit/s). +pub const LIBUSB_SPEED_HIGH: libusb_speed = 3; +/// The device is operating at super speed (5000MBit/s). +pub const LIBUSB_SPEED_SUPER: libusb_speed = 4; +/// \ingroup libusb_dev +/// Speed codes. Indicates the speed at which the device is operating. +pub type libusb_speed = u32; +/// Low speed operation supported (1.5MBit/s). +pub const LIBUSB_LOW_SPEED_OPERATION: libusb_supported_speed = 1; +/// Full speed operation supported (12MBit/s). +pub const LIBUSB_FULL_SPEED_OPERATION: libusb_supported_speed = 2; +/// High speed operation supported (480MBit/s). +pub const LIBUSB_HIGH_SPEED_OPERATION: libusb_supported_speed = 4; +/// Superspeed operation supported (5000MBit/s). +pub const LIBUSB_SUPER_SPEED_OPERATION: libusb_supported_speed = 8; +/// \ingroup libusb_dev +/// Supported speeds (wSpeedSupported) bitfield. Indicates what +/// speeds the device supports. +pub type libusb_supported_speed = u32; +/// Supports Link Power Management (LPM) +pub const LIBUSB_BM_LPM_SUPPORT: libusb_usb_2_0_extension_attributes = 2; +/// \ingroup libusb_dev +/// Masks for the bits of the +/// \ref libusb_usb_2_0_extension_descriptor::bmAttributes "bmAttributes" field +/// of the USB 2.0 Extension descriptor. +pub type libusb_usb_2_0_extension_attributes = u32; +/// Supports Latency Tolerance Messages (LTM) +pub const LIBUSB_BM_LTM_SUPPORT: libusb_ss_usb_device_capability_attributes = 2; +/// \ingroup libusb_dev +/// Masks for the bits of the +/// \ref libusb_ss_usb_device_capability_descriptor::bmAttributes "bmAttributes" field +/// field of the SuperSpeed USB Device Capability descriptor. +pub type libusb_ss_usb_device_capability_attributes = u32; +/// Wireless USB device capability +pub const LIBUSB_BT_WIRELESS_USB_DEVICE_CAPABILITY: libusb_bos_type = 1; +/// USB 2.0 extensions +pub const LIBUSB_BT_USB_2_0_EXTENSION: libusb_bos_type = 2; +/// SuperSpeed USB device capability +pub const LIBUSB_BT_SS_USB_DEVICE_CAPABILITY: libusb_bos_type = 3; +/// Container ID type +pub const LIBUSB_BT_CONTAINER_ID: libusb_bos_type = 4; +/// \ingroup libusb_dev +/// USB capability types +pub type libusb_bos_type = u32; +/// Success (no error) +pub const LIBUSB_SUCCESS: libusb_error = 0; +/// Input/output error +pub const LIBUSB_ERROR_IO: libusb_error = -1; +/// Invalid parameter +pub const LIBUSB_ERROR_INVALID_PARAM: libusb_error = -2; +/// Access denied (insufficient permissions) +pub const LIBUSB_ERROR_ACCESS: libusb_error = -3; +/// No such device (it may have been disconnected) +pub const LIBUSB_ERROR_NO_DEVICE: libusb_error = -4; +/// Entity not found +pub const LIBUSB_ERROR_NOT_FOUND: libusb_error = -5; +/// Resource busy +pub const LIBUSB_ERROR_BUSY: libusb_error = -6; +/// Operation timed out +pub const LIBUSB_ERROR_TIMEOUT: libusb_error = -7; +/// Overflow +pub const LIBUSB_ERROR_OVERFLOW: libusb_error = -8; +/// Pipe error +pub const LIBUSB_ERROR_PIPE: libusb_error = -9; +/// System call interrupted (perhaps due to signal) +pub const LIBUSB_ERROR_INTERRUPTED: libusb_error = -10; +/// Insufficient memory +pub const LIBUSB_ERROR_NO_MEM: libusb_error = -11; +/// Operation not supported or unimplemented on this platform +pub const LIBUSB_ERROR_NOT_SUPPORTED: libusb_error = -12; +/// Other error +pub const LIBUSB_ERROR_OTHER: libusb_error = -99; +/// \ingroup libusb_misc +/// Error codes. Most libusb functions return 0 on success or one of these +/// codes on failure. +/// You can call libusb_error_name() to retrieve a string representation of an +/// error code or libusb_strerror() to get an end-user suitable description of +/// an error code. +pub type libusb_error = i32; +/// Transfer completed without error. Note that this does not indicate +/// that the entire amount of requested data was transferred. +pub const LIBUSB_TRANSFER_COMPLETED: libusb_transfer_status = 0; +/// Transfer failed +pub const LIBUSB_TRANSFER_ERROR: libusb_transfer_status = 1; +/// Transfer timed out +pub const LIBUSB_TRANSFER_TIMED_OUT: libusb_transfer_status = 2; +/// Transfer was cancelled +pub const LIBUSB_TRANSFER_CANCELLED: libusb_transfer_status = 3; +/// For bulk/interrupt endpoints: halt condition detected (endpoint +/// stalled). For control endpoints: control request not supported. +pub const LIBUSB_TRANSFER_STALL: libusb_transfer_status = 4; +/// Device was disconnected +pub const LIBUSB_TRANSFER_NO_DEVICE: libusb_transfer_status = 5; +/// Device sent more data than requested +pub const LIBUSB_TRANSFER_OVERFLOW: libusb_transfer_status = 6; +/// \ingroup libusb_asyncio +/// Transfer status codes +pub type libusb_transfer_status = u32; +/// Report short frames as errors +pub const LIBUSB_TRANSFER_SHORT_NOT_OK: libusb_transfer_flags = 1; +/// Automatically free() transfer buffer during libusb_free_transfer(). +/// Note that buffers allocated with libusb_dev_mem_alloc() should not +/// be attempted freed in this way, since free() is not an appropriate +/// way to release such memory. +pub const LIBUSB_TRANSFER_FREE_BUFFER: libusb_transfer_flags = 2; +/// Automatically call libusb_free_transfer() after callback returns. +/// If this flag is set, it is illegal to call libusb_free_transfer() +/// from your transfer callback, as this will result in a double-free +/// when this flag is acted upon. +pub const LIBUSB_TRANSFER_FREE_TRANSFER: libusb_transfer_flags = 4; +/// Terminate transfers that are a multiple of the endpoint's +/// wMaxPacketSize with an extra zero length packet. This is useful +/// when a device protocol mandates that each logical request is +/// terminated by an incomplete packet (i.e. the logical requests are +/// not separated by other means). +/// +/// This flag only affects host-to-device transfers to bulk and interrupt +/// endpoints. In other situations, it is ignored. +/// +/// This flag only affects transfers with a length that is a multiple of +/// the endpoint's wMaxPacketSize. On transfers of other lengths, this +/// flag has no effect. Therefore, if you are working with a device that +/// needs a ZLP whenever the end of the logical request falls on a packet +/// boundary, then it is sensible to set this flag on every +/// transfer (you do not have to worry about only setting it on transfers +/// that end on the boundary). +/// +/// This flag is currently only supported on Linux. +/// On other systems, libusb_submit_transfer() will return +/// LIBUSB_ERROR_NOT_SUPPORTED for every transfer where this flag is set. +/// +/// Available since libusb-1.0.9. +pub const LIBUSB_TRANSFER_ADD_ZERO_PACKET: libusb_transfer_flags = 8; +/// \ingroup libusb_asyncio +/// libusb_transfer.flags values +pub type libusb_transfer_flags = u32; +/// \ingroup libusb_asyncio +/// Isochronous packet descriptor. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct libusb_iso_packet_descriptor { + /// Length of data to request in this packet + pub length: ::std::os::raw::c_uint, + /// Amount of data that was actually transferred + pub actual_length: ::std::os::raw::c_uint, + /// Status code for this packet + pub status: libusb_transfer_status, +} +#[test] +fn bindgen_test_layout_libusb_iso_packet_descriptor() { + assert_eq!( + ::std::mem::size_of::(), + 12usize, + concat!("Size of: ", stringify!(libusb_iso_packet_descriptor)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(libusb_iso_packet_descriptor)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).length as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(libusb_iso_packet_descriptor), + "::", + stringify!(length) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).actual_length as *const _ + as usize + }, + 4usize, + concat!( + "Offset of field: ", + stringify!(libusb_iso_packet_descriptor), + "::", + stringify!(actual_length) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).status as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(libusb_iso_packet_descriptor), + "::", + stringify!(status) + ) + ); +} +/// \ingroup libusb_asyncio +/// Asynchronous transfer callback function type. When submitting asynchronous +/// transfers, you pass a pointer to a callback function of this type via the +/// \ref libusb_transfer::callback "callback" member of the libusb_transfer +/// structure. libusb will call this function later, when the transfer has +/// completed or failed. See \ref libusb_asyncio for more information. +/// \param transfer The libusb_transfer struct the callback function is being +/// notified about. +pub type libusb_transfer_cb_fn = + ::std::option::Option; +/// \ingroup libusb_asyncio +/// The generic USB transfer structure. The user populates this structure and +/// then submits it in order to request a transfer. After the transfer has +/// completed, the library populates the transfer with the results and passes +/// it back to the user. +#[repr(C)] +#[derive(Debug)] +pub struct libusb_transfer { + /// Handle of the device that this transfer will be submitted to + pub dev_handle: *mut libusb_device_handle, + /// A bitwise OR combination of \ref libusb_transfer_flags. + pub flags: u8, + /// Address of the endpoint where this transfer will be sent. + pub endpoint: ::std::os::raw::c_uchar, + /// Type of the endpoint from \ref libusb_transfer_type + pub type_: ::std::os::raw::c_uchar, + /// Timeout for this transfer in millseconds. A value of 0 indicates no + /// timeout. + pub timeout: ::std::os::raw::c_uint, + /// The status of the transfer. Read-only, and only for use within + /// transfer callback function. + /// + /// If this is an isochronous transfer, this field may read COMPLETED even + /// if there were errors in the frames. Use the + /// \ref libusb_iso_packet_descriptor::status "status" field in each packet + /// to determine if errors occurred. + pub status: libusb_transfer_status, + /// Length of the data buffer + pub length: ::std::os::raw::c_int, + /// Actual length of data that was transferred. Read-only, and only for + /// use within transfer callback function. Not valid for isochronous + /// endpoint transfers. + pub actual_length: ::std::os::raw::c_int, + /// Callback function. This will be invoked when the transfer completes, + /// fails, or is cancelled. + pub callback: libusb_transfer_cb_fn, + /// User context data to pass to the callback function. + pub user_data: *mut ::std::os::raw::c_void, + /// Data buffer + pub buffer: *mut ::std::os::raw::c_uchar, + /// Number of isochronous packets. Only used for I/O with isochronous + /// endpoints. + pub num_iso_packets: ::std::os::raw::c_int, + /// Isochronous packet descriptors, for isochronous transfers only. + pub iso_packet_desc: __IncompleteArrayField, +} +#[test] +fn bindgen_test_layout_libusb_transfer() { + assert_eq!( + ::std::mem::size_of::(), + 64usize, + concat!("Size of: ", stringify!(libusb_transfer)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(libusb_transfer)) + ); +} +/// The libusb_has_capability() API is available. +pub const LIBUSB_CAP_HAS_CAPABILITY: libusb_capability = 0; +/// Hotplug support is available on this platform. +pub const LIBUSB_CAP_HAS_HOTPLUG: libusb_capability = 1; +/// The library can access HID devices without requiring user intervention. +/// Note that before being able to actually access an HID device, you may +/// still have to call additional libusb functions such as +/// \ref libusb_detach_kernel_driver(). +pub const LIBUSB_CAP_HAS_HID_ACCESS: libusb_capability = 256; +/// The library supports detaching of the default USB driver, using +/// \ref libusb_detach_kernel_driver(), if one is set by the OS kernel +pub const LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER: libusb_capability = 257; +/// \ingroup libusb_misc +/// Capabilities supported by an instance of libusb on the current running +/// platform. Test if the loaded library supports a given capability by calling +/// \ref libusb_has_capability(). +pub type libusb_capability = u32; +pub const LIBUSB_LOG_LEVEL_NONE: libusb_log_level = 0; +pub const LIBUSB_LOG_LEVEL_ERROR: libusb_log_level = 1; +pub const LIBUSB_LOG_LEVEL_WARNING: libusb_log_level = 2; +pub const LIBUSB_LOG_LEVEL_INFO: libusb_log_level = 3; +pub const LIBUSB_LOG_LEVEL_DEBUG: libusb_log_level = 4; +/// \ingroup libusb_lib +/// Log message levels. +/// - LIBUSB_LOG_LEVEL_NONE (0) : no messages ever printed by the library (default) +/// - LIBUSB_LOG_LEVEL_ERROR (1) : error messages are printed to stderr +/// - LIBUSB_LOG_LEVEL_WARNING (2) : warning and error messages are printed to stderr +/// - LIBUSB_LOG_LEVEL_INFO (3) : informational messages are printed to stdout, warning +/// and error messages are printed to stderr +/// - LIBUSB_LOG_LEVEL_DEBUG (4) : debug and informational messages are printed to stdout, +/// warnings and errors to stderr +pub type libusb_log_level = u32; +extern "C" { + pub fn libusb_init(ctx: *mut *mut libusb_context) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_exit(ctx: *mut libusb_context); +} +extern "C" { + pub fn libusb_set_debug(ctx: *mut libusb_context, level: ::std::os::raw::c_int); +} +extern "C" { + pub fn libusb_get_version() -> *const libusb_version; +} +extern "C" { + pub fn libusb_has_capability(capability: u32) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_error_name(errcode: ::std::os::raw::c_int) -> *const ::std::os::raw::c_char; +} +extern "C" { + pub fn libusb_setlocale(locale: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_strerror(errcode: libusb_error) -> *const ::std::os::raw::c_char; +} +extern "C" { + pub fn libusb_get_device_list( + ctx: *mut libusb_context, + list: *mut *mut *mut libusb_device, + ) -> isize; +} +extern "C" { + pub fn libusb_free_device_list( + list: *mut *mut libusb_device, + unref_devices: ::std::os::raw::c_int, + ); +} +extern "C" { + pub fn libusb_ref_device(dev: *mut libusb_device) -> *mut libusb_device; +} +extern "C" { + pub fn libusb_unref_device(dev: *mut libusb_device); +} +extern "C" { + pub fn libusb_get_configuration( + dev: *mut libusb_device_handle, + config: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_get_device_descriptor( + dev: *mut libusb_device, + desc: *mut libusb_device_descriptor, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_get_active_config_descriptor( + dev: *mut libusb_device, + config: *mut *mut libusb_config_descriptor, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_get_config_descriptor( + dev: *mut libusb_device, + config_index: u8, + config: *mut *mut libusb_config_descriptor, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_get_config_descriptor_by_value( + dev: *mut libusb_device, + bConfigurationValue: u8, + config: *mut *mut libusb_config_descriptor, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_free_config_descriptor(config: *mut libusb_config_descriptor); +} +extern "C" { + pub fn libusb_get_ss_endpoint_companion_descriptor( + ctx: *mut libusb_context, + endpoint: *const libusb_endpoint_descriptor, + ep_comp: *mut *mut libusb_ss_endpoint_companion_descriptor, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_free_ss_endpoint_companion_descriptor( + ep_comp: *mut libusb_ss_endpoint_companion_descriptor, + ); +} +extern "C" { + pub fn libusb_get_bos_descriptor( + dev_handle: *mut libusb_device_handle, + bos: *mut *mut libusb_bos_descriptor, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_free_bos_descriptor(bos: *mut libusb_bos_descriptor); +} +extern "C" { + pub fn libusb_get_usb_2_0_extension_descriptor( + ctx: *mut libusb_context, + dev_cap: *mut libusb_bos_dev_capability_descriptor, + usb_2_0_extension: *mut *mut libusb_usb_2_0_extension_descriptor, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_free_usb_2_0_extension_descriptor( + usb_2_0_extension: *mut libusb_usb_2_0_extension_descriptor, + ); +} +extern "C" { + pub fn libusb_get_ss_usb_device_capability_descriptor( + ctx: *mut libusb_context, + dev_cap: *mut libusb_bos_dev_capability_descriptor, + ss_usb_device_cap: *mut *mut libusb_ss_usb_device_capability_descriptor, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_free_ss_usb_device_capability_descriptor( + ss_usb_device_cap: *mut libusb_ss_usb_device_capability_descriptor, + ); +} +extern "C" { + pub fn libusb_get_container_id_descriptor( + ctx: *mut libusb_context, + dev_cap: *mut libusb_bos_dev_capability_descriptor, + container_id: *mut *mut libusb_container_id_descriptor, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_free_container_id_descriptor(container_id: *mut libusb_container_id_descriptor); +} +extern "C" { + pub fn libusb_get_bus_number(dev: *mut libusb_device) -> u8; +} +extern "C" { + pub fn libusb_get_port_number(dev: *mut libusb_device) -> u8; +} +extern "C" { + pub fn libusb_get_port_numbers( + dev: *mut libusb_device, + port_numbers: *mut u8, + port_numbers_len: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_get_port_path( + ctx: *mut libusb_context, + dev: *mut libusb_device, + path: *mut u8, + path_length: u8, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_get_parent(dev: *mut libusb_device) -> *mut libusb_device; +} +extern "C" { + pub fn libusb_get_device_address(dev: *mut libusb_device) -> u8; +} +extern "C" { + pub fn libusb_get_device_speed(dev: *mut libusb_device) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_get_max_packet_size( + dev: *mut libusb_device, + endpoint: ::std::os::raw::c_uchar, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_get_max_iso_packet_size( + dev: *mut libusb_device, + endpoint: ::std::os::raw::c_uchar, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_open( + dev: *mut libusb_device, + dev_handle: *mut *mut libusb_device_handle, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_close(dev_handle: *mut libusb_device_handle); +} +extern "C" { + pub fn libusb_get_device(dev_handle: *mut libusb_device_handle) -> *mut libusb_device; +} +extern "C" { + pub fn libusb_set_configuration( + dev_handle: *mut libusb_device_handle, + configuration: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_claim_interface( + dev_handle: *mut libusb_device_handle, + interface_number: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_release_interface( + dev_handle: *mut libusb_device_handle, + interface_number: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_open_device_with_vid_pid( + ctx: *mut libusb_context, + vendor_id: u16, + product_id: u16, + ) -> *mut libusb_device_handle; +} +extern "C" { + pub fn libusb_set_interface_alt_setting( + dev_handle: *mut libusb_device_handle, + interface_number: ::std::os::raw::c_int, + alternate_setting: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_clear_halt( + dev_handle: *mut libusb_device_handle, + endpoint: ::std::os::raw::c_uchar, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_reset_device(dev_handle: *mut libusb_device_handle) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_alloc_streams( + dev_handle: *mut libusb_device_handle, + num_streams: u32, + endpoints: *mut ::std::os::raw::c_uchar, + num_endpoints: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_free_streams( + dev_handle: *mut libusb_device_handle, + endpoints: *mut ::std::os::raw::c_uchar, + num_endpoints: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_dev_mem_alloc( + dev_handle: *mut libusb_device_handle, + length: usize, + ) -> *mut ::std::os::raw::c_uchar; +} +extern "C" { + pub fn libusb_dev_mem_free( + dev_handle: *mut libusb_device_handle, + buffer: *mut ::std::os::raw::c_uchar, + length: usize, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_kernel_driver_active( + dev_handle: *mut libusb_device_handle, + interface_number: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_detach_kernel_driver( + dev_handle: *mut libusb_device_handle, + interface_number: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_attach_kernel_driver( + dev_handle: *mut libusb_device_handle, + interface_number: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_set_auto_detach_kernel_driver( + dev_handle: *mut libusb_device_handle, + enable: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_alloc_transfer(iso_packets: ::std::os::raw::c_int) -> *mut libusb_transfer; +} +extern "C" { + pub fn libusb_submit_transfer(transfer: *mut libusb_transfer) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_cancel_transfer(transfer: *mut libusb_transfer) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_free_transfer(transfer: *mut libusb_transfer); +} +extern "C" { + pub fn libusb_transfer_set_stream_id(transfer: *mut libusb_transfer, stream_id: u32); +} +extern "C" { + pub fn libusb_transfer_get_stream_id(transfer: *mut libusb_transfer) -> u32; +} +extern "C" { + pub fn libusb_control_transfer( + dev_handle: *mut libusb_device_handle, + request_type: u8, + bRequest: u8, + wValue: u16, + wIndex: u16, + data: *mut ::std::os::raw::c_uchar, + wLength: u16, + timeout: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_bulk_transfer( + dev_handle: *mut libusb_device_handle, + endpoint: ::std::os::raw::c_uchar, + data: *mut ::std::os::raw::c_uchar, + length: ::std::os::raw::c_int, + actual_length: *mut ::std::os::raw::c_int, + timeout: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_interrupt_transfer( + dev_handle: *mut libusb_device_handle, + endpoint: ::std::os::raw::c_uchar, + data: *mut ::std::os::raw::c_uchar, + length: ::std::os::raw::c_int, + actual_length: *mut ::std::os::raw::c_int, + timeout: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_get_string_descriptor_ascii( + dev_handle: *mut libusb_device_handle, + desc_index: u8, + data: *mut ::std::os::raw::c_uchar, + length: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_try_lock_events(ctx: *mut libusb_context) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_lock_events(ctx: *mut libusb_context); +} +extern "C" { + pub fn libusb_unlock_events(ctx: *mut libusb_context); +} +extern "C" { + pub fn libusb_event_handling_ok(ctx: *mut libusb_context) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_event_handler_active(ctx: *mut libusb_context) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_interrupt_event_handler(ctx: *mut libusb_context); +} +extern "C" { + pub fn libusb_lock_event_waiters(ctx: *mut libusb_context); +} +extern "C" { + pub fn libusb_unlock_event_waiters(ctx: *mut libusb_context); +} +extern "C" { + pub fn libusb_wait_for_event( + ctx: *mut libusb_context, + tv: *mut timeval, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_handle_events_timeout( + ctx: *mut libusb_context, + tv: *mut timeval, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_handle_events_timeout_completed( + ctx: *mut libusb_context, + tv: *mut timeval, + completed: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_handle_events(ctx: *mut libusb_context) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_handle_events_completed( + ctx: *mut libusb_context, + completed: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_handle_events_locked( + ctx: *mut libusb_context, + tv: *mut timeval, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_pollfds_handle_timeouts(ctx: *mut libusb_context) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn libusb_get_next_timeout( + ctx: *mut libusb_context, + tv: *mut timeval, + ) -> ::std::os::raw::c_int; +} +/// \ingroup libusb_poll +/// File descriptor for polling +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct libusb_pollfd { + /// Numeric file descriptor + pub fd: ::std::os::raw::c_int, + /// Event flags to poll for from . POLLIN indicates that you + /// should monitor this file descriptor for becoming ready to read from, + /// and POLLOUT indicates that you should monitor this file descriptor for + /// nonblocking write readiness. + pub events: ::std::os::raw::c_short, +} +#[test] +fn bindgen_test_layout_libusb_pollfd() { + assert_eq!( + ::std::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(libusb_pollfd)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(libusb_pollfd)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).fd as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(libusb_pollfd), + "::", + stringify!(fd) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).events as *const _ as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(libusb_pollfd), + "::", + stringify!(events) + ) + ); +} +/// \ingroup libusb_poll +/// Callback function, invoked when a new file descriptor should be added +/// to the set of file descriptors monitored for events. +/// \param fd the new file descriptor +/// \param events events to monitor for, see \ref libusb_pollfd for a +/// description +/// \param user_data User data pointer specified in +/// libusb_set_pollfd_notifiers() call +/// \see libusb_set_pollfd_notifiers() +pub type libusb_pollfd_added_cb = ::std::option::Option< + unsafe extern "C" fn( + fd: ::std::os::raw::c_int, + events: ::std::os::raw::c_short, + user_data: *mut ::std::os::raw::c_void, + ), +>; +/// \ingroup libusb_poll +/// Callback function, invoked when a file descriptor should be removed from +/// the set of file descriptors being monitored for events. After returning +/// from this callback, do not use that file descriptor again. +/// \param fd the file descriptor to stop monitoring +/// \param user_data User data pointer specified in +/// libusb_set_pollfd_notifiers() call +/// \see libusb_set_pollfd_notifiers() +pub type libusb_pollfd_removed_cb = ::std::option::Option< + unsafe extern "C" fn(fd: ::std::os::raw::c_int, user_data: *mut ::std::os::raw::c_void), +>; +extern "C" { + pub fn libusb_get_pollfds(ctx: *mut libusb_context) -> *mut *const libusb_pollfd; +} +extern "C" { + pub fn libusb_free_pollfds(pollfds: *mut *const libusb_pollfd); +} +extern "C" { + pub fn libusb_set_pollfd_notifiers( + ctx: *mut libusb_context, + added_cb: libusb_pollfd_added_cb, + removed_cb: libusb_pollfd_removed_cb, + user_data: *mut ::std::os::raw::c_void, + ); +} +/// \ingroup libusb_hotplug +/// Callback handle. +/// +/// Callbacks handles are generated by libusb_hotplug_register_callback() +/// and can be used to deregister callbacks. Callback handles are unique +/// per libusb_context and it is safe to call libusb_hotplug_deregister_callback() +/// on an already deregisted callback. +/// +/// Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 +/// +/// For more information, see \ref libusb_hotplug. +pub type libusb_hotplug_callback_handle = ::std::os::raw::c_int; +/// Default value when not using any flags. +pub const LIBUSB_HOTPLUG_NO_FLAGS: libusb_hotplug_flag = 0; +/// Arm the callback and fire it for all matching currently attached devices. +pub const LIBUSB_HOTPLUG_ENUMERATE: libusb_hotplug_flag = 1; +/// \ingroup libusb_hotplug +/// +/// Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 +/// +/// Flags for hotplug events +pub type libusb_hotplug_flag = u32; +/// A device has been plugged in and is ready to use +pub const LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED: libusb_hotplug_event = 1; +/// A device has left and is no longer available. +/// It is the user's responsibility to call libusb_close on any handle associated with a disconnected device. +/// It is safe to call libusb_get_device_descriptor on a device that has left +pub const LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT: libusb_hotplug_event = 2; +/// \ingroup libusb_hotplug +/// +/// Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 +/// +/// Hotplug events +pub type libusb_hotplug_event = u32; +/// \ingroup libusb_hotplug +/// Hotplug callback function type. When requesting hotplug event notifications, +/// you pass a pointer to a callback function of this type. +/// +/// This callback may be called by an internal event thread and as such it is +/// recommended the callback do minimal processing before returning. +/// +/// libusb will call this function later, when a matching event had happened on +/// a matching device. See \ref libusb_hotplug for more information. +/// +/// It is safe to call either libusb_hotplug_register_callback() or +/// libusb_hotplug_deregister_callback() from within a callback function. +/// +/// Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 +/// +/// \param ctx context of this notification +/// \param device libusb_device this event occurred on +/// \param event event that occurred +/// \param user_data user data provided when this callback was registered +/// \returns bool whether this callback is finished processing events. +/// returning 1 will cause this callback to be deregistered +pub type libusb_hotplug_callback_fn = ::std::option::Option< + unsafe extern "C" fn( + ctx: *mut libusb_context, + device: *mut libusb_device, + event: libusb_hotplug_event, + user_data: *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int, +>; +extern "C" { + /// \ingroup libusb_hotplug + /// Register a hotplug callback function + /// + /// Register a callback with the libusb_context. The callback will fire + /// when a matching event occurs on a matching device. The callback is + /// armed until either it is deregistered with libusb_hotplug_deregister_callback() + /// or the supplied callback returns 1 to indicate it is finished processing events. + /// + /// If the \ref LIBUSB_HOTPLUG_ENUMERATE is passed the callback will be + /// called with a \ref LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED for all devices + /// already plugged into the machine. Note that libusb modifies its internal + /// device list from a separate thread, while calling hotplug callbacks from + /// libusb_handle_events(), so it is possible for a device to already be present + /// on, or removed from, its internal device list, while the hotplug callbacks + /// still need to be dispatched. This means that when using \ref + /// LIBUSB_HOTPLUG_ENUMERATE, your callback may be called twice for the arrival + /// of the same device, once from libusb_hotplug_register_callback() and once + /// from libusb_handle_events(); and/or your callback may be called for the + /// removal of a device for which an arrived call was never made. + /// + /// Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + /// + /// \param[in] ctx context to register this callback with + /// \param[in] events bitwise or of events that will trigger this callback. See \ref + /// libusb_hotplug_event + /// \param[in] flags hotplug callback flags. See \ref libusb_hotplug_flag + /// \param[in] vendor_id the vendor id to match or \ref LIBUSB_HOTPLUG_MATCH_ANY + /// \param[in] product_id the product id to match or \ref LIBUSB_HOTPLUG_MATCH_ANY + /// \param[in] dev_class the device class to match or \ref LIBUSB_HOTPLUG_MATCH_ANY + /// \param[in] cb_fn the function to be invoked on a matching event/device + /// \param[in] user_data user data to pass to the callback function + /// \param[out] callback_handle pointer to store the handle of the allocated callback (can be NULL) + /// \returns LIBUSB_SUCCESS on success LIBUSB_ERROR code on failure + pub fn libusb_hotplug_register_callback( + ctx: *mut libusb_context, + events: libusb_hotplug_event, + flags: libusb_hotplug_flag, + vendor_id: ::std::os::raw::c_int, + product_id: ::std::os::raw::c_int, + dev_class: ::std::os::raw::c_int, + cb_fn: libusb_hotplug_callback_fn, + user_data: *mut ::std::os::raw::c_void, + callback_handle: *mut libusb_hotplug_callback_handle, + ) -> ::std::os::raw::c_int; +} +extern "C" { + /// \ingroup libusb_hotplug + /// Deregisters a hotplug callback. + /// + /// Deregister a callback from a libusb_context. This function is safe to call from within + /// a hotplug callback. + /// + /// Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + /// + /// \param[in] ctx context this callback is registered with + /// \param[in] callback_handle the handle of the callback to deregister + pub fn libusb_hotplug_deregister_callback( + ctx: *mut libusb_context, + callback_handle: libusb_hotplug_callback_handle, + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __locale_data { + pub _address: u8, +} diff --git a/usb_util/src/config_descriptor.rs b/usb_util/src/config_descriptor.rs new file mode 100644 index 0000000..37bd7d6 --- /dev/null +++ b/usb_util/src/config_descriptor.rs @@ -0,0 +1,32 @@ +// Copyright 2018 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +use bindings; +use bindings::libusb_config_descriptor; + +/// ConfigDescriptor wraps libusb_config_descriptor. +/// TODO(jkwang) Add utility functions to make ConfigDescriptor actually useful. +pub struct ConfigDescriptor { + descriptor: *mut libusb_config_descriptor, +} + +impl Drop for ConfigDescriptor { + // Free configuration descriptor. + // Safe because 'self' is intialized with a valid libusb_config_descriptor from libusb + // functions. + fn drop(&mut self) { + unsafe { + bindings::libusb_free_config_descriptor(self.descriptor); + } + } +} + +impl ConfigDescriptor { + /// Build ConfigDescriptor. 'descriptor' should be a valid pointer from + /// libusb_config_descriptor. This function will panic if it's null. + pub unsafe fn new(descriptor: *mut libusb_config_descriptor) -> ConfigDescriptor { + assert!(!descriptor.is_null()); + ConfigDescriptor { descriptor } + } +} diff --git a/usb_util/src/device_handle.rs b/usb_util/src/device_handle.rs new file mode 100644 index 0000000..e07f6f2 --- /dev/null +++ b/usb_util/src/device_handle.rs @@ -0,0 +1,129 @@ +// Copyright 2018 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +use std::os::raw::c_int; +use std::sync::Arc; + +use bindings; +use error::{Error, Result}; +use libusb_context::LibUsbContextInner; + +/// DeviceHandle wraps libusb_device_handle. +pub struct DeviceHandle { + _context: Arc, + handle: *mut bindings::libusb_device_handle, +} + +unsafe impl Send for DeviceHandle {} + +impl Drop for DeviceHandle { + fn drop(&mut self) { + // Safe because self.handle is a valid pointer to libusb_device_handle. + unsafe { + bindings::libusb_close(self.handle); + } + } +} + +impl DeviceHandle { + /// Create a new DeviceHande. 'handle' should be a valid pointer to libusb_device_handle. + pub unsafe fn new( + ctx: Arc, + handle: *mut bindings::libusb_device_handle, + ) -> DeviceHandle { + DeviceHandle { + _context: ctx, + handle, + } + } + + /// Get bConfigurationValue of the currently active configuration. + pub fn get_active_configuration(&self) -> Result { + let mut config: c_int = 0; + // Safe because 'self.handle' is a valid pointer to device handle and '&mut config' is a + // valid output location. + try_libusb!(unsafe { bindings::libusb_get_configuration(self.handle, &mut config) }); + Ok(config as i32) + } + + /// Set active configuration for a device. + pub fn set_active_configuration(&mut self, config: i32) -> Result<()> { + // Safe because 'self.handle' is a valid pointer to device handle. + try_libusb!(unsafe { bindings::libusb_set_configuration(self.handle, config as c_int) }); + Ok(()) + } + + /// Claim an interface on this deivce handle. + pub fn claim_interface(&self, interface_number: i32) -> Result<()> { + // Safe because 'self.handle' is a valid pointer to device handle. + try_libusb!(unsafe { bindings::libusb_claim_interface(self.handle, interface_number) }); + Ok(()) + } + + /// Release an interface previously claimed with libusb_claim_interface. + pub fn release_interface(&self, interface_number: i32) -> Result<()> { + // Safe because 'self.handle' is a valid pointer to device handle. + try_libusb!(unsafe { bindings::libusb_release_interface(self.handle, interface_number) }); + Ok(()) + } + + /// Perform a USB port reset to reinitialize a device. + pub fn reset_device(&self) -> Result<()> { + // Safe because 'self.handle' is a valid pointer to device handle. + try_libusb!(unsafe { bindings::libusb_reset_device(self.handle) }); + Ok(()) + } + + /// Determine if a kernel driver is active on an interface. + pub fn kernel_driver_active(&self, interface_number: i32) -> Result { + // Safe because 'self.handle' is a valid pointer to device handle. + let v = try_libusb!(unsafe { + bindings::libusb_kernel_driver_active(self.handle, interface_number) + }); + Ok(v != 0) + } + + /// Detach a kernel driver from an interface. + pub fn detach_kernel_driver(&self, interface_number: i32) -> Result<()> { + // Safe because 'self.handle' is a valid pointer to device handle. + try_libusb!(unsafe { + bindings::libusb_detach_kernel_driver(self.handle, interface_number) + }); + Ok(()) + } + + /// Re-attach an interfae's kernel driver, which was previously detached using + /// detach_kernel_driver. + pub fn attach_kernel_driver(&self, interface_number: i32) -> Result<()> { + // Safe because 'self.handle' is a valid pointer to device handle. + try_libusb!(unsafe { + bindings::libusb_attach_kernel_driver(self.handle, interface_number) + }); + Ok(()) + } + + /// Active an alternate setting for an interface. + pub fn set_interface_alt_setting( + &self, + interface_number: i32, + alternative_setting: i32, + ) -> Result<()> { + // Safe because 'self.handle' is a valid pointer to device handle. + try_libusb!(unsafe { + bindings::libusb_set_interface_alt_setting( + self.handle, + interface_number, + alternative_setting, + ) + }); + Ok(()) + } + + /// Clear the halt/stall condition for an endpoint. + pub fn clear_halt(&self, endpoint: u8) -> Result<()> { + // Safe because 'self.handle' is a valid pointer to device handle. + try_libusb!(unsafe { bindings::libusb_clear_halt(self.handle, endpoint) }); + Ok(()) + } +} diff --git a/usb_util/src/error.rs b/usb_util/src/error.rs new file mode 100644 index 0000000..6ba5421 --- /dev/null +++ b/usb_util/src/error.rs @@ -0,0 +1,85 @@ +// Copyright 2018 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +use std; +use std::fmt; + +use bindings; + +/// Error type for libusb. +pub enum Error { + Success(i32), + IO, + InvalidParam, + Access, + NoDevice, + NotFound, + Busy, + Timeout, + Overflow, + Pipe, + Interrupted, + NoMem, + NotSupported, + Other, +} + +impl fmt::Debug for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + &Error::Success(_v) => write!(f, "Success (no error)"), + &Error::IO => write!(f, "Input/output error"), + &Error::InvalidParam => write!(f, "Invalid parameter"), + &Error::Access => write!(f, "Access denied (insufficient permissions)"), + &Error::NoDevice => write!(f, "No such device (it may have been disconnected)"), + &Error::NotFound => write!(f, "Entity not found"), + &Error::Busy => write!(f, "Resource busy"), + &Error::Timeout => write!(f, "Operation timed out"), + &Error::Overflow => write!(f, "Overflow"), + &Error::Pipe => write!(f, "Pipe error"), + &Error::Interrupted => write!(f, "System call interrupted (perhaps due to signal)"), + &Error::NoMem => write!(f, "Insufficient memory"), + &Error::NotSupported => write!( + f, + "Operation not supported or unimplemented on this platform" + ), + &Error::Other => write!(f, "Other error"), + } + } +} + +impl From for Error { + fn from(e: bindings::libusb_error) -> Self { + match e { + bindings::LIBUSB_ERROR_IO => Error::IO, + bindings::LIBUSB_ERROR_INVALID_PARAM => Error::InvalidParam, + bindings::LIBUSB_ERROR_ACCESS => Error::Access, + bindings::LIBUSB_ERROR_NO_DEVICE => Error::NoDevice, + bindings::LIBUSB_ERROR_NOT_FOUND => Error::NotFound, + bindings::LIBUSB_ERROR_BUSY => Error::Busy, + bindings::LIBUSB_ERROR_TIMEOUT => Error::Timeout, + bindings::LIBUSB_ERROR_OVERFLOW => Error::Overflow, + bindings::LIBUSB_ERROR_PIPE => Error::Pipe, + bindings::LIBUSB_ERROR_INTERRUPTED => Error::Interrupted, + bindings::LIBUSB_ERROR_NO_MEM => Error::NoMem, + bindings::LIBUSB_ERROR_NOT_SUPPORTED => Error::NotSupported, + bindings::LIBUSB_ERROR_OTHER => Error::Other, + // All possible errors are defined above, other values mean success, + // see libusb_get_device_list for example. + _ => Error::Success(e), + } + } +} + +pub type Result = std::result::Result; + +#[macro_export] +macro_rules! try_libusb { + ($x:expr) => { + match Error::from($x as i32) { + Error::Success(e) => e, + err => return Err(err), + } + }; +} diff --git a/usb_util/src/lib.rs b/usb_util/src/lib.rs new file mode 100644 index 0000000..0860d71 --- /dev/null +++ b/usb_util/src/lib.rs @@ -0,0 +1,19 @@ +// Copyright 2018 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Generated with bindgen libusb.h -no-prepend-enum-name -o bindings.rs. +#![allow(dead_code)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +mod bindings; + +extern crate data_model; +#[macro_use] +pub mod error; +pub mod config_descriptor; +pub mod device_handle; +pub mod libusb_context; +pub mod libusb_device; +pub mod types; diff --git a/usb_util/src/libusb_context.rs b/usb_util/src/libusb_context.rs new file mode 100644 index 0000000..821d2ad --- /dev/null +++ b/usb_util/src/libusb_context.rs @@ -0,0 +1,156 @@ +// Copyright 2018 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +use std; + +use bindings; +use error::{Error, Result}; +use libusb_device::LibUsbDevice; +use std::sync::Arc; + +pub struct LibUsbContextInner { + context: *mut bindings::libusb_context, +} + +// Safe because libusb_context could be accessed from multiple threads safely. +unsafe impl Send for LibUsbContextInner {} +unsafe impl Sync for LibUsbContextInner {} + +impl Drop for LibUsbContextInner { + fn drop(&mut self) { + // Safe beacuse 'self.context' points to a valid context allocated by libusb_init. + unsafe { + bindings::libusb_exit(self.context); + } + } +} + +/// Wrapper for libusb_context. The libusb libary initialization/deinitialization +/// is managed by this context. +/// See: http://libusb.sourceforge.net/api-1.0/group__libusb__lib.html +#[derive(Clone)] +pub struct LibUsbContext { + inner: Arc, +} + +impl LibUsbContext { + /// Create a new LibUsbContext. + pub fn new() -> Result { + let mut ctx: *mut bindings::libusb_context = std::ptr::null_mut(); + // Safe because '&mut ctx' points to a valid memory (on stack). + try_libusb!(unsafe { bindings::libusb_init(&mut ctx) }); + Ok(LibUsbContext { + inner: Arc::new(LibUsbContextInner { context: ctx }), + }) + } + + /// Returns a list of USB devices currently attached to the system. + pub fn get_device_iter(&self) -> Result { + let mut list: *mut *mut bindings::libusb_device = std::ptr::null_mut(); + // Safe because 'inner.context' points to a valid context and '&mut list' points to a valid + // memory. + try_libusb!(unsafe { bindings::libusb_get_device_list(self.inner.context, &mut list) }); + + Ok(DeviceIter { + context: self.inner.clone(), + list, + index: 0, + }) + } + + /// Check at runtime if the loaded library has a given capability. + pub fn has_capability(&self, cap: u32) -> bool { + // Safe because libusb_init is called before this call happens. + unsafe { bindings::libusb_has_capability(cap) != 0 } + } + + /// Return an iter of poll fds. Those fds that should be polled to handle libusb events. + pub fn get_pollfd_iter(&self) -> PollFdIter { + // Safe because 'inner.context' is inited. + let list: *mut *const bindings::libusb_pollfd = + unsafe { bindings::libusb_get_pollfds(self.inner.context) }; + PollFdIter { list, index: 0 } + } + + /// Handle libusb events in a non block way. + pub fn handle_event_nonblock(&self) { + static mut zero_time: bindings::timeval = bindings::timeval { + tv_sec: 0, + tv_usec: 0, + }; + // Safe because 'inner.context' points to valid context. + unsafe { + bindings::libusb_handle_events_timeout_completed( + self.inner.context, + &mut zero_time as *mut bindings::timeval, + std::ptr::null_mut(), + ); + } + } +} + +/// Iterator for device list. +pub struct DeviceIter { + context: Arc, + list: *mut *mut bindings::libusb_device, + index: isize, +} + +impl Drop for DeviceIter { + fn drop(&mut self) { + // Safe because 'self.list' is inited by a valid pointer from libusb_get_device_list. + unsafe { + bindings::libusb_free_device_list(self.list, 1); + } + } +} + +impl Iterator for DeviceIter { + type Item = LibUsbDevice; + + fn next(&mut self) -> Option { + // Safe becuase 'self.list' is valid, the list is null terminated. + unsafe { + let current_ptr = self.list.offset(self.index); + if (*current_ptr).is_null() { + return None; + } + self.index += 1; + Some(LibUsbDevice::new(self.context.clone(), *current_ptr)) + } + } +} + +/// Iterator for pollfds. +pub struct PollFdIter { + list: *mut *const bindings::libusb_pollfd, + index: isize, +} + +impl Drop for PollFdIter { + fn drop(&mut self) { + // Safe because 'self.list' points to valid memory of pollfd list. + unsafe { + bindings::libusb_free_pollfds(self.list); + } + } +} + +impl Iterator for PollFdIter { + type Item = bindings::libusb_pollfd; + + fn next(&mut self) -> Option { + // Safe because 'self.index' never grow out of the null pointer index. + unsafe { + let current_ptr = self.list.offset(self.index); + if (*current_ptr).is_null() { + return None; + } + + self.index += 1; + // Safe because 'current_ptr' is not null. + Some((**current_ptr).clone()) + } + } +} diff --git a/usb_util/src/libusb_device.rs b/usb_util/src/libusb_device.rs new file mode 100644 index 0000000..fa248df --- /dev/null +++ b/usb_util/src/libusb_device.rs @@ -0,0 +1,109 @@ +// Copyright 2018 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +use std; + +use bindings; +use config_descriptor::ConfigDescriptor; +use device_handle::DeviceHandle; +use error::{Error, Result}; +use libusb_context::LibUsbContextInner; +use std::sync::Arc; +use types::Speed; + +pub type DeviceDescriptor = bindings::libusb_device_descriptor; + +/// LibUsbDevice wraps libusb_device. +pub struct LibUsbDevice { + _context: Arc, + device: *mut bindings::libusb_device, +} + +unsafe impl Send for LibUsbDevice {} + +impl Drop for LibUsbDevice { + fn drop(&mut self) { + // Safe because 'self.device' is a valid pointer and libusb_ref_device is invoked when + // 'self' is built. + unsafe { + bindings::libusb_unref_device(self.device); + } + } +} + +impl LibUsbDevice { + /// Create a new LibUsbDevice. 'device' should be a valid pointer to libusb_device. + pub unsafe fn new( + ctx: Arc, + device: *mut bindings::libusb_device, + ) -> LibUsbDevice { + bindings::libusb_ref_device(device); + LibUsbDevice { + _context: ctx, + device, + } + } + + /// Get device descriptor of this device. + pub fn get_device_descriptor(&self) -> Result { + // Safe because memory is initialized later. + let mut descriptor: bindings::libusb_device_descriptor = + unsafe { std::mem::uninitialized() }; + // Safe because 'self.device' is valid and '&mut descriptor' is valid. + try_libusb!(unsafe { + bindings::libusb_get_device_descriptor(self.device, &mut descriptor) + }); + Ok(descriptor) + } + + /// Get config descriptor at index of idx. + pub fn get_config_descriptor(&self, idx: u8) -> Result { + let mut descriptor: *mut bindings::libusb_config_descriptor = std::ptr::null_mut(); + // Safe because 'self.device' is valid and '&mut descriptor' is valid. + try_libusb!(unsafe { + bindings::libusb_get_config_descriptor(self.device, idx, &mut descriptor) + }); + // Safe because descriptor is inited with valid pointer. + Ok(unsafe { ConfigDescriptor::new(descriptor) }) + } + + /// Get active config descriptor of this device. + pub fn get_active_config_descriptor(&self) -> Result { + let mut descriptor: *mut bindings::libusb_config_descriptor = std::ptr::null_mut(); + // Safe because 'self.device' is valid and '&mut descriptor' is valid. + try_libusb!(unsafe { + bindings::libusb_get_active_config_descriptor(self.device, &mut descriptor) + }); + // Safe becuase descriptor points to valid memory. + Ok(unsafe { ConfigDescriptor::new(descriptor) }) + } + + /// Get bus number of this device. + pub fn get_bus_number(&self) -> u8 { + // Safe because 'self.device' is valid. + unsafe { bindings::libusb_get_bus_number(self.device) } + } + + /// Get address of this device. + pub fn get_address(&self) -> u8 { + // Safe because 'self.device' is valid. + unsafe { bindings::libusb_get_device_address(self.device) } + } + + /// Get speed of this device. + pub fn get_speed(&self) -> Speed { + // Safe because 'self.device' is valid. + let speed = unsafe { bindings::libusb_get_device_speed(self.device) }; + Speed::from(speed as u32) + } + + /// Get device handle of this device. + pub fn open(&self) -> Result { + let mut handle: *mut bindings::libusb_device_handle = std::ptr::null_mut(); + // Safe because 'self.device' is valid and handle is on stack. + try_libusb!(unsafe { bindings::libusb_open(self.device, &mut handle) }); + // Safe because handle points to valid memory. + Ok(unsafe { DeviceHandle::new(self._context.clone(), handle) }) + } +} diff --git a/usb_util/src/types.rs b/usb_util/src/types.rs new file mode 100644 index 0000000..59bb5ed --- /dev/null +++ b/usb_util/src/types.rs @@ -0,0 +1,198 @@ +// Copyright 2018 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +use bindings; +use data_model::DataInit; + +/// Speed of usb device. See usb spec for more details. +#[derive(Debug)] +pub enum Speed { + /// The OS doesn't report or know the device speed. + Unknown, + /// The device is operating at low speed (1.5MBit/s). + Low, + /// The device is operating at full speed (12MBit/s). + Full, + /// The device is operating at high speed (480MBit/s). + High, + /// The device is operating at super speed (5000MBit/s). + Super, +} + +impl From for Speed { + fn from(speed: bindings::libusb_speed) -> Speed { + match speed { + bindings::LIBUSB_SPEED_LOW => Speed::Low, + bindings::LIBUSB_SPEED_FULL => Speed::Full, + bindings::LIBUSB_SPEED_HIGH => Speed::High, + bindings::LIBUSB_SPEED_SUPER => Speed::Super, + _ => Speed::Unknown, + } + } +} + +/// Endpoint types. +#[derive(PartialEq)] +pub enum EndpointType { + Control, + Isochronous, + Bulk, + Interrupt, +} + +/// Endpoint Directions. +#[derive(PartialEq, Clone, Copy)] +pub enum EndpointDirection { + HostToDevice = 0, + DeviceToHost = 1, +} +/// Endpoint direction offset. +pub const ENDPOINT_DIRECTION_OFFSET: u8 = 7; + +/// Offset of data phase transfer direction. +pub const DATA_PHASE_DIRECTION_OFFSET: u8 = 7; +/// Bit mask of data phase transfer direction. +pub const DATA_PHASE_DIRECTION: u8 = 1u8 << DATA_PHASE_DIRECTION_OFFSET; +// Types of data phase transfer directions. +#[derive(PartialEq)] +pub enum ControlRequestDataPhaseTransferDirection { + HostToDevice = 0, + DeviceToHost = 1, +} + +/// Offset of control request type. +pub const CONTROL_REQUEST_TYPE_OFFSET: u8 = 5; +/// Bit mask of control request type. +pub const CONTROL_REQUEST_TYPE: u8 = 0b11 << CONTROL_REQUEST_TYPE_OFFSET; +/// Request types. +#[derive(PartialEq)] +pub enum ControlRequestType { + Standard = 0, + Class = 1, + Vendor = 2, + Reserved = 3, +} + +/// Recipient type bits. +pub const REQUEST_RECIPIENT_TYPE: u8 = 0b1111; +/// Recipient type of control request. +#[derive(PartialEq)] +pub enum ControlRequestRecipient { + Device = 0, + Interface = 1, + Endpoint = 2, + Other = 3, + Reserved, +} + +/// Standard request defined in usb spec. +#[derive(PartialEq)] +pub enum StandardControlRequest { + GetStatus = 0x00, + ClearFeature = 0x01, + SetFeature = 0x03, + SetAddress = 0x05, + GetDescriptor = 0x06, + SetDescriptor = 0x07, + GetConfiguration = 0x08, + SetConfiguration = 0x09, + GetInterface = 0x0a, + SetInterface = 0x11, + SynchFrame = 0x12, +} + +/// RequestSetup is first part of control transfer buffer. +#[repr(C, packed)] +#[derive(Copy, Clone, Debug)] +pub struct UsbRequestSetup { + // USB Device Request. USB spec. rev. 2.0 9.3 + pub request_type: u8, // bmRequestType + pub request: u8, // bRequest + pub value: u16, // wValue + pub index: u16, // wIndex + pub length: u16, // wLength +} + +unsafe impl DataInit for UsbRequestSetup {} + +impl UsbRequestSetup { + pub fn new( + request_type: u8, + request: u8, + value: u16, + index: u16, + length: u16, + ) -> UsbRequestSetup { + UsbRequestSetup { + request_type, + request, + value, + index, + length, + } + } + + /// Get type of request. + pub fn get_type(&self) -> Option { + let ty = (self.request_type & CONTROL_REQUEST_TYPE) >> CONTROL_REQUEST_TYPE_OFFSET; + match ty { + 0 => Some(ControlRequestType::Standard), + 1 => Some(ControlRequestType::Class), + 2 => Some(ControlRequestType::Vendor), + 3 => Some(ControlRequestType::Reserved), + _ => None, + } + } + + /// Get request direction. + pub fn get_direction(&self) -> Option { + let dir = (self.request_type & DATA_PHASE_DIRECTION) >> DATA_PHASE_DIRECTION_OFFSET; + match dir { + 0 => Some(ControlRequestDataPhaseTransferDirection::HostToDevice), + 1 => Some(ControlRequestDataPhaseTransferDirection::DeviceToHost), + _ => None, + } + } + + /// Get recipient of this control transfer. + pub fn get_recipient(&self) -> ControlRequestRecipient { + let recipienet = self.request_type & REQUEST_RECIPIENT_TYPE; + match recipienet { + 0 => ControlRequestRecipient::Device, + 1 => ControlRequestRecipient::Interface, + 2 => ControlRequestRecipient::Endpoint, + 3 => ControlRequestRecipient::Other, + _ => ControlRequestRecipient::Reserved, + } + } + + /// Return the type of standard control request. + pub fn get_standard_request(&self) -> Option { + match self.request { + 0x00 => Some(StandardControlRequest::GetStatus), + 0x01 => Some(StandardControlRequest::ClearFeature), + 0x03 => Some(StandardControlRequest::SetFeature), + 0x05 => Some(StandardControlRequest::SetAddress), + 0x06 => Some(StandardControlRequest::GetDescriptor), + 0x07 => Some(StandardControlRequest::SetDescriptor), + 0x08 => Some(StandardControlRequest::GetConfiguration), + 0x09 => Some(StandardControlRequest::SetConfiguration), + 0x0a => Some(StandardControlRequest::GetInterface), + 0x11 => Some(StandardControlRequest::SetInterface), + 0x12 => Some(StandardControlRequest::SynchFrame), + _ => None, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::mem::size_of; + + #[test] + fn check_request_setup_size() { + assert_eq!(size_of::(), 8); + } +} -- cgit 1.4.1