2 * LibUSB over LibUCW Mainloop
4 * (c) 2014--2022 Martin Mares <mj@ucw.cz>
6 * Originally developed as a part of the Ursary project.
12 #include <ucw/clists.h>
14 #include <ucw/mainloop.h>
21 #include "usb-mainloop.h"
23 libusb_context *usb_ctx;
25 static struct main_file **usb_fds;
27 static int usb_fd_ready(struct main_file *f UNUSED)
29 DBG("USB: Handling events (ready on fd %d)", f->fd);
30 struct timeval tv = { 0, 0 };
32 int err = libusb_handle_events_timeout_completed(usb_ctx, &tv, &comp);
34 msg(L_ERROR, "libusb_handle_events: error %d", err);
38 static void usb_added_fd(int fd, short events, void *user_data UNUSED)
40 if (fd >= (int) GARY_SIZE(usb_fds))
41 GARY_RESIZE(usb_fds, fd + 1);
43 struct main_file *f = usb_fds[fd];
45 f = xmalloc_zero(sizeof(*f));
47 } else if (file_is_active(f)) {
48 DBG("USB: Releasing fd %d", fd);
52 DBG("USB: Adding fd %d with event mask %u", fd, events);
54 f->read_handler = (events & POLLIN) ? usb_fd_ready : NULL;
55 f->write_handler = (events & POLLOUT) ? usb_fd_ready : NULL;
59 static void usb_removed_fd(int fd, void *user_data UNUSED)
61 DBG("USB: Releasing fd %d", fd);
62 ASSERT(fd < (int) GARY_SIZE(usb_fds));
63 struct main_file *f = usb_fds[fd];
65 ASSERT(file_is_active(f));
69 void usb_init_mainloop(void)
74 if ((err = libusb_init(&usb_ctx)) < 0)
75 die("libusb_init failed: error %d", err);
77 // Connect libusb to UCW mainloop
79 if (!libusb_pollfds_handle_timeouts(usb_ctx))
80 die("Unsupported version of libusb, please fix me");
82 GARY_INIT_ZERO(usb_fds, 0);
83 libusb_set_pollfd_notifiers(usb_ctx, usb_added_fd, usb_removed_fd, NULL);
85 const struct libusb_pollfd **fds = libusb_get_pollfds(usb_ctx);
87 for (int i=0; fds[i]; i++)
88 usb_added_fd(fds[i]->fd, fds[i]->events, NULL);