This document describes libusb APIs and how to develop USB applications.
1 Introduction
1.1 Overview
This document describes libusb-0.1 APIs and USB-related content.
1.2 Current OS support
Linux 2.2 or later
FreeBSD/NetBSD/OpenBSD
Darwin/MacOSX
2 API
2.1 Devices and interfaces
A device may have multiple interfaces, so a handle can return multiple interface instances. Do not forget to call usb_claim_interface ().
2.2 timeout
Always in milliseconds.
2.3 Data Type
Both abstract and non-abstract structures are used to maintain portability.
2.4 Synchronization
All libusb v0.1 functions are synchronized, which means that no response is returned before the operation is completed or times out. Asynchronous operations are supported from libusb v1.0.
2.5 Return Value
Libusb v0.1 has two return values. One is the handle returned by usb_open (), and the other is an integer int. A negative number is returned, indicating an error.
3 Function
3.1 core functions
Void usb_init (void );
Initialize libusb.
Int usb_find_busses (void );
Find all buses and return the number of changed buses (including new and removed buses) after the last call ).
Int usb_find_devices (void );
Find all devices on each bus. It should be called after usb_find_busses. Returns the number of changes (including new and removed devices) after the last call ).
Struct usb_bus * usb_get_busses (void );
Return the global variable usb_busses. This only applies to languages that support C call specifications and can use shared libraries, but does not support C global variables (such as Delphi ).
3.2 device operations
These functions are used to operate devices. Allows you to enable and disable devices, set configurations, rotate settings, and clean devices. It also provides OS-level operations, such as claim and release interfaces.
Usb_dev_handle * usb_open (struct * usb_device dev );
Open the device for use and return the device handle.
Int usb_close (usb_dev_handle * dev );
If the device is disabled, 0 is returned, and a negative number is returned.
Int usb_set_configuration (usb_dev_handle * dev, int configuration );
Set active configurations. The configuration parameter is the value of the descriptor bConfigurationValue field. 0 is returned, and a negative number is returned.
Int usb_set_altinterface (usb_dev_handle * dev, int alternate );
Set active rotation settings for the current interface. The alternate parameter is the value of the bAlternateSetting field of the descriptor. 0 is returned, and a negative number is returned.
Int usb_resetep (usb_dev_handle * dev, unsigned int ep );
Resets all statuses of a specified endpoint. The ep parameter is the value of the bEndpointAddress field of the descriptor. The return value is 0, which is a negative value.
This interface is not recommended. You may need usb_clear_halt ().
Int usb_clear_halt (usb_dev_handle * dev, unsigned int ep );
Clear all stop statuses of the endpoint. ep is the value of the bEndpointAddress field of the descriptor. 0 is returned, and a negative number is returned.
Int usb_reset (usb_dev_handle * dev );
RESET the specified device by sending the RESET command. 0 is returned, and a negative number is returned.
After executing this function, you need to list it again and find the device. The current handle cannot work any more.
Int usb_claim_interface (usb_dev_handle * dev, int interface );
Claim an interface through the OS. The interface parameter is the bInterfaceNumber field of the descriptor. 0 is returned, and a negative number is returned.
It must be called before any interface-related operations (such as usb_set_altinterface () and usb_bulk_write.
Return code:
EBUSY: the interface is invalid and cannot be claimed
ENOMEM: insufficient memory
Int usb_release_interface (usb_dev_handle * dev, int interface );
Release the previously claimed API. The interface parameter is the bInterfaceNumber field of the descriptor. 0 is returned, and a negative number is returned.
3.3 Control Transmission
Send messages to the default control MPs queue.
Int usb_control_msg (usb_dev_handle * dev, int requesttype, int request, int value, int index, char * bytes, int size, int timeout );
Send control requests to the default control MPs queue of the device. The parameter corresponds to the same name type in the USB specification. Failed to return the number of read/write bytes.
Int usb_get_string (usb_dev_handle * dev, int index, int langid, char * buf, size_t buflen );
Obtains the device's string description through index and langdi index. Returns the Unicode string to the buf. Returns the number of bytes actually written to the buf. A negative number fails.
Int usb_get_string_simple (usb_dev_handle * dev, int index, char * buf, size_t buflen );
The usb_get_string () function is encapsulated, returns the string description of the index specified in the first language, and converts it to C-style ASCII. Failed to return the number of bytes written to the buf.
Int usb_get_descriptor (usb_dev_handle * dev, unsigned char type, unsigned char index, void * buf, int size );
Obtains the descriptor of the default control pipeline of the device, and uses the type and index indexes. Returns the number of bytes actually written to the buf. A negative number fails.
See usb_get_descriptor_by_endpoint () to learn about the allowed control endpoint.
Int usb_get_descriptor_by_endpoint (usb_dev_handle * dev, int ep, unsigned char type, unsigned char index, void * buf, int size );
Get the descriptor from the device, index with type and index, and use the control pipeline of the ep sign. Failed to return the number of read bytes.
3.4 Transmission
This part allows the application to send and receive data from the data block pipeline.
Int usb_bulk_write (usb_dev_handle * dev, int ep, char * bytes, int size, int timeout );
Write a piece of data to the endpoint ep, and return the number of successfully written bytes. A negative number fails.
Int usb_bulk_read (usb_dev_handle * dev, int ep, char * bytes, int size, int timeout );
Read a piece of data, from the endpoint ep, returns the number of successfully read bytes, negative number failed.
3.5 interrupted transmission
This set of functions allows applications to send and receive data through the interrupt pipeline.
Int usb_interrupt_write (usb_dev_handle * dev, int ep, char * bytes, int size, int timeout );
An error occurred while executing the interrupt write operation on the endpoint ep. The actual number of written bytes is returned and a negative number is returned.
Int usb_interrupt_read (usb_dev_handle * dev, int ep, char * bytes, int size, int timeout );
An error occurred while executing the read operation on the interrupt endpoint ep. The actual number of read bytes is returned.
3.6 cannot be transplanted
These functions cannot be transplanted. Some of them expose OS USB APIs. They all add the function name suffix _ np.
A c Preprocessor macro defines the implemented functions. The format is LIBUSB_HAS _ with the function name, without the usb _ prefix. For example, if usb_get_driver_np () is implemented, LIBUSB_HAS_GET_DRIVER_NP is defined.
Int usb_get_driver_np (usb_dev_handle * dev, int interface, char * name, int namelen );
This function gets the name of the interface driver. 0 is returned for success and a negative number is returned for failure.
Only available in Linux.
Int usb_detach_kernel_driver_np (usb_dev_handle * dev, int interface );
This function stripped the kernel driver from the interface. Applications that use libusb can then claim the interface again. 0 is returned, and a negative number is returned.
Only available in Linux.
4 Examples
4.1 simple example
Find the device before communicating with it. You need to first find all bus (busses) and then find all devices:
Struct usb_bus * busses;
Usb_init ();
Usb_find_busses ();
Usb_find_devices ();
Busses = usb_get_busses ();
After that, the application should manually poll all bus and devices to match the desired:
Struct usb_bus * bus;
Int c, I,;
For (bus = busses; bus = bus-> next ){
Struct usb_device * dev;
For (dev = bus-> devices; dev = dev-> next ){
If (dev-> descriptor. bDeviceClass = 7 ){
/* Open the device, claim the interface, and then perform the operation */
}
/* Traverse all configurations cyclically */
For (c = 0; c <dev-> descriptor. bNumConfigurations; c ++ ){
/* Traverse all interfaces cyclically */
For (I = 0; I <dev-> config [c]. bNumInterfaces; I ++ ){
/* Cyclically traverse all rotation settings */
For (a = 0; a <dev-> config [c]. interface [I]. num_altsetting; a ++ ){
/* Check whether the interface is a printer */
If (dev-> config [c]. interface [I]. altsetting [a]. bInterfaceClass = 7 ){
/* Open the device, set the rotation configuration, claim the interface, and then operate */
}
}
}
}
}
}
4.2 source code package example
The tests directory has a program named testlibusb. c. It simply calls libusb to find all the devices, then traverse and print the descriptor. The result is very simple, but it is of limited use. It can be used as a good entry point.
4.3 Other Applications
For other applications, refer to other projects:
GPhoto: Use libusb to communicate with the camera
Rio500: Use libusb and SONICblue Rio 500 player