USB Sync Interrupt(Read Mouse)

USB2.0 协议

USB 2.0 Cable
Typical High-full-speed Cable ConstructionExample High-speed Capable Transceiver Circuitdownstream: host, upstream: device
Pull-up Resistor (RPU): 1.5KΩ ±5%
Pull-down Resistor (RPD): 15 kΩ ±5%
Low-/full-speed Driver: 45 Ω ±10%

Low-/full-speed Signaling LevelsLow-/full-speed Packet Voltage LevelsDevice State Diagram

位填充

Bit Stuffing

Sync Pattern Low-full-speed

Sync Pattern Low-full-speed

USB 2.0 Pakage format

USB 2.0 Pakage formatSetup DATA

SOPSYNCPIDDATACRCEOP
---addr + ep--

PID Format

Bit0(LSb)Bit1Bit2Bit3Bit4Bit5Bit6Bit7(MSb)
PID0PID1PID2PID3PID0PID1PID2PID3

PID Types

PID TypePID NamePID<3:0>Description
TokenOUT0001Bhost-to-function
TokenIN1001Bfunction-to-host
TokenSOF0101BStart-of-Frame
TokenSETUP1101Bhost-to-function SETUP to a control pipe
DataDATA00011BData packet PID even
DataDATA11011BData packet PID odd
DataDATA20111BData packet PID high-speed, high bandwidth isochronous transaction in a microframe
DataMDATA1111BData packet PID high-speed for split and high bandwidth isochronous transactions
HandshakeACK0010BReceiver accepts error-free data packet
HandshakeNAK1010BReceiving device cannot accept data or transmitting device cannot send data
HandshakeSTALL1110BEndpoint is halted or a control pipe request is not supported
HandshakeNYET0110BNo response yet from receiver
SpecialPRE1100B(Token) Host-issued preamble. Enables downstream bus traffic to low-speed devices.
SpecialERR1100B(Handshake) Split Transaction Error Handshake (reuses PRE value)
SpecialSPLIT1000B(Token) High-speed Split Transaction Token
SpecialPING0100B(Token) High-speed flow control probe for a bulk/control endpoint
SpecialReserved0000BReserved 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 ResponseControl Write Transfer(data phase)Control Read Transfer(handshake phase)
Function completesZero-length data packetACK handshake
Function has an errorSTALL handshakeSTALL handshake
Function is busyNAK handshakeNAK handshake

Control Transfers

Control SETUP Transaction

Control SETUP Transaction

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

Format of Setup Data

Standard Device Requests

bmRequestTypebRequestwValuewIndexwLengthData
00000000B 00000001B 00000010BCLEAR_FEATUREFeature SelectorZero Interface EndpointZeroNone
10000000BGET_CONFIGURATIONZeroZeroOneConfiguration Value
10000000BGET_DESCRIPTORDescriptor Type and Descriptor IndexZero or Language IDDescriptor LengthDescriptor
10000001BGET_INTERFACEZeroInterfaceOneAlternate Interface
10000000B 10000001B 10000010BGET_STATUSZeroZero Interface EndpointTwoDevice, Interface, or Endpoint Status
00000000BSET_ADDRESSDevice AddressZeroZeroNone
00000000BSET_CONFIGURATIONConfiguration ValueZeroZeroNone
00000000BSET_DESCRIPTORDescriptor Type and Descriptor IndexZero or Language IDDescriptor LengthDescriptor
00000000B 00000001B 00000010BSET_FEATUREFeature SelectorZero Interface EndpointZeroNone
00000001BSET_INTERFACEAlternate SettingInterfaceZeroNone
10000010BSYNCH_FRAMEZeroEndpointTwoFrame Number

Standard Request Codes

bRequestValue
GET_STATUS0
CLEAR_FEATURE1
Reserved2
SET_FEATURE3
Reserved4
SET_ADDRESS5
GET_DESCRIPTOR6
SET_DESCRIPTOR7
GET_CONFIGURATION8
SET_CONFIGURATION9
GET_INTERFACE10
SET_INTERFACE11
SYNCH_FRAME12

Standard Feature Selectors

Feature SelectorRecipientValue
DEVICE_REMOTE_WAKEUPDevice1
ENDPOINT_HALTEndpoint0
TEST_MODEDevice2

Descriptor Types

Descriptor TypesValue
DEVICE1
CONFIGURATION2
STRING3
INTERFACE4
ENDPOINT5
DEVICE_QUALIFIER6
OTHER_SPEED_CONFIGURATION7
INTERFACE_POWER8

Note: The INTERFACE_POWER descriptor is defined in the current revision of the USB Interface Power Management Specification.

Standard Device Descriptor

