102 lines
3 KiB
C
102 lines
3 KiB
C
#include "usb_device_detection.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
int hotplug_callback(struct libusb_context*,
|
|
struct libusb_device*,
|
|
libusb_hotplug_event event,
|
|
void* user_data)
|
|
{
|
|
struct usb_detector* detector = user_data;
|
|
|
|
if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED) {
|
|
detector->is_connected = true;
|
|
if (detector->has_hotplug_callbacks) detector->on_connected();
|
|
} else if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT) {
|
|
detector->is_connected = false;
|
|
if (detector->has_hotplug_callbacks) detector->on_disconnected();
|
|
} else
|
|
printf("Unexpected USB device event %d\n", event);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int libusb_event_handler(void* data)
|
|
{
|
|
struct usb_detector* detector = data;
|
|
|
|
while (!detector->event_handler_should_exit) {
|
|
thrd_sleep(&(struct timespec){.tv_sec = 1}, NULL);
|
|
libusb_handle_events_completed(detector->usb_context, NULL);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct usb_detector* create_detector(uint16_t vendor_id, uint16_t product_id)
|
|
{
|
|
|
|
struct libusb_context* usb_context;
|
|
libusb_init(&usb_context);
|
|
|
|
if (!usb_context) {
|
|
fprintf(stderr,
|
|
"Couldn't get USB contexxt. Device detection will not work\n");
|
|
return 0;
|
|
}
|
|
|
|
struct usb_detector* detector = calloc(1, sizeof(struct usb_detector));
|
|
detector->usb_context = usb_context;
|
|
detector->is_connected = false;
|
|
detector->event_handler_should_exit = false;
|
|
|
|
detector->has_hotplug_callbacks = false;
|
|
|
|
if (libusb_hotplug_register_callback(detector->usb_context,
|
|
LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |
|
|
LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT,
|
|
LIBUSB_HOTPLUG_ENUMERATE,
|
|
vendor_id,
|
|
product_id,
|
|
LIBUSB_HOTPLUG_MATCH_ANY,
|
|
hotplug_callback,
|
|
detector,
|
|
&detector->hotplug_handle) !=
|
|
LIBUSB_SUCCESS) {
|
|
|
|
fprintf(stderr,
|
|
"Couldn't register usb hotplug listener. Device detection "
|
|
"will not work.\n");
|
|
free(detector);
|
|
return 0;
|
|
}
|
|
|
|
if (thrd_create(&detector->event_handler_thread,
|
|
&libusb_event_handler,
|
|
detector) != thrd_success) {
|
|
fprintf(stderr,
|
|
"Couldn't start event handler. Device detection will not "
|
|
"work.\n");
|
|
free(detector);
|
|
return 0;
|
|
}
|
|
|
|
return detector;
|
|
}
|
|
|
|
void destroy_detector(struct usb_detector* detector)
|
|
{
|
|
libusb_hotplug_deregister_callback(detector->usb_context,
|
|
detector->hotplug_handle);
|
|
|
|
detector->event_handler_should_exit = true;
|
|
if (thrd_join(detector->event_handler_thread, 0) != thrd_success)
|
|
fprintf(stderr,
|
|
"Couldn't join with usb event handler thread, something went "
|
|
"really wrong, we likely won't exit cleanly\n");
|
|
|
|
libusb_exit(detector->usb_context);
|
|
|
|
free(detector);
|
|
}
|