]> sigrok.org Git - libsigrok.git/blob - src/usb.c
drivers: Add and use STD_CONFIG_LIST().
[libsigrok.git] / src / usb.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2012 Uwe Hermann <uwe@hermann-uwe.de>
5  * Copyright (C) 2012 Bert Vermeulen <bert@biot.com>
6  * Copyright (C) 2015 Daniel Elstner <daniel.kitta@gmail.com>
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include <config.h>
23 #include <stdlib.h>
24 #include <memory.h>
25 #include <glib.h>
26 #include <libusb.h>
27 #include <libsigrok/libsigrok.h>
28 #include "libsigrok-internal.h"
29
30 /* SR_CONF_CONN takes one of these: */
31 #define CONN_USB_VIDPID  "^([0-9a-fA-F]{4})\\.([0-9a-fA-F]{4})$"
32 #define CONN_USB_BUSADDR "^(\\d+)\\.(\\d+)$"
33
34 #define LOG_PREFIX "usb"
35
36 #if !HAVE_LIBUSB_OS_HANDLE
37 typedef int libusb_os_handle;
38 #endif
39
40 /** Custom GLib event source for libusb I/O.
41  * @internal
42  */
43 struct usb_source {
44         GSource base;
45
46         int64_t timeout_us;
47         int64_t due_us;
48
49         /* Needed to keep track of installed sources */
50         struct sr_session *session;
51
52         struct libusb_context *usb_ctx;
53         GPtrArray *pollfds;
54 };
55
56 /** USB event source prepare() method.
57  */
58 static gboolean usb_source_prepare(GSource *source, int *timeout)
59 {
60         int64_t now_us, usb_due_us;
61         struct usb_source *usource;
62         struct timeval usb_timeout;
63         int remaining_ms;
64         int ret;
65
66         usource = (struct usb_source *)source;
67
68         ret = libusb_get_next_timeout(usource->usb_ctx, &usb_timeout);
69         if (G_UNLIKELY(ret < 0)) {
70                 sr_err("Failed to get libusb timeout: %s",
71                         libusb_error_name(ret));
72         }
73         now_us = g_source_get_time(source);
74
75         if (usource->due_us == 0) {
76                 /* First-time initialization of the expiration time */
77                 usource->due_us = now_us + usource->timeout_us;
78         }
79         if (ret == 1) {
80                 usb_due_us = (int64_t)usb_timeout.tv_sec * G_USEC_PER_SEC
81                                 + usb_timeout.tv_usec + now_us;
82                 if (usb_due_us < usource->due_us)
83                         usource->due_us = usb_due_us;
84         }
85         if (usource->due_us != INT64_MAX)
86                 remaining_ms = (MAX(0, usource->due_us - now_us) + 999) / 1000;
87         else
88                 remaining_ms = -1;
89
90         *timeout = remaining_ms;
91
92         return (remaining_ms == 0);
93 }
94
95 /** USB event source check() method.
96  */
97 static gboolean usb_source_check(GSource *source)
98 {
99         struct usb_source *usource;
100         GPollFD *pollfd;
101         unsigned int revents;
102         unsigned int i;
103
104         usource = (struct usb_source *)source;
105         revents = 0;
106
107         for (i = 0; i < usource->pollfds->len; i++) {
108                 pollfd = g_ptr_array_index(usource->pollfds, i);
109                 revents |= pollfd->revents;
110         }
111         return (revents != 0 || (usource->due_us != INT64_MAX
112                         && usource->due_us <= g_source_get_time(source)));
113 }
114
115 /** USB event source dispatch() method.
116  */
117 static gboolean usb_source_dispatch(GSource *source,
118                 GSourceFunc callback, void *user_data)
119 {
120         struct usb_source *usource;
121         GPollFD *pollfd;
122         unsigned int revents;
123         unsigned int i;
124         gboolean keep;
125
126         usource = (struct usb_source *)source;
127         revents = 0;
128         /*
129          * This is somewhat arbitrary, but drivers use revents to distinguish
130          * actual I/O from timeouts. When we remove the user timeout from the
131          * driver API, this will no longer be needed.
132          */
133         for (i = 0; i < usource->pollfds->len; i++) {
134                 pollfd = g_ptr_array_index(usource->pollfds, i);
135                 revents |= pollfd->revents;
136         }
137
138         if (!callback) {
139                 sr_err("Callback not set, cannot dispatch event.");
140                 return G_SOURCE_REMOVE;
141         }
142         keep = (*(sr_receive_data_callback)callback)(-1, revents, user_data);
143
144         if (G_LIKELY(keep) && G_LIKELY(!g_source_is_destroyed(source))) {
145                 if (usource->timeout_us >= 0)
146                         usource->due_us = g_source_get_time(source)
147                                         + usource->timeout_us;
148                 else
149                         usource->due_us = INT64_MAX;
150         }
151         return keep;
152 }
153
154 /** USB event source finalize() method.
155  */
156 static void usb_source_finalize(GSource *source)
157 {
158         struct usb_source *usource;
159
160         usource = (struct usb_source *)source;
161
162         sr_spew("%s", __func__);
163
164         libusb_set_pollfd_notifiers(usource->usb_ctx, NULL, NULL, NULL);
165
166         g_ptr_array_unref(usource->pollfds);
167         usource->pollfds = NULL;
168
169         sr_session_source_destroyed(usource->session,
170                         usource->usb_ctx, source);
171 }
172
173 /** Callback invoked when a new libusb FD should be added to the poll set.
174  */
175 static LIBUSB_CALL void usb_pollfd_added(libusb_os_handle fd,
176                 short events, void *user_data)
177 {
178         struct usb_source *usource;
179         GPollFD *pollfd;
180
181         usource = user_data;
182
183         if (G_UNLIKELY(g_source_is_destroyed(&usource->base)))
184                 return;
185
186         pollfd = g_slice_new(GPollFD);
187 #ifdef G_OS_WIN32
188         events = G_IO_IN;
189 #endif
190         pollfd->fd = (gintptr)fd;
191         pollfd->events = events;
192         pollfd->revents = 0;
193
194         g_ptr_array_add(usource->pollfds, pollfd);
195         g_source_add_poll(&usource->base, pollfd);
196 }
197
198 /** Callback invoked when a libusb FD should be removed from the poll set.
199  */
200 static LIBUSB_CALL void usb_pollfd_removed(libusb_os_handle fd, void *user_data)
201 {
202         struct usb_source *usource;
203         GPollFD *pollfd;
204         unsigned int i;
205
206         usource = user_data;
207
208         if (G_UNLIKELY(g_source_is_destroyed(&usource->base)))
209                 return;
210
211         /* It's likely that the removed poll FD is at the end.
212          */
213         for (i = usource->pollfds->len; G_LIKELY(i > 0); i--) {
214                 pollfd = g_ptr_array_index(usource->pollfds, i - 1);
215
216                 if ((libusb_os_handle)pollfd->fd == fd) {
217                         g_source_remove_poll(&usource->base, pollfd);
218                         g_ptr_array_remove_index_fast(usource->pollfds, i - 1);
219                         return;
220                 }
221         }
222         sr_err("FD to be removed (%" G_GINTPTR_FORMAT
223                 ") not found in event source poll set.", (gintptr)fd);
224 }
225
226 /** Destroy notify callback for FDs maintained by the USB event source.
227  */
228 static void usb_source_free_pollfd(void *data)
229 {
230         g_slice_free(GPollFD, data);
231 }
232
233 /** Create an event source for libusb I/O.
234  *
235  * TODO: The combination of the USB I/O source with a user timeout is
236  * conceptually broken. The user timeout supplied here is completely
237  * unrelated to I/O -- the actual I/O timeout is set when submitting
238  * a USB transfer.
239  * The sigrok drivers generally use the timeout to poll device state.
240  * Usually, this polling can be sensibly done only when there is no
241  * active USB transfer -- i.e. it's actually mutually exclusive with
242  * waiting for transfer completion.
243  * Thus, the user timeout should be removed from the USB event source
244  * API at some point. Instead, drivers should install separate timer
245  * event sources for their polling needs.
246  *
247  * @param session The session the event source belongs to.
248  * @param usb_ctx The libusb context for which to handle events.
249  * @param timeout_ms The timeout interval in ms, or -1 to wait indefinitely.
250  * @return A new event source object, or NULL on failure.
251  */
252 static GSource *usb_source_new(struct sr_session *session,
253                 struct libusb_context *usb_ctx, int timeout_ms)
254 {
255         static GSourceFuncs usb_source_funcs = {
256                 .prepare  = &usb_source_prepare,
257                 .check    = &usb_source_check,
258                 .dispatch = &usb_source_dispatch,
259                 .finalize = &usb_source_finalize
260         };
261         GSource *source;
262         struct usb_source *usource;
263         const struct libusb_pollfd **upollfds, **upfd;
264
265         upollfds = libusb_get_pollfds(usb_ctx);
266         if (!upollfds) {
267                 sr_err("Failed to get libusb file descriptors.");
268                 return NULL;
269         }
270         source = g_source_new(&usb_source_funcs, sizeof(struct usb_source));
271         usource = (struct usb_source *)source;
272
273         g_source_set_name(source, "usb");
274
275         if (timeout_ms >= 0) {
276                 usource->timeout_us = 1000 * (int64_t)timeout_ms;
277                 usource->due_us = 0;
278         } else {
279                 usource->timeout_us = -1;
280                 usource->due_us = INT64_MAX;
281         }
282         usource->session = session;
283         usource->usb_ctx = usb_ctx;
284         usource->pollfds = g_ptr_array_new_full(8, &usb_source_free_pollfd);
285
286         for (upfd = upollfds; *upfd != NULL; upfd++)
287                 usb_pollfd_added((*upfd)->fd, (*upfd)->events, usource);
288
289 #if (LIBUSB_API_VERSION >= 0x01000104)
290         libusb_free_pollfds(upollfds);
291 #else
292         free(upollfds);
293 #endif
294         libusb_set_pollfd_notifiers(usb_ctx,
295                 &usb_pollfd_added, &usb_pollfd_removed, usource);
296
297         return source;
298 }
299
300 /**
301  * Find USB devices according to a connection string.
302  *
303  * @param usb_ctx libusb context to use while scanning.
304  * @param conn Connection string specifying the device(s) to match. This
305  * can be of the form "<bus>.<address>", or "<vendorid>.<productid>".
306  *
307  * @return A GSList of struct sr_usb_dev_inst, with bus and address fields
308  * matching the device that matched the connection string. The GSList and
309  * its contents must be freed by the caller.
310  */
311 SR_PRIV GSList *sr_usb_find(libusb_context *usb_ctx, const char *conn)
312 {
313         struct sr_usb_dev_inst *usb;
314         struct libusb_device **devlist;
315         struct libusb_device_descriptor des;
316         GSList *devices;
317         GRegex *reg;
318         GMatchInfo *match;
319         int vid, pid, bus, addr, b, a, ret, i;
320         char *mstr;
321
322         vid = pid = bus = addr = 0;
323         reg = g_regex_new(CONN_USB_VIDPID, 0, 0, NULL);
324         if (g_regex_match(reg, conn, 0, &match)) {
325                 if ((mstr = g_match_info_fetch(match, 1)))
326                         vid = strtoul(mstr, NULL, 16);
327                 g_free(mstr);
328
329                 if ((mstr = g_match_info_fetch(match, 2)))
330                         pid = strtoul(mstr, NULL, 16);
331                 g_free(mstr);
332                 /* Trying to find USB device via VID:PID. */
333         } else {
334                 g_match_info_unref(match);
335                 g_regex_unref(reg);
336                 reg = g_regex_new(CONN_USB_BUSADDR, 0, 0, NULL);
337                 if (g_regex_match(reg, conn, 0, &match)) {
338                         if ((mstr = g_match_info_fetch(match, 1)))
339                                 bus = strtoul(mstr, NULL, 10);
340                         g_free(mstr);
341
342                         if ((mstr = g_match_info_fetch(match, 2)))
343                                 addr = strtoul(mstr, NULL, 10);
344                         g_free(mstr);
345                         /* Trying to find USB device via bus.address. */
346                 }
347         }
348         g_match_info_unref(match);
349         g_regex_unref(reg);
350
351         if (vid + pid + bus + addr == 0) {
352                 sr_err("Neither VID:PID nor bus.address was specified.");
353                 return NULL;
354         }
355
356         if (bus > 255) {
357                 sr_err("Invalid bus specified: %d.", bus);
358                 return NULL;
359         }
360
361         if (addr > 127) {
362                 sr_err("Invalid address specified: %d.", addr);
363                 return NULL;
364         }
365
366         /* Looks like a valid USB device specification, but is it connected? */
367         devices = NULL;
368         libusb_get_device_list(usb_ctx, &devlist);
369         for (i = 0; devlist[i]; i++) {
370                 if ((ret = libusb_get_device_descriptor(devlist[i], &des))) {
371                         sr_err("Failed to get device descriptor: %s.",
372                                libusb_error_name(ret));
373                         continue;
374                 }
375
376                 if (vid + pid && (des.idVendor != vid || des.idProduct != pid))
377                         continue;
378
379                 b = libusb_get_bus_number(devlist[i]);
380                 a = libusb_get_device_address(devlist[i]);
381                 if (bus + addr && (b != bus || a != addr))
382                         continue;
383
384                 sr_dbg("Found USB device (VID:PID = %04x:%04x, bus.address = "
385                        "%d.%d).", des.idVendor, des.idProduct, b, a);
386
387                 usb = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]),
388                                 libusb_get_device_address(devlist[i]), NULL);
389                 devices = g_slist_append(devices, usb);
390         }
391         libusb_free_device_list(devlist, 1);
392
393         /* No log message for #devices found (caller will log that). */
394
395         return devices;
396 }
397
398 SR_PRIV int sr_usb_open(libusb_context *usb_ctx, struct sr_usb_dev_inst *usb)
399 {
400         struct libusb_device **devlist;
401         struct libusb_device_descriptor des;
402         int ret, r, cnt, i, a, b;
403
404         sr_dbg("Trying to open USB device %d.%d.", usb->bus, usb->address);
405
406         if ((cnt = libusb_get_device_list(usb_ctx, &devlist)) < 0) {
407                 sr_err("Failed to retrieve device list: %s.",
408                        libusb_error_name(cnt));
409                 return SR_ERR;
410         }
411
412         ret = SR_ERR;
413         for (i = 0; i < cnt; i++) {
414                 if ((r = libusb_get_device_descriptor(devlist[i], &des)) < 0) {
415                         sr_err("Failed to get device descriptor: %s.",
416                                libusb_error_name(r));
417                         continue;
418                 }
419
420                 b = libusb_get_bus_number(devlist[i]);
421                 a = libusb_get_device_address(devlist[i]);
422                 if (b != usb->bus || a != usb->address)
423                         continue;
424
425                 if ((r = libusb_open(devlist[i], &usb->devhdl)) < 0) {
426                         sr_err("Failed to open device: %s.",
427                                libusb_error_name(r));
428                         break;
429                 }
430
431                 sr_dbg("Opened USB device (VID:PID = %04x:%04x, bus.address = "
432                        "%d.%d).", des.idVendor, des.idProduct, b, a);
433
434                 ret = SR_OK;
435                 break;
436         }
437
438         libusb_free_device_list(devlist, 1);
439
440         return ret;
441 }
442
443 SR_PRIV void sr_usb_close(struct sr_usb_dev_inst *usb)
444 {
445         libusb_close(usb->devhdl);
446         usb->devhdl = NULL;
447         sr_dbg("Closed USB device %d.%d.", usb->bus, usb->address);
448 }
449
450 SR_PRIV int usb_source_add(struct sr_session *session, struct sr_context *ctx,
451                 int timeout, sr_receive_data_callback cb, void *cb_data)
452 {
453         GSource *source;
454         int ret;
455
456         source = usb_source_new(session, ctx->libusb_ctx, timeout);
457         if (!source)
458                 return SR_ERR;
459
460         g_source_set_callback(source, (GSourceFunc)cb, cb_data, NULL);
461
462         ret = sr_session_source_add_internal(session, ctx->libusb_ctx, source);
463         g_source_unref(source);
464
465         return ret;
466 }
467
468 SR_PRIV int usb_source_remove(struct sr_session *session, struct sr_context *ctx)
469 {
470         return sr_session_source_remove_internal(session, ctx->libusb_ctx);
471 }
472
473 SR_PRIV int usb_get_port_path(libusb_device *dev, char *path, int path_len)
474 {
475         uint8_t port_numbers[8];
476         int i, n, len;
477
478 /*
479  * FreeBSD requires that devices prior to calling libusb_get_port_numbers()
480  * have been opened with libusb_open().
481  * This apparently also applies to some Mac OS X versions.
482  */
483 #if defined(__FreeBSD__) || defined(__APPLE__)
484         struct libusb_device_handle *devh;
485         if (libusb_open(dev, &devh) != 0)
486                 return SR_ERR;
487 #endif
488         n = libusb_get_port_numbers(dev, port_numbers, sizeof(port_numbers));
489 #if defined(__FreeBSD__) || defined(__APPLE__)
490         libusb_close(devh);
491 #endif
492
493 /* Workaround FreeBSD / Mac OS X libusb_get_port_numbers() returning 0. */
494 #if defined(__FreeBSD__) || defined(__APPLE__)
495         if (n == 0) {
496                 port_numbers[0] = libusb_get_device_address(dev);
497                 n = 1;
498         }
499 #endif
500         if (n < 1)
501                 return SR_ERR;
502
503         len = snprintf(path, path_len, "usb/%d-%d",
504                        libusb_get_bus_number(dev), port_numbers[0]);
505
506         for (i = 1; i < n; i++)
507                 len += snprintf(path+len, path_len-len, ".%d", port_numbers[i]);
508
509         return SR_OK;
510 }
511
512 /**
513  * Check the USB configuration to determine if this device has a given 
514  * manufacturer and product string.
515  *
516  * @return TRUE if the device's configuration profile strings
517  *         configuration, FALSE otherwise.
518  */
519 SR_PRIV gboolean usb_match_manuf_prod(libusb_device *dev,
520                 const char *manufacturer, const char *product)
521 {
522         struct libusb_device_descriptor des;
523         struct libusb_device_handle *hdl;
524         gboolean ret;
525         unsigned char strdesc[64];
526
527         hdl = NULL;
528         ret = FALSE;
529         while (!ret) {
530                 /* Assume the FW has not been loaded, unless proven wrong. */
531                 libusb_get_device_descriptor(dev, &des);
532
533                 if (libusb_open(dev, &hdl) != 0)
534                         break;
535
536                 if (libusb_get_string_descriptor_ascii(hdl,
537                                 des.iManufacturer, strdesc, sizeof(strdesc)) < 0)
538                         break;
539                 if (strcmp((const char *)strdesc, manufacturer))
540                         break;
541
542                 if (libusb_get_string_descriptor_ascii(hdl,
543                                 des.iProduct, strdesc, sizeof(strdesc)) < 0)
544                         break;
545                 if (strcmp((const char *)strdesc, product))
546                         break;
547
548                 ret = TRUE;
549         }
550         if (hdl)
551                 libusb_close(hdl);
552
553         return ret;
554 }