eXpand your USB potential
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 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, iow 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:

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 a libusb_device_handles for the device it is up to you to call libusb_close() on each 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 libusbx function that takes a libusb_device. On the other hand, 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:

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 *handle = NULL;
int rc;
(void)libusb_get_device_descriptor(dev, &desc);
rc = libusb_open(dev, &handle);
if (LIBUSB_SUCCESS != rc) {
printf("Could not open USB device\n");
}
} else if (LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == event) {
if (handle) {
libusb_close(handle);
handle = NULL;
}
} else {
printf("Unhandled event %d\n", event);
}
count++;
return 0;
}
int main (void) {
int rc;
libusb_init(NULL);
LIBUSB_HOTPLUG_MATCH_ANY, hotplug_callback, NULL,
&handle);
if (LIBUSB_SUCCESS != rc) {
printf("Error creating a hotplug callback\n");
libusb_exit(NULL);
return EXIT_FAILURE;
}
while (count < 2) {
usleep(10000);
}
libusb_exit(NULL);
return 0;
}