OffsetFieldSizeValueDescription
0bLength1NumberSize of this descriptor in bytes
1bDescriptorType1ConstantDEVICE Descriptor Type
2bcdUSB2BCDUSB Specification Release Number in Binary-Coded Decimal (i.e., 2.10 is 210H).
4bDeviceClass1ClassClass code(assigned by the USB-IF).
5bDeviceSubClass1SubClassThese codes are qualified by the value of the bDeviceClass field.
6bDeviceProtocol1ProtocolProtocol code (assigned by the USB-IF).
7bMaxPacketSize01NumberMaximum packet size for endpoint zero (only 8, 16, 32, or 64 are valid)
8idVendor2IDVendor ID (assigned by the USB-IF)
10idProduct2IDProduct ID (assigned by the manufacturer)
12bcdDevice2BCDDevice release number in binary-coded decimal
14iManufacturer1IndexIndex of string descriptor describing manufacturer
15iProduct1IndexIndex of string descriptor describing product
16iSerialNumber1IndexIndex of string descriptor describing the device’s serial number
17bNumConfigurations1NumberNumber of possible configurations

Device_Qualifier Descriptor: GetDescriptor()

OffsetFieldSizeValueDescription
0bLength1NumberSize of descriptor
1bDescriptorType1ConstantDevice Qualifier Type
2bcdUSB2BCDUSB specification version number (e.g., 0200H for V2.00 )
4bDeviceClass1ClassClass Code
5bDeviceSubClass1SubClassSubClass Code
6bDeviceProtocol1ProtocolProtocol Code
7bMaxPacketSize01NumberMaximum packet size for other speed
8bNumConfigurations1NumberNumber of Other-speed Configurations
9bReserved1ZeroReserved for future use, must be zero

Standard Configuration Descriptor: SetConfiguration()

OffsetFieldSizeValueDescription
0bLength1NumberSize of this descriptor in bytes
1bDescriptorType1ConstantCONFIGURATION Descriptor Type
2wTotalLength2NumberTotal 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.
4bNumInterfaces1NumberNumber of interfaces supported by this configuration
5bConfigurationValue1NumberValue to use as an argument to the SetConfiguration() request to select this configuration
6iConfiguration1IndexIndex of string descriptor describing this configuration
7bmAttributes1BitmapConfiguration characteristics [D7:Reserved (set to one), D6:Self-powered, D5: Remote Wakeup, D4…0:Reserved (reset to zero)]
8bMaxPower1mAMaximum 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()

OffsetFieldSizeValueDescription
0bLength1NumberSize of descriptor
1bDescriptorType1ConstantOther_speed_Configuration Type
2wTotalLength2NumberTotal length of data returned
4bNumInterfaces1NumberNumber of interfaces supported by this speed configuration
5bConfigurationValue1NumberValue to use to select configuration
6iConfiguration1IndexIndex of string descriptor
7bmAttributes1BitmapSame as Configuration descriptor
8bMaxPower1mASame as Configuration descriptor

Standard Interface Descriptor

OffsetFieldSizeValueDescription
0bLength1NumberSize of this descriptor in bytes
1bDescriptorType1ConstantINTERFACE Descriptor Type
2bInterfaceNumber1NumberNumber of this interface. Zero-based value identifying the index in the array of concurrent interfaces supported by this configuration.
3bAlternateSetting1NumberValue used to select this alternate setting for the interface identified in the prior field
4bNumEndpoints1NumberNumber of endpoints used by this interface (excluding endpoint zero). If this value is zero, this interface only uses the Default Control Pipe.
5bInterfaceClass1ClassClass code (assigned by the USB-IF).
6bInterfaceSubClass1SubClassSubclass code (assigned by the USB-IF). These codes are qualified by the value of the bInterfaceClass field.
7bInterfaceProtocol1ProtocolProtocol code (assigned by the USB). These codes are qualified by the value of the bInterfaceClass and the bInterfaceSubClass fields.
8iInterface1IndexIndex of string descriptor describing this interface

Standard Endpoint Descriptor: GetDescriptor(Configuration)

OffsetFieldSizeValueDescription
0bLength1NumberSize of this descriptor in bytes
1bDescriptorType1ConstantENDPOINT Descriptor Type
2bEndpointAddress1EndpointThe address of the endpoint on the USB device described by this descriptor.
3bmAttributes1BitmapThis field describes the endpoint’s attributes when it is configured using the bConfigurationValue.
4wMaxPacketSize2NumberMaximum packet size this endpoint is capable of sending or receiving when this configuration is selected.
6bInterval1Numbernterval 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 SequencesControl Read and Write Sequences Control SETUP Transaction

Control SETUP Transaction

Isochronous Transaction Format

Isochronous Transaction Format

Interrupt Transaction FormatInterrupt Transaction Format

Bulk Transfers

Bulk Transaction FormatBulk Transaction Format

Bulk Reads and Writes

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)

ByteBitsDescription
00Button 1(LEFT)
01Button 2(RIGHT)
02Button 3(MIDDLE)
04 to 7Device-specific
10 to 7X displacement
20 to 7Y displacement
3 to n0 to 7Device specific (optional)

class libusb_config_descriptor/interface/endpoint

