LIBUSB(3)
libusb(3) โ USB access library, but make it a group-chat moment ๐
๐ NAME ๐
libusb โ USB access library
๐ LIBRARY ๐
USB access library (libusb, -lusb)
โจ SYNOPSIS โจ
#include <libusb.h>
๐ฆ DESCRIPTION ๐ฆ
The libusb library contains interfaces for directly managing a usb device. The current implementation supports v1.0 of the libusb API.
๐ LIBRARY INITIALISATION AND DEINITIALISATION ๐
Okay bestie, this is the setup-and-cleanup era. Do it in the right order or the USB vibes will be off, no cap.
๐ libusb_get_version
const struct libusb_version * libusb_get_version(void)
This function returns version information about LibUSB.
๐ libusb_init
int libusb_init(libusb_context **ctx)
Call this function before any other libusb v1.0 API function, to initialise a valid libusb v1.0 context. If the ctx argument is non-NULL, a pointer to the libusb context is stored at the given location. This function returns 0 upon success or LIBUSB_ERROR on failure.
๐ง libusb_init_context
int libusb_init_context(libusb_context **ctx, const struct libusb_init_option [], int num_options)
Call this function before any other libusb v1.0 API function, to initialise a valid libusb v1.0 context. If the ctx argument is non-NULL, a pointer to the libusb context is stored at the given location. Additional options, like the USB debug level, may be given using the second and third argument. If no options are needed, simply use libusb_init(). This function returns 0 upon success or a LIBUSB_ERROR value on failure.
๐ซถ libusb_exit
void libusb_exit(libusb_context *ctx)
Deinitialise libusb. Must be called at the end of the application. Other libusb routines may not be called after this function. Like, thatโs the final goodbye โ respect it ๐
๐ฅ libusb_has_capability
int libusb_has_capability(uint32_t capability)
This function checks the runtime capabilities of libusb. This function will return non-zero if the given capability is supported, 0 if it is not supported. The valid values for capability are:
LIBUSB_CAP_HAS_CAPABILITYโ libusb supportslibusb_has_capability().LIBUSB_CAP_HAS_HOTPLUGโ libusb supports hotplug notifications.LIBUSB_CAP_HAS_HID_ACCESSโ libusb can access HID devices without requiring user intervention.LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVERโ libusb supports detaching of the default USB driver withlibusb_detach_kernel_driver().
๐ฌ libusb_strerror
const char * libusb_strerror(int code)
Get the ASCII representation of the error given by the code argument. This function does not return NULL. Iconic of it, honestly.
๐ libusb_setlocale
int libusb_setlocale(const char *locale)
Set locale for the error message when using libusb_strerror() to locale. Note other libusb implementations only support the first two bytes, that means โen-USโ is equivalent to โen-CAโ.
๐ libusb_error_name
const char * libusb_error_name(int code)
Get the ASCII representation of the error enum given by the code argument. This function does not return NULL.
๐
libusb_set_debug
void libusb_set_debug(libusb_context *ctx, int level)
Set the debug level to level.
๐ getting the device list ๐
ssize_t libusb_get_device_list(libusb_context *ctx, libusb_device ***list)โ fills inlistwith every USB device it can find, and adds a reference to each device in that list โจ. It returns the number of devices in the list, or aLIBUSB_ERRORcode.
โ ๏ธ bestie, this one comes with homework: every entry this function makes has to have its reference counter decremented when you're done with it, and the list itself has to be freed. Do not just walk away from it, I'm begging ๐ญ๐
void libusb_free_device_list(libusb_device **list, int unref_devices)โ frees the list of devices thatlibusb_get_device_listfound for you. Ifunref_deviceis set to1, every device in the list gets its reference counter decremented once ๐
๐ bus, port, and address vibes ๐
uint8_t libusb_get_bus_number(libusb_device *dev)โ returns the number of the bus that devicedevlives on ๐uint8_t libusb_get_port_number(libusb_device *dev)โ returns the port number thatdevis attached to ๐int libusb_get_port_numbers(libusb_device *dev, uint8_t *buf, uint8_t bufsize)โ stashes the whole list of port numbers, from the root down todev, into the bufferbuf(which isbufsizebig) ๐ฆint libusb_get_port_path(libusb_context *ctx, libusb_device *dev, uint8_t *buf, uint8_t bufsize)โ the deprecated girlie ๐ she's equivalent tolibusb_get_port_numbersuint8_t libusb_get_device_address(libusb_device *dev)โ returns thedevice_addressthat devicedevis holding ๐
โก speed and packet sizes โก
enum libusb_speed libusb_get_device_speed(libusb_device *dev)โ tells you the wire speed the device is connected at. Peep theLIBUSB_SPEED_XXXenums for the deets ๐ and if the wire speed is a mystery, you getLIBUSB_SPEED_UNKNOWNback ๐ซint libusb_get_max_packet_size(libusb_device *dev, unsigned char endpoint)โ returns thewMaxPacketSizevalue on success,LIBUSB_ERROR_NOT_FOUNDif that endpoint doesn't exist, andLIBUSB_ERROR_OTHERSon any other failure ๐ฎโ๐จint libusb_get_max_iso_packet_size(libusb_device *dev, unsigned char endpoint)โ returns the packet size multiplied by the packet multiplier on success,LIBUSB_ERROR_NOT_FOUNDif the endpoint doesn't exist, andLIBUSB_ERROR_OTHERSon other failure โจ
๐ซถ reference counting, the iconic duo ๐ซถ
libusb_device * libusb_ref_device(libusb_device *dev)โ bumps up the reference counter of devicedevโฌ๏ธvoid libusb_unref_device(libusb_device *dev)โ brings the reference counter of devicedevdown โฌ๏ธ
๐ช wrapping and opening ๐ช
int libusb_wrap_sys_device(libusb_context *ctx, intptr_t sys_dev, libusb_device_handle **dev_handle)โ supposed to make a libusb handler out of an already-opened fd,sys_dev. She's here for compatibility only and is currently unimplemented โ always returnsLIBUSB_ERROR_NOT_SUPPORTED๐int libusb_open(libusb_device *dev, libusb_device_handle **devh)โ opens a device and hands you adevice_handle. Returns0on success,LIBUSB_ERROR_NO_MEMif memory allocation goes sideways,LIBUSB_ERROR_ACCESSon permission problems,LIBUSB_ERROR_NO_DEVICEif the device got disconnected, and aLIBUSB_ERRORcode on other errors ๐ซกlibusb_device_handle * libusb_open_device_with_vid_pid(libusb_context *ctx, uint16_t vid, uint16_t pid)โ the convenience queen ๐ opens a device by its vendor and product IDs,vidandpid. ReturnsNULLon error ๐ฅฒ
โจ closing and looking things up โจ
void libusb_close(libusb_device_handle *devh)โ closes a device handle, doors shut, lights off ๐ชlibusb_device * libusb_get_device(libusb_device_handle *devh)โ gets the device thatdevhis holding. ReturnsNULLon error ๐ฌlibusb_device * libusb_get_parent(libusb_device *dev)โ getsdev's parent device. ReturnsNULLif the device has no parent (i.e. it's a root device) ๐ณ
๐ configurations ๐
int libusb_get_configuration(libusb_device_handle *devh, int *config)โ returns the value of the current configuration. Returns0on success,LIBUSB_ERROR_NO_DEVICEif the device has been disconnected, and aLIBUSB_ERRORcode on error ๐int libusb_set_configuration(libusb_device_handle *devh, int config)โ sets the active configuration toconfigfor the device thatdevhis holding. Returns0on success,LIBUSB_ERROR_NOT_FOUNDif the configuration you asked for doesn't exist,LIBUSB_ERROR_BUSYif the interfaces are currently claimed,LIBUSB_ERROR_NO_DEVICEif the device has been disconnected, and aLIBUSB_ERRORcode on failure ๐ฎโ๐จ
๐ฆ interfaces, claiming and releasing ๐ฆ
int libusb_claim_interface(libusb_device_handle *devh, int interface_number)โ claims an interface on the givenlibusb_handledevh. She's a non-blocking function, okurrr ๐ Returns0on success,LIBUSB_ERROR_NOT_FOUNDif the requested interface doesn't exist,LIBUSB_ERROR_BUSYif a program or driver already claimed it,LIBUSB_ERROR_NO_DEVICEif the device has been disconnected, and aLIBUSB_ERRORcode on failure โจint libusb_release_interface(libusb_device_handle *devh, int interface_number)โ releases an interface. All the claimed interfaces on a device have to be released before you close the device โ yes, all of them, I said what I said ๐ฃ๏ธ Returns0on success,LIBUSB_ERROR_NOT_FOUNDif the interface wasn't claimed,LIBUSB_ERROR_NO_DEVICEif the device has been disconnected, andLIBUSB_ERRORon failure ๐int libusb_set_interface_alt_setting(libusb_device_handle *dev, int interface_number, int alternate_setting)โ activates an alternate setting for an interface. Returns0on success,LIBUSB_ERROR_NOT_FOUNDif the interface wasn't claimed or the requested setting doesn't exist,LIBUSB_ERROR_NO_DEVICEif the device has been disconnected, and aLIBUSB_ERRORcode on failure ๐
๐ฅ halts, resets, and is-it-still-there checks ๐ฅ
int libusb_clear_halt(libusb_device_handle *devh, unsigned char endpoint)โ clears a halt/stall on an endpoint. Returns0on success,LIBUSB_ERROR_NOT_FOUNDif the endpoint doesn't exist,LIBUSB_ERROR_NO_DEVICEif the device has been disconnected, and aLIBUSB_ERRORcode on failure ๐ฟint libusb_reset_device(libusb_device_handle *devh)โ does a USB port reset on a USB device. Returns0on success,LIBUSB_ERROR_NOT_FOUNDif re-enumeration is required or if the device has been disconnected, and aLIBUSB_ERRORcode on failure ๐int libusb_check_connected(libusb_device_handle *devh)โ vibe checks whether the USB device is still connected ๐ซถ Returns0on success,LIBUSB_ERROR_NO_DEVICEif it has been disconnected, and aLIBUSB_ERRORcode on failure ๐ญ
๐ง kernel drivers, the whole saga ๐ง
int libusb_kernel_driver_active(libusb_device_handle *devh, int interface)โ finds out if a driver is active on an interface. Returns0if no kernel driver is active,1if a kernel driver is active,LIBUSB_ERROR_NO_DEVICEif the device has been disconnected, and aLIBUSB_ERRORcode on failure ๐int libusb_get_driver(libusb_device_handle *devh, int interface, char *name, int namelen)orint libusb_get_driver_np(libusb_device_handle *devh, int interface, char *name, int namelen)โ copies the name of the driver attached to the given device and interface into the buffername, which isnamelenlong. Returns0on success,LIBUSB_ERROR_NOT_FOUNDif no kernel driver is attached to the given interface, andLIBUSB_ERROR_INVALID_PARAMif the interface doesn't exist. Heads up: this function is non-portable ๐ฉ and the buffernamepoints to is only zero-terminated on successint libusb_detach_kernel_driver(libusb_device_handle *devh, int interface)orint libusb_detach_kernel_driver_np(libusb_device_handle *devh, int interface)โ detaches a kernel driver from an interface. You need this to claim an interface that a kernel driver already claimed, no cap ๐ Returns0on success,LIBUSB_ERROR_NOT_FOUNDif no kernel driver was active,LIBUSB_ERROR_INVALID_PARAMif the interface doesn't exist,LIBUSB_ERROR_NO_DEVICEif the device has been disconnected, and aLIBUSB_ERRORcode on failure. Also non-portable ๐ฉint libusb_attach_kernel_driver(libusb_device_handle *devh, int interface)โ re-attaches an interface's kernel driver that you previously detached ๐ Returns0on success,LIBUSB_ERROR_INVALID_PARAMif the interface doesn't exist,LIBUSB_ERROR_NO_DEVICEif the device has been disconnected,LIBUSB_ERROR_BUSYif the driver can't be attached because the interface is claimed by a program or driver, and aLIBUSB_ERRORcode on failure ๐ฎโ๐จint libusb_set_auto_detach_kernel_driver(libusb_device_handle *devh, int enable)โ turns on automatic kernel interface driver detaching for when an interface gets claimed, and when the interface is restored the kernel driver is allowed to be re-attached ๐ช Ifenableis non-zero the feature is enabled. Else disabled. Returns0on success and aLIBUSB_ERRORcode on failure โจ
๐ DMA memory (allegedly) ๐
unsigned char * libusb_dev_mem_alloc(libusb_device_handle *devh)โ tries to allocate a DMA memory block from the givendevhso we can enjoy that zero-copy transfer from the kernel ๐ She's provided for compatibility, is currently unimplemented, and always returnsNULL๐int libusb_dev_mem_free(libusb_device_handle *devh, unsigned char *buffer, size_t size)โ frees the DMA memory indevhfrom the givenbufferwithsize. Also unimplemented, always returnsLIBUSB_ERROR_NOT_SUPPORTED๐
๐ฆ USB DESCRIPTORS ๐ฆ
okay so descriptors are literally the device's little info cards โ its whole personality, its whole resume ๐ and these are the functions that go get them for you. Buckle up bestie, there's a bunch:
int libusb_get_device_descriptor(libusb_device *dev, libusb_device_descriptor *desc)โ grabs the USB device descriptor for the devicedev. This one is non-blocking, it does not sit there waiting on anything ๐ Returns0on success and aLIBUSB_ERRORcode on failure.int libusb_get_active_config_descriptor(libusb_device *dev, struct libusb_config_descriptor **config)โ gets the USB configuration descriptor for the active configuration. Returns0on success,LIBUSB_ERROR_NOT_FOUNDif the device is in an unconfigured state, and aLIBUSB_ERRORcode on error.int libusb_get_config_descriptor(libusb_device *dev, uint8_t config_index, libusb_config_descriptor **config)โ gets a USB configuration descriptor based on its indexidx. Returns0on success,LIBUSB_ERROR_NOT_FOUNDif the configuration does not exist, and aLIBUSB_ERRORcode on error.int libusb_get_config_descriptor_by_value(libusb_device *dev, uint8 bConfigurationValue, libusb_config_descriptor **config)โ gets a USB configuration descriptor with a specificbConfigurationValue. This is a non-blocking function which does not send a request through the device ๐ซถ Returns0on success,LIBUSB_ERROR_NOT_FOUNDif the configuration does not exist, and aLIBUSB_ERRORcode on failure.void libusb_free_config_descriptor(libusb_config_descriptor *config)โ frees a configuration descriptor. bye bestie ๐int libusb_get_string_descriptor(libusb_device_handle *devh, uint8_t desc_idx, uint16_t langid, unsigned char *data, int length)โ retrieves a string descriptor in raw format. Returns the number of bytes actually transferred on success, or a negativeLIBUSB_ERRORcode on failure.int libusb_get_string_descriptor_ascii(libusb_device_handle *devh, uint8_t desc_idx, unsigned char *data, int length)โ retrieves a string descriptor in C style ASCII, so it's actually readable instead of raw bytes โจ Returns the positive number of bytes in the resulting ASCII string on success and aLIBUSB_ERRORcode on failure.int libusb_parse_ss_endpoint_comp(const void *buf, int len, libusb_ss_endpoint_companion_descriptor **ep_comp)โ parses the USB 3.0 endpoint companion descriptor in host endian format pointed to bybufand having a length oflen. Typically these arguments are theextraandextra_lengthfields of the endpoint descriptor, iykyk. On success the pointer to the resulting descriptor is stored at the location given byep_comp. Returns zero on success and aLIBUSB_ERRORcode on failure. On success the parsed USB 3.0 endpoint companion descriptor must be freed using thelibusb_free_ss_endpoint_compfunction โ don't leave it hanging, that's not the vibe ๐void libusb_free_ss_endpoint_comp(libusb_ss_endpoint_companion_descriptor *ep_comp)โ this function is NULL safe and frees a parsed USB 3.0 endpoint companion descriptor given byep_comp.int libusb_get_ss_endpoint_companion_descriptor(struct libusb_context *ctx, const struct libusb_endpoint_descriptor *endpoint, struct libusb_ss_endpoint_companion_descriptor **ep_comp)โ finds and parses the USB 3.0 endpoint companion descriptor given byendpoint. Returns zero on success and aLIBUSB_ERRORcode on failure. On success the parsed USB 3.0 endpoint companion descriptor must be freed using thelibusb_free_ss_endpoint_companion_descriptorfunction.void libusb_free_ss_endpoint_companion_descriptor(struct libusb_ss_endpoint_companion_descriptor *ep_comp)โ NULL safe, frees a parsed USB 3.0 endpoint companion descriptor given byep_comp. ๐int libusb_get_bos_descriptor(libusb_device_handle *handle, struct libusb_bos_descriptor **bos)โ queries the USB device given byhandleand stores a pointer to a parsed BOS descriptor intobos. Returns zero on success and aLIBUSB_ERRORcode on failure. On success the parsed BOS descriptor must be freed using thelibusb_free_bos_descriptorfunction.int libusb_parse_bos_descriptor(const void *buf, int len, libusb_bos_descriptor **bos)โ parses a Binary Object Store, BOS, descriptor into host endian format pointed to bybufand having a length oflen. On success the pointer to the resulting descriptor is stored at the location given bybos. Returns zero on success and aLIBUSB_ERRORcode on failure. On success the parsed BOS descriptor must be freed using thelibusb_free_bos_descriptorfunction.void libusb_free_bos_descriptor(libusb_bos_descriptor *bos)โ NULL safe, frees a parsed BOS descriptor given bybos. ๐int libusb_get_usb_2_0_extension_descriptor(struct libusb_context *ctx, struct libusb_bos_dev_capability_descriptor *dev_cap, struct libusb_usb_2_0_extension_descriptor **usb_2_0_extension)โ parses the USB 2.0 extension descriptor from the descriptor given bydev_capand stores a pointer to the parsed descriptor intousb_2_0_extension. Returns zero on success and aLIBUSB_ERRORcode on failure. On success the parsed USB 2.0 extension descriptor must be freed using thelibusb_free_usb_2_0_extension_descriptorfunction.void libusb_free_usb_2_0_extension_descriptor(struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension)โ NULL safe, frees a parsed USB 2.0 extension descriptor given byusb_2_0_extension.int libusb_get_ss_usb_device_capability_descriptor(struct libusb_context *ctx, struct libusb_bos_dev_capability_descriptor *dev_cap, struct libusb_ss_usb_device_capability_descriptor **ss_usb_device_capability)โ parses the SuperSpeed device capability descriptor from the descriptor given bydev_capand stores a pointer to the parsed descriptor intoss_usb_device_capability. Returns zero on success and aLIBUSB_ERRORcode on failure. On success the parsed SuperSpeed device capability descriptor must be freed using thelibusb_free_ss_usb_device_capability_descriptorfunction. SuperSpeed, literally in the name ๐ฅvoid libusb_free_ss_usb_device_capability_descriptor(struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_capability)โ NULL safe, frees a parsed SuperSpeed device capability descriptor given byss_usb_device_capability.int libusb_get_container_id_descriptor(struct libusb_context *ctx, struct libusb_bos_dev_capability_descriptor *dev_cap, struct libusb_container_id_descriptor **container_id)โ parses the container ID descriptor from the descriptor given bydev_capand stores a pointer to the parsed descriptor intocontainer_id. Returns zero on success and aLIBUSB_ERRORcode on failure. On success the parsed container ID descriptor must be freed using thelibusb_free_container_id_descriptorfunction.void libusb_free_container_id_descriptor(struct libusb_container_id_descriptor *container_id)โ NULL safe, frees a parsed container ID descriptor given bycontainer_id. ๐int libusb_get_platform_descriptor(struct libusb_context *ctx, struct libusb_bos_dev_capability_descriptor *dev_cap, struct libusb_platform_descriptor **platform_descriptor)โ parses the platform descriptor from the descriptor given bydev_capand stores a pointer to the parsed descriptor intoplatform_descriptor. Returns zero on success and aLIBUSB_ERRORcode on failure. On success the parsed platform descriptor must be freed using thelibusb_free_platform_descriptorfunction.void libusb_free_platform_descriptor(struct libusb_platform_descriptor *platform_descriptor)โ NULL safe, frees a parsed platform descriptor given byplatform_descriptor. ๐ง
โก USB ASYNCHRONOUS I/O โก
async I/O is the "don't wait around, go live your life" era of USB โ you hand off the transfer and the library hits you back later. main character energy fr fr ๐ซ
struct libusb_transfer * libusb_alloc_transfer(int iso_packets)โ allocates a transfer with the number of isochronous packet descriptors specified byiso_packets. ReturnsNULLon error ๐ญvoid libusb_free_transfer(struct libusb_transfer *tr)โ frees a transfer.int libusb_submit_transfer(struct libusb_transfer *tr)โ submits a transfer and returns immediately, no waiting, no blocking, we love to see it. Returns0on success,LIBUSB_ERROR_NO_DEVICEif the device has been disconnected, and aLIBUSB_ERRORcode on other failure.int libusb_cancel_transfer(struct libusb_transfer *tr)โ asynchronously cancels a transfer. Returns0on success and aLIBUSB_ERRORcode on failure.
๐งธ USB SYNCHRONOUS I/O ๐งธ
the chill, old-school way: you ask, you wait, you get your answer. no cap, sometimes that's exactly what you want ๐
int libusb_control_transfer(libusb_device_handle *devh, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, unsigned char *data, uint16_t wLength, unsigned int timeout)โ performs a USB control transfer. Returns the actual number of bytes transferred on success, in the range from and including zero up to and includingwLength. On error aLIBUSB_ERRORcode is returned โ for exampleLIBUSB_ERROR_TIMEOUTif the transfer timed out,LIBUSB_ERROR_PIPEif the control request was not supported,LIBUSB_ERROR_NO_DEVICEif the device has been disconnected, and anotherLIBUSB_ERRORcode on other failures. TheLIBUSB_ERRORcodes are all negative ๐
watch the sign bestie โ success is >= 0, errors are negative. don't go reading a negative error like it's a byte count ๐
int libusb_bulk_transfer(libusb_device_handle *devh, unsigned char endpoint, unsigned char *data, int length, int *transferred, unsigned int timeout)โ performs an USB bulk transfer. Atimeoutvalue of zero means no timeout. Thetimeoutvalue is given in milliseconds. Returns0on success,LIBUSB_ERROR_TIMEOUTif the transfer timed out,LIBUSB_ERROR_PIPEif the control request was not supported,LIBUSB_ERROR_OVERFLOWif the device offered more data,LIBUSB_ERROR_NO_DEVICEif the device has been disconnected and aLIBUSB_ERRORcode on other failure.int libusb_interrupt_transfer(libusb_device_handle *devh, unsigned char endpoint, unsigned char *data, int length, int *transferred, unsigned int timeout)โ performs an USB Interrupt transfer. Atimeoutvalue of zero means no timeout. Thetimeoutvalue is given in milliseconds. Returns0on success,LIBUSB_ERROR_TIMEOUTif the transfer timed out,LIBUSB_ERROR_PIPEif the control request was not supported,LIBUSB_ERROR_OVERFLOWif the device offered more data,LIBUSB_ERROR_NO_DEVICEif the device has been disconnected and aLIBUSB_ERRORcode on other failure. ๐
๐ฆ USB STREAMS SUPPORT ๐ฆ
okay so streams!! this is the โจfancyโจ multiqueue-ish stuff, and bestie, there's a catch โ it's lowkey simplified rn:
int libusb_alloc_streams(libusb_device_handle *dev, uint32_t num_streams, unsigned char *endpoints, int num_endpoints)โ this one does a vibe check on your request: it verifies that the given number of streams using the given number of endpoints is actually allowed, then allocates all the resources you need to use so-called USB streams. but heads up: currently only a single stream per endpoint is supported, to simplify the internals of LibUSB. so likeโฆ don't get too ambitious ๐ญ. returns0on success or aLIBUSB_ERRORcode on failure.int libusb_free_streams(libusb_device_handle *dev, unsigned char *endpoints, int num_endpoints)โ the cleanup era ๐ releases the resources needed for streams usage. returns0on success or aLIBUSB_ERRORcode on failure.void libusb_transfer_set_stream_id(struct libusb_transfer *transfer, uint32_t stream_id)โ sets the stream ID for the given USB transfer. that's it, that's the whole job ๐uint32_t libusb_transfer_get_stream_id(struct libusb_transfer *transfer)โ hands you back the stream ID for the given USB transfer. and if no stream ID is used? you get a value of0. zero. nada. the void ๐
๐ USB EVENTS ๐
this is the whole threading-and-locking saga, and honestly it's giving "group project where only one person is allowed to touch the doc at a time". let's get into it ๐ซถ
int libusb_try_lock_events(libusb_context *ctx)โ tries to acquire the event handling lock (note the "try" โ she's not gonna wait around for you, queen). returns0if the lock was obtained and1if not.void libusb_lock_events(libusb_context *ctx)โ actually acquires the event handling lock. this function is blocking, so yeah, you're gonna sit there until it's your turn. no cap.void libusb_unlock_events(libusb_context *ctx)โ releases the event handling lock. this will wake up any thread blocked onlibusb_wait_for_event(). you're literally the main character doing a dramatic exit that frees everyone ๐ธint libusb_event_handling_ok(libusb_context *ctx)โ determines if it's still OK for this thread to be doing event handling. returns1if event handling can start or continue. returns0if this thread must give up the events lock. iykyk, that0is your cue to leave ๐int libusb_event_handler_active(libusb_context *ctx)โ determines if an active thread is handling events. returns1if there is a thread handling events and0if there are no threads currently handling events. it's a "is anyone home" check ๐void libusb_interrupt_event_handler(libusb_context *ctx)โ causes thelibusb_handle_events()family of functions to return to the caller one time. and the good news? thelibusb_handle_events()functions may be called again after calling this function. so it's a nudge, not a breakup ๐void libusb_lock_event_waiters(libusb_context *ctx)โ acquires theevent_waiterslock. this lock is designed to be obtained in the situation where you want to be aware when events are completed, but some other thread is event handling so callinglibusb_handle_events()is not allowed. it's the "i'm just watching, not touching" lock ๐void libusb_unlock_event_waiters(libusb_context *ctx)โ releases theevent_waiterslock. slay, you're done observing ๐int libusb_wait_for_event(libusb_context *ctx, struct timeval *tv)โ waits for another thread to signal completion of an event. must be called with the event waiters lock held, seelibusb_lock_event_waiters(). this will block until the timeout expires or a transfer completes or a thread releases the event handling lock throughlibusb_unlock_events(). returns0after a transfer completes or another thread stops event handling, and1if the timeout expired. so0= something happened,1= you waited for nothing bestie ๐ญint libusb_handle_events_timeout_completed(libusb_context *ctx, struct timeval *tv, int *completed)โ handles any pending events by checking if timeouts have expired and by checking the set of file descriptors for activity. if the completed argument is not equal toNULL, this function will loop until a transfer completion callback sets the variable pointed to by the completed argument to non-zero. if the tv argument is not equal toNULL, this function will returnLIBUSB_ERROR_TIMEOUTafter the given timeout. returns0on success, or aLIBUSB_ERRORcode on failure or timeout. she does a lot, okay, she's booked and busy โญint libusb_handle_events_completed(libusb_context *ctx, int *completed)โ handles any pending events by checking the set of file descriptors for activity. if the completed argument is not equal toNULL, this function will loop until a transfer completion callback sets the variable pointed to by the completed argument to non-zero. returns0on success, or aLIBUSB_ERRORcode on failure. same energy, minus the timer drama ๐int libusb_handle_events_timeout(libusb_context *ctx, struct timeval *tv)โ handles any pending events by checking if timeouts have expired and by checking the set of file descriptors for activity. returns0on success, or aLIBUSB_ERRORcode on failure or timeout. the classic โจint libusb_handle_events(libusb_context *ctx)โ handles any pending events in blocking mode with a sensible timeout. "sensible" is doing so much work in that sentence and i respect it. returns0on success and aLIBUSB_ERRORcode on failure ๐int libusb_handle_events_locked(libusb_context *ctx, struct timeval *tv)โ handles any pending events by polling file descriptors, without checking if another thread is already doing so. must be called with the event lock held. like, fr fr, do not skip that part ๐int libusb_pollfds_handle_timeouts(libusb_context *ctx)โ this function determines whether applications maintaining libusb events usinglibusb_get_pollfds()are responsible for handling timeout events themselves. returns1if libusb handles the timeout internally,0if the application needs to set a dedicated timer to handle it. so:1= she's got it covered,0= you're on your own, bestie ๐int libusb_get_next_timeout(libusb_context *ctx, struct timeval *tv)โ determines the next internal timeout that libusb needs to handle. returns0if there are no pending timeouts,1if a timeout was returned, or aLIBUSB_ERRORcode on failure or timeout. three outcomes, three moods ๐ซvoid libusb_set_pollfd_notifiers(libusb_context *ctx, libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb remove_cb, void *user_data)โ registers notification functions for file descriptor additions/removals. these functions will be invoked for every new or removed file descriptor that libusb uses as an event source. it's giving "notify me when the group chat changes" ๐ฆconst struct libusb_pollfd ** libusb_get_pollfds(libusb_context *ctx)โ retrieves a list of file descriptors that should be polled by your main loop as libusb event sources. returns aNULL-terminated list on success orNULLon failure. terminated byNULLspecifically โ don't go walking past the end, that's not the vibe ๐int libusb_hotplug_register_callback(libusb_context *ctx, libusb_hotplug_event events, libusb_hotplug_flag flags, int vendor_id, int product_id, int dev_class, libusb_hotplug_callback_fn cb_fn, void *user_data, libusb_hotplug_callback_handle *handle)โ this function registers a hotplug filter. the events argument selects which events make the hotplug filter trigger. available event values areLIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVEDandLIBUSB_HOTPLUG_EVENT_DEVICE_LEFT. one or more events must be specified. the vendor_id, product_id and dev_class arguments can be set toLIBUSB_HOTPLUG_MATCH_ANYto match any value in the USB device descriptor โ else the specified value is used for matching. if the flags argument is set toLIBUSB_HOTPLUG_ENUMERATE, all currently attached and matching USB devices will be passed to the hotplug filter, given by the cb_fn argument. else the flags argument should be set toLIBUSB_HOTPLUG_NO_FLAGS. this function returns0upon success or aLIBUSB_ERRORcode on failure. plug-and-play but make it โจfashionโจ ๐int libusb_hotplug_callback_fn(libusb_context *ctx, libusb_device *device, libusb_hotplug_event event, void *user_data)โ the hotplug filter function itself. if this function returns non-zero, the filter is removed. else the filter is kept and can receive more events. the user_data argument is the same as given when the filter was registered. the event argument can be either ofLIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVEDorLIBUSB_HOTPLUG_EVENT_DEVICE_LEFT. so returning non-zero is literally you saying "i'm done here" ๐void libusb_hotplug_deregister_callback(libusb_context *ctx, libusb_hotplug_callback_handle handle)โ this function unregisters a hotplug filter. bye bestie ๐ซถvoid libusb_free_pollfds(const struct libusb_pollfd **pollfds)โ this function releases the memory storage in pollfds, and is safe to call when the argument isNULL. grab the free win, we love a defensive function ๐ธlibusb_hotplug_get_user_data(struct libusb_context *ctx, libusb_hotplug_callback_handle callback_handle)โ this function returns the user data from the opaque callback_handle, or returnsNULLif no matching handle is found. (yes the signature in the docs has no return type written and we're not gonna invent one, that's between you and the header ๐)
๐ง LIBUSB VERSION 0.1 COMPATIBILITY ๐ง
the library is also compliant with LibUSB version 0.1.12. yes, the old stuff still works โ legacy icons stay iconic ๐
usb_open() usb_close() usb_get_string() usb_get_string_simple()
usb_get_descriptor_by_endpoint() usb_get_descriptor()
usb_parse_descriptor() usb_parse_configuration()
usb_destroy_configuration() usb_fetch_and_parse_descriptors()
usb_bulk_write() usb_bulk_read() usb_interrupt_write()
usb_interrupt_read() usb_control_msg() usb_set_configuration()
usb_claim_interface() usb_release_interface() usb_set_altinterface()
usb_resetep() usb_clear_halt() usb_reset() usb_strerror() usb_init()
usb_set_debug() usb_find_busses() usb_find_devices() usb_device()
usb_get_busses() usb_check_connected() usb_get_driver_np()
usb_detach_kernel_driver_np()
๐ฅ SEE ALSO ๐ฅ
go read these next, bestie, they're required reading for the lore:
and the official website, which we're allowed to just print as a string here:
https://libusb.info/
๐ HISTORY ๐
libusb support first appeared in FreeBSD 8.0. a true icon since day one, no cap ๐
and that's the whole page, bestie!! you made it to the end, which means you're officially a libusb girlie now ๐ This gorgeous thing came from Debian, dated July 9, 2025, filed under LIBUSB(3) โ go forth and poll some file descriptors, you absolute queen ๐๐
๐ฆ where this page comes from
- freebsd 15.1: base 15.1
- Copyright (c) 2009 Sylvestre Gallon
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms