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