USB2.0 协议
downstream: host, upstream: device
Pull-up Resistor (RPU): 1.5KΩ ±5%
Pull-down Resistor (RPD): 15 kΩ ±5%
Low-/full-speed Driver: 45 Ω ±10%
位填充
Sync Pattern Low-full-speed
USB 2.0 Pakage format
Setup DATA
SOP | SYNC | PID | DATA | CRC | EOP |
---|---|---|---|---|---|
- | - | - | addr + ep | - | - |
PID Format
Bit0(LSb) | Bit1 | Bit2 | Bit3 | Bit4 | Bit5 | Bit6 | Bit7(MSb) |
---|---|---|---|---|---|---|---|
PID0 | PID1 | PID2 | PID3 | PID0 | PID1 | PID2 | PID3 |
PID Types
PID Type | PID Name | PID<3:0> | Description |
---|---|---|---|
Token | OUT | 0001B | host-to-function |
Token | IN | 1001B | function-to-host |
Token | SOF | 0101B | Start-of-Frame |
Token | SETUP | 1101B | host-to-function SETUP to a control pipe |
Data | DATA0 | 0011B | Data packet PID even |
Data | DATA1 | 1011B | Data packet PID odd |
Data | DATA2 | 0111B | Data packet PID high-speed, high bandwidth isochronous transaction in a microframe |
Data | MDATA | 1111B | Data packet PID high-speed for split and high bandwidth isochronous transactions |
Handshake | ACK | 0010B | Receiver accepts error-free data packet |
Handshake | NAK | 1010B | Receiving device cannot accept data or transmitting device cannot send data |
Handshake | STALL | 1110B | Endpoint is halted or a control pipe request is not supported |
Handshake | NYET | 0110B | No response yet from receiver |
Special | PRE | 1100B | (Token) Host-issued preamble. Enables downstream bus traffic to low-speed devices. |
Special | ERR | 1100B | (Handshake) Split Transaction Error Handshake (reuses PRE value) |
Special | SPLIT | 1000B | (Token) High-speed Split Transaction Token |
Special | PING | 0100B | (Token) High-speed flow control probe for a bulk/control endpoint |
Special | Reserved | 0000B | Reserved PID |
*Note: PID bits are shown in MSb order. When sent on the USB, the rightmost bit (bit 0) will be sent first.
定义(Signaling Levels)->域定义(Field)->包定义(Packet)->事务定义(Transaction)->传输定义(Transfer)
****帧号域(Frame Number Field): **** 是一个11位的域,由主机在每帧的基础上递增。帧号域在达到其最大值7FFH时清0,并且只在每个(微)帧开始时发送SOF令牌。
帧号域只有SOF令牌包用,主机没啥事情做就发这个,让设备知道主机还活着,SOF令牌大家都能收到,与地址无关。全速设备每秒1000个,称为帧(frame),高速设备每秒8000个,称为微帧(micro frame)。
Status Stage Responses
Status Response | Control Write Transfer(data phase) | Control Read Transfer(handshake phase) |
---|---|---|
Function completes | Zero-length data packet | ACK handshake |
Function has an error | STALL handshake | STALL handshake |
Function is busy | NAK handshake | NAK handshake |
Control Transfers
Control SETUP Transaction

Format of Setup Data[8 Bytes] Host-to-Device

