1 /* usbredirhost.c usb network redirection usb host code.
2
3 Copyright 2010-2012 Red Hat, Inc.
4
5 Red Hat Authors:
6 Hans de Goede <hdegoede@redhat.com>
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12
13 This library 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 GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 */
21 #include "config.h"
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <stdarg.h>
26 #include <stdbool.h>
27 #include <string.h>
28 #include <errno.h>
29 #include <unistd.h>
30 #include <inttypes.h>
31 #include "usbredirhost.h"
32
33 #define MAX_ENDPOINTS 32
34 #define MAX_INTERFACES 32 /* Max 32 endpoints and thus interfaces */
35 #define CTRL_TIMEOUT 5000 /* USB specifies a 5 second max timeout */
36 #define BULK_TIMEOUT 0 /* No timeout for bulk transfers */
37 #define ISO_TIMEOUT 1000
38 #define INTERRUPT_TIMEOUT 0 /* No timeout for interrupt transfers */
39
40 #define MAX_TRANSFER_COUNT 16
41 #define MAX_PACKETS_PER_TRANSFER 32
42 #define INTERRUPT_TRANSFER_COUNT 5
43 /* Special packet_idx value indicating a submitted transfer */
44 #define SUBMITTED_IDX -1
45
46 /* quirk flags */
47 #define QUIRK_DO_NOT_RESET 0x01
48
49 /* Macros to go from an endpoint address to an index for our ep array */
50 #define EP2I(ep_address) (((ep_address & 0x80) >> 3) | (ep_address & 0x0f))
51 #define I2EP(i) (((i & 0x10) << 3) | (i & 0x0f))
52
53 /* Locking convenience macros */
54 #define LOCK(host) \
55 do { \
56 if ((host)->lock) \
57 (host)->parser->lock_func((host)->lock); \
58 } while (0)
59
60 #define UNLOCK(host) \
61 do { \
62 if ((host)->lock) \
63 (host)->parser->unlock_func((host)->lock); \
64 } while (0)
65
66 #define FLUSH(host) \
67 do { \
68 if ((host)->flush_writes_func) \
69 (host)->flush_writes_func((host)->func_priv); \
70 } while (0)
71
72 struct usbredirtransfer {
73 struct usbredirhost *host; /* Back pointer to the the redirhost */
74 struct libusb_transfer *transfer; /* Back pointer to the libusb transfer */
75 uint64_t id;
76 uint8_t cancelled;
77 int packet_idx;
78 union {
79 struct usb_redir_control_packet_header control_packet;
80 struct usb_redir_bulk_packet_header bulk_packet;
81 struct usb_redir_iso_packet_header iso_packet;
82 struct usb_redir_interrupt_packet_header interrupt_packet;
83 };
84 struct usbredirtransfer *next;
85 struct usbredirtransfer *prev;
86 };
87
88 struct usbredirhost_ep {
89 uint8_t type;
90 uint8_t interval;
91 uint8_t interface;
92 uint8_t warn_on_drop;
93 uint8_t stream_started;
94 uint8_t pkts_per_transfer;
95 uint8_t transfer_count;
96 int out_idx;
97 int drop_packets;
98 int max_packetsize;
99 unsigned int max_streams;
100 struct usbredirtransfer *transfer[MAX_TRANSFER_COUNT];
101 };
102
103 struct usbredirhost {
104 struct usbredirparser *parser;
105
106 void *lock;
107 void *disconnect_lock;
108
109 usbredirparser_log log_func;
110 usbredirparser_read read_func;
111 usbredirparser_write write_func;
112 usbredirhost_flush_writes flush_writes_func;
113 usbredirhost_buffered_output_size buffered_output_size_func;
114 void *func_priv;
115 int verbose;
116 libusb_context *ctx;
117 libusb_device *dev;
118 libusb_device_handle *handle;
119 struct libusb_device_descriptor desc;
120 struct libusb_config_descriptor *config;
121 int quirks;
122 int restore_config;
123 int claimed;
124 int reset;
125 int disconnected;
126 int read_status;
127 int cancels_pending;
128 int wait_disconnect;
129 int connect_pending;
130 struct usbredirhost_ep endpoint[MAX_ENDPOINTS];
131 uint8_t alt_setting[MAX_INTERFACES];
132 struct usbredirtransfer transfers_head;
133 struct usbredirfilter_rule *filter_rules;
134 int filter_rules_count;
135 struct {
136 uint64_t higher;
137 uint64_t lower;
138 bool dropping;
139 } iso_threshold;
140 };
141
142 struct usbredirhost_dev_ids {
143 int vendor_id;
144 int product_id;
145 };
146
147 static const struct usbredirhost_dev_ids usbredirhost_reset_blacklist[] = {
148 { 0x1210, 0x001c },
149 { 0x2798, 0x0001 },
150 { -1, -1 } /* Terminating Entry */
151 };
152
153 static void
154 #if defined __GNUC__
155 __attribute__((format(printf, 3, 4)))
156 #endif
va_log(struct usbredirhost * host,int level,const char * fmt,...)157 va_log(struct usbredirhost *host, int level, const char *fmt, ...)
158 {
159 char buf[512];
160 va_list ap;
161 int n;
162
163 if (level > host->verbose) {
164 return;
165 }
166
167 n = sprintf(buf, "usbredirhost: ");
168 va_start(ap, fmt);
169 vsnprintf(buf + n, sizeof(buf) - n, fmt, ap);
170 va_end(ap);
171
172 host->log_func(host->func_priv, level, buf);
173 }
174
175 #ifdef ERROR /* defined on WIN32 */
176 #undef ERROR
177 #endif
178 #define ERROR(...) va_log(host, usbredirparser_error, __VA_ARGS__)
179 #define WARNING(...) va_log(host, usbredirparser_warning, __VA_ARGS__)
180 #define INFO(...) va_log(host, usbredirparser_info, __VA_ARGS__)
181 #define DEBUG(...) va_log(host, usbredirparser_debug, __VA_ARGS__)
182
183 static void usbredirhost_hello(void *priv, struct usb_redir_hello_header *h);
184 static void usbredirhost_reset(void *priv);
185 static void usbredirhost_set_configuration(void *priv, uint64_t id,
186 struct usb_redir_set_configuration_header *set_configuration);
187 static void usbredirhost_get_configuration(void *priv, uint64_t id);
188 static void usbredirhost_set_alt_setting(void *priv, uint64_t id,
189 struct usb_redir_set_alt_setting_header *set_alt_setting);
190 static void usbredirhost_get_alt_setting(void *priv, uint64_t id,
191 struct usb_redir_get_alt_setting_header *get_alt_setting);
192 static void usbredirhost_start_iso_stream(void *priv, uint64_t id,
193 struct usb_redir_start_iso_stream_header *start_iso_stream);
194 static void usbredirhost_stop_iso_stream(void *priv, uint64_t id,
195 struct usb_redir_stop_iso_stream_header *stop_iso_stream);
196 static void usbredirhost_start_interrupt_receiving(void *priv, uint64_t id,
197 struct usb_redir_start_interrupt_receiving_header *start_interrupt_receiving);
198 static void usbredirhost_stop_interrupt_receiving(void *priv, uint64_t id,
199 struct usb_redir_stop_interrupt_receiving_header *stop_interrupt_receiving);
200 static void usbredirhost_alloc_bulk_streams(void *priv, uint64_t id,
201 struct usb_redir_alloc_bulk_streams_header *alloc_bulk_streams);
202 static void usbredirhost_free_bulk_streams(void *priv, uint64_t id,
203 struct usb_redir_free_bulk_streams_header *free_bulk_streams);
204 static void usbredirhost_cancel_data_packet(void *priv, uint64_t id);
205 static void usbredirhost_filter_reject(void *priv);
206 static void usbredirhost_filter_filter(void *priv,
207 struct usbredirfilter_rule *rules, int rules_count);
208 static void usbredirhost_device_disconnect_ack(void *priv);
209 static void usbredirhost_start_bulk_receiving(void *priv, uint64_t id,
210 struct usb_redir_start_bulk_receiving_header *start_bulk_receiving);
211 static void usbredirhost_stop_bulk_receiving(void *priv, uint64_t id,
212 struct usb_redir_stop_bulk_receiving_header *stop_bulk_receiving);
213 static void usbredirhost_control_packet(void *priv, uint64_t id,
214 struct usb_redir_control_packet_header *control_packet,
215 uint8_t *data, int data_len);
216 static void usbredirhost_bulk_packet(void *priv, uint64_t id,
217 struct usb_redir_bulk_packet_header *bulk_packet,
218 uint8_t *data, int data_len);
219 static void usbredirhost_iso_packet(void *priv, uint64_t id,
220 struct usb_redir_iso_packet_header *iso_packet,
221 uint8_t *data, int data_len);
222 static void usbredirhost_interrupt_packet(void *priv, uint64_t id,
223 struct usb_redir_interrupt_packet_header *interrupt_packet,
224 uint8_t *data, int data_len);
225
226 static void LIBUSB_CALL usbredirhost_iso_packet_complete(
227 struct libusb_transfer *libusb_transfer);
228 static void LIBUSB_CALL usbredirhost_buffered_packet_complete(
229 struct libusb_transfer *libusb_transfer);
230 static int usbredirhost_cancel_pending_urbs(struct usbredirhost *host,
231 int notify_guest);
232 static void usbredirhost_wait_for_cancel_completion(struct usbredirhost *host);
233 static void usbredirhost_clear_device(struct usbredirhost *host);
234
usbredirhost_log(void * priv,int level,const char * msg)235 static void usbredirhost_log(void *priv, int level, const char *msg)
236 {
237 struct usbredirhost *host = priv;
238
239 host->log_func(host->func_priv, level, msg);
240 }
241
usbredirhost_read(void * priv,uint8_t * data,int count)242 static int usbredirhost_read(void *priv, uint8_t *data, int count)
243 {
244 struct usbredirhost *host = priv;
245
246 if (host->read_status) {
247 int ret = host->read_status;
248 host->read_status = 0;
249 return ret;
250 }
251
252 return host->read_func(host->func_priv, data, count);
253 }
254
usbredirhost_write(void * priv,uint8_t * data,int count)255 static int usbredirhost_write(void *priv, uint8_t *data, int count)
256 {
257 struct usbredirhost *host = priv;
258
259 return host->write_func(host->func_priv, data, count);
260 }
261
262 /* Can be called both from parser read callbacks as well as from libusb
263 packet completion callbacks */
usbredirhost_handle_disconnect(struct usbredirhost * host)264 static void usbredirhost_handle_disconnect(struct usbredirhost *host)
265 {
266 /* Disconnect uses its own lock to avoid needing nesting capable locks */
267 if (host->disconnect_lock) {
268 host->parser->lock_func(host->disconnect_lock);
269 }
270 if (!host->disconnected) {
271 INFO("device disconnected");
272 usbredirparser_send_device_disconnect(host->parser);
273 if (usbredirparser_peer_has_cap(host->parser,
274 usb_redir_cap_device_disconnect_ack))
275 host->wait_disconnect = 1;
276 host->disconnected = 1;
277 }
278 if (host->disconnect_lock) {
279 host->parser->unlock_func(host->disconnect_lock);
280 }
281 }
282
283 /* One function to convert either a transfer status code, or a libusb error
284 code to a usb_redir status. We handle both in one conversion function so
285 that we can pass error codes as status codes to the completion handler
286 in case of submission error (the codes don't overlap), using the completion
287 handler to report back the status and cleanup as it would on completion of
288 a successfully submitted transfer. */
libusb_status_or_error_to_redir_status(struct usbredirhost * host,int status)289 static int libusb_status_or_error_to_redir_status(struct usbredirhost *host,
290 int status)
291 {
292 switch (status) {
293 case LIBUSB_TRANSFER_COMPLETED:
294 return usb_redir_success;
295 case LIBUSB_TRANSFER_ERROR:
296 return usb_redir_ioerror;
297 case LIBUSB_TRANSFER_TIMED_OUT:
298 return usb_redir_timeout;
299 case LIBUSB_TRANSFER_CANCELLED:
300 return usb_redir_cancelled;
301 case LIBUSB_TRANSFER_STALL:
302 return usb_redir_stall;
303 case LIBUSB_TRANSFER_NO_DEVICE:
304 usbredirhost_handle_disconnect(host);
305 return usb_redir_ioerror;
306 case LIBUSB_TRANSFER_OVERFLOW:
307 return usb_redir_babble;
308
309 case LIBUSB_ERROR_INVALID_PARAM:
310 return usb_redir_inval;
311 case LIBUSB_ERROR_NO_DEVICE:
312 usbredirhost_handle_disconnect(host);
313 return usb_redir_ioerror;
314 case LIBUSB_ERROR_TIMEOUT:
315 return usb_redir_timeout;
316 default:
317 return usb_redir_ioerror;
318 }
319 }
320
usbredirhost_set_max_packetsize(struct usbredirhost * host,uint8_t ep,uint16_t wMaxPacketSize)321 static void usbredirhost_set_max_packetsize(struct usbredirhost *host,
322 uint8_t ep, uint16_t wMaxPacketSize)
323 {
324 int maxp, mult = 1;
325
326 maxp = wMaxPacketSize & 0x7ff;
327
328 if (libusb_get_device_speed(host->dev) == LIBUSB_SPEED_HIGH &&
329 host->endpoint[EP2I(ep)].type == usb_redir_type_iso) {
330 switch ((wMaxPacketSize >> 11) & 3) {
331 case 1: mult = 2; break;
332 case 2: mult = 3; break;
333 default: mult = 1; break;
334 }
335 }
336
337 host->endpoint[EP2I(ep)].max_packetsize = maxp * mult;
338 }
339
usbredirhost_set_max_streams(struct usbredirhost * host,const struct libusb_endpoint_descriptor * endp)340 static void usbredirhost_set_max_streams(struct usbredirhost *host,
341 const struct libusb_endpoint_descriptor *endp)
342 {
343 #if LIBUSBX_API_VERSION >= 0x01000102
344 struct libusb_ss_endpoint_companion_descriptor *endp_ss_comp;
345 int max_streams, i = EP2I(endp->bEndpointAddress);
346
347 host->endpoint[i].max_streams = 0;
348
349 if (host->endpoint[i].type == usb_redir_type_bulk &&
350 libusb_get_ss_endpoint_companion_descriptor(host->ctx, endp,
351 &endp_ss_comp) == LIBUSB_SUCCESS) {
352 max_streams = endp_ss_comp->bmAttributes & 0x1f;
353 if (max_streams)
354 host->endpoint[i].max_streams = 1 << max_streams;
355 libusb_free_ss_endpoint_companion_descriptor(endp_ss_comp);
356 }
357 #endif
358 }
359
360 /* Called from open/close and parser read callbacks */
usbredirhost_send_interface_n_ep_info(struct usbredirhost * host)361 static void usbredirhost_send_interface_n_ep_info(struct usbredirhost *host)
362 {
363 int i;
364 const struct libusb_interface_descriptor *intf_desc;
365 struct usb_redir_ep_info_header ep_info;
366 struct usb_redir_interface_info_header interface_info = { 0, };
367
368 if (host->config)
369 interface_info.interface_count = host->config->bNumInterfaces;
370
371 for (i = 0; i < interface_info.interface_count; i++) {
372 intf_desc =
373 &host->config->interface[i].altsetting[host->alt_setting[i]];
374
375 interface_info.interface[i] = intf_desc->bInterfaceNumber;
376 interface_info.interface_class[i] = intf_desc->bInterfaceClass;
377 interface_info.interface_subclass[i] = intf_desc->bInterfaceSubClass;
378 interface_info.interface_protocol[i] = intf_desc->bInterfaceProtocol;
379 }
380 usbredirparser_send_interface_info(host->parser, &interface_info);
381
382 for (i = 0; i < MAX_ENDPOINTS; i++) {
383 ep_info.type[i] = host->endpoint[i].type;
384 ep_info.interval[i] = host->endpoint[i].interval;
385 ep_info.interface[i] = host->endpoint[i].interface;
386 ep_info.max_packet_size[i] = host->endpoint[i].max_packetsize;
387 ep_info.max_streams[i] = host->endpoint[i].max_streams;
388 }
389 usbredirparser_send_ep_info(host->parser, &ep_info);
390 }
391
392 /* Called from open/close and parser read callbacks */
usbredirhost_send_device_connect(struct usbredirhost * host)393 static void usbredirhost_send_device_connect(struct usbredirhost *host)
394 {
395 struct usb_redir_device_connect_header device_connect;
396 enum libusb_speed speed;
397
398 if (!host->disconnected) {
399 ERROR("internal error sending device_connect but already connected");
400 return;
401 }
402
403 if (!usbredirparser_have_peer_caps(host->parser) ||
404 host->wait_disconnect) {
405 host->connect_pending = 1;
406 return;
407 }
408
409 speed = libusb_get_device_speed(host->dev);
410 switch (speed) {
411 case LIBUSB_SPEED_LOW:
412 device_connect.speed = usb_redir_speed_low; break;
413 case LIBUSB_SPEED_FULL:
414 device_connect.speed = usb_redir_speed_full; break;
415 case LIBUSB_SPEED_HIGH:
416 device_connect.speed = usb_redir_speed_high; break;
417 case LIBUSB_SPEED_SUPER:
418 device_connect.speed = usb_redir_speed_super; break;
419 default:
420 device_connect.speed = usb_redir_speed_unknown;
421 }
422 device_connect.device_class = host->desc.bDeviceClass;
423 device_connect.device_subclass = host->desc.bDeviceSubClass;
424 device_connect.device_protocol = host->desc.bDeviceProtocol;
425 device_connect.vendor_id = host->desc.idVendor;
426 device_connect.product_id = host->desc.idProduct;
427 device_connect.device_version_bcd = host->desc.bcdDevice;
428
429 usbredirhost_send_interface_n_ep_info(host);
430 usbredirparser_send_device_connect(host->parser, &device_connect);
431 host->connect_pending = 0;
432 host->disconnected = 0; /* The guest may now use the device */
433
434 FLUSH(host);
435 }
436
437 /* Called from open/close and parser read callbacks */
usbredirhost_parse_interface(struct usbredirhost * host,int i)438 static void usbredirhost_parse_interface(struct usbredirhost *host, int i)
439 {
440 int j;
441 const struct libusb_interface_descriptor *intf_desc;
442 uint8_t ep_address;
443
444 intf_desc =
445 &host->config->interface[i].altsetting[host->alt_setting[i]];
446
447 for (j = 0; j < intf_desc->bNumEndpoints; j++) {
448 ep_address = intf_desc->endpoint[j].bEndpointAddress;
449 host->endpoint[EP2I(ep_address)].type =
450 intf_desc->endpoint[j].bmAttributes & LIBUSB_TRANSFER_TYPE_MASK;
451 host->endpoint[EP2I(ep_address)].interval =
452 intf_desc->endpoint[j].bInterval;
453 host->endpoint[EP2I(ep_address)].interface =
454 intf_desc->bInterfaceNumber;
455 usbredirhost_set_max_packetsize(host, ep_address,
456 intf_desc->endpoint[j].wMaxPacketSize);
457 usbredirhost_set_max_streams(host, &intf_desc->endpoint[j]);
458 host->endpoint[EP2I(ep_address)].warn_on_drop = 1;
459 }
460 }
461
usbredirhost_parse_config(struct usbredirhost * host)462 static void usbredirhost_parse_config(struct usbredirhost *host)
463 {
464 int i;
465
466 for (i = 0; i < MAX_ENDPOINTS; i++) {
467 if ((i & 0x0f) == 0) {
468 host->endpoint[i].type = usb_redir_type_control;
469 } else {
470 host->endpoint[i].type = usb_redir_type_invalid;
471 }
472 host->endpoint[i].interval = 0;
473 host->endpoint[i].interface = 0;
474 host->endpoint[i].max_packetsize = 0;
475 host->endpoint[i].max_streams = 0;
476 }
477
478 for (i = 0; host->config && i < host->config->bNumInterfaces; i++) {
479 usbredirhost_parse_interface(host, i);
480 }
481 }
482
483 /* Called from open/close and parser read callbacks */
usbredirhost_claim(struct usbredirhost * host,int initial_claim)484 static int usbredirhost_claim(struct usbredirhost *host, int initial_claim)
485 {
486 int i, n, r;
487
488 if (host->config) {
489 libusb_free_config_descriptor(host->config);
490 host->config = NULL;
491 }
492
493 r = libusb_get_device_descriptor(host->dev, &host->desc);
494 if (r < 0) {
495 ERROR("could not get device descriptor: %s", libusb_error_name(r));
496 return libusb_status_or_error_to_redir_status(host, r);
497 }
498
499 r = libusb_get_active_config_descriptor(host->dev, &host->config);
500 if (r < 0 && r != LIBUSB_ERROR_NOT_FOUND) {
501 ERROR("could not get descriptors for active configuration: %s",
502 libusb_error_name(r));
503 return libusb_status_or_error_to_redir_status(host, r);
504 }
505 if (host->config && host->config->bNumInterfaces > MAX_INTERFACES) {
506 ERROR("usb decriptor has too much intefaces (%d > %d)",
507 (int)host->config->bNumInterfaces, MAX_INTERFACES);
508 return usb_redir_ioerror;
509 }
510
511 if (initial_claim) {
512 if (host->config)
513 host->restore_config = host->config->bConfigurationValue;
514 else
515 host->restore_config = -1; /* unconfigured */
516
517 /* If the device is unconfigured and has only 1 config, we assume
518 this is the result of the user doing "safely remove hardware",
519 and we try to reset the device configuration to this config when
520 we release the device, so that it becomes usable again. */
521 if (host->restore_config == -1 && host->desc.bNumConfigurations == 1) {
522 struct libusb_config_descriptor *config;
523
524 r = libusb_get_config_descriptor(host->dev, 0, &config);
525 if (r == 0) {
526 host->restore_config = config->bConfigurationValue;
527 libusb_free_config_descriptor(config);
528 }
529 }
530 }
531
532 /* All interfaces begin at alt setting 0 when (re)claimed */
533 memset(host->alt_setting, 0, MAX_INTERFACES);
534
535 host->claimed = 1;
536 #if LIBUSBX_API_VERSION >= 0x01000102
537 libusb_set_auto_detach_kernel_driver(host->handle, 1);
538 #endif
539 for (i = 0; host->config && i < host->config->bNumInterfaces; i++) {
540 n = host->config->interface[i].altsetting[0].bInterfaceNumber;
541
542 #if LIBUSBX_API_VERSION < 0x01000102
543 r = libusb_detach_kernel_driver(host->handle, n);
544 if (r < 0 && r != LIBUSB_ERROR_NOT_FOUND
545 && r != LIBUSB_ERROR_NOT_SUPPORTED) {
546 ERROR("could not detach driver from interface %d (configuration %d): %s",
547 n, host->config->bConfigurationValue, libusb_error_name(r));
548 return libusb_status_or_error_to_redir_status(host, r);
549 }
550 #endif
551
552 r = libusb_claim_interface(host->handle, n);
553 if (r < 0) {
554 if (r == LIBUSB_ERROR_BUSY)
555 ERROR("Device is in use by another application");
556 else
557 ERROR("could not claim interface %d (configuration %d): %s",
558 n, host->config->bConfigurationValue,
559 libusb_error_name(r));
560 return libusb_status_or_error_to_redir_status(host, r);
561 }
562 }
563
564 usbredirhost_parse_config(host);
565 return usb_redir_success;
566 }
567
568 /* Called from open/close and parser read callbacks */
usbredirhost_release(struct usbredirhost * host,int attach_drivers)569 static void usbredirhost_release(struct usbredirhost *host, int attach_drivers)
570 {
571 int i, n, r, current_config = -1;
572
573 if (!host->claimed)
574 return;
575
576 #if LIBUSBX_API_VERSION >= 0x01000102
577 /* We want to always do the attach ourselves because:
578 1) For compound interfaces such as usb-audio we must first release all
579 interfaces before we can attach the driver;
580 2) When releasing interfaces before calling libusb_set_configuration,
581 we don't want the kernel driver to get attached (our attach_drivers
582 parameter is 0 in this case). */
583 libusb_set_auto_detach_kernel_driver(host->handle, 0);
584 #endif
585
586 for (i = 0; host->config && i < host->config->bNumInterfaces; i++) {
587 n = host->config->interface[i].altsetting[0].bInterfaceNumber;
588
589 r = libusb_release_interface(host->handle, n);
590 if (r < 0 && r != LIBUSB_ERROR_NOT_FOUND
591 && r != LIBUSB_ERROR_NO_DEVICE) {
592 ERROR("could not release interface %d (configuration %d): %s",
593 n, host->config->bConfigurationValue, libusb_error_name(r));
594 }
595 }
596
597 if (!attach_drivers)
598 return;
599
600 host->claimed = 0;
601
602 /* reset the device before re-binding the kernel drivers, so that the
603 kernel drivers get the device in a clean state. */
604 if (!(host->quirks & QUIRK_DO_NOT_RESET)) {
605 r = libusb_reset_device(host->handle);
606 if (r != 0) {
607 /* if we're releasing the device because it was removed, resetting
608 * will fail. Don't print a warning in this situation */
609 if (r != LIBUSB_ERROR_NO_DEVICE) {
610 ERROR("error resetting device: %s", libusb_error_name(r));
611 }
612 return;
613 }
614 }
615
616 if (host->config)
617 current_config = host->config->bConfigurationValue;
618
619 if (current_config != host->restore_config) {
620 r = libusb_set_configuration(host->handle, host->restore_config);
621 if (r < 0)
622 ERROR("could not restore configuration to %d: %s",
623 host->restore_config, libusb_error_name(r));
624 return; /* set_config automatically binds drivers for the new config */
625 }
626
627 for (i = 0; host->config && i < host->config->bNumInterfaces; i++) {
628 n = host->config->interface[i].altsetting[0].bInterfaceNumber;
629 r = libusb_attach_kernel_driver(host->handle, n);
630 if (r < 0 && r != LIBUSB_ERROR_NOT_FOUND /* No driver */
631 && r != LIBUSB_ERROR_NO_DEVICE /* Device unplugged */
632 && r != LIBUSB_ERROR_NOT_SUPPORTED /* Not supported */
633 && r != LIBUSB_ERROR_BUSY /* driver rebound already */) {
634 ERROR("could not re-attach driver to interface %d (configuration %d): %s",
635 n, host->config->bConfigurationValue, libusb_error_name(r));
636 }
637 }
638 }
639
usbredirhost_open(libusb_context * usb_ctx,libusb_device_handle * usb_dev_handle,usbredirparser_log log_func,usbredirparser_read read_guest_data_func,usbredirparser_write write_guest_data_func,void * func_priv,const char * version,int verbose,int flags)640 struct usbredirhost *usbredirhost_open(
641 libusb_context *usb_ctx,
642 libusb_device_handle *usb_dev_handle,
643 usbredirparser_log log_func,
644 usbredirparser_read read_guest_data_func,
645 usbredirparser_write write_guest_data_func,
646 void *func_priv, const char *version, int verbose, int flags)
647 {
648 return usbredirhost_open_full(usb_ctx, usb_dev_handle, log_func,
649 read_guest_data_func, write_guest_data_func,
650 NULL, NULL, NULL, NULL, NULL,
651 func_priv, version, verbose, flags);
652 }
653
usbredirhost_open_full(libusb_context * usb_ctx,libusb_device_handle * usb_dev_handle,usbredirparser_log log_func,usbredirparser_read read_guest_data_func,usbredirparser_write write_guest_data_func,usbredirhost_flush_writes flush_writes_func,usbredirparser_alloc_lock alloc_lock_func,usbredirparser_lock lock_func,usbredirparser_unlock unlock_func,usbredirparser_free_lock free_lock_func,void * func_priv,const char * version,int verbose,int flags)654 struct usbredirhost *usbredirhost_open_full(
655 libusb_context *usb_ctx,
656 libusb_device_handle *usb_dev_handle,
657 usbredirparser_log log_func,
658 usbredirparser_read read_guest_data_func,
659 usbredirparser_write write_guest_data_func,
660 usbredirhost_flush_writes flush_writes_func,
661 usbredirparser_alloc_lock alloc_lock_func,
662 usbredirparser_lock lock_func,
663 usbredirparser_unlock unlock_func,
664 usbredirparser_free_lock free_lock_func,
665 void *func_priv, const char *version, int verbose, int flags)
666 {
667 struct usbredirhost *host;
668 int parser_flags = usbredirparser_fl_usb_host;
669 uint32_t caps[USB_REDIR_CAPS_SIZE] = { 0, };
670
671 host = calloc(1, sizeof(*host));
672 if (!host) {
673 log_func(func_priv, usbredirparser_error,
674 "usbredirhost error: Out of memory allocating usbredirhost");
675 libusb_close(usb_dev_handle);
676 return NULL;
677 }
678
679 host->ctx = usb_ctx;
680 host->log_func = log_func;
681 host->read_func = read_guest_data_func;
682 host->write_func = write_guest_data_func;
683 host->flush_writes_func = flush_writes_func;
684 host->func_priv = func_priv;
685 host->verbose = verbose;
686 host->disconnected = 1; /* No device is connected initially */
687 host->parser = usbredirparser_create();
688 if (!host->parser) {
689 log_func(func_priv, usbredirparser_error,
690 "usbredirhost error: Out of memory allocating usbredirparser");
691 usbredirhost_close(host);
692 return NULL;
693 }
694 host->parser->priv = host;
695 host->parser->log_func = usbredirhost_log;
696 host->parser->read_func = usbredirhost_read;
697 host->parser->write_func = usbredirhost_write;
698 host->parser->hello_func = usbredirhost_hello;
699 host->parser->reset_func = usbredirhost_reset;
700 host->parser->set_configuration_func = usbredirhost_set_configuration;
701 host->parser->get_configuration_func = usbredirhost_get_configuration;
702 host->parser->set_alt_setting_func = usbredirhost_set_alt_setting;
703 host->parser->get_alt_setting_func = usbredirhost_get_alt_setting;
704 host->parser->start_iso_stream_func = usbredirhost_start_iso_stream;
705 host->parser->stop_iso_stream_func = usbredirhost_stop_iso_stream;
706 host->parser->start_interrupt_receiving_func =
707 usbredirhost_start_interrupt_receiving;
708 host->parser->stop_interrupt_receiving_func =
709 usbredirhost_stop_interrupt_receiving;
710 host->parser->alloc_bulk_streams_func = usbredirhost_alloc_bulk_streams;
711 host->parser->free_bulk_streams_func = usbredirhost_free_bulk_streams;
712 host->parser->cancel_data_packet_func = usbredirhost_cancel_data_packet;
713 host->parser->filter_reject_func = usbredirhost_filter_reject;
714 host->parser->filter_filter_func = usbredirhost_filter_filter;
715 host->parser->device_disconnect_ack_func =
716 usbredirhost_device_disconnect_ack;
717 host->parser->start_bulk_receiving_func =
718 usbredirhost_start_bulk_receiving;
719 host->parser->stop_bulk_receiving_func =
720 usbredirhost_stop_bulk_receiving;
721 host->parser->control_packet_func = usbredirhost_control_packet;
722 host->parser->bulk_packet_func = usbredirhost_bulk_packet;
723 host->parser->iso_packet_func = usbredirhost_iso_packet;
724 host->parser->interrupt_packet_func = usbredirhost_interrupt_packet;
725 host->parser->alloc_lock_func = alloc_lock_func;
726 host->parser->lock_func = lock_func;
727 host->parser->unlock_func = unlock_func;
728 host->parser->free_lock_func = free_lock_func;
729
730 if (host->parser->alloc_lock_func) {
731 host->lock = host->parser->alloc_lock_func();
732 host->disconnect_lock = host->parser->alloc_lock_func();
733 }
734
735 if (flags & usbredirhost_fl_write_cb_owns_buffer) {
736 parser_flags |= usbredirparser_fl_write_cb_owns_buffer;
737 }
738
739 usbredirparser_caps_set_cap(caps, usb_redir_cap_connect_device_version);
740 usbredirparser_caps_set_cap(caps, usb_redir_cap_filter);
741 usbredirparser_caps_set_cap(caps, usb_redir_cap_device_disconnect_ack);
742 usbredirparser_caps_set_cap(caps, usb_redir_cap_ep_info_max_packet_size);
743 usbredirparser_caps_set_cap(caps, usb_redir_cap_64bits_ids);
744 usbredirparser_caps_set_cap(caps, usb_redir_cap_32bits_bulk_length);
745 usbredirparser_caps_set_cap(caps, usb_redir_cap_bulk_receiving);
746 #if LIBUSBX_API_VERSION >= 0x01000103
747 usbredirparser_caps_set_cap(caps, usb_redir_cap_bulk_streams);
748 #endif
749
750 usbredirparser_init(host->parser, version, caps, USB_REDIR_CAPS_SIZE,
751 parser_flags);
752
753 #if LIBUSB_API_VERSION >= 0x01000106
754 libusb_set_option(host->ctx, LIBUSB_OPTION_LOG_LEVEL, host->verbose);
755 #else
756 libusb_set_debug(host->ctx, host->verbose);
757 #endif
758
759 if (usbredirhost_set_device(host, usb_dev_handle) != usb_redir_success) {
760 usbredirhost_close(host);
761 return NULL;
762 }
763
764 FLUSH(host);
765
766 return host;
767 }
768
usbredirhost_close(struct usbredirhost * host)769 void usbredirhost_close(struct usbredirhost *host)
770 {
771 usbredirhost_clear_device(host);
772
773 if (host->lock) {
774 host->parser->free_lock_func(host->lock);
775 }
776 if (host->disconnect_lock) {
777 host->parser->free_lock_func(host->disconnect_lock);
778 }
779 if (host->parser) {
780 usbredirparser_destroy(host->parser);
781 }
782 free(host->filter_rules);
783 free(host);
784 }
785
usbredirhost_reset_device(struct usbredirhost * host)786 static int usbredirhost_reset_device(struct usbredirhost *host)
787 {
788 int r;
789
790 if (host->quirks & QUIRK_DO_NOT_RESET) {
791 return 0;
792 }
793
794 r = libusb_reset_device(host->handle);
795 if (r != 0) {
796 ERROR("error resetting device: %s", libusb_error_name(r));
797 usbredirhost_clear_device(host);
798 return r;
799 }
800
801 host->reset = 1;
802 return 0;
803 }
804
usbredirhost_set_device(struct usbredirhost * host,libusb_device_handle * usb_dev_handle)805 int usbredirhost_set_device(struct usbredirhost *host,
806 libusb_device_handle *usb_dev_handle)
807 {
808 int i, r, status;
809
810 usbredirhost_clear_device(host);
811
812 if (!usb_dev_handle)
813 return usb_redir_success;
814
815 host->dev = libusb_get_device(usb_dev_handle);
816 host->handle = usb_dev_handle;
817
818 status = usbredirhost_claim(host, 1);
819 if (status != usb_redir_success) {
820 usbredirhost_clear_device(host);
821 return status;
822 }
823
824 for (i = 0; usbredirhost_reset_blacklist[i].vendor_id != -1; i++) {
825 if (host->desc.idVendor == usbredirhost_reset_blacklist[i].vendor_id &&
826 host->desc.idProduct ==
827 usbredirhost_reset_blacklist[i].product_id) {
828 host->quirks |= QUIRK_DO_NOT_RESET;
829 break;
830 }
831 }
832
833 /* The first thing almost any usb-guest does is a (slow) device-reset
834 so lets do that before hand */
835 r = usbredirhost_reset_device(host);
836 if (r != 0) {
837 return libusb_status_or_error_to_redir_status(host, r);
838 }
839
840 usbredirhost_send_device_connect(host);
841
842 return usb_redir_success;
843 }
844
usbredirhost_clear_device(struct usbredirhost * host)845 static void usbredirhost_clear_device(struct usbredirhost *host)
846 {
847 if (!host->dev)
848 return;
849
850 if (usbredirhost_cancel_pending_urbs(host, 0))
851 usbredirhost_wait_for_cancel_completion(host);
852
853 usbredirhost_release(host, 1);
854
855 if (host->config) {
856 libusb_free_config_descriptor(host->config);
857 host->config = NULL;
858 }
859 if (host->handle) {
860 libusb_close(host->handle);
861 host->handle = NULL;
862 }
863
864 host->connect_pending = 0;
865 host->quirks = 0;
866 host->dev = NULL;
867
868 usbredirhost_handle_disconnect(host);
869 FLUSH(host);
870 }
871
usbredirhost_read_guest_data(struct usbredirhost * host)872 int usbredirhost_read_guest_data(struct usbredirhost *host)
873 {
874 return usbredirparser_do_read(host->parser);
875 }
876
usbredirhost_has_data_to_write(struct usbredirhost * host)877 int usbredirhost_has_data_to_write(struct usbredirhost *host)
878 {
879 return usbredirparser_has_data_to_write(host->parser);
880 }
881
usbredirhost_write_guest_data(struct usbredirhost * host)882 int usbredirhost_write_guest_data(struct usbredirhost *host)
883 {
884 return usbredirparser_do_write(host->parser);
885 }
886
usbredirhost_free_write_buffer(struct usbredirhost * host,uint8_t * data)887 void usbredirhost_free_write_buffer(struct usbredirhost *host, uint8_t *data)
888 {
889 usbredirparser_free_write_buffer(host->parser, data);
890 }
891
892 /**************************************************************************/
893
usbredirhost_alloc_transfer(struct usbredirhost * host,int iso_packets)894 static struct usbredirtransfer *usbredirhost_alloc_transfer(
895 struct usbredirhost *host, int iso_packets)
896 {
897 struct usbredirtransfer *redir_transfer;
898 struct libusb_transfer *libusb_transfer;
899
900 redir_transfer = calloc(1, sizeof(*redir_transfer));
901 libusb_transfer = libusb_alloc_transfer(iso_packets);
902 if (!redir_transfer || !libusb_transfer) {
903 ERROR("out of memory allocating usb transfer, dropping packet");
904 free(redir_transfer);
905 libusb_free_transfer(libusb_transfer);
906 return NULL;
907 }
908 redir_transfer->host = host;
909 redir_transfer->transfer = libusb_transfer;
910 libusb_transfer->user_data = redir_transfer;
911
912 return redir_transfer;
913 }
914
usbredirhost_free_transfer(struct usbredirtransfer * transfer)915 static void usbredirhost_free_transfer(struct usbredirtransfer *transfer)
916 {
917 if (!transfer)
918 return;
919
920 /* In certain cases this should really be a usbredirparser_free_packet_data
921 but since we use the same malloc impl. as usbredirparser this is ok. */
922 free(transfer->transfer->buffer);
923 libusb_free_transfer(transfer->transfer);
924 free(transfer);
925 }
926
usbredirhost_add_transfer(struct usbredirhost * host,struct usbredirtransfer * new_transfer)927 static void usbredirhost_add_transfer(struct usbredirhost *host,
928 struct usbredirtransfer *new_transfer)
929 {
930 struct usbredirtransfer *transfer = &host->transfers_head;
931
932 LOCK(host);
933 while (transfer->next) {
934 transfer = transfer->next;
935 }
936
937 new_transfer->prev = transfer;
938 transfer->next = new_transfer;
939 UNLOCK(host);
940 }
941
942 /* Note caller must hold the host lock */
usbredirhost_remove_and_free_transfer(struct usbredirtransfer * transfer)943 static void usbredirhost_remove_and_free_transfer(
944 struct usbredirtransfer *transfer)
945 {
946 if (transfer->next)
947 transfer->next->prev = transfer->prev;
948 if (transfer->prev)
949 transfer->prev->next = transfer->next;
950 usbredirhost_free_transfer(transfer);
951 }
952
953 /**************************************************************************/
954
955 /* Called from both parser read and packet complete callbacks */
usbredirhost_cancel_stream_unlocked(struct usbredirhost * host,uint8_t ep)956 static void usbredirhost_cancel_stream_unlocked(struct usbredirhost *host,
957 uint8_t ep)
958 {
959 int i;
960 struct usbredirtransfer *transfer;
961
962 for (i = 0; i < host->endpoint[EP2I(ep)].transfer_count; i++) {
963 transfer = host->endpoint[EP2I(ep)].transfer[i];
964 if (transfer->packet_idx == SUBMITTED_IDX) {
965 libusb_cancel_transfer(transfer->transfer);
966 transfer->cancelled = 1;
967 host->cancels_pending++;
968 } else {
969 usbredirhost_free_transfer(transfer);
970 }
971 host->endpoint[EP2I(ep)].transfer[i] = NULL;
972 }
973 host->endpoint[EP2I(ep)].out_idx = 0;
974 host->endpoint[EP2I(ep)].stream_started = 0;
975 host->endpoint[EP2I(ep)].drop_packets = 0;
976 host->endpoint[EP2I(ep)].pkts_per_transfer = 0;
977 host->endpoint[EP2I(ep)].transfer_count = 0;
978 }
979
usbredirhost_cancel_stream(struct usbredirhost * host,uint8_t ep)980 static void usbredirhost_cancel_stream(struct usbredirhost *host,
981 uint8_t ep)
982 {
983 LOCK(host);
984 usbredirhost_cancel_stream_unlocked(host, ep);
985 UNLOCK(host);
986 }
987
usbredirhost_send_stream_status(struct usbredirhost * host,uint64_t id,uint8_t ep,uint8_t status)988 static void usbredirhost_send_stream_status(struct usbredirhost *host,
989 uint64_t id, uint8_t ep, uint8_t status)
990 {
991 switch (host->endpoint[EP2I(ep)].type) {
992 case usb_redir_type_iso: {
993 struct usb_redir_iso_stream_status_header iso_status = {
994 .endpoint = ep,
995 .status = status,
996 };
997 usbredirparser_send_iso_stream_status(host->parser, id, &iso_status);
998 break;
999 }
1000 case usb_redir_type_bulk: {
1001 struct usb_redir_bulk_receiving_status_header bulk_status = {
1002 .endpoint = ep,
1003 .status = status,
1004 };
1005 usbredirparser_send_bulk_receiving_status(host->parser, id,
1006 &bulk_status);
1007 break;
1008 }
1009 case usb_redir_type_interrupt: {
1010 struct usb_redir_interrupt_receiving_status_header interrupt_status = {
1011 .endpoint = ep,
1012 .status = status,
1013 };
1014 usbredirparser_send_interrupt_receiving_status(host->parser, id,
1015 &interrupt_status);
1016 break;
1017 }
1018 }
1019 }
1020
usbredirhost_can_write_iso_package(struct usbredirhost * host)1021 static int usbredirhost_can_write_iso_package(struct usbredirhost *host)
1022 {
1023 uint64_t size;
1024
1025 if (!host->buffered_output_size_func)
1026 return true;
1027
1028 size = host->buffered_output_size_func(host->func_priv);
1029 if (size >= host->iso_threshold.higher) {
1030 if (!host->iso_threshold.dropping)
1031 DEBUG("START dropping isoc packets %" PRIu64 " buffer > %" PRIu64 " hi threshold",
1032 size, host->iso_threshold.higher);
1033 host->iso_threshold.dropping = true;
1034 } else if (size < host->iso_threshold.lower) {
1035 if (host->iso_threshold.dropping)
1036 DEBUG("STOP dropping isoc packets %" PRIu64 " buffer < %" PRIu64 " low threshold",
1037 size, host->iso_threshold.lower);
1038
1039 host->iso_threshold.dropping = false;
1040 }
1041
1042 return !host->iso_threshold.dropping;
1043 }
1044
usbredirhost_send_stream_data(struct usbredirhost * host,uint64_t id,uint8_t ep,uint8_t status,uint8_t * data,int len)1045 static void usbredirhost_send_stream_data(struct usbredirhost *host,
1046 uint64_t id, uint8_t ep, uint8_t status, uint8_t *data, int len)
1047 {
1048 /* USB-2 is max 8000 packets / sec, if we've queued up more then 0.1 sec,
1049 assume our connection is not keeping up and start dropping packets. */
1050 if (usbredirparser_has_data_to_write(host->parser) > 800) {
1051 if (host->endpoint[EP2I(ep)].warn_on_drop) {
1052 WARNING("buffered stream on endpoint %02X, connection too slow, "
1053 "dropping packets", ep);
1054 host->endpoint[EP2I(ep)].warn_on_drop = 0;
1055 }
1056 DEBUG("buffered complete ep %02X dropping packet status %d len %d",
1057 ep, status, len);
1058 return;
1059 }
1060
1061 DEBUG("buffered complete ep %02X status %d len %d", ep, status, len);
1062
1063 switch (host->endpoint[EP2I(ep)].type) {
1064 case usb_redir_type_iso: {
1065 struct usb_redir_iso_packet_header iso_packet = {
1066 .endpoint = ep,
1067 .status = status,
1068 .length = len,
1069 };
1070
1071 if (usbredirhost_can_write_iso_package(host))
1072 usbredirparser_send_iso_packet(host->parser, id, &iso_packet,
1073 data, len);
1074 break;
1075 }
1076 case usb_redir_type_bulk: {
1077 struct usb_redir_buffered_bulk_packet_header bulk_packet = {
1078 .endpoint = ep,
1079 .status = status,
1080 .length = len,
1081 };
1082 usbredirparser_send_buffered_bulk_packet(host->parser, id,
1083 &bulk_packet, data, len);
1084 break;
1085 }
1086 case usb_redir_type_interrupt: {
1087 struct usb_redir_interrupt_packet_header interrupt_packet = {
1088 .endpoint = ep,
1089 .status = status,
1090 .length = len,
1091 };
1092 usbredirparser_send_interrupt_packet(host->parser, id,
1093 &interrupt_packet, data, len);
1094 break;
1095 }
1096 }
1097 }
1098
1099 /* Called from both parser read and packet complete callbacks */
usbredirhost_submit_stream_transfer_unlocked(struct usbredirhost * host,struct usbredirtransfer * transfer)1100 static int usbredirhost_submit_stream_transfer_unlocked(
1101 struct usbredirhost *host, struct usbredirtransfer *transfer)
1102 {
1103 int r;
1104
1105 host->reset = 0;
1106
1107 r = libusb_submit_transfer(transfer->transfer);
1108 if (r < 0) {
1109 uint8_t ep = transfer->transfer->endpoint;
1110 if (r == LIBUSB_ERROR_NO_DEVICE) {
1111 usbredirhost_handle_disconnect(host);
1112 } else {
1113 ERROR("error submitting transfer on ep %02X: %s, stopping stream",
1114 ep, libusb_error_name(r));
1115 usbredirhost_cancel_stream_unlocked(host, ep);
1116 usbredirhost_send_stream_status(host, transfer->id, ep,
1117 usb_redir_stall);
1118 }
1119 return usb_redir_stall;
1120 }
1121
1122 transfer->packet_idx = SUBMITTED_IDX;
1123 return usb_redir_success;
1124 }
1125
1126 /* Called from both parser read and packet complete callbacks */
usbredirhost_start_stream_unlocked(struct usbredirhost * host,uint8_t ep)1127 static int usbredirhost_start_stream_unlocked(struct usbredirhost *host,
1128 uint8_t ep)
1129 {
1130 unsigned int i, count = host->endpoint[EP2I(ep)].transfer_count;
1131 int status;
1132
1133 /* For out endpoints 1/2 the transfers are a buffer for usb-guest data */
1134 if (!(ep & LIBUSB_ENDPOINT_IN)) {
1135 count /= 2;
1136 }
1137 for (i = 0; i < count; i++) {
1138 if (ep & LIBUSB_ENDPOINT_IN) {
1139 host->endpoint[EP2I(ep)].transfer[i]->id =
1140 i * host->endpoint[EP2I(ep)].pkts_per_transfer;
1141 }
1142 status = usbredirhost_submit_stream_transfer_unlocked(host,
1143 host->endpoint[EP2I(ep)].transfer[i]);
1144 if (status != usb_redir_success) {
1145 return status;
1146 }
1147 }
1148 host->endpoint[EP2I(ep)].stream_started = 1;
1149 return usb_redir_success;
1150 }
1151
usbredirhost_stop_stream(struct usbredirhost * host,uint64_t id,uint8_t ep)1152 static void usbredirhost_stop_stream(struct usbredirhost *host,
1153 uint64_t id, uint8_t ep)
1154 {
1155 if (host->disconnected) {
1156 return;
1157 }
1158
1159 usbredirhost_cancel_stream(host, ep);
1160 usbredirhost_send_stream_status(host, id, ep, usb_redir_success);
1161 FLUSH(host);
1162 }
1163
usbredirhost_set_iso_threshold(struct usbredirhost * host,uint8_t pkts_per_transfer,uint8_t transfer_count,uint16_t max_packetsize)1164 static void usbredirhost_set_iso_threshold(struct usbredirhost *host,
1165 uint8_t pkts_per_transfer, uint8_t transfer_count, uint16_t max_packetsize)
1166 {
1167 uint64_t reference = pkts_per_transfer * transfer_count * max_packetsize;
1168 host->iso_threshold.lower = reference / 2;
1169 host->iso_threshold.higher = reference * 3;
1170 DEBUG("higher threshold is %" PRIu64 " bytes | lower threshold is %" PRIu64 " bytes",
1171 host->iso_threshold.higher, host->iso_threshold.lower);
1172 }
1173
1174 /* Called from both parser read and packet complete callbacks */
usbredirhost_alloc_stream_unlocked(struct usbredirhost * host,uint64_t id,uint8_t ep,uint8_t type,uint8_t pkts_per_transfer,int pkt_size,uint8_t transfer_count,int send_success)1175 static void usbredirhost_alloc_stream_unlocked(struct usbredirhost *host,
1176 uint64_t id, uint8_t ep, uint8_t type, uint8_t pkts_per_transfer,
1177 int pkt_size, uint8_t transfer_count, int send_success)
1178 {
1179 int i, buf_size, status = usb_redir_success;
1180 unsigned char *buffer;
1181
1182 if (host->disconnected) {
1183 goto error;
1184 }
1185
1186 if (host->endpoint[EP2I(ep)].type != type) {
1187 ERROR("error start stream type %d on type %d endpoint",
1188 type, host->endpoint[EP2I(ep)].type);
1189 goto error;
1190 }
1191
1192 if ( pkts_per_transfer < 1 ||
1193 pkts_per_transfer > MAX_PACKETS_PER_TRANSFER ||
1194 transfer_count < 1 ||
1195 transfer_count > MAX_TRANSFER_COUNT ||
1196 host->endpoint[EP2I(ep)].max_packetsize == 0 ||
1197 (pkt_size % host->endpoint[EP2I(ep)].max_packetsize) != 0) {
1198 ERROR("error start stream type %d invalid parameters", type);
1199 goto error;
1200 }
1201
1202 if (host->endpoint[EP2I(ep)].transfer_count) {
1203 ERROR("error received start type %d for already started stream", type);
1204 usbredirhost_send_stream_status(host, id, ep, usb_redir_inval);
1205 return;
1206 }
1207
1208 DEBUG("allocating stream ep %02X type %d packet-size %d pkts %d urbs %d",
1209 ep, type, pkt_size, pkts_per_transfer, transfer_count);
1210 for (i = 0; i < transfer_count; i++) {
1211 host->endpoint[EP2I(ep)].transfer[i] =
1212 usbredirhost_alloc_transfer(host, (type == usb_redir_type_iso) ?
1213 pkts_per_transfer : 0);
1214 if (!host->endpoint[EP2I(ep)].transfer[i]) {
1215 goto alloc_error;
1216 }
1217
1218 buf_size = pkt_size * pkts_per_transfer;
1219 buffer = malloc(buf_size);
1220 if (!buffer) {
1221 goto alloc_error;
1222 }
1223 switch (type) {
1224 case usb_redir_type_iso:
1225 libusb_fill_iso_transfer(
1226 host->endpoint[EP2I(ep)].transfer[i]->transfer, host->handle,
1227 ep, buffer, buf_size, pkts_per_transfer,
1228 usbredirhost_iso_packet_complete,
1229 host->endpoint[EP2I(ep)].transfer[i], ISO_TIMEOUT);
1230 libusb_set_iso_packet_lengths(
1231 host->endpoint[EP2I(ep)].transfer[i]->transfer, pkt_size);
1232
1233 usbredirhost_set_iso_threshold(
1234 host, pkts_per_transfer, transfer_count,
1235 host->endpoint[EP2I(ep)].max_packetsize);
1236 break;
1237 case usb_redir_type_bulk:
1238 libusb_fill_bulk_transfer(
1239 host->endpoint[EP2I(ep)].transfer[i]->transfer, host->handle,
1240 ep, buffer, buf_size, usbredirhost_buffered_packet_complete,
1241 host->endpoint[EP2I(ep)].transfer[i], BULK_TIMEOUT);
1242 break;
1243 case usb_redir_type_interrupt:
1244 libusb_fill_interrupt_transfer(
1245 host->endpoint[EP2I(ep)].transfer[i]->transfer, host->handle,
1246 ep, buffer, buf_size, usbredirhost_buffered_packet_complete,
1247 host->endpoint[EP2I(ep)].transfer[i], INTERRUPT_TIMEOUT);
1248 break;
1249 }
1250 }
1251 host->endpoint[EP2I(ep)].out_idx = 0;
1252 host->endpoint[EP2I(ep)].drop_packets = 0;
1253 host->endpoint[EP2I(ep)].pkts_per_transfer = pkts_per_transfer;
1254 host->endpoint[EP2I(ep)].transfer_count = transfer_count;
1255
1256 /* For input endpoints submit the transfers now */
1257 if (ep & LIBUSB_ENDPOINT_IN) {
1258 status = usbredirhost_start_stream_unlocked(host, ep);
1259 }
1260
1261 if (send_success && status == usb_redir_success) {
1262 usbredirhost_send_stream_status(host, id, ep, status);
1263 }
1264 return;
1265
1266 alloc_error:
1267 ERROR("out of memory allocating type %d stream buffers", type);
1268 do {
1269 usbredirhost_free_transfer(host->endpoint[EP2I(ep)].transfer[i]);
1270 host->endpoint[EP2I(ep)].transfer[i] = NULL;
1271 i--;
1272 } while (i >= 0);
1273 error:
1274 usbredirhost_send_stream_status(host, id, ep, usb_redir_stall);
1275 }
1276
usbredirhost_alloc_stream(struct usbredirhost * host,uint64_t id,uint8_t ep,uint8_t type,uint8_t pkts_per_transfer,int pkt_size,uint8_t transfer_count,int send_success)1277 static void usbredirhost_alloc_stream(struct usbredirhost *host,
1278 uint64_t id, uint8_t ep, uint8_t type, uint8_t pkts_per_transfer,
1279 int pkt_size, uint8_t transfer_count, int send_success)
1280 {
1281 LOCK(host);
1282 usbredirhost_alloc_stream_unlocked(host, id, ep, type, pkts_per_transfer,
1283 pkt_size, transfer_count, send_success);
1284 UNLOCK(host);
1285 }
1286
usbredirhost_clear_stream_stall_unlocked(struct usbredirhost * host,uint64_t id,uint8_t ep)1287 static void usbredirhost_clear_stream_stall_unlocked(
1288 struct usbredirhost *host, uint64_t id, uint8_t ep)
1289 {
1290 int r;
1291 uint8_t pkts_per_transfer = host->endpoint[EP2I(ep)].pkts_per_transfer;
1292 uint8_t transfer_count = host->endpoint[EP2I(ep)].transfer_count;
1293 int pkt_size = host->endpoint[EP2I(ep)].transfer[0]->transfer->length /
1294 pkts_per_transfer;
1295
1296 WARNING("buffered stream on endpoint %02X stalled, clearing stall", ep);
1297
1298 usbredirhost_cancel_stream_unlocked(host, ep);
1299 r = libusb_clear_halt(host->handle, ep);
1300 if (r < 0) {
1301 usbredirhost_send_stream_status(host, id, ep, usb_redir_stall);
1302 return;
1303 }
1304 usbredirhost_alloc_stream_unlocked(host, id, ep,
1305 host->endpoint[EP2I(ep)].type,
1306 pkts_per_transfer, pkt_size,
1307 transfer_count, 0);
1308 }
1309
1310 /**************************************************************************/
1311
1312 /* Called from close and parser read callbacks */
usbredirhost_cancel_pending_urbs(struct usbredirhost * host,int notify_guest)1313 static int usbredirhost_cancel_pending_urbs(struct usbredirhost *host,
1314 int notify_guest)
1315 {
1316 struct usbredirtransfer *t;
1317 int i, wait;
1318
1319 LOCK(host);
1320 for (i = 0; i < MAX_ENDPOINTS; i++) {
1321 if (notify_guest && host->endpoint[i].transfer_count)
1322 usbredirhost_send_stream_status(host, 0, I2EP(i), usb_redir_stall);
1323 usbredirhost_cancel_stream_unlocked(host, I2EP(i));
1324 }
1325
1326 wait = host->cancels_pending;
1327 for (t = host->transfers_head.next; t; t = t->next) {
1328 libusb_cancel_transfer(t->transfer);
1329 wait = 1;
1330 }
1331 UNLOCK(host);
1332
1333 if (notify_guest)
1334 FLUSH(host);
1335
1336 return wait;
1337 }
1338
1339 /* Called from close and parser read callbacks */
usbredirhost_wait_for_cancel_completion(struct usbredirhost * host)1340 void usbredirhost_wait_for_cancel_completion(struct usbredirhost *host)
1341 {
1342 int wait;
1343 struct timeval tv;
1344
1345 do {
1346 memset(&tv, 0, sizeof(tv));
1347 tv.tv_usec = 2500;
1348 libusb_handle_events_timeout(host->ctx, &tv);
1349 LOCK(host);
1350 wait = host->cancels_pending || host->transfers_head.next;
1351 UNLOCK(host);
1352 } while (wait);
1353 }
1354
1355 /* Only called from read callbacks */
usbredirhost_cancel_pending_urbs_on_interface(struct usbredirhost * host,int i)1356 static void usbredirhost_cancel_pending_urbs_on_interface(
1357 struct usbredirhost *host, int i)
1358 {
1359 struct usbredirtransfer *t;
1360 const struct libusb_interface_descriptor *intf_desc;
1361
1362 LOCK(host);
1363
1364 intf_desc = &host->config->interface[i].altsetting[host->alt_setting[i]];
1365 for (i = 0; i < intf_desc->bNumEndpoints; i++) {
1366 uint8_t ep = intf_desc->endpoint[i].bEndpointAddress;
1367
1368 usbredirhost_cancel_stream_unlocked(host, ep);
1369
1370 for (t = host->transfers_head.next; t; t = t->next) {
1371 if (t->transfer->endpoint == ep)
1372 libusb_cancel_transfer(t->transfer);
1373 }
1374 }
1375
1376 UNLOCK(host);
1377 }
1378
1379 /* Only called from read callbacks */
usbredirhost_bInterfaceNumber_to_index(struct usbredirhost * host,uint8_t bInterfaceNumber)1380 static int usbredirhost_bInterfaceNumber_to_index(
1381 struct usbredirhost *host, uint8_t bInterfaceNumber)
1382 {
1383 int i, n;
1384
1385 for (i = 0; host->config && i < host->config->bNumInterfaces; i++) {
1386 n = host->config->interface[i].altsetting[0].bInterfaceNumber;
1387 if (n == bInterfaceNumber) {
1388 return i;
1389 }
1390 }
1391
1392 ERROR("invalid bNumInterface: %d\n", (int)bInterfaceNumber);
1393 return -1;
1394 }
1395
usbredirhost_log_data(struct usbredirhost * host,const char * desc,const uint8_t * data,int len)1396 static void usbredirhost_log_data(struct usbredirhost *host, const char *desc,
1397 const uint8_t *data, int len)
1398 {
1399 if (usbredirparser_debug_data <= host->verbose) {
1400 int i, j, n;
1401
1402 for (i = 0; i < len; i += j) {
1403 char buf[128];
1404
1405 n = sprintf(buf, "%s", desc);
1406 for (j = 0; j < 8 && i + j < len; j++){
1407 n += sprintf(buf + n, " %02X", data[i + j]);
1408 }
1409 va_log(host, usbredirparser_debug_data, "%s", buf);
1410 }
1411 }
1412 }
1413
1414 /**************************************************************************/
1415
usbredirhost_set_buffered_output_size_cb(struct usbredirhost * host,usbredirhost_buffered_output_size buffered_output_size_func)1416 void usbredirhost_set_buffered_output_size_cb(struct usbredirhost *host,
1417 usbredirhost_buffered_output_size buffered_output_size_func)
1418 {
1419 if (!host) {
1420 fprintf(stderr, "%s: invalid usbredirhost", __func__);
1421 return;
1422 }
1423
1424 host->buffered_output_size_func = buffered_output_size_func;
1425 }
1426
1427 /* Return value:
1428 0 All ok
1429 1 Packet borked, continue with next packet / urb
1430 2 Stream borked, full stop, no resubmit, etc.
1431 Note in the case of a return value of 2 this function takes care of
1432 sending an iso status message to the usb-guest. */
usbredirhost_handle_iso_status(struct usbredirhost * host,uint64_t id,uint8_t ep,int r)1433 static int usbredirhost_handle_iso_status(struct usbredirhost *host,
1434 uint64_t id, uint8_t ep, int r)
1435 {
1436 switch (r) {
1437 case LIBUSB_TRANSFER_COMPLETED:
1438 case -EXDEV: /* FIXlibusb: Passing regular error codes, bad libusb, bad! */
1439 return 0;
1440 case LIBUSB_TRANSFER_CANCELLED:
1441 /* Stream was intentionally stopped */
1442 return 2;
1443 case LIBUSB_TRANSFER_STALL:
1444 usbredirhost_clear_stream_stall_unlocked(host, id, ep);
1445 return 2;
1446 case LIBUSB_TRANSFER_NO_DEVICE:
1447 usbredirhost_handle_disconnect(host);
1448 return 2;
1449 case LIBUSB_TRANSFER_OVERFLOW:
1450 case LIBUSB_TRANSFER_ERROR:
1451 case LIBUSB_TRANSFER_TIMED_OUT:
1452 default:
1453 ERROR("iso stream error on endpoint %02X: %d", ep, r);
1454 return 1;
1455 }
1456 }
1457
usbredirhost_iso_packet_complete(struct libusb_transfer * libusb_transfer)1458 static void LIBUSB_CALL usbredirhost_iso_packet_complete(
1459 struct libusb_transfer *libusb_transfer)
1460 {
1461 struct usbredirtransfer *transfer = libusb_transfer->user_data;
1462 uint8_t ep = libusb_transfer->endpoint;
1463 struct usbredirhost *host = transfer->host;
1464 int i, r, len, status;
1465
1466 LOCK(host);
1467 if (transfer->cancelled) {
1468 host->cancels_pending--;
1469 usbredirhost_free_transfer(transfer);
1470 goto unlock;
1471 }
1472
1473 /* Mark transfer completed (iow not submitted) */
1474 transfer->packet_idx = 0;
1475
1476 /* Check overal transfer status */
1477 r = libusb_transfer->status;
1478 switch (usbredirhost_handle_iso_status(host, transfer->id, ep, r)) {
1479 case 0:
1480 break;
1481 case 1:
1482 status = libusb_status_or_error_to_redir_status(host, r);
1483 if (ep & LIBUSB_ENDPOINT_IN) {
1484 struct usb_redir_iso_packet_header iso_packet = {
1485 .endpoint = ep,
1486 .status = status,
1487 .length = 0
1488 };
1489 usbredirparser_send_iso_packet(host->parser, transfer->id,
1490 &iso_packet, NULL, 0);
1491 transfer->id += libusb_transfer->num_iso_packets;
1492 goto resubmit;
1493 } else {
1494 usbredirhost_send_stream_status(host, transfer->id, ep, status);
1495 goto unlock;
1496 }
1497 break;
1498 case 2:
1499 goto unlock;
1500 }
1501
1502 /* Check per packet status and send ok input packets to usb-guest */
1503 for (i = 0; i < libusb_transfer->num_iso_packets; i++) {
1504 r = libusb_transfer->iso_packet_desc[i].status;
1505 len = libusb_transfer->iso_packet_desc[i].actual_length;
1506 status = libusb_status_or_error_to_redir_status(host, r);
1507 switch (usbredirhost_handle_iso_status(host, transfer->id, ep, r)) {
1508 case 0:
1509 break;
1510 case 1:
1511 if (ep & LIBUSB_ENDPOINT_IN) {
1512 len = 0;
1513 } else {
1514 usbredirhost_send_stream_status(host, transfer->id, ep,
1515 status);
1516 goto unlock; /* We send max one iso status message per urb */
1517 }
1518 break;
1519 case 2:
1520 goto unlock;
1521 }
1522 if (ep & LIBUSB_ENDPOINT_IN) {
1523 usbredirhost_send_stream_data(host, transfer->id, ep, status,
1524 libusb_get_iso_packet_buffer(libusb_transfer, i), len);
1525 transfer->id++;
1526 } else {
1527 DEBUG("iso-in complete ep %02X pkt %d len %d id %"PRIu64,
1528 ep, i, len, transfer->id);
1529 }
1530 }
1531
1532 /* And for input transfers resubmit the transfer (output transfers
1533 get resubmitted when they have all their packets filled with data) */
1534 if (ep & LIBUSB_ENDPOINT_IN) {
1535 resubmit:
1536 transfer->id += (host->endpoint[EP2I(ep)].transfer_count - 1) *
1537 libusb_transfer->num_iso_packets;
1538 usbredirhost_submit_stream_transfer_unlocked(host, transfer);
1539 } else {
1540 for (i = 0; i < host->endpoint[EP2I(ep)].transfer_count; i++) {
1541 transfer = host->endpoint[EP2I(ep)].transfer[i];
1542 if (transfer->packet_idx == SUBMITTED_IDX)
1543 break;
1544 }
1545 if (i == host->endpoint[EP2I(ep)].transfer_count) {
1546 DEBUG("underflow of iso out queue on ep: %02X", ep);
1547 /* Re-fill buffers before submitting urbs again */
1548 for (i = 0; i < host->endpoint[EP2I(ep)].transfer_count; i++)
1549 host->endpoint[EP2I(ep)].transfer[i]->packet_idx = 0;
1550 host->endpoint[EP2I(ep)].out_idx = 0;
1551 host->endpoint[EP2I(ep)].stream_started = 0;
1552 host->endpoint[EP2I(ep)].drop_packets = 0;
1553 }
1554 }
1555 unlock:
1556 UNLOCK(host);
1557 FLUSH(host);
1558 }
1559
1560 /**************************************************************************/
1561
usbredirhost_buffered_packet_complete(struct libusb_transfer * libusb_transfer)1562 static void LIBUSB_CALL usbredirhost_buffered_packet_complete(
1563 struct libusb_transfer *libusb_transfer)
1564 {
1565 struct usbredirtransfer *transfer = libusb_transfer->user_data;
1566 uint8_t ep = libusb_transfer->endpoint;
1567 struct usbredirhost *host = transfer->host;
1568 int r, len = libusb_transfer->actual_length;
1569
1570 LOCK(host);
1571
1572 if (transfer->cancelled) {
1573 host->cancels_pending--;
1574 usbredirhost_free_transfer(transfer);
1575 goto unlock;
1576 }
1577
1578 /* Mark transfer completed (iow not submitted) */
1579 transfer->packet_idx = 0;
1580
1581 r = libusb_transfer->status;
1582 switch (r) {
1583 case LIBUSB_TRANSFER_COMPLETED:
1584 break;
1585 case LIBUSB_TRANSFER_STALL:
1586 usbredirhost_clear_stream_stall_unlocked(host, transfer->id, ep);
1587 goto unlock;
1588 case LIBUSB_TRANSFER_NO_DEVICE:
1589 usbredirhost_handle_disconnect(host);
1590 goto unlock;
1591 default:
1592 ERROR("buffered in error on endpoint %02X: %d", ep, r);
1593 len = 0;
1594 }
1595
1596 usbredirhost_send_stream_data(host, transfer->id, ep,
1597 libusb_status_or_error_to_redir_status(host, r),
1598 transfer->transfer->buffer, len);
1599 usbredirhost_log_data(host, "buffered data in:",
1600 transfer->transfer->buffer, len);
1601
1602 transfer->id += host->endpoint[EP2I(ep)].transfer_count;
1603 usbredirhost_submit_stream_transfer_unlocked(host, transfer);
1604 unlock:
1605 UNLOCK(host);
1606 FLUSH(host);
1607 }
1608
1609 /**************************************************************************/
1610
usbredirhost_hello(void * priv,struct usb_redir_hello_header * h)1611 static void usbredirhost_hello(void *priv, struct usb_redir_hello_header *h)
1612 {
1613 struct usbredirhost *host = priv;
1614
1615 if (host->connect_pending)
1616 usbredirhost_send_device_connect(host);
1617 }
1618
usbredirhost_reset(void * priv)1619 static void usbredirhost_reset(void *priv)
1620 {
1621 struct usbredirhost *host = priv;
1622 int r;
1623
1624 if (host->disconnected || host->reset) {
1625 return;
1626 }
1627
1628 /*
1629 * The guest should have cancelled any pending urbs already, but the
1630 * cancellations may be awaiting completion, and if we then do a reset
1631 * they will complete with an error code of LIBUSB_TRANSFER_NO_DEVICE.
1632 *
1633 * And we also need to cleanly shutdown any streams (and let the guest
1634 * know they should be restarted after the reset).
1635 */
1636 if (usbredirhost_cancel_pending_urbs(host, 1))
1637 usbredirhost_wait_for_cancel_completion(host);
1638
1639 r = usbredirhost_reset_device(host);
1640 if (r != 0) {
1641 host->read_status = usbredirhost_read_device_lost;
1642 }
1643 }
1644
usbredirhost_set_configuration(void * priv,uint64_t id,struct usb_redir_set_configuration_header * set_config)1645 static void usbredirhost_set_configuration(void *priv, uint64_t id,
1646 struct usb_redir_set_configuration_header *set_config)
1647 {
1648 struct usbredirhost *host = priv;
1649 int r, claim_status;
1650 struct usb_redir_configuration_status_header status = {
1651 .status = usb_redir_success,
1652 };
1653
1654 if (host->disconnected) {
1655 status.status = usb_redir_ioerror;
1656 goto exit;
1657 }
1658
1659 if (host->config &&
1660 host->config->bConfigurationValue == set_config->configuration) {
1661 goto exit;
1662 }
1663
1664 host->reset = 0;
1665
1666 usbredirhost_cancel_pending_urbs(host, 0);
1667 usbredirhost_release(host, 0);
1668
1669 r = libusb_set_configuration(host->handle, set_config->configuration);
1670 if (r < 0) {
1671 ERROR("could not set active configuration to %d: %s",
1672 (int)set_config->configuration, libusb_error_name(r));
1673 status.status = usb_redir_ioerror;
1674 }
1675
1676 claim_status = usbredirhost_claim(host, 0);
1677 if (claim_status != usb_redir_success) {
1678 usbredirhost_clear_device(host);
1679 host->read_status = usbredirhost_read_device_lost;
1680 status.status = usb_redir_ioerror;
1681 goto exit;
1682 }
1683
1684 usbredirhost_send_interface_n_ep_info(host);
1685
1686 exit:
1687 status.configuration = host->config ? host->config->bConfigurationValue:0;
1688 usbredirparser_send_configuration_status(host->parser, id, &status);
1689 FLUSH(host);
1690 }
1691
usbredirhost_get_configuration(void * priv,uint64_t id)1692 static void usbredirhost_get_configuration(void *priv, uint64_t id)
1693 {
1694 struct usbredirhost *host = priv;
1695 struct usb_redir_configuration_status_header status;
1696
1697 if (host->disconnected)
1698 status.status = usb_redir_ioerror;
1699 else
1700 status.status = usb_redir_success;
1701 status.configuration = host->config ? host->config->bConfigurationValue:0;
1702 usbredirparser_send_configuration_status(host->parser, id, &status);
1703 FLUSH(host);
1704 }
1705
usbredirhost_set_alt_setting(void * priv,uint64_t id,struct usb_redir_set_alt_setting_header * set_alt_setting)1706 static void usbredirhost_set_alt_setting(void *priv, uint64_t id,
1707 struct usb_redir_set_alt_setting_header *set_alt_setting)
1708 {
1709 struct usbredirhost *host = priv;
1710 int i, j, r;
1711 struct usb_redir_alt_setting_status_header status = {
1712 .status = usb_redir_success,
1713 };
1714
1715 if (host->disconnected) {
1716 status.status = usb_redir_ioerror;
1717 status.alt = -1;
1718 goto exit_unknown_interface;
1719 }
1720
1721 i = usbredirhost_bInterfaceNumber_to_index(host,
1722 set_alt_setting->interface);
1723 if (i == -1) {
1724 status.status = usb_redir_inval;
1725 status.alt = -1;
1726 goto exit_unknown_interface;
1727 }
1728
1729 host->reset = 0;
1730
1731 usbredirhost_cancel_pending_urbs_on_interface(host, i);
1732
1733 r = libusb_set_interface_alt_setting(host->handle,
1734 set_alt_setting->interface,
1735 set_alt_setting->alt);
1736 if (r < 0) {
1737 ERROR("could not set alt setting for interface %d to %d: %s",
1738 set_alt_setting->interface, set_alt_setting->alt,
1739 libusb_error_name(r));
1740 status.status = libusb_status_or_error_to_redir_status(host, r);
1741 goto exit;
1742 }
1743
1744 /* The new alt setting may have lost endpoints compared to the old! ->
1745 Clear settings for all endpoints which used to be part of the intf. */
1746 for (j = 0; j < MAX_ENDPOINTS; j++) {
1747 if (host->endpoint[j].interface != set_alt_setting->interface)
1748 continue;
1749
1750 if ((j & 0x0f) == 0) {
1751 host->endpoint[j].type = usb_redir_type_control;
1752 } else {
1753 host->endpoint[j].type = usb_redir_type_invalid;
1754 }
1755 host->endpoint[j].interval = 0;
1756 host->endpoint[j].interface = 0;
1757 host->endpoint[j].max_packetsize = 0;
1758 }
1759
1760 host->alt_setting[i] = set_alt_setting->alt;
1761 usbredirhost_parse_interface(host, i);
1762 usbredirhost_send_interface_n_ep_info(host);
1763
1764 exit:
1765 status.alt = host->alt_setting[i];
1766 exit_unknown_interface:
1767 status.interface = set_alt_setting->interface;
1768 usbredirparser_send_alt_setting_status(host->parser, id, &status);
1769 FLUSH(host);
1770 }
1771
usbredirhost_get_alt_setting(void * priv,uint64_t id,struct usb_redir_get_alt_setting_header * get_alt_setting)1772 static void usbredirhost_get_alt_setting(void *priv, uint64_t id,
1773 struct usb_redir_get_alt_setting_header *get_alt_setting)
1774 {
1775 struct usbredirhost *host = priv;
1776 struct usb_redir_alt_setting_status_header status;
1777 int i;
1778
1779 if (host->disconnected) {
1780 status.status = usb_redir_ioerror;
1781 status.alt = -1;
1782 goto exit;
1783 }
1784
1785 i = usbredirhost_bInterfaceNumber_to_index(host,
1786 get_alt_setting->interface);
1787 if (i >= 0) {
1788 status.status = usb_redir_success;
1789 status.alt = host->alt_setting[i];
1790 } else {
1791 status.status = usb_redir_inval;
1792 status.alt = -1;
1793 }
1794
1795 exit:
1796 status.interface = get_alt_setting->interface;
1797 usbredirparser_send_alt_setting_status(host->parser, id, &status);
1798 FLUSH(host);
1799 }
1800
usbredirhost_start_iso_stream(void * priv,uint64_t id,struct usb_redir_start_iso_stream_header * start_iso_stream)1801 static void usbredirhost_start_iso_stream(void *priv, uint64_t id,
1802 struct usb_redir_start_iso_stream_header *start_iso_stream)
1803 {
1804 struct usbredirhost *host = priv;
1805 uint8_t ep = start_iso_stream->endpoint;
1806
1807 usbredirhost_alloc_stream(host, id, ep, usb_redir_type_iso,
1808 start_iso_stream->pkts_per_urb,
1809 host->endpoint[EP2I(ep)].max_packetsize,
1810 start_iso_stream->no_urbs, 1);
1811 FLUSH(host);
1812 }
1813
usbredirhost_stop_iso_stream(void * priv,uint64_t id,struct usb_redir_stop_iso_stream_header * stop_iso_stream)1814 static void usbredirhost_stop_iso_stream(void *priv, uint64_t id,
1815 struct usb_redir_stop_iso_stream_header *stop_iso_stream)
1816 {
1817 usbredirhost_stop_stream(priv, id, stop_iso_stream->endpoint);
1818 }
1819
usbredirhost_start_interrupt_receiving(void * priv,uint64_t id,struct usb_redir_start_interrupt_receiving_header * start_interrupt_receiving)1820 static void usbredirhost_start_interrupt_receiving(void *priv, uint64_t id,
1821 struct usb_redir_start_interrupt_receiving_header *start_interrupt_receiving)
1822 {
1823 struct usbredirhost *host = priv;
1824 uint8_t ep = start_interrupt_receiving->endpoint;
1825
1826 usbredirhost_alloc_stream(host, id, ep, usb_redir_type_interrupt, 1,
1827 host->endpoint[EP2I(ep)].max_packetsize,
1828 INTERRUPT_TRANSFER_COUNT, 1);
1829 FLUSH(host);
1830 }
1831
usbredirhost_stop_interrupt_receiving(void * priv,uint64_t id,struct usb_redir_stop_interrupt_receiving_header * stop_interrupt_receiving)1832 static void usbredirhost_stop_interrupt_receiving(void *priv, uint64_t id,
1833 struct usb_redir_stop_interrupt_receiving_header *stop_interrupt_receiving)
1834 {
1835 usbredirhost_stop_stream(priv, id, stop_interrupt_receiving->endpoint);
1836 }
1837
1838 #if LIBUSBX_API_VERSION >= 0x01000103
usbredirhost_ep_mask_to_eps(uint32_t ep_mask,unsigned char * eps)1839 static int usbredirhost_ep_mask_to_eps(uint32_t ep_mask, unsigned char *eps)
1840 {
1841 int i, j;
1842
1843 for (i = 0, j = 0; i < MAX_ENDPOINTS; i++) {
1844 if (ep_mask & (1 << i))
1845 eps[j++] = I2EP(i);
1846 }
1847
1848 return j;
1849 }
1850 #endif
1851
usbredirhost_alloc_bulk_streams(void * priv,uint64_t id,struct usb_redir_alloc_bulk_streams_header * alloc_bulk_streams)1852 static void usbredirhost_alloc_bulk_streams(void *priv, uint64_t id,
1853 struct usb_redir_alloc_bulk_streams_header *alloc_bulk_streams)
1854 {
1855 #if LIBUSBX_API_VERSION >= 0x01000103
1856 struct usbredirhost *host = priv;
1857 unsigned char eps[MAX_ENDPOINTS];
1858 int r, no_eps;
1859 struct usb_redir_bulk_streams_status_header streams_status = {
1860 .endpoints = alloc_bulk_streams->endpoints,
1861 .no_streams = alloc_bulk_streams->no_streams,
1862 .status = usb_redir_success,
1863 };
1864
1865 no_eps = usbredirhost_ep_mask_to_eps(alloc_bulk_streams->endpoints, eps);
1866 r = libusb_alloc_streams(host->handle, alloc_bulk_streams->no_streams,
1867 eps, no_eps);
1868 if (r < 0) {
1869 ERROR("could not alloc bulk streams: %s", libusb_error_name(r));
1870 streams_status.status =
1871 libusb_status_or_error_to_redir_status(host, r);
1872 } else if (r < alloc_bulk_streams->no_streams) {
1873 ERROR("tried to alloc %u bulk streams but got only %d",
1874 alloc_bulk_streams->no_streams, r);
1875 streams_status.status = usb_redir_ioerror;
1876 }
1877
1878 usbredirparser_send_bulk_streams_status(host->parser, id, &streams_status);
1879 FLUSH(host);
1880 #endif
1881 }
1882
usbredirhost_free_bulk_streams(void * priv,uint64_t id,struct usb_redir_free_bulk_streams_header * free_bulk_streams)1883 static void usbredirhost_free_bulk_streams(void *priv, uint64_t id,
1884 struct usb_redir_free_bulk_streams_header *free_bulk_streams)
1885 {
1886 #if LIBUSBX_API_VERSION >= 0x01000103
1887 struct usbredirhost *host = priv;
1888 unsigned char eps[MAX_ENDPOINTS];
1889 int r, no_eps;
1890 struct usb_redir_bulk_streams_status_header streams_status = {
1891 .endpoints = free_bulk_streams->endpoints,
1892 .no_streams = 0,
1893 .status = usb_redir_success,
1894 };
1895
1896 no_eps = usbredirhost_ep_mask_to_eps(free_bulk_streams->endpoints, eps);
1897 r = libusb_free_streams(host->handle, eps, no_eps);
1898 if (r < 0) {
1899 ERROR("could not free bulk streams: %s", libusb_error_name(r));
1900 streams_status.status =
1901 libusb_status_or_error_to_redir_status(host, r);
1902 }
1903
1904 usbredirparser_send_bulk_streams_status(host->parser, id, &streams_status);
1905 FLUSH(host);
1906 #endif
1907 }
1908
usbredirhost_filter_reject(void * priv)1909 static void usbredirhost_filter_reject(void *priv)
1910 {
1911 struct usbredirhost *host = priv;
1912
1913 if (host->disconnected)
1914 return;
1915
1916 INFO("device rejected");
1917 host->read_status = usbredirhost_read_device_rejected;
1918 }
1919
usbredirhost_filter_filter(void * priv,struct usbredirfilter_rule * rules,int rules_count)1920 static void usbredirhost_filter_filter(void *priv,
1921 struct usbredirfilter_rule *rules, int rules_count)
1922 {
1923 struct usbredirhost *host = priv;
1924
1925 free(host->filter_rules);
1926 host->filter_rules = rules;
1927 host->filter_rules_count = rules_count;
1928 }
1929
usbredirhost_device_disconnect_ack(void * priv)1930 static void usbredirhost_device_disconnect_ack(void *priv)
1931 {
1932 struct usbredirhost *host = priv;
1933
1934 if (!host->wait_disconnect) {
1935 ERROR("error received disconnect ack without sending a disconnect");
1936 return;
1937 }
1938
1939 host->wait_disconnect = 0;
1940
1941 if (host->connect_pending)
1942 usbredirhost_send_device_connect(host);
1943 }
1944
usbredirhost_start_bulk_receiving(void * priv,uint64_t id,struct usb_redir_start_bulk_receiving_header * start_bulk_receiving)1945 static void usbredirhost_start_bulk_receiving(void *priv, uint64_t id,
1946 struct usb_redir_start_bulk_receiving_header *start_bulk_receiving)
1947 {
1948 struct usbredirhost *host = priv;
1949 uint8_t ep = start_bulk_receiving->endpoint;
1950
1951 usbredirhost_alloc_stream(host, id, ep, usb_redir_type_bulk, 1,
1952 start_bulk_receiving->bytes_per_transfer,
1953 start_bulk_receiving->no_transfers, 1);
1954 FLUSH(host);
1955 }
1956
usbredirhost_stop_bulk_receiving(void * priv,uint64_t id,struct usb_redir_stop_bulk_receiving_header * stop_bulk_receiving)1957 static void usbredirhost_stop_bulk_receiving(void *priv, uint64_t id,
1958 struct usb_redir_stop_bulk_receiving_header *stop_bulk_receiving)
1959 {
1960 usbredirhost_stop_stream(priv, id, stop_bulk_receiving->endpoint);
1961 }
1962
1963 /**************************************************************************/
1964
usbredirhost_cancel_data_packet(void * priv,uint64_t id)1965 static void usbredirhost_cancel_data_packet(void *priv, uint64_t id)
1966 {
1967 struct usbredirhost *host = priv;
1968 struct usbredirtransfer *t;
1969 struct usb_redir_control_packet_header control_packet;
1970 struct usb_redir_bulk_packet_header bulk_packet;
1971 struct usb_redir_interrupt_packet_header interrupt_packet;
1972
1973 /*
1974 * This is a bit tricky, we are run from a parser read callback, while
1975 * at the same time the packet completion callback may run from another
1976 * thread.
1977 *
1978 * Since the completion handler will remove the transfer from our list,
1979 * send it back to the usb-guest (which we don't want to do twice),
1980 * and *free* the transfer, we must do the libusb_cancel_transfer()
1981 * with the lock held to ensure that it is not freed while we try to
1982 * cancel it.
1983 *
1984 * Doing this means libusb taking the transfer lock, while
1985 * we are holding our own lock, this is ok, since libusb releases the
1986 * transfer lock before calling the packet completion callback, so there
1987 * is no deadlock here.
1988 */
1989
1990 LOCK(host);
1991 for (t = host->transfers_head.next; t; t = t->next) {
1992 /* After cancellation the guest may re-use the id, so skip already
1993 cancelled packets */
1994 if (!t->cancelled && t->id == id) {
1995 break;
1996 }
1997 }
1998
1999 /*
2000 * Note not finding the transfer is not an error, the transfer may have
2001 * completed by the time we receive the cancel.
2002 */
2003 if (t) {
2004 t->cancelled = 1;
2005 libusb_cancel_transfer(t->transfer);
2006 switch(t->transfer->type) {
2007 case LIBUSB_TRANSFER_TYPE_CONTROL:
2008 control_packet = t->control_packet;
2009 control_packet.status = usb_redir_cancelled;
2010 control_packet.length = 0;
2011 usbredirparser_send_control_packet(host->parser, t->id,
2012 &control_packet, NULL, 0);
2013 DEBUG("cancelled control packet ep %02x id %"PRIu64,
2014 control_packet.endpoint, id);
2015 break;
2016 case LIBUSB_TRANSFER_TYPE_BULK:
2017 #if LIBUSBX_API_VERSION >= 0x01000103
2018 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
2019 #endif
2020 bulk_packet = t->bulk_packet;
2021 bulk_packet.status = usb_redir_cancelled;
2022 bulk_packet.length = 0;
2023 bulk_packet.length_high = 0;
2024 usbredirparser_send_bulk_packet(host->parser, t->id,
2025 &bulk_packet, NULL, 0);
2026 DEBUG("cancelled bulk packet ep %02x id %"PRIu64,
2027 bulk_packet.endpoint, id);
2028 break;
2029 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2030 interrupt_packet = t->interrupt_packet;
2031 interrupt_packet.status = usb_redir_cancelled;
2032 interrupt_packet.length = 0;
2033 usbredirparser_send_interrupt_packet(host->parser, t->id,
2034 &interrupt_packet, NULL, 0);
2035 DEBUG("cancelled interrupt packet ep %02x id %"PRIu64,
2036 interrupt_packet.endpoint, id);
2037 break;
2038 }
2039 } else
2040 DEBUG("cancel packet id %"PRIu64" not found", id);
2041 UNLOCK(host);
2042 FLUSH(host);
2043 }
2044
usbredirhost_control_packet_complete(struct libusb_transfer * libusb_transfer)2045 static void LIBUSB_CALL usbredirhost_control_packet_complete(
2046 struct libusb_transfer *libusb_transfer)
2047 {
2048 struct usb_redir_control_packet_header control_packet;
2049 struct usbredirtransfer *transfer = libusb_transfer->user_data;
2050 struct usbredirhost *host = transfer->host;
2051
2052 LOCK(host);
2053
2054 control_packet = transfer->control_packet;
2055 control_packet.status = libusb_status_or_error_to_redir_status(host,
2056 libusb_transfer->status);
2057 control_packet.length = libusb_transfer->actual_length;
2058
2059 DEBUG("control complete ep %02X status %d len %d id %"PRIu64,
2060 control_packet.endpoint, control_packet.status,
2061 control_packet.length, transfer->id);
2062
2063 if (!transfer->cancelled) {
2064 if (control_packet.endpoint & LIBUSB_ENDPOINT_IN) {
2065 usbredirhost_log_data(host, "ctrl data in:",
2066 libusb_transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE,
2067 libusb_transfer->actual_length);
2068 usbredirparser_send_control_packet(host->parser, transfer->id,
2069 &control_packet,
2070 libusb_transfer->buffer +
2071 LIBUSB_CONTROL_SETUP_SIZE,
2072 libusb_transfer->actual_length);
2073 } else {
2074 usbredirparser_send_control_packet(host->parser, transfer->id,
2075 &control_packet, NULL, 0);
2076 }
2077 }
2078
2079 usbredirhost_remove_and_free_transfer(transfer);
2080 UNLOCK(host);
2081 FLUSH(host);
2082 }
2083
usbredirhost_send_control_status(struct usbredirhost * host,uint64_t id,struct usb_redir_control_packet_header * control_packet,uint8_t status)2084 static void usbredirhost_send_control_status(struct usbredirhost *host,
2085 uint64_t id, struct usb_redir_control_packet_header *control_packet,
2086 uint8_t status)
2087 {
2088 control_packet->status = status;
2089 control_packet->length = 0;
2090 usbredirparser_send_control_packet(host->parser, id, control_packet,
2091 NULL, 0);
2092 }
2093
usbredirhost_control_packet(void * priv,uint64_t id,struct usb_redir_control_packet_header * control_packet,uint8_t * data,int data_len)2094 static void usbredirhost_control_packet(void *priv, uint64_t id,
2095 struct usb_redir_control_packet_header *control_packet,
2096 uint8_t *data, int data_len)
2097 {
2098 struct usbredirhost *host = priv;
2099 uint8_t ep = control_packet->endpoint;
2100 struct usbredirtransfer *transfer;
2101 unsigned char *buffer;
2102 int r;
2103
2104 DEBUG("control submit ep %02X len %d id %"PRIu64, ep,
2105 control_packet->length, id);
2106
2107 if (host->disconnected) {
2108 usbredirhost_send_control_status(host, id, control_packet,
2109 usb_redir_ioerror);
2110 usbredirparser_free_packet_data(host->parser, data);
2111 FLUSH(host);
2112 return;
2113 }
2114
2115 /* Verify endpoint type */
2116 if (host->endpoint[EP2I(ep)].type != usb_redir_type_control) {
2117 ERROR("error control packet on non control ep %02X", ep);
2118 usbredirhost_send_control_status(host, id, control_packet,
2119 usb_redir_inval);
2120 usbredirparser_free_packet_data(host->parser, data);
2121 FLUSH(host);
2122 return;
2123 }
2124
2125 host->reset = 0;
2126
2127 /* If it is a clear stall, we need to do an actual clear stall, rather then
2128 just forward the control packet, so that the usbhost usbstack knows
2129 the stall is cleared */
2130 if (control_packet->requesttype == LIBUSB_RECIPIENT_ENDPOINT &&
2131 control_packet->request == LIBUSB_REQUEST_CLEAR_FEATURE &&
2132 control_packet->value == 0x00 && data_len == 0) {
2133 r = libusb_clear_halt(host->handle, control_packet->index);
2134 r = libusb_status_or_error_to_redir_status(host, r);
2135 DEBUG("clear halt ep %02X status %d", control_packet->index, r);
2136 usbredirhost_send_control_status(host, id, control_packet, r);
2137 FLUSH(host);
2138 return;
2139 }
2140
2141 buffer = malloc(LIBUSB_CONTROL_SETUP_SIZE + control_packet->length);
2142 if (!buffer) {
2143 ERROR("out of memory allocating transfer buffer, dropping packet");
2144 usbredirparser_free_packet_data(host->parser, data);
2145 return;
2146 }
2147
2148 transfer = usbredirhost_alloc_transfer(host, 0);
2149 if (!transfer) {
2150 free(buffer);
2151 usbredirparser_free_packet_data(host->parser, data);
2152 return;
2153 }
2154
2155 libusb_fill_control_setup(buffer,
2156 control_packet->requesttype,
2157 control_packet->request,
2158 control_packet->value,
2159 control_packet->index,
2160 control_packet->length);
2161
2162 if (!(ep & LIBUSB_ENDPOINT_IN)) {
2163 usbredirhost_log_data(host, "ctrl data out:", data, data_len);
2164 memcpy(buffer + LIBUSB_CONTROL_SETUP_SIZE, data, data_len);
2165 usbredirparser_free_packet_data(host->parser, data);
2166 }
2167
2168 libusb_fill_control_transfer(transfer->transfer, host->handle, buffer,
2169 usbredirhost_control_packet_complete,
2170 transfer, CTRL_TIMEOUT);
2171 transfer->id = id;
2172 transfer->control_packet = *control_packet;
2173
2174 usbredirhost_add_transfer(host, transfer);
2175
2176 r = libusb_submit_transfer(transfer->transfer);
2177 if (r < 0) {
2178 ERROR("error submitting control transfer on ep %02X: %s",
2179 ep, libusb_error_name(r));
2180 transfer->transfer->actual_length = 0;
2181 transfer->transfer->status = r;
2182 usbredirhost_control_packet_complete(transfer->transfer);
2183 }
2184 }
2185
usbredirhost_bulk_packet_complete(struct libusb_transfer * libusb_transfer)2186 static void LIBUSB_CALL usbredirhost_bulk_packet_complete(
2187 struct libusb_transfer *libusb_transfer)
2188 {
2189 struct usb_redir_bulk_packet_header bulk_packet;
2190 struct usbredirtransfer *transfer = libusb_transfer->user_data;
2191 struct usbredirhost *host = transfer->host;
2192
2193 LOCK(host);
2194
2195 bulk_packet = transfer->bulk_packet;
2196 bulk_packet.status = libusb_status_or_error_to_redir_status(host,
2197 libusb_transfer->status);
2198 bulk_packet.length = libusb_transfer->actual_length;
2199 bulk_packet.length_high = libusb_transfer->actual_length >> 16;
2200
2201 DEBUG("bulk complete ep %02X status %d len %d id %"PRIu64,
2202 bulk_packet.endpoint, bulk_packet.status,
2203 libusb_transfer->actual_length, transfer->id);
2204
2205 if (!transfer->cancelled) {
2206 if (bulk_packet.endpoint & LIBUSB_ENDPOINT_IN) {
2207 usbredirhost_log_data(host, "bulk data in:",
2208 libusb_transfer->buffer,
2209 libusb_transfer->actual_length);
2210 usbredirparser_send_bulk_packet(host->parser, transfer->id,
2211 &bulk_packet,
2212 libusb_transfer->buffer,
2213 libusb_transfer->actual_length);
2214 } else {
2215 usbredirparser_send_bulk_packet(host->parser, transfer->id,
2216 &bulk_packet, NULL, 0);
2217 }
2218 }
2219
2220 usbredirhost_remove_and_free_transfer(transfer);
2221 UNLOCK(host);
2222 FLUSH(host);
2223 }
2224
usbredirhost_send_bulk_status(struct usbredirhost * host,uint64_t id,struct usb_redir_bulk_packet_header * bulk_packet,uint8_t status)2225 static void usbredirhost_send_bulk_status(struct usbredirhost *host,
2226 uint64_t id, struct usb_redir_bulk_packet_header *bulk_packet,
2227 uint8_t status)
2228 {
2229 bulk_packet->status = status;
2230 bulk_packet->length = 0;
2231 bulk_packet->length_high = 0;
2232 usbredirparser_send_bulk_packet(host->parser, id, bulk_packet, NULL, 0);
2233 }
2234
usbredirhost_bulk_packet(void * priv,uint64_t id,struct usb_redir_bulk_packet_header * bulk_packet,uint8_t * data,int data_len)2235 static void usbredirhost_bulk_packet(void *priv, uint64_t id,
2236 struct usb_redir_bulk_packet_header *bulk_packet,
2237 uint8_t *data, int data_len)
2238 {
2239 struct usbredirhost *host = priv;
2240 uint8_t ep = bulk_packet->endpoint;
2241 int len = (bulk_packet->length_high << 16) | bulk_packet->length;
2242 struct usbredirtransfer *transfer;
2243 int r;
2244
2245 DEBUG("bulk submit ep %02X len %d id %"PRIu64, ep, len, id);
2246
2247 if (host->disconnected) {
2248 usbredirhost_send_bulk_status(host, id, bulk_packet,
2249 usb_redir_ioerror);
2250 usbredirparser_free_packet_data(host->parser, data);
2251 FLUSH(host);
2252 return;
2253 }
2254
2255 if (host->endpoint[EP2I(ep)].type != usb_redir_type_bulk) {
2256 ERROR("error bulk packet on non bulk ep %02X", ep);
2257 usbredirhost_send_bulk_status(host, id, bulk_packet, usb_redir_inval);
2258 usbredirparser_free_packet_data(host->parser, data);
2259 FLUSH(host);
2260 return;
2261 }
2262
2263 if (ep & LIBUSB_ENDPOINT_IN) {
2264 data = malloc(len);
2265 if (!data) {
2266 ERROR("out of memory allocating bulk buffer, dropping packet");
2267 return;
2268 }
2269 } else {
2270 usbredirhost_log_data(host, "bulk data out:", data, data_len);
2271 /* Note no memcpy, we can re-use the data buffer the parser
2272 malloc-ed for us and expects us to free */
2273 }
2274
2275 transfer = usbredirhost_alloc_transfer(host, 0);
2276 if (!transfer) {
2277 free(data);
2278 return;
2279 }
2280
2281 host->reset = 0;
2282
2283 if (bulk_packet->stream_id) {
2284 #if LIBUSBX_API_VERSION >= 0x01000103
2285 libusb_fill_bulk_stream_transfer(transfer->transfer, host->handle, ep,
2286 bulk_packet->stream_id, data, len,
2287 usbredirhost_bulk_packet_complete,
2288 transfer, BULK_TIMEOUT);
2289 #else
2290 r = LIBUSB_ERROR_INVALID_PARAM;
2291 free(data);
2292 goto error;
2293 #endif
2294 } else {
2295 libusb_fill_bulk_transfer(transfer->transfer, host->handle, ep,
2296 data, len, usbredirhost_bulk_packet_complete,
2297 transfer, BULK_TIMEOUT);
2298 }
2299 transfer->id = id;
2300 transfer->bulk_packet = *bulk_packet;
2301
2302 usbredirhost_add_transfer(host, transfer);
2303
2304 r = libusb_submit_transfer(transfer->transfer);
2305 if (r < 0) {
2306 #if LIBUSBX_API_VERSION < 0x01000103
2307 error:
2308 #endif
2309 ERROR("error submitting bulk transfer on ep %02X: %s",
2310 ep, libusb_error_name(r));
2311 transfer->transfer->actual_length = 0;
2312 transfer->transfer->status = r;
2313 usbredirhost_bulk_packet_complete(transfer->transfer);
2314 }
2315 }
2316
usbredirhost_iso_packet(void * priv,uint64_t id,struct usb_redir_iso_packet_header * iso_packet,uint8_t * data,int data_len)2317 static void usbredirhost_iso_packet(void *priv, uint64_t id,
2318 struct usb_redir_iso_packet_header *iso_packet,
2319 uint8_t *data, int data_len)
2320 {
2321 struct usbredirhost *host = priv;
2322 uint8_t ep = iso_packet->endpoint;
2323 struct usbredirtransfer *transfer;
2324 int i, j, status = usb_redir_success;
2325
2326 LOCK(host);
2327
2328 if (host->disconnected) {
2329 status = usb_redir_ioerror;
2330 goto leave;
2331 }
2332
2333 if (host->endpoint[EP2I(ep)].type != usb_redir_type_iso) {
2334 ERROR("error received iso packet for non iso ep %02X", ep);
2335 status = usb_redir_inval;
2336 goto leave;
2337 }
2338
2339 if (host->endpoint[EP2I(ep)].transfer_count == 0) {
2340 ERROR("error received iso out packet for non started iso stream");
2341 status = usb_redir_inval;
2342 goto leave;
2343 }
2344
2345 if (data_len > host->endpoint[EP2I(ep)].max_packetsize) {
2346 ERROR("error received iso out packet is larger than wMaxPacketSize");
2347 status = usb_redir_inval;
2348 goto leave;
2349 }
2350
2351 if (host->endpoint[EP2I(ep)].drop_packets) {
2352 host->endpoint[EP2I(ep)].drop_packets--;
2353 goto leave;
2354 }
2355
2356 i = host->endpoint[EP2I(ep)].out_idx;
2357 transfer = host->endpoint[EP2I(ep)].transfer[i];
2358 j = transfer->packet_idx;
2359 if (j == SUBMITTED_IDX) {
2360 DEBUG("overflow of iso out queue on ep: %02X, dropping packet", ep);
2361 /* Since we're interupting the stream anyways, drop enough packets to
2362 get back to our target buffer size */
2363 host->endpoint[EP2I(ep)].drop_packets =
2364 (host->endpoint[EP2I(ep)].pkts_per_transfer *
2365 host->endpoint[EP2I(ep)].transfer_count) / 2;
2366 goto leave;
2367 }
2368
2369 /* Store the id of the first packet in the urb */
2370 if (j == 0) {
2371 transfer->id = id;
2372 }
2373 memcpy(libusb_get_iso_packet_buffer(transfer->transfer, j),
2374 data, data_len);
2375 transfer->transfer->iso_packet_desc[j].length = data_len;
2376 DEBUG("iso-in queue ep %02X urb %d pkt %d len %d id %"PRIu64,
2377 ep, i, j, data_len, transfer->id);
2378
2379 j++;
2380 transfer->packet_idx = j;
2381 if (j == host->endpoint[EP2I(ep)].pkts_per_transfer) {
2382 i = (i + 1) % host->endpoint[EP2I(ep)].transfer_count;
2383 host->endpoint[EP2I(ep)].out_idx = i;
2384 j = 0;
2385 }
2386
2387 if (host->endpoint[EP2I(ep)].stream_started) {
2388 if (transfer->packet_idx ==
2389 host->endpoint[EP2I(ep)].pkts_per_transfer) {
2390 usbredirhost_submit_stream_transfer_unlocked(host, transfer);
2391 }
2392 } else {
2393 /* We've not started the stream (submitted some transfers) yet,
2394 do so once we have half our buffers filled */
2395 int available = i * host->endpoint[EP2I(ep)].pkts_per_transfer + j;
2396 int needed = (host->endpoint[EP2I(ep)].pkts_per_transfer *
2397 host->endpoint[EP2I(ep)].transfer_count) / 2;
2398 if (available == needed) {
2399 DEBUG("iso-in starting stream on ep %02X", ep);
2400 usbredirhost_start_stream_unlocked(host, ep);
2401 }
2402 }
2403
2404 leave:
2405 UNLOCK(host);
2406 usbredirparser_free_packet_data(host->parser, data);
2407 if (status != usb_redir_success) {
2408 usbredirhost_send_stream_status(host, id, ep, status);
2409 }
2410 FLUSH(host);
2411 }
2412
usbredirhost_interrupt_out_packet_complete(struct libusb_transfer * libusb_transfer)2413 static void LIBUSB_CALL usbredirhost_interrupt_out_packet_complete(
2414 struct libusb_transfer *libusb_transfer)
2415 {
2416 struct usbredirtransfer *transfer = libusb_transfer->user_data;
2417 struct usb_redir_interrupt_packet_header interrupt_packet;
2418 struct usbredirhost *host = transfer->host;
2419
2420 LOCK(host);
2421
2422 interrupt_packet = transfer->interrupt_packet;
2423 interrupt_packet.status = libusb_status_or_error_to_redir_status(host,
2424 libusb_transfer->status);
2425 interrupt_packet.length = libusb_transfer->actual_length;
2426
2427 DEBUG("interrupt out complete ep %02X status %d len %d id %"PRIu64,
2428 interrupt_packet.endpoint, interrupt_packet.status,
2429 interrupt_packet.length, transfer->id);
2430
2431 if (!transfer->cancelled) {
2432 usbredirparser_send_interrupt_packet(host->parser, transfer->id,
2433 &interrupt_packet, NULL, 0);
2434 }
2435 usbredirhost_remove_and_free_transfer(transfer);
2436 UNLOCK(host);
2437 FLUSH(host);
2438 }
2439
usbredirhost_send_interrupt_status(struct usbredirhost * host,uint64_t id,struct usb_redir_interrupt_packet_header * interrupt_packet,uint8_t status)2440 static void usbredirhost_send_interrupt_status(struct usbredirhost *host,
2441 uint64_t id, struct usb_redir_interrupt_packet_header *interrupt_packet,
2442 uint8_t status)
2443 {
2444 interrupt_packet->status = status;
2445 interrupt_packet->length = 0;
2446 usbredirparser_send_interrupt_packet(host->parser, id, interrupt_packet,
2447 NULL, 0);
2448 }
2449
usbredirhost_interrupt_packet(void * priv,uint64_t id,struct usb_redir_interrupt_packet_header * interrupt_packet,uint8_t * data,int data_len)2450 static void usbredirhost_interrupt_packet(void *priv, uint64_t id,
2451 struct usb_redir_interrupt_packet_header *interrupt_packet,
2452 uint8_t *data, int data_len)
2453 {
2454 struct usbredirhost *host = priv;
2455 uint8_t ep = interrupt_packet->endpoint;
2456 struct usbredirtransfer *transfer;
2457 int r;
2458
2459 DEBUG("interrupt submit ep %02X len %d id %"PRIu64, ep,
2460 interrupt_packet->length, id);
2461
2462 if (host->disconnected) {
2463 usbredirhost_send_interrupt_status(host, id, interrupt_packet,
2464 usb_redir_ioerror);
2465 usbredirparser_free_packet_data(host->parser, data);
2466 FLUSH(host);
2467 return;
2468 }
2469
2470 if (host->endpoint[EP2I(ep)].type != usb_redir_type_interrupt) {
2471 ERROR("error received interrupt packet for non interrupt ep %02X", ep);
2472 usbredirhost_send_interrupt_status(host, id, interrupt_packet,
2473 usb_redir_inval);
2474 usbredirparser_free_packet_data(host->parser, data);
2475 FLUSH(host);
2476 return;
2477 }
2478
2479 if (data_len > host->endpoint[EP2I(ep)].max_packetsize) {
2480 ERROR("error received interrupt out packet is larger than wMaxPacketSize");
2481 usbredirhost_send_interrupt_status(host, id, interrupt_packet,
2482 usb_redir_inval);
2483 usbredirparser_free_packet_data(host->parser, data);
2484 FLUSH(host);
2485 return;
2486 }
2487
2488 usbredirhost_log_data(host, "interrupt data out:", data, data_len);
2489
2490 /* Note no memcpy, we can re-use the data buffer the parser
2491 malloc-ed for us and expects us to free */
2492
2493 transfer = usbredirhost_alloc_transfer(host, 0);
2494 if (!transfer) {
2495 usbredirparser_free_packet_data(host->parser, data);
2496 return;
2497 }
2498
2499 host->reset = 0;
2500
2501 libusb_fill_interrupt_transfer(transfer->transfer, host->handle, ep,
2502 data, data_len, usbredirhost_interrupt_out_packet_complete,
2503 transfer, INTERRUPT_TIMEOUT);
2504 transfer->id = id;
2505 transfer->interrupt_packet = *interrupt_packet;
2506
2507 usbredirhost_add_transfer(host, transfer);
2508
2509 r = libusb_submit_transfer(transfer->transfer);
2510 if (r < 0) {
2511 ERROR("error submitting interrupt transfer on ep %02X: %s",
2512 ep, libusb_error_name(r));
2513 transfer->transfer->actual_length = 0;
2514 transfer->transfer->status = r;
2515 usbredirhost_interrupt_out_packet_complete(transfer->transfer);
2516 }
2517 }
2518
2519 /**************************************************************************/
2520
usbredirhost_get_guest_filter(struct usbredirhost * host,const struct usbredirfilter_rule ** rules_ret,int * rules_count_ret)2521 void usbredirhost_get_guest_filter(struct usbredirhost *host,
2522 const struct usbredirfilter_rule **rules_ret, int *rules_count_ret)
2523 {
2524 *rules_ret = host->filter_rules;
2525 *rules_count_ret = host->filter_rules_count;
2526 }
2527
usbredirhost_check_device_filter(const struct usbredirfilter_rule * rules,int rules_count,libusb_device * dev,int flags)2528 int usbredirhost_check_device_filter(const struct usbredirfilter_rule *rules,
2529 int rules_count, libusb_device *dev, int flags)
2530 {
2531 int i, r, num_interfaces;
2532 struct libusb_device_descriptor dev_desc;
2533 struct libusb_config_descriptor *config = NULL;
2534 uint8_t interface_class[MAX_INTERFACES];
2535 uint8_t interface_subclass[MAX_INTERFACES];
2536 uint8_t interface_protocol[MAX_INTERFACES];
2537
2538 r = libusb_get_device_descriptor(dev, &dev_desc);
2539 if (r < 0) {
2540 if (r == LIBUSB_ERROR_NO_MEM)
2541 return -ENOMEM;
2542 return -EIO;
2543 }
2544
2545 r = libusb_get_active_config_descriptor(dev, &config);
2546 if (r < 0 && r != LIBUSB_ERROR_NOT_FOUND) {
2547 if (r == LIBUSB_ERROR_NO_MEM)
2548 return -ENOMEM;
2549 return -EIO;
2550 }
2551 if (config == NULL) {
2552 return usbredirfilter_check(rules, rules_count, dev_desc.bDeviceClass,
2553 dev_desc.bDeviceSubClass, dev_desc.bDeviceProtocol,
2554 NULL, NULL, NULL, 0,
2555 dev_desc.idVendor, dev_desc.idProduct,
2556 dev_desc.bcdDevice, flags);
2557 }
2558
2559 num_interfaces = config->bNumInterfaces;
2560 for (i = 0; i < num_interfaces; i++) {
2561 const struct libusb_interface_descriptor *intf_desc =
2562 config->interface[i].altsetting;
2563 interface_class[i] = intf_desc->bInterfaceClass;
2564 interface_subclass[i] = intf_desc->bInterfaceSubClass;
2565 interface_protocol[i] = intf_desc->bInterfaceProtocol;
2566 }
2567 libusb_free_config_descriptor(config);
2568
2569 return usbredirfilter_check(rules, rules_count, dev_desc.bDeviceClass,
2570 dev_desc.bDeviceSubClass, dev_desc.bDeviceProtocol,
2571 interface_class, interface_subclass, interface_protocol,
2572 num_interfaces, dev_desc.idVendor, dev_desc.idProduct,
2573 dev_desc.bcdDevice, flags);
2574 }
2575