libusb: Device hotplug event notification

| libusb 1.0.27 A cross-platform user library to access USB devices

Device hotplug event notification

# Introduction

Version 1.0.16, LIBUSBX_API_VERSION >= 0x01000102, has added support for hotplug events on some platforms (you should test if your platform supports hotplug notification by calling libusb_has_capability() with parameter LIBUSB_CAP_HAS_HOTPLUG).

This interface allows you to request notification for the arrival and departure of matching USB devices.

To receive hotplug notification you register a callback by calling libusb_hotplug_register_callback(). This function will optionally return a callback handle that can be passed to libusb_hotplug_deregister_callback().

A callback function must return an int (0 or 1) indicating whether the callback is expecting additional events. Returning 0 will rearm the callback and 1 will cause the callback to be deregistered. Note that when callbacks are called from libusb_hotplug_register_callback() because of the LIBUSB_HOTPLUG_ENUMERATE flag, the callback return value is ignored. In other words, you cannot cause a callback to be deregistered by returning 1 when it is called from libusb_hotplug_register_callback().

Callbacks for a particular context are automatically deregistered by libusb_exit().

As of 1.0.16 there are two supported hotplug events:

- LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED: A device has arrived and is ready to use
- LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT: A device has left and is no longer available

A hotplug event can listen for either or both of these events.

Note: If you receive notification that a device has left and you have any libusb_device_handles for the device it is up to you to call libusb_close() on each device handle to free up any remaining resources associated with the device. Once a device has left any libusb_device_handle associated with the device are invalid and will remain so even if the device comes back.

When handling a LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED event it is considered safe to call any libusb function that takes a libusb_device. It also safe to open a device and submit asynchronous transfers. However, most other functions that take a libusb_device_handle are not safe to call. Examples of such functions are any of the synchronous API functions or the blocking functions that retrieve various USB descriptors. These functions must be used outside of the context of the hotplug callback.

When handling a LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT event the only safe function is libusb_get_device_descriptor().

The following code provides an example of the usage of the hotplug interface:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <libusb.h>
static int count = 0;
int hotplug_callback(struct libusb_context *ctx, struct libusb_device *dev,
libusb_hotplug_event event, void *user_data) {
static libusb_device_handle *dev_handle = NULL;
struct libusb_device_descriptor desc;
int rc;
(void)libusb_get_device_descriptor(dev, &desc);
if (LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED == event) {
rc = libusb_open(dev, &dev_handle);
if (LIBUSB_SUCCESS != rc) {
printf("Could not open USB device\n");
}
} else if (LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == event) {
if (dev_handle) {
libusb_close(dev_handle);
dev_handle = NULL;
}
} else {
printf("Unhandled event %d\n", event);
}
count++;
return 0;
}
int main (void) {
libusb_hotplug_callback_handle callback_handle;
int rc;
libusb_init_context(NULL, NULL, 0);
rc = libusb_hotplug_register_callback(NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |
LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, 0x045a, 0x5005,
LIBUSB_HOTPLUG_MATCH_ANY, hotplug_callback, NULL,
&callback_handle);
if (LIBUSB_SUCCESS != rc) {
printf("Error creating a hotplug callback\n");
libusb_exit(NULL);
return EXIT_FAILURE;
}
while (count < 2) {
libusb_handle_events_completed(NULL, NULL);
nanosleep(&(struct timespec){0, 10000000UL}, NULL);
}
libusb_hotplug_deregister_callback(NULL, callback_handle);
libusb_exit(NULL);
return 0;
}
libusb_get_device_descriptor
int libusb_get_device_descriptor(libusb_device *dev, struct libusb_device_descriptor *desc)
Get the USB device descriptor for a given device.
Definition descriptor.c:531
libusb_open
int libusb_open(libusb_device *dev, libusb_device_handle **dev_handle)
Open a device and obtain a device handle.
Definition core.c:1405
libusb_close
void libusb_close(libusb_device_handle *dev_handle)
Close a device handle.
Definition core.c:1562
libusb_device
struct libusb_device libusb_device
Structure representing a USB device detected on the system.
Definition libusb.h:1137
libusb_device_handle
struct libusb_device_handle libusb_device_handle
Structure representing a handle on a USB device.
Definition libusb.h:1148
libusb_hotplug_callback_handle
int libusb_hotplug_callback_handle
Callback handle.
Definition libusb.h:2175
libusb_hotplug_event
libusb_hotplug_event
Since version 1.0.16, LIBUSB_API_VERSION >= 0x01000102.
Definition libusb.h:2182
libusb_hotplug_register_callback
int libusb_hotplug_register_callback(libusb_context *ctx, int events, int flags, int vendor_id, int product_id, int dev_class, libusb_hotplug_callback_fn cb_fn, void *user_data, libusb_hotplug_callback_handle *callback_handle)
Register a hotplug callback function.
Definition hotplug.c:323
LIBUSB_HOTPLUG_MATCH_ANY
#define LIBUSB_HOTPLUG_MATCH_ANY
Wildcard matching for hotplug events.
Definition libusb.h:2208
libusb_hotplug_deregister_callback
void libusb_hotplug_deregister_callback(libusb_context *ctx, libusb_hotplug_callback_handle callback_handle)
Deregisters a hotplug callback.
Definition hotplug.c:408
LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED
@ LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED
A device has been plugged in and is ready to use.
Definition libusb.h:2184
LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT
@ LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT
A device has left and is no longer available.
Definition libusb.h:2189
libusb_context
struct libusb_context libusb_context
Structure representing a libusb session.
Definition libusb.h:1120
libusb_init_context
int libusb_init_context(libusb_context **ctx, const struct libusb_init_option options[], int num_options)
Initialize libusb.
Definition core.c:2424
libusb_exit
void libusb_exit(libusb_context *ctx)
Deinitialize libusb.
Definition core.c:2577
LIBUSB_SUCCESS
@ LIBUSB_SUCCESS
Success (no error)
Definition libusb.h:1182
libusb_handle_events_completed
int libusb_handle_events_completed(libusb_context *ctx, int *completed)
Handle any pending events in blocking mode.
Definition io.c:2462
libusb_device_descriptor
A structure representing the standard USB device descriptor.
Definition libusb.h:573