Standard Device Requests
bmRequestType | bRequest | wValue | wIndex | wLength | Data |
---|---|---|---|---|---|
00000000B 00000001B 00000010B | CLEAR_FEATURE | Feature Selector | Zero Interface Endpoint | Zero | None |
10000000B | GET_CONFIGURATION | Zero | Zero | One | Configuration Value |
10000000B | GET_DESCRIPTOR | Descriptor Type and Descriptor Index | Zero or Language ID | Descriptor Length | Descriptor |
10000001B | GET_INTERFACE | Zero | Interface | One | Alternate Interface |
10000000B 10000001B 10000010B | GET_STATUS | Zero | Zero Interface Endpoint | Two | Device, Interface, or Endpoint Status |
00000000B | SET_ADDRESS | Device Address | Zero | Zero | None |
00000000B | SET_CONFIGURATION | Configuration Value | Zero | Zero | None |
00000000B | SET_DESCRIPTOR | Descriptor Type and Descriptor Index | Zero or Language ID | Descriptor Length | Descriptor |
00000000B 00000001B 00000010B | SET_FEATURE | Feature Selector | Zero Interface Endpoint | Zero | None |
00000001B | SET_INTERFACE | Alternate Setting | Interface | Zero | None |
10000010B | SYNCH_FRAME | Zero | Endpoint | Two | Frame Number |
Standard Request Codes
bRequest | Value |
---|---|
GET_STATUS | 0 |
CLEAR_FEATURE | 1 |
Reserved | 2 |
SET_FEATURE | 3 |
Reserved | 4 |
SET_ADDRESS | 5 |
GET_DESCRIPTOR | 6 |
SET_DESCRIPTOR | 7 |
GET_CONFIGURATION | 8 |
SET_CONFIGURATION | 9 |
GET_INTERFACE | 10 |
SET_INTERFACE | 11 |
SYNCH_FRAME | 12 |
Standard Feature Selectors
Feature Selector | Recipient | Value |
---|---|---|
DEVICE_REMOTE_WAKEUP | Device | 1 |
ENDPOINT_HALT | Endpoint | 0 |
TEST_MODE | Device | 2 |
Descriptor Types
Descriptor Types | Value |
---|---|
DEVICE | 1 |
CONFIGURATION | 2 |
STRING | 3 |
INTERFACE | 4 |
ENDPOINT | 5 |
DEVICE_QUALIFIER | 6 |
OTHER_SPEED_CONFIGURATION | 7 |
INTERFACE_POWER | 8 |
Note: The INTERFACE_POWER descriptor is defined in the current revision of the USB Interface Power Management Specification.
Standard Device Descriptor
Offset | Field | Size | Value | Description |
---|---|---|---|---|
0 | bLength | 1 | Number | Size of this descriptor in bytes |
1 | bDescriptorType | 1 | Constant | DEVICE Descriptor Type |
2 | bcdUSB | 2 | BCD | USB Specification Release Number in Binary-Coded Decimal (i.e., 2.10 is 210H). |
4 | bDeviceClass | 1 | Class | Class code(assigned by the USB-IF). |
5 | bDeviceSubClass | 1 | SubClass | These codes are qualified by the value of the bDeviceClass field. |
6 | bDeviceProtocol | 1 | Protocol | Protocol code (assigned by the USB-IF). |
7 | bMaxPacketSize0 | 1 | Number | Maximum packet size for endpoint zero (only 8, 16, 32, or 64 are valid) |
8 | idVendor | 2 | ID | Vendor ID (assigned by the USB-IF) |
10 | idProduct | 2 | ID | Product ID (assigned by the manufacturer) |
12 | bcdDevice | 2 | BCD | Device release number in binary-coded decimal |
14 | iManufacturer | 1 | Index | Index of string descriptor describing manufacturer |
15 | iProduct | 1 | Index | Index of string descriptor describing product |
16 | iSerialNumber | 1 | Index | Index of string descriptor describing the device’s serial number |
17 | bNumConfigurations | 1 | Number | Number of possible configurations |
Device_Qualifier Descriptor: GetDescriptor()
Offset | Field | Size | Value | Description |
---|---|---|---|---|
0 | bLength | 1 | Number | Size of descriptor |
1 | bDescriptorType | 1 | Constant | Device Qualifier Type |
2 | bcdUSB | 2 | BCD | USB specification version number (e.g., 0200H for V2.00 ) |
4 | bDeviceClass | 1 | Class | Class Code |
5 | bDeviceSubClass | 1 | SubClass | SubClass Code |
6 | bDeviceProtocol | 1 | Protocol | Protocol Code |
7 | bMaxPacketSize0 | 1 | Number | Maximum packet size for other speed |
8 | bNumConfigurations | 1 | Number | Number of Other-speed Configurations |
9 | bReserved | 1 | Zero | Reserved for future use, must be zero |
Standard Configuration Descriptor: SetConfiguration()
Offset | Field | Size | Value | Description |
---|---|---|---|---|
0 | bLength | 1 | Number | Size of this descriptor in bytes |
1 | bDescriptorType | 1 | Constant | CONFIGURATION Descriptor Type |
2 | wTotalLength | 2 | Number | Total length of data returned for this configuration. Includes the combined length of all descriptors (configuration, interface, endpoint, and class- or vendor-specific) returned for this configuration. |
4 | bNumInterfaces | 1 | Number | Number of interfaces supported by this configuration |
5 | bConfigurationValue | 1 | Number | Value to use as an argument to the SetConfiguration() request to select this configuration |
6 | iConfiguration | 1 | Index | Index of string descriptor describing this configuration |
7 | bmAttributes | 1 | Bitmap | Configuration characteristics [D7:Reserved (set to one), D6:Self-powered, D5: Remote Wakeup, D4…0:Reserved (reset to zero)] |
8 | bMaxPower | 1 | mA | Maximum power consumption of the USB device from the bus in this specific configuration when the device is fully operational. Expressed in 2 mA units (i.e., 50 = 100 mA). |
Other_Speed_Configuration Descriptor: GetDescriptor()
Offset | Field | Size | Value | Description |
---|---|---|---|---|
0 | bLength | 1 | Number | Size of descriptor |
1 | bDescriptorType | 1 | Constant | Other_speed_Configuration Type |
2 | wTotalLength | 2 | Number | Total length of data returned |
4 | bNumInterfaces | 1 | Number | Number of interfaces supported by this speed configuration |
5 | bConfigurationValue | 1 | Number | Value to use to select configuration |
6 | iConfiguration | 1 | Index | Index of string descriptor |
7 | bmAttributes | 1 | Bitmap | Same as Configuration descriptor |
8 | bMaxPower | 1 | mA | Same as Configuration descriptor |
Standard Interface Descriptor
Offset | Field | Size | Value | Description |
---|---|---|---|---|
0 | bLength | 1 | Number | Size of this descriptor in bytes |
1 | bDescriptorType | 1 | Constant | INTERFACE Descriptor Type |
2 | bInterfaceNumber | 1 | Number | Number of this interface. Zero-based value identifying the index in the array of concurrent interfaces supported by this configuration. |
3 | bAlternateSetting | 1 | Number | Value used to select this alternate setting for the interface identified in the prior field |
4 | bNumEndpoints | 1 | Number | Number of endpoints used by this interface (excluding endpoint zero). If this value is zero, this interface only uses the Default Control Pipe. |
5 | bInterfaceClass | 1 | Class | Class code (assigned by the USB-IF). |
6 | bInterfaceSubClass | 1 | SubClass | Subclass code (assigned by the USB-IF). These codes are qualified by the value of the bInterfaceClass field. |
7 | bInterfaceProtocol | 1 | Protocol | Protocol code (assigned by the USB). These codes are qualified by the value of the bInterfaceClass and the bInterfaceSubClass fields. |
8 | iInterface | 1 | Index | Index of string descriptor describing this interface |
Standard Endpoint Descriptor: GetDescriptor(Configuration)
Offset | Field | Size | Value | Description |
---|---|---|---|---|
0 | bLength | 1 | Number | Size of this descriptor in bytes |
1 | bDescriptorType | 1 | Constant | ENDPOINT Descriptor Type |
2 | bEndpointAddress | 1 | Endpoint | The address of the endpoint on the USB device described by this descriptor. |
3 | bmAttributes | 1 | Bitmap | This field describes the endpoint’s attributes when it is configured using the bConfigurationValue. |
4 | wMaxPacketSize | 2 | Number | Maximum packet size this endpoint is capable of sending or receiving when this configuration is selected. |
6 | bInterval | 1 | Number | nterval for polling endpoint for data transfers. Expressed in frames or microframes depending on the device operating speed (i.e., either 1 millisecond or 125 µs units). |
bEndpointAddress:
Bit 3...0: The endpoint number
Bit 6...4: Reserved, reset to zero
Bit 7: Direction, ignored for control endpoints
0 = OUT endpoint
1 = IN endpoint
bmAttributes:
bmAttributes:
This field describes the endpoint’s attributes when it is
configured using the bConfigurationValue.
Bits 1..0: Transfer Type
00 = Control
01 = Isochronous
10 = Bulk
11 = Interrupt
If not an isochronous endpoint, bits 5..2 are reserved
and must be set to zero. If isochronous, they are
defined as follows:
Bits 3..2: Synchronization Type
00 = No Synchronization
01 = Asynchronous
10 = Adaptive
11 = Synchronous
Bits 5..4: Usage Type
00 = Data endpoint
01 = Feedback endpoint
10 = Implicit feedback Data endpoint
11 = Reserved
Refer to Chapter 5 for more information.
All other bits are reserved and must be reset to zero.
Reserved bits must be ignored by the host.
wMaxPacketSize:
For all endpoints, bits 10..0 specify the maximum packet size (in bytes).
For high-speed isochronous and interrupt endpoints:
Bits 12..11 specify the number of additional transaction opportunities per microframe:
00 = None (1 transaction per microframe)
01 = 1 additional (2 per microframe)
10 = 2 additional (3 per microframe)
11 = Reserved
Bits 15..13 are reserved and must be set to zero.
Control Read and Write Sequences
Control SETUP Transaction
Isochronous Transaction Format
Interrupt Transaction Format
Bulk Transfers
Bulk Transaction Format
Bulk Reads and Writes
### USB HID 1.11
bInterfaceClass
3: HID class code
bInterfaceSubClass
0: No Subclass
1: Boot Interface Subclass
2 - 255: Reserved
bInterfaceProtocol
0: None
1: Keyboard
2: Mouse
3 - 255: Reserved
Protocol 2 (Mouse)
Byte | Bits | Description |
---|---|---|
0 | 0 | Button 1(LEFT) |
0 | 1 | Button 2(RIGHT) |
0 | 2 | Button 3(MIDDLE) |
0 | 4 to 7 | Device-specific |
1 | 0 to 7 | X displacement |
2 | 0 to 7 | Y displacement |
3 to n | 0 to 7 | Device specific (optional) |
class libusb_config_descriptor/interface/endpoint
class libusb_device/context
Sequence Diagram
去读鼠标数据的序列图
示例代码
Note:
查找到鼠标USB 设备,并读取1000次数据
编译命令: $ gcc $(CFLAGS) main.c -lusb-1.0 -o test
运行命令: $ sudo ./test
执行操作: 晃动鼠标
编译选项(可不加):
CFLAGS := -Wall -Wundef -Wshadow -Wconversion -Werror=return-type -Werror=implicit-function-declaration -Werror=unused-variable -fno-strict-aliasing -fno-common -fshort-wchar -Wno-trigraphs -Os
#include <stdio.h>
#include <string.h>
#include "libusb-1.0/libusb.h"
#define le16_to_cpu(x) libusb_cpu_to_le16(libusb_cpu_to_le16(x))
static void print_device(libusb_device *dev, libusb_device_handle *handle)
{
struct libusb_device_descriptor dev_desc;
unsigned char iManufacturer_string[256] = {0};
unsigned char iProduct_string[256] = {0};
unsigned char iSerialNumber_string[256] = {0};
const char *speed;
int ret;
switch (libusb_get_device_speed(dev)) {
case LIBUSB_SPEED_LOW: speed = "1.5M"; break;
case LIBUSB_SPEED_FULL: speed = "12M"; break;
case LIBUSB_SPEED_HIGH: speed = "480M"; break;
case LIBUSB_SPEED_SUPER: speed = "5G"; break;
case LIBUSB_SPEED_SUPER_PLUS: speed = "10G"; break;
default: speed = "Unknown";
}
ret = libusb_get_device_descriptor(dev, &dev_desc);
if (ret < 0) {
fprintf(stderr, "failed to get device descriptor");
return;
}
if (!handle){
ret = libusb_open(dev, &handle);
if (ret < 0){
perror("Opend libusb device failed");
}
}
printf("Dev (bus %03d, device %03d): ID %04x:%04x speed: %s\r\n" \
, libusb_get_bus_number(dev), libusb_get_device_address(dev), \
dev_desc.idVendor, dev_desc.idProduct, speed);
if (NULL != handle){
if (dev_desc.iManufacturer) {
ret = libusb_get_string_descriptor_ascii(handle, dev_desc.iManufacturer, iManufacturer_string, sizeof(iManufacturer_string));
if (ret <= 0)
printf("Get iManufacturer string descriptor failed %s\n", (char *)iManufacturer_string);
}
if (dev_desc.iProduct) {
ret = libusb_get_string_descriptor_ascii(handle, dev_desc.iProduct, iProduct_string, sizeof(iProduct_string));
if (ret <= 0)
printf("Get iProduct string descriptor failed %s\n", (char *)iProduct_string);
}
if (dev_desc.iSerialNumber) {
ret = libusb_get_string_descriptor_ascii(handle, dev_desc.iSerialNumber, iSerialNumber_string, sizeof(iSerialNumber_string));
if (ret <= 0)
printf("Get iManufacturer string descriptor failed %s\n", (char *)iSerialNumber_string);
}
}
printf("Deivces Descriptor:\n");
printf(" bLength: \t%9d\n", dev_desc.bLength);
printf(" bDescriptorType:%8d\n", dev_desc.bDescriptorType);
printf(" bcdUSB: \t%6x.%02x\n", dev_desc.bcdUSB >> 8, dev_desc.bcdUSB & 0xFF);
printf(" bDeviceClass: \t%9d\n", dev_desc.bDeviceClass);
printf(" bDeviceSubClass:%8d\n", dev_desc.bDeviceSubClass);
printf(" bDeviceProtocol:%8d\n", dev_desc.bDeviceProtocol);
printf(" bMaxPacketSize0:%8d\n", dev_desc.bMaxPacketSize0);
printf(" idVendor: \t 0x%04x\n", dev_desc.idVendor);
printf(" idProduct: \t 0x%04x\n", dev_desc.idProduct);
printf(" bcdDevice: \t%6x.%02x\n", dev_desc.bcdDevice >> 8, dev_desc.bcdDevice & 0xFF);
printf(" iManufacturer: \t%d %s\n", dev_desc.iManufacturer, iManufacturer_string);
printf(" iProduct: \t\t%d %s\n", dev_desc.iProduct, iProduct_string);
printf(" iSerialNumber: \t%d %s\n", dev_desc.iSerialNumber, iSerialNumber_string);
printf(" bNumConfigurations: \t%d\n", dev_desc.bNumConfigurations);
if (handle)
libusb_close(handle);
}
static void print_configration(struct libusb_config_descriptor *conf_desc)
{
printf(" Configuration Descriptor:\n");
printf(" bLength: \t\t%9d\n", conf_desc->bLength);
printf(" bDescriptorType: \t%9d\n", conf_desc->bDescriptorType);
printf(" wTotalLength: \t 0x%04x\n", conf_desc->wTotalLength);
printf(" bNumInterfaces: \t%9d\n", conf_desc->bNumInterfaces);
printf(" bConfigurationValue: \t%d\n", conf_desc->bConfigurationValue);
printf(" iConfiguration: \t%9d\n", conf_desc->iConfiguration);
printf(" bmAttributes: \t 0x%x\n", conf_desc->bmAttributes);
printf(" MaxPower: \t\t%9dmA\n", 2*conf_desc->MaxPower);
}
static void print_interface(struct libusb_interface_descriptor *if_desc, unsigned char if_num, unsigned char alt)
{
printf(" Interface Descriptor: %d altsetting %d\n", if_num, alt);
printf(" bLength: \t\t%9d\n", if_desc->bLength);
printf(" bDescriptorType: \t%9d\n", if_desc->bDescriptorType);
printf(" bInterfaceNumber: \t%9d\n", if_desc->bInterfaceNumber);
printf(" bAlternateSetting: %9d\n", if_desc->bAlternateSetting);
printf(" bNumEndpoints: \t%9d\n", if_desc->bNumEndpoints);
printf(" bInterfaceClass: \t%9d\n", if_desc->bInterfaceClass);
printf(" bInterfaceSubClass:%9d\n", if_desc->bInterfaceSubClass);
printf(" bInterfaceProtocol:%9d\n", if_desc->bInterfaceProtocol);
printf(" iInterface: \t%9d\n", if_desc->iInterface);
}
static void print_endpoint(struct libusb_endpoint_descriptor *ep_desc, unsigned char ep_num)
{
static const char * const typeattr[] = {
"Control",
"Isochronous",
"Bulk",
"Interrupt"
};
static const char * const syncattr[] = {
"None",
"Asynchronous",
"Adaptive",
"Synchronous"
};
static const char * const usage[] = {
"Data",
"Feedback",
"Implicit feedback Data",
"(reserved)"
};
static const char * const hb[] = { "1x", "2x", "3x", "(?\?)" };
unsigned wmax = le16_to_cpu(ep_desc->wMaxPacketSize);
printf(" Endpoint Descriptor:\n"
" bLength %5u\n"
" bDescriptorType %5u\n"
" bEndpointAddress 0x%02x EP %u %s\n"
" bmAttributes %5u\n"
" Transfer Type %s\n"
" Synch Type %s\n"
" Usage Type %s\n"
" wMaxPacketSize 0x%04x %s %d bytes\n"
" bInterval %5u\n",
ep_desc->bLength,
ep_desc->bDescriptorType,
ep_desc->bEndpointAddress,
ep_desc->bEndpointAddress & 0x0f,
(ep_desc->bEndpointAddress & 0x80) ? "IN" : "OUT",
ep_desc->bmAttributes,
typeattr[ep_desc->bmAttributes & 3],
syncattr[(ep_desc->bmAttributes >> 2) & 3],
usage[(ep_desc->bmAttributes >> 4) & 3],
wmax, hb[(wmax >> 11) & 3], wmax & 0x7ff,
ep_desc->bInterval);
}
int main(int argc, char *argv[])
{
int ret, i;
ssize_t list_size;
libusb_device **devs;
struct libusb_device *dev;
// libusb_device_handle *handle = NULL;
struct libusb_device_descriptor device_desc;
struct libusb_config_descriptor *config_desc;
struct libusb_interface_descriptor *interface_desc;
struct libusb_endpoint_descriptor *endpoint_desc;
libusb_device_handle *handle;
// unsigned int dev_interface = 0;
unsigned char dev_endpoint = 0;
unsigned char data_buf[64] = {0};
int transferred = 0;
/* libusb_init */
ret = libusb_init(NULL);
if (ret < 0)
return ret;
/* get deive list */
list_size = libusb_get_device_list(NULL, &devs);
if (list_size < 0) {
libusb_exit(NULL);
return 1;
}
for (i = 0; i < list_size; i++){
if (devs[i] == NULL){
printf("fialed to parse device descriptor");
continue;
}
dev = devs[i];
ret = libusb_get_device_descriptor(dev, &device_desc);
if (ret < 0) {
printf("failed to get device descriptor");
continue;
}
// ret = libusb_open(dev, &handle);
// if (0 != ret){
// perror("Opend libusb device failed");
// }
// print_device(dev, NULL);
for (unsigned char conf = 0; conf < device_desc.bNumConfigurations; conf++){
/* entry device configuration, for descriptor */
ret = libusb_get_config_descriptor(dev, conf, &config_desc);
if (LIBUSB_SUCCESS != ret) {
printf("Couldn't retrieve config descriptors\n");
continue;
}
// print_configration(config_desc);
/* entry configration interface, for descriptor */
for (unsigned char interface = 0; interface < config_desc->bNumInterfaces; interface++)
{
for (unsigned char altsetting = 0; altsetting < config_desc->interface[interface].num_altsetting; altsetting++)
{
interface_desc = (struct libusb_interface_descriptor *)(&config_desc->interface[interface].altsetting[altsetting]);
if ((LIBUSB_CLASS_HID != interface_desc->bInterfaceClass) || /* Human Interface Device */
(1 != interface_desc->bInterfaceSubClass) || /* Boot Interface Subclass */
(2 != interface_desc->bInterfaceProtocol) /* Mouse */
){
continue;
}
print_device(dev, NULL);
print_configration(config_desc);
print_interface(interface_desc, interface, altsetting);
for (unsigned char endpoint = 0; endpoint < interface_desc->bNumEndpoints; endpoint++)
{
endpoint_desc = (struct libusb_endpoint_descriptor *)(&interface_desc->endpoint[endpoint]);
print_endpoint(endpoint_desc, endpoint);
#if 1
/* open */
ret = libusb_open(dev, &handle);
if (0 != ret)
{
printf("opend usb handle fialed!!! %d", ret);
}
// dev_interface = interface;
dev_endpoint = endpoint_desc->bEndpointAddress;
/* claim interface */
ret = libusb_set_auto_detach_kernel_driver(handle, 1);
//ret = libusb_detach_kernel_driver(handle, interface);
if(ret < 0) {
printf("*** libusb_detach_kernel_driver failed! %d\n",ret);
return -1;
}
ret = libusb_claim_interface(handle, interface);
if(ret < 0)
{
printf("*** libusb_claim_interface failed! %d\n",ret);
return -1;
}
for(int count = 0; count <1000; count++)
{
/* transfer data */
ret = libusb_interrupt_transfer(handle, dev_endpoint, data_buf, 8, &transferred, 10000);
if(ret != 0) {
printf("*** interrupt_transfer failed! %d\n", ret);
if (ret == LIBUSB_ERROR_TIMEOUT){
printf("interrupt_transfer: timeout\r\n");
}
return -1;
}
printf(" data: %02x %02x %02x %02x %02x %02x %02x %02x: size %d\r\n"
, data_buf[0], data_buf[1], data_buf[2], data_buf[3], data_buf[4], data_buf[5], data_buf[6], data_buf[7]
, transferred);
}
/* release interface */
libusb_release_interface(handle, interface);
/* close */
libusb_close(handle);
#endif
}
}
}
libusb_free_config_descriptor(config_desc);
}
}
libusb_free_device_list(devs, 1);
/* parse interface descriptor, find usb <Mouse> */
/* exit */
libusb_exit(NULL);
return 0;
}