Device hotplug event notification

Introduction

Version 1.0.16, LIBUSB_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 libusb 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;
  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, &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) {
  libusb_hotplug_callback_handle handle;
  int rc;

  libusb_init(NULL);

  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,
                                        &handle);
  if (LIBUSB_SUCCESS != rc) {
    printf("Error creating a hotplug callback\n");
    libusb_exit(NULL);
    return EXIT_FAILURE;
  }

  while (count < 2) {
    usleep(10000);
  }

  libusb_hotplug_deregister_callback(handle);
  libusb_exit(NULL);

  return 0;
}

Generated on Thu Jan 30 21:40:13 2014 by  doxygen 1.5.6