libusb_config_descriptor
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wTotalLength;
uint8_t bNumInterfaces;
uint8_t bConfigurationValue;
uint8_t iConfiguration;
uint8_t bmAttributes;
uint8_t MaxPower;
const struct libusb_interface *interface;
const unsigned char *extra;
int extra_length;
libusb_interface
const struct libusb_interface_descriptor *altsetting;
int num_altsetting;
libusb_interface_descriptor
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bInterfaceNumber;
uint8_t bAlternateSetting;
uint8_t bNumEndpoints;
uint8_t bInterfaceClass;
uint8_t bInterfaceSubClass;
uint8_t bInterfaceProtocol;
uint8_t iInterface;
const struct libusb_endpoint_descriptor *endpoint;
const unsigned char *extra;
int extra_length;
libusb_endpoint_descriptor
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint16_t wMaxPacketSize;
uint8_t bInterval;
uint8_t bRefresh;
uint8_t bSynchAddress;
const unsigned char *extra;
int extra_length;

class libusb_device/context

libusb_device
usbi_atomic_t refcnt;
struct libusb_context *ctx;
struct libusb_device *parent_dev;
uint8_t bus_number;
uint8_t port_number;
uint8_t device_address;
enum libusb_speed speed;
struct list_head list;
unsigned long session_data;
struct libusb_device_descriptor device_descriptor;
usbi_atomic_t attached;
libusb_context
usbi_event_t event;
struct list_head usb_devs;
usbi_mutex_t usb_devs_lock;
struct list_head open_devs;
usbi_mutex_t open_devs_lock;
struct list_head hotplug_cbs;
libusb_hotplug_callback_handle next_hotplug_cb_handle;
usbi_mutex_t hotplug_cbs_lock;
usbi_atomic_t hotplug_ready;
struct list_head flying_transfers;
usbi_mutex_t flying_transfers_lock;
usbi_mutex_t events_lock;
int event_handler_active;
usbi_tls_key_t event_handling_key;
usbi_mutex_t event_waiters_lock;
usbi_cond_t event_waiters_cond;
usbi_mutex_t event_data_lock;
unsigned int event_flags;
unsigned int device_close;
struct list_head event_sources;
struct list_head removed_event_sources;
void *event_data;
unsigned int event_data_cnt;
struct list_head hotplug_msgs;
struct list_head completed_transfers;
struct list_head list;

Sequence Diagram

去读鼠标数据的序列图

App Libusb Initail libusb libusb_init(NULL) return ret get usb deive list libusb_get_device_list(NULL, &devs) return list_size loop all usb device, to find mouse device. dev = devs[i] libusb_get_device_descriptor(dev, &device_desc) continue to next dev alt [0 > ret] loop all device configuration, to find mouse Configurations. libusb_get_config_descriptor(dev, conf, &config_desc) continue to next Configurations alt [LIBUSB_SUCCESS != ret] loop all device interface, to find mouse interface. loop all device altsetting, to find mouse altsetting. interface_desc = &config_desc->>interface[interface].altsetting[altsetting] if((LIBUSB_CLASS_HID != interface_desc->>bInterfaceClass) || (1 != interface_desc->>bInterfaceSubClass) || (2 != interface_desc->>bInterfaceProtocol)) continue goto next altsetting(config_desc->>interface[interface].num_altsetting) alt [find matching HID-Mouse usb devices] record each mouse device idVendor, idProduct, bEndpointAddress. endpoint_desc = &interface_desc->>endpoint[endpoint] mouse_id[mouse_num] = (device_desc.idVendor & 0xFFFF) | ((device_desc.idProduct << 16) & 0xFFFF0000) mouse_interface[mouse_num] = interface mouse_endpoint[mouse_num] = endpoint_desc->>bEndpointAddress mouse_num++ loop [Traverse all endpoint] loop [Traverse all altsetting (config_desc->>interface[interface].num_altsetting)] loop [Traverse all interface(config_desc->>bNumInterfaces)] libusb_free_config_descriptor(config_desc) loop [Traverse all Configurations(device_desc.bNumConfigurations)] libusb_free_device_list(devs, 1) open Mouse deivce mouse_handle = libusb_open_device_with_vid_pid(NULL, (mouse_id[j] & 0xFFFF) , ((mouse_id[j] >> 16) & 0xFFFF)) claim Mouse deivce libusb_set_auto_detach_kernel_driver(mouse_handle, 1) return ret libusb_claim_interface(mouse_handle, mouse_interface[j]) return ret recieve Mouse device data(read 8 Bytes) libusb_interrupt_transfer(mouse_handle, mouse_endpoint[j], mouse_buf, sizeof(mouse_buf), &transferred, 10000) return ret print all recieve data to screen libusb_release_interface(mouse_handle, mouse_interface[j]) libusb_close(mouse_handle) loop [Traverse all devs[i] and (i < list_size)] libusb_exit(NULL) App Libusb

示例代码

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值