2 * LibUSB over LibUCW Mainloop
4 * (c) 2014--2020 Martin Mares <mj@ucw.cz>
10 #include <ucw/clists.h>
12 #include <ucw/mainloop.h>
22 libusb_context *usb_ctx;
24 static struct main_file **usb_fds;
26 static int usb_fd_ready(struct main_file *f UNUSED)
28 DBG("USB: Handling events (ready on fd %d)", f->fd);
29 struct timeval tv = { 0, 0 };
31 int err = libusb_handle_events_timeout_completed(usb_ctx, &tv, &comp);
33 msg(L_ERROR, "libusb_handle_events: error %d", err);
37 static void usb_added_fd(int fd, short events, void *user_data UNUSED)
39 if (fd >= (int) GARY_SIZE(usb_fds))
40 GARY_RESIZE(usb_fds, fd + 1);
42 struct main_file *f = usb_fds[fd];
45 f = xmalloc_zero(sizeof(*f));
48 else if (file_is_active(f))
50 DBG("USB: Releasing fd %d", fd);
54 DBG("USB: Adding fd %d with event mask %u", fd, events);
56 f->read_handler = (events & POLLIN) ? usb_fd_ready : NULL;
57 f->write_handler = (events & POLLOUT) ? usb_fd_ready : NULL;
61 static void usb_removed_fd(int fd, void *user_data UNUSED)
63 DBG("USB: Releasing fd %d", fd);
64 ASSERT(fd < (int) GARY_SIZE(usb_fds));
65 struct main_file *f = usb_fds[fd];
67 ASSERT(file_is_active(f));
76 if ((err = libusb_init(&usb_ctx)) < 0)
77 die("libusb_init failed: error %d", err);
79 // Connect libusb to UCW mainloop
81 if (!libusb_pollfds_handle_timeouts(usb_ctx))
82 die("Unsupported version of libusb, please fix me");
84 GARY_INIT_ZERO(usb_fds, 0);
85 libusb_set_pollfd_notifiers(usb_ctx, usb_added_fd, usb_removed_fd, NULL);
87 const struct libusb_pollfd **fds = libusb_get_pollfds(usb_ctx);
89 for (int i=0; fds[i]; i++)
90 usb_added_fd(fds[i]->fd, fds[i]->events, NULL);