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