]> git.proxmox.com Git - qemu.git/blob - hw/usb/redirect.c
6593d506b3b533baa750ad44f1c84830ed67c38b
[qemu.git] / hw / usb / redirect.c
1 /*
2 * USB redirector usb-guest
3 *
4 * Copyright (c) 2011-2012 Red Hat, Inc.
5 *
6 * Red Hat Authors:
7 * Hans de Goede <hdegoede@redhat.com>
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 */
27
28 #include "qemu-common.h"
29 #include "qemu-timer.h"
30 #include "monitor.h"
31 #include "sysemu.h"
32
33 #include <dirent.h>
34 #include <sys/ioctl.h>
35 #include <signal.h>
36 #include <usbredirparser.h>
37 #include <usbredirfilter.h>
38
39 #include "hw/usb.h"
40
41 #define MAX_ENDPOINTS 32
42 #define NO_INTERFACE_INFO 255 /* Valid interface_count always <= 32 */
43 #define EP2I(ep_address) (((ep_address & 0x80) >> 3) | (ep_address & 0x0f))
44 #define I2EP(i) (((i & 0x10) << 3) | (i & 0x0f))
45
46 typedef struct AsyncURB AsyncURB;
47 typedef struct USBRedirDevice USBRedirDevice;
48
49 /* Struct to hold buffered packets (iso or int input packets) */
50 struct buf_packet {
51 uint8_t *data;
52 int len;
53 int status;
54 QTAILQ_ENTRY(buf_packet)next;
55 };
56
57 struct endp_data {
58 uint8_t type;
59 uint8_t interval;
60 uint8_t interface; /* bInterfaceNumber this ep belongs to */
61 uint8_t iso_started;
62 uint8_t iso_error; /* For reporting iso errors to the HC */
63 uint8_t interrupt_started;
64 uint8_t interrupt_error;
65 uint8_t bufpq_prefilled;
66 uint8_t bufpq_dropping_packets;
67 QTAILQ_HEAD(, buf_packet) bufpq;
68 int bufpq_size;
69 int bufpq_target_size;
70 };
71
72 struct USBRedirDevice {
73 USBDevice dev;
74 /* Properties */
75 CharDriverState *cs;
76 uint8_t debug;
77 char *filter_str;
78 int32_t bootindex;
79 /* Data passed from chardev the fd_read cb to the usbredirparser read cb */
80 const uint8_t *read_buf;
81 int read_buf_size;
82 /* For async handling of close */
83 QEMUBH *chardev_close_bh;
84 /* To delay the usb attach in case of quick chardev close + open */
85 QEMUTimer *attach_timer;
86 int64_t next_attach_time;
87 struct usbredirparser *parser;
88 struct endp_data endpoint[MAX_ENDPOINTS];
89 uint32_t packet_id;
90 QTAILQ_HEAD(, AsyncURB) asyncq;
91 /* Data for device filtering */
92 struct usb_redir_device_connect_header device_info;
93 struct usb_redir_interface_info_header interface_info;
94 struct usbredirfilter_rule *filter_rules;
95 int filter_rules_count;
96 };
97
98 struct AsyncURB {
99 USBPacket *packet;
100 uint32_t packet_id;
101 QTAILQ_ENTRY(AsyncURB)next;
102 };
103
104 static void usbredir_hello(void *priv, struct usb_redir_hello_header *h);
105 static void usbredir_device_connect(void *priv,
106 struct usb_redir_device_connect_header *device_connect);
107 static void usbredir_device_disconnect(void *priv);
108 static void usbredir_interface_info(void *priv,
109 struct usb_redir_interface_info_header *interface_info);
110 static void usbredir_ep_info(void *priv,
111 struct usb_redir_ep_info_header *ep_info);
112 static void usbredir_configuration_status(void *priv, uint32_t id,
113 struct usb_redir_configuration_status_header *configuration_status);
114 static void usbredir_alt_setting_status(void *priv, uint32_t id,
115 struct usb_redir_alt_setting_status_header *alt_setting_status);
116 static void usbredir_iso_stream_status(void *priv, uint32_t id,
117 struct usb_redir_iso_stream_status_header *iso_stream_status);
118 static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
119 struct usb_redir_interrupt_receiving_status_header
120 *interrupt_receiving_status);
121 static void usbredir_bulk_streams_status(void *priv, uint32_t id,
122 struct usb_redir_bulk_streams_status_header *bulk_streams_status);
123 static void usbredir_control_packet(void *priv, uint32_t id,
124 struct usb_redir_control_packet_header *control_packet,
125 uint8_t *data, int data_len);
126 static void usbredir_bulk_packet(void *priv, uint32_t id,
127 struct usb_redir_bulk_packet_header *bulk_packet,
128 uint8_t *data, int data_len);
129 static void usbredir_iso_packet(void *priv, uint32_t id,
130 struct usb_redir_iso_packet_header *iso_packet,
131 uint8_t *data, int data_len);
132 static void usbredir_interrupt_packet(void *priv, uint32_t id,
133 struct usb_redir_interrupt_packet_header *interrupt_header,
134 uint8_t *data, int data_len);
135
136 static int usbredir_handle_status(USBRedirDevice *dev,
137 int status, int actual_len);
138
139 /*
140 * Logging stuff
141 */
142
143 #define ERROR(...) \
144 do { \
145 if (dev->debug >= usbredirparser_error) { \
146 error_report("usb-redir error: " __VA_ARGS__); \
147 } \
148 } while (0)
149 #define WARNING(...) \
150 do { \
151 if (dev->debug >= usbredirparser_warning) { \
152 error_report("usb-redir warning: " __VA_ARGS__); \
153 } \
154 } while (0)
155 #define INFO(...) \
156 do { \
157 if (dev->debug >= usbredirparser_info) { \
158 error_report("usb-redir: " __VA_ARGS__); \
159 } \
160 } while (0)
161 #define DPRINTF(...) \
162 do { \
163 if (dev->debug >= usbredirparser_debug) { \
164 error_report("usb-redir: " __VA_ARGS__); \
165 } \
166 } while (0)
167 #define DPRINTF2(...) \
168 do { \
169 if (dev->debug >= usbredirparser_debug_data) { \
170 error_report("usb-redir: " __VA_ARGS__); \
171 } \
172 } while (0)
173
174 static void usbredir_log(void *priv, int level, const char *msg)
175 {
176 USBRedirDevice *dev = priv;
177
178 if (dev->debug < level) {
179 return;
180 }
181
182 error_report("%s", msg);
183 }
184
185 static void usbredir_log_data(USBRedirDevice *dev, const char *desc,
186 const uint8_t *data, int len)
187 {
188 int i, j, n;
189
190 if (dev->debug < usbredirparser_debug_data) {
191 return;
192 }
193
194 for (i = 0; i < len; i += j) {
195 char buf[128];
196
197 n = sprintf(buf, "%s", desc);
198 for (j = 0; j < 8 && i + j < len; j++) {
199 n += sprintf(buf + n, " %02X", data[i + j]);
200 }
201 error_report("%s", buf);
202 }
203 }
204
205 /*
206 * usbredirparser io functions
207 */
208
209 static int usbredir_read(void *priv, uint8_t *data, int count)
210 {
211 USBRedirDevice *dev = priv;
212
213 if (dev->read_buf_size < count) {
214 count = dev->read_buf_size;
215 }
216
217 memcpy(data, dev->read_buf, count);
218
219 dev->read_buf_size -= count;
220 if (dev->read_buf_size) {
221 dev->read_buf += count;
222 } else {
223 dev->read_buf = NULL;
224 }
225
226 return count;
227 }
228
229 static int usbredir_write(void *priv, uint8_t *data, int count)
230 {
231 USBRedirDevice *dev = priv;
232
233 if (!dev->cs->opened) {
234 return 0;
235 }
236
237 return qemu_chr_fe_write(dev->cs, data, count);
238 }
239
240 /*
241 * Async and buffered packets helpers
242 */
243
244 static AsyncURB *async_alloc(USBRedirDevice *dev, USBPacket *p)
245 {
246 AsyncURB *aurb = (AsyncURB *) g_malloc0(sizeof(AsyncURB));
247 aurb->packet = p;
248 aurb->packet_id = dev->packet_id;
249 QTAILQ_INSERT_TAIL(&dev->asyncq, aurb, next);
250 dev->packet_id++;
251
252 return aurb;
253 }
254
255 static void async_free(USBRedirDevice *dev, AsyncURB *aurb)
256 {
257 QTAILQ_REMOVE(&dev->asyncq, aurb, next);
258 g_free(aurb);
259 }
260
261 static AsyncURB *async_find(USBRedirDevice *dev, uint32_t packet_id)
262 {
263 AsyncURB *aurb;
264
265 QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
266 if (aurb->packet_id == packet_id) {
267 return aurb;
268 }
269 }
270 DPRINTF("could not find async urb for packet_id %u\n", packet_id);
271 return NULL;
272 }
273
274 static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p)
275 {
276 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
277 AsyncURB *aurb;
278
279 QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
280 if (p != aurb->packet) {
281 continue;
282 }
283
284 DPRINTF("async cancel id %u\n", aurb->packet_id);
285 usbredirparser_send_cancel_data_packet(dev->parser, aurb->packet_id);
286 usbredirparser_do_write(dev->parser);
287
288 /* Mark it as dead */
289 aurb->packet = NULL;
290 break;
291 }
292 }
293
294 static void bufp_alloc(USBRedirDevice *dev,
295 uint8_t *data, int len, int status, uint8_t ep)
296 {
297 struct buf_packet *bufp;
298
299 if (!dev->endpoint[EP2I(ep)].bufpq_dropping_packets &&
300 dev->endpoint[EP2I(ep)].bufpq_size >
301 2 * dev->endpoint[EP2I(ep)].bufpq_target_size) {
302 DPRINTF("bufpq overflow, dropping packets ep %02X\n", ep);
303 dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 1;
304 }
305 /* Since we're interupting the stream anyways, drop enough packets to get
306 back to our target buffer size */
307 if (dev->endpoint[EP2I(ep)].bufpq_dropping_packets) {
308 if (dev->endpoint[EP2I(ep)].bufpq_size >
309 dev->endpoint[EP2I(ep)].bufpq_target_size) {
310 free(data);
311 return;
312 }
313 dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
314 }
315
316 bufp = g_malloc(sizeof(struct buf_packet));
317 bufp->data = data;
318 bufp->len = len;
319 bufp->status = status;
320 QTAILQ_INSERT_TAIL(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
321 dev->endpoint[EP2I(ep)].bufpq_size++;
322 }
323
324 static void bufp_free(USBRedirDevice *dev, struct buf_packet *bufp,
325 uint8_t ep)
326 {
327 QTAILQ_REMOVE(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
328 dev->endpoint[EP2I(ep)].bufpq_size--;
329 free(bufp->data);
330 g_free(bufp);
331 }
332
333 static void usbredir_free_bufpq(USBRedirDevice *dev, uint8_t ep)
334 {
335 struct buf_packet *buf, *buf_next;
336
337 QTAILQ_FOREACH_SAFE(buf, &dev->endpoint[EP2I(ep)].bufpq, next, buf_next) {
338 bufp_free(dev, buf, ep);
339 }
340 }
341
342 /*
343 * USBDevice callbacks
344 */
345
346 static void usbredir_handle_reset(USBDevice *udev)
347 {
348 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
349
350 DPRINTF("reset device\n");
351 usbredirparser_send_reset(dev->parser);
352 usbredirparser_do_write(dev->parser);
353 }
354
355 static int usbredir_handle_iso_data(USBRedirDevice *dev, USBPacket *p,
356 uint8_t ep)
357 {
358 int status, len;
359 if (!dev->endpoint[EP2I(ep)].iso_started &&
360 !dev->endpoint[EP2I(ep)].iso_error) {
361 struct usb_redir_start_iso_stream_header start_iso = {
362 .endpoint = ep,
363 };
364 int pkts_per_sec;
365
366 if (dev->dev.speed == USB_SPEED_HIGH) {
367 pkts_per_sec = 8000 / dev->endpoint[EP2I(ep)].interval;
368 } else {
369 pkts_per_sec = 1000 / dev->endpoint[EP2I(ep)].interval;
370 }
371 /* Testing has shown that we need circa 60 ms buffer */
372 dev->endpoint[EP2I(ep)].bufpq_target_size = (pkts_per_sec * 60) / 1000;
373
374 /* Aim for approx 100 interrupts / second on the client to
375 balance latency and interrupt load */
376 start_iso.pkts_per_urb = pkts_per_sec / 100;
377 if (start_iso.pkts_per_urb < 1) {
378 start_iso.pkts_per_urb = 1;
379 } else if (start_iso.pkts_per_urb > 32) {
380 start_iso.pkts_per_urb = 32;
381 }
382
383 start_iso.no_urbs = (dev->endpoint[EP2I(ep)].bufpq_target_size +
384 start_iso.pkts_per_urb - 1) /
385 start_iso.pkts_per_urb;
386 /* Output endpoints pre-fill only 1/2 of the packets, keeping the rest
387 as overflow buffer. Also see the usbredir protocol documentation */
388 if (!(ep & USB_DIR_IN)) {
389 start_iso.no_urbs *= 2;
390 }
391 if (start_iso.no_urbs > 16) {
392 start_iso.no_urbs = 16;
393 }
394
395 /* No id, we look at the ep when receiving a status back */
396 usbredirparser_send_start_iso_stream(dev->parser, 0, &start_iso);
397 usbredirparser_do_write(dev->parser);
398 DPRINTF("iso stream started pkts/sec %d pkts/urb %d urbs %d ep %02X\n",
399 pkts_per_sec, start_iso.pkts_per_urb, start_iso.no_urbs, ep);
400 dev->endpoint[EP2I(ep)].iso_started = 1;
401 dev->endpoint[EP2I(ep)].bufpq_prefilled = 0;
402 dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
403 }
404
405 if (ep & USB_DIR_IN) {
406 struct buf_packet *isop;
407
408 if (dev->endpoint[EP2I(ep)].iso_started &&
409 !dev->endpoint[EP2I(ep)].bufpq_prefilled) {
410 if (dev->endpoint[EP2I(ep)].bufpq_size <
411 dev->endpoint[EP2I(ep)].bufpq_target_size) {
412 return usbredir_handle_status(dev, 0, 0);
413 }
414 dev->endpoint[EP2I(ep)].bufpq_prefilled = 1;
415 }
416
417 isop = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
418 if (isop == NULL) {
419 DPRINTF("iso-token-in ep %02X, no isop, iso_error: %d\n",
420 ep, dev->endpoint[EP2I(ep)].iso_error);
421 /* Re-fill the buffer */
422 dev->endpoint[EP2I(ep)].bufpq_prefilled = 0;
423 /* Check iso_error for stream errors, otherwise its an underrun */
424 status = dev->endpoint[EP2I(ep)].iso_error;
425 dev->endpoint[EP2I(ep)].iso_error = 0;
426 return status ? USB_RET_IOERROR : 0;
427 }
428 DPRINTF2("iso-token-in ep %02X status %d len %d queue-size: %d\n", ep,
429 isop->status, isop->len, dev->endpoint[EP2I(ep)].bufpq_size);
430
431 status = isop->status;
432 if (status != usb_redir_success) {
433 bufp_free(dev, isop, ep);
434 return USB_RET_IOERROR;
435 }
436
437 len = isop->len;
438 if (len > p->iov.size) {
439 ERROR("received iso data is larger then packet ep %02X (%d > %d)\n",
440 ep, len, (int)p->iov.size);
441 bufp_free(dev, isop, ep);
442 return USB_RET_BABBLE;
443 }
444 usb_packet_copy(p, isop->data, len);
445 bufp_free(dev, isop, ep);
446 return len;
447 } else {
448 /* If the stream was not started because of a pending error don't
449 send the packet to the usb-host */
450 if (dev->endpoint[EP2I(ep)].iso_started) {
451 struct usb_redir_iso_packet_header iso_packet = {
452 .endpoint = ep,
453 .length = p->iov.size
454 };
455 uint8_t buf[p->iov.size];
456 /* No id, we look at the ep when receiving a status back */
457 usb_packet_copy(p, buf, p->iov.size);
458 usbredirparser_send_iso_packet(dev->parser, 0, &iso_packet,
459 buf, p->iov.size);
460 usbredirparser_do_write(dev->parser);
461 }
462 status = dev->endpoint[EP2I(ep)].iso_error;
463 dev->endpoint[EP2I(ep)].iso_error = 0;
464 DPRINTF2("iso-token-out ep %02X status %d len %zd\n", ep, status,
465 p->iov.size);
466 return usbredir_handle_status(dev, status, p->iov.size);
467 }
468 }
469
470 static void usbredir_stop_iso_stream(USBRedirDevice *dev, uint8_t ep)
471 {
472 struct usb_redir_stop_iso_stream_header stop_iso_stream = {
473 .endpoint = ep
474 };
475 if (dev->endpoint[EP2I(ep)].iso_started) {
476 usbredirparser_send_stop_iso_stream(dev->parser, 0, &stop_iso_stream);
477 DPRINTF("iso stream stopped ep %02X\n", ep);
478 dev->endpoint[EP2I(ep)].iso_started = 0;
479 }
480 dev->endpoint[EP2I(ep)].iso_error = 0;
481 usbredir_free_bufpq(dev, ep);
482 }
483
484 static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
485 uint8_t ep)
486 {
487 AsyncURB *aurb = async_alloc(dev, p);
488 struct usb_redir_bulk_packet_header bulk_packet;
489
490 DPRINTF("bulk-out ep %02X len %zd id %u\n", ep,
491 p->iov.size, aurb->packet_id);
492
493 bulk_packet.endpoint = ep;
494 bulk_packet.length = p->iov.size;
495 bulk_packet.stream_id = 0;
496
497 if (ep & USB_DIR_IN) {
498 usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
499 &bulk_packet, NULL, 0);
500 } else {
501 uint8_t buf[p->iov.size];
502 usb_packet_copy(p, buf, p->iov.size);
503 usbredir_log_data(dev, "bulk data out:", buf, p->iov.size);
504 usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
505 &bulk_packet, buf, p->iov.size);
506 }
507 usbredirparser_do_write(dev->parser);
508 return USB_RET_ASYNC;
509 }
510
511 static int usbredir_handle_interrupt_data(USBRedirDevice *dev,
512 USBPacket *p, uint8_t ep)
513 {
514 if (ep & USB_DIR_IN) {
515 /* Input interrupt endpoint, buffered packet input */
516 struct buf_packet *intp;
517 int status, len;
518
519 if (!dev->endpoint[EP2I(ep)].interrupt_started &&
520 !dev->endpoint[EP2I(ep)].interrupt_error) {
521 struct usb_redir_start_interrupt_receiving_header start_int = {
522 .endpoint = ep,
523 };
524 /* No id, we look at the ep when receiving a status back */
525 usbredirparser_send_start_interrupt_receiving(dev->parser, 0,
526 &start_int);
527 usbredirparser_do_write(dev->parser);
528 DPRINTF("interrupt recv started ep %02X\n", ep);
529 dev->endpoint[EP2I(ep)].interrupt_started = 1;
530 /* We don't really want to drop interrupt packets ever, but
531 having some upper limit to how much we buffer is good. */
532 dev->endpoint[EP2I(ep)].bufpq_target_size = 1000;
533 dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
534 }
535
536 intp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
537 if (intp == NULL) {
538 DPRINTF2("interrupt-token-in ep %02X, no intp\n", ep);
539 /* Check interrupt_error for stream errors */
540 status = dev->endpoint[EP2I(ep)].interrupt_error;
541 dev->endpoint[EP2I(ep)].interrupt_error = 0;
542 if (status) {
543 return usbredir_handle_status(dev, status, 0);
544 }
545 return USB_RET_NAK;
546 }
547 DPRINTF("interrupt-token-in ep %02X status %d len %d\n", ep,
548 intp->status, intp->len);
549
550 status = intp->status;
551 if (status != usb_redir_success) {
552 bufp_free(dev, intp, ep);
553 return usbredir_handle_status(dev, status, 0);
554 }
555
556 len = intp->len;
557 if (len > p->iov.size) {
558 ERROR("received int data is larger then packet ep %02X\n", ep);
559 bufp_free(dev, intp, ep);
560 return USB_RET_BABBLE;
561 }
562 usb_packet_copy(p, intp->data, len);
563 bufp_free(dev, intp, ep);
564 return len;
565 } else {
566 /* Output interrupt endpoint, normal async operation */
567 AsyncURB *aurb = async_alloc(dev, p);
568 struct usb_redir_interrupt_packet_header interrupt_packet;
569 uint8_t buf[p->iov.size];
570
571 DPRINTF("interrupt-out ep %02X len %zd id %u\n", ep, p->iov.size,
572 aurb->packet_id);
573
574 interrupt_packet.endpoint = ep;
575 interrupt_packet.length = p->iov.size;
576
577 usb_packet_copy(p, buf, p->iov.size);
578 usbredir_log_data(dev, "interrupt data out:", buf, p->iov.size);
579 usbredirparser_send_interrupt_packet(dev->parser, aurb->packet_id,
580 &interrupt_packet, buf, p->iov.size);
581 usbredirparser_do_write(dev->parser);
582 return USB_RET_ASYNC;
583 }
584 }
585
586 static void usbredir_stop_interrupt_receiving(USBRedirDevice *dev,
587 uint8_t ep)
588 {
589 struct usb_redir_stop_interrupt_receiving_header stop_interrupt_recv = {
590 .endpoint = ep
591 };
592 if (dev->endpoint[EP2I(ep)].interrupt_started) {
593 usbredirparser_send_stop_interrupt_receiving(dev->parser, 0,
594 &stop_interrupt_recv);
595 DPRINTF("interrupt recv stopped ep %02X\n", ep);
596 dev->endpoint[EP2I(ep)].interrupt_started = 0;
597 }
598 dev->endpoint[EP2I(ep)].interrupt_error = 0;
599 usbredir_free_bufpq(dev, ep);
600 }
601
602 static int usbredir_handle_data(USBDevice *udev, USBPacket *p)
603 {
604 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
605 uint8_t ep;
606
607 ep = p->ep->nr;
608 if (p->pid == USB_TOKEN_IN) {
609 ep |= USB_DIR_IN;
610 }
611
612 switch (dev->endpoint[EP2I(ep)].type) {
613 case USB_ENDPOINT_XFER_CONTROL:
614 ERROR("handle_data called for control transfer on ep %02X\n", ep);
615 return USB_RET_NAK;
616 case USB_ENDPOINT_XFER_ISOC:
617 return usbredir_handle_iso_data(dev, p, ep);
618 case USB_ENDPOINT_XFER_BULK:
619 return usbredir_handle_bulk_data(dev, p, ep);
620 case USB_ENDPOINT_XFER_INT:
621 return usbredir_handle_interrupt_data(dev, p, ep);
622 default:
623 ERROR("handle_data ep %02X has unknown type %d\n", ep,
624 dev->endpoint[EP2I(ep)].type);
625 return USB_RET_NAK;
626 }
627 }
628
629 static int usbredir_set_config(USBRedirDevice *dev, USBPacket *p,
630 int config)
631 {
632 struct usb_redir_set_configuration_header set_config;
633 AsyncURB *aurb = async_alloc(dev, p);
634 int i;
635
636 DPRINTF("set config %d id %u\n", config, aurb->packet_id);
637
638 for (i = 0; i < MAX_ENDPOINTS; i++) {
639 switch (dev->endpoint[i].type) {
640 case USB_ENDPOINT_XFER_ISOC:
641 usbredir_stop_iso_stream(dev, I2EP(i));
642 break;
643 case USB_ENDPOINT_XFER_INT:
644 if (i & 0x10) {
645 usbredir_stop_interrupt_receiving(dev, I2EP(i));
646 }
647 break;
648 }
649 usbredir_free_bufpq(dev, I2EP(i));
650 }
651
652 set_config.configuration = config;
653 usbredirparser_send_set_configuration(dev->parser, aurb->packet_id,
654 &set_config);
655 usbredirparser_do_write(dev->parser);
656 return USB_RET_ASYNC;
657 }
658
659 static int usbredir_get_config(USBRedirDevice *dev, USBPacket *p)
660 {
661 AsyncURB *aurb = async_alloc(dev, p);
662
663 DPRINTF("get config id %u\n", aurb->packet_id);
664
665 usbredirparser_send_get_configuration(dev->parser, aurb->packet_id);
666 usbredirparser_do_write(dev->parser);
667 return USB_RET_ASYNC;
668 }
669
670 static int usbredir_set_interface(USBRedirDevice *dev, USBPacket *p,
671 int interface, int alt)
672 {
673 struct usb_redir_set_alt_setting_header set_alt;
674 AsyncURB *aurb = async_alloc(dev, p);
675 int i;
676
677 DPRINTF("set interface %d alt %d id %u\n", interface, alt,
678 aurb->packet_id);
679
680 for (i = 0; i < MAX_ENDPOINTS; i++) {
681 if (dev->endpoint[i].interface == interface) {
682 switch (dev->endpoint[i].type) {
683 case USB_ENDPOINT_XFER_ISOC:
684 usbredir_stop_iso_stream(dev, I2EP(i));
685 break;
686 case USB_ENDPOINT_XFER_INT:
687 if (i & 0x10) {
688 usbredir_stop_interrupt_receiving(dev, I2EP(i));
689 }
690 break;
691 }
692 usbredir_free_bufpq(dev, I2EP(i));
693 }
694 }
695
696 set_alt.interface = interface;
697 set_alt.alt = alt;
698 usbredirparser_send_set_alt_setting(dev->parser, aurb->packet_id,
699 &set_alt);
700 usbredirparser_do_write(dev->parser);
701 return USB_RET_ASYNC;
702 }
703
704 static int usbredir_get_interface(USBRedirDevice *dev, USBPacket *p,
705 int interface)
706 {
707 struct usb_redir_get_alt_setting_header get_alt;
708 AsyncURB *aurb = async_alloc(dev, p);
709
710 DPRINTF("get interface %d id %u\n", interface, aurb->packet_id);
711
712 get_alt.interface = interface;
713 usbredirparser_send_get_alt_setting(dev->parser, aurb->packet_id,
714 &get_alt);
715 usbredirparser_do_write(dev->parser);
716 return USB_RET_ASYNC;
717 }
718
719 static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
720 int request, int value, int index, int length, uint8_t *data)
721 {
722 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
723 struct usb_redir_control_packet_header control_packet;
724 AsyncURB *aurb;
725
726 /* Special cases for certain standard device requests */
727 switch (request) {
728 case DeviceOutRequest | USB_REQ_SET_ADDRESS:
729 DPRINTF("set address %d\n", value);
730 dev->dev.addr = value;
731 return 0;
732 case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
733 return usbredir_set_config(dev, p, value & 0xff);
734 case DeviceRequest | USB_REQ_GET_CONFIGURATION:
735 return usbredir_get_config(dev, p);
736 case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
737 return usbredir_set_interface(dev, p, index, value);
738 case InterfaceRequest | USB_REQ_GET_INTERFACE:
739 return usbredir_get_interface(dev, p, index);
740 }
741
742 /* "Normal" ctrl requests */
743 aurb = async_alloc(dev, p);
744
745 /* Note request is (bRequestType << 8) | bRequest */
746 DPRINTF("ctrl-out type 0x%x req 0x%x val 0x%x index %d len %d id %u\n",
747 request >> 8, request & 0xff, value, index, length,
748 aurb->packet_id);
749
750 control_packet.request = request & 0xFF;
751 control_packet.requesttype = request >> 8;
752 control_packet.endpoint = control_packet.requesttype & USB_DIR_IN;
753 control_packet.value = value;
754 control_packet.index = index;
755 control_packet.length = length;
756
757 if (control_packet.requesttype & USB_DIR_IN) {
758 usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
759 &control_packet, NULL, 0);
760 } else {
761 usbredir_log_data(dev, "ctrl data out:", data, length);
762 usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
763 &control_packet, data, length);
764 }
765 usbredirparser_do_write(dev->parser);
766 return USB_RET_ASYNC;
767 }
768
769 /*
770 * Close events can be triggered by usbredirparser_do_write which gets called
771 * from within the USBDevice data / control packet callbacks and doing a
772 * usb_detach from within these callbacks is not a good idea.
773 *
774 * So we use a bh handler to take care of close events.
775 */
776 static void usbredir_chardev_close_bh(void *opaque)
777 {
778 USBRedirDevice *dev = opaque;
779
780 usbredir_device_disconnect(dev);
781
782 if (dev->parser) {
783 usbredirparser_destroy(dev->parser);
784 dev->parser = NULL;
785 }
786 }
787
788 static void usbredir_chardev_open(USBRedirDevice *dev)
789 {
790 uint32_t caps[USB_REDIR_CAPS_SIZE] = { 0, };
791 char version[32];
792
793 /* Make sure any pending closes are handled (no-op if none pending) */
794 usbredir_chardev_close_bh(dev);
795 qemu_bh_cancel(dev->chardev_close_bh);
796
797 strcpy(version, "qemu usb-redir guest ");
798 pstrcat(version, sizeof(version), qemu_get_version());
799
800 dev->parser = qemu_oom_check(usbredirparser_create());
801 dev->parser->priv = dev;
802 dev->parser->log_func = usbredir_log;
803 dev->parser->read_func = usbredir_read;
804 dev->parser->write_func = usbredir_write;
805 dev->parser->hello_func = usbredir_hello;
806 dev->parser->device_connect_func = usbredir_device_connect;
807 dev->parser->device_disconnect_func = usbredir_device_disconnect;
808 dev->parser->interface_info_func = usbredir_interface_info;
809 dev->parser->ep_info_func = usbredir_ep_info;
810 dev->parser->configuration_status_func = usbredir_configuration_status;
811 dev->parser->alt_setting_status_func = usbredir_alt_setting_status;
812 dev->parser->iso_stream_status_func = usbredir_iso_stream_status;
813 dev->parser->interrupt_receiving_status_func =
814 usbredir_interrupt_receiving_status;
815 dev->parser->bulk_streams_status_func = usbredir_bulk_streams_status;
816 dev->parser->control_packet_func = usbredir_control_packet;
817 dev->parser->bulk_packet_func = usbredir_bulk_packet;
818 dev->parser->iso_packet_func = usbredir_iso_packet;
819 dev->parser->interrupt_packet_func = usbredir_interrupt_packet;
820 dev->read_buf = NULL;
821 dev->read_buf_size = 0;
822
823 usbredirparser_caps_set_cap(caps, usb_redir_cap_connect_device_version);
824 usbredirparser_caps_set_cap(caps, usb_redir_cap_filter);
825 usbredirparser_init(dev->parser, version, caps, USB_REDIR_CAPS_SIZE, 0);
826 usbredirparser_do_write(dev->parser);
827 }
828
829 static void usbredir_do_attach(void *opaque)
830 {
831 USBRedirDevice *dev = opaque;
832
833 if (usb_device_attach(&dev->dev) != 0) {
834 usbredir_device_disconnect(dev);
835 if (usbredirparser_peer_has_cap(dev->parser, usb_redir_cap_filter)) {
836 usbredirparser_send_filter_reject(dev->parser);
837 usbredirparser_do_write(dev->parser);
838 }
839 }
840 }
841
842 /*
843 * chardev callbacks
844 */
845
846 static int usbredir_chardev_can_read(void *opaque)
847 {
848 USBRedirDevice *dev = opaque;
849
850 if (!dev->parser) {
851 WARNING("chardev_can_read called on non open chardev!\n");
852 return 0;
853 }
854
855 /* usbredir_parser_do_read will consume *all* data we give it */
856 return 1024 * 1024;
857 }
858
859 static void usbredir_chardev_read(void *opaque, const uint8_t *buf, int size)
860 {
861 USBRedirDevice *dev = opaque;
862
863 /* No recursion allowed! */
864 assert(dev->read_buf == NULL);
865
866 dev->read_buf = buf;
867 dev->read_buf_size = size;
868
869 usbredirparser_do_read(dev->parser);
870 /* Send any acks, etc. which may be queued now */
871 usbredirparser_do_write(dev->parser);
872 }
873
874 static void usbredir_chardev_event(void *opaque, int event)
875 {
876 USBRedirDevice *dev = opaque;
877
878 switch (event) {
879 case CHR_EVENT_OPENED:
880 usbredir_chardev_open(dev);
881 break;
882 case CHR_EVENT_CLOSED:
883 qemu_bh_schedule(dev->chardev_close_bh);
884 break;
885 }
886 }
887
888 /*
889 * init + destroy
890 */
891
892 static int usbredir_initfn(USBDevice *udev)
893 {
894 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
895 int i;
896
897 if (dev->cs == NULL) {
898 qerror_report(QERR_MISSING_PARAMETER, "chardev");
899 return -1;
900 }
901
902 if (dev->filter_str) {
903 i = usbredirfilter_string_to_rules(dev->filter_str, ":", "|",
904 &dev->filter_rules,
905 &dev->filter_rules_count);
906 if (i) {
907 qerror_report(QERR_INVALID_PARAMETER_VALUE, "filter",
908 "a usb device filter string");
909 return -1;
910 }
911 }
912
913 dev->chardev_close_bh = qemu_bh_new(usbredir_chardev_close_bh, dev);
914 dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
915
916 QTAILQ_INIT(&dev->asyncq);
917 for (i = 0; i < MAX_ENDPOINTS; i++) {
918 QTAILQ_INIT(&dev->endpoint[i].bufpq);
919 }
920
921 /* We'll do the attach once we receive the speed from the usb-host */
922 udev->auto_attach = 0;
923
924 /* Let the backend know we are ready */
925 qemu_chr_fe_open(dev->cs);
926 qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read,
927 usbredir_chardev_read, usbredir_chardev_event, dev);
928
929 add_boot_device_path(dev->bootindex, &udev->qdev, NULL);
930 return 0;
931 }
932
933 static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
934 {
935 AsyncURB *aurb, *next_aurb;
936 int i;
937
938 QTAILQ_FOREACH_SAFE(aurb, &dev->asyncq, next, next_aurb) {
939 async_free(dev, aurb);
940 }
941 for (i = 0; i < MAX_ENDPOINTS; i++) {
942 usbredir_free_bufpq(dev, I2EP(i));
943 }
944 }
945
946 static void usbredir_handle_destroy(USBDevice *udev)
947 {
948 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
949
950 qemu_chr_fe_close(dev->cs);
951 qemu_chr_delete(dev->cs);
952 /* Note must be done after qemu_chr_close, as that causes a close event */
953 qemu_bh_delete(dev->chardev_close_bh);
954
955 qemu_del_timer(dev->attach_timer);
956 qemu_free_timer(dev->attach_timer);
957
958 usbredir_cleanup_device_queues(dev);
959
960 if (dev->parser) {
961 usbredirparser_destroy(dev->parser);
962 }
963
964 free(dev->filter_rules);
965 }
966
967 static int usbredir_check_filter(USBRedirDevice *dev)
968 {
969 if (dev->interface_info.interface_count == NO_INTERFACE_INFO) {
970 ERROR("No interface info for device\n");
971 goto error;
972 }
973
974 if (dev->filter_rules) {
975 if (!usbredirparser_peer_has_cap(dev->parser,
976 usb_redir_cap_connect_device_version)) {
977 ERROR("Device filter specified and peer does not have the "
978 "connect_device_version capability\n");
979 goto error;
980 }
981
982 if (usbredirfilter_check(
983 dev->filter_rules,
984 dev->filter_rules_count,
985 dev->device_info.device_class,
986 dev->device_info.device_subclass,
987 dev->device_info.device_protocol,
988 dev->interface_info.interface_class,
989 dev->interface_info.interface_subclass,
990 dev->interface_info.interface_protocol,
991 dev->interface_info.interface_count,
992 dev->device_info.vendor_id,
993 dev->device_info.product_id,
994 dev->device_info.device_version_bcd,
995 0) != 0) {
996 goto error;
997 }
998 }
999
1000 return 0;
1001
1002 error:
1003 usbredir_device_disconnect(dev);
1004 if (usbredirparser_peer_has_cap(dev->parser, usb_redir_cap_filter)) {
1005 usbredirparser_send_filter_reject(dev->parser);
1006 usbredirparser_do_write(dev->parser);
1007 }
1008 return -1;
1009 }
1010
1011 /*
1012 * usbredirparser packet complete callbacks
1013 */
1014
1015 static int usbredir_handle_status(USBRedirDevice *dev,
1016 int status, int actual_len)
1017 {
1018 switch (status) {
1019 case usb_redir_success:
1020 return actual_len;
1021 case usb_redir_stall:
1022 return USB_RET_STALL;
1023 case usb_redir_cancelled:
1024 /*
1025 * When the usbredir-host unredirects a device, it will report a status
1026 * of cancelled for all pending packets, followed by a disconnect msg.
1027 */
1028 return USB_RET_IOERROR;
1029 case usb_redir_inval:
1030 WARNING("got invalid param error from usb-host?\n");
1031 return USB_RET_IOERROR;
1032 case usb_redir_babble:
1033 return USB_RET_BABBLE;
1034 case usb_redir_ioerror:
1035 case usb_redir_timeout:
1036 default:
1037 return USB_RET_IOERROR;
1038 }
1039 }
1040
1041 static void usbredir_hello(void *priv, struct usb_redir_hello_header *h)
1042 {
1043 USBRedirDevice *dev = priv;
1044
1045 /* Try to send the filter info now that we've the usb-host's caps */
1046 if (usbredirparser_peer_has_cap(dev->parser, usb_redir_cap_filter) &&
1047 dev->filter_rules) {
1048 usbredirparser_send_filter_filter(dev->parser, dev->filter_rules,
1049 dev->filter_rules_count);
1050 usbredirparser_do_write(dev->parser);
1051 }
1052 }
1053
1054 static void usbredir_device_connect(void *priv,
1055 struct usb_redir_device_connect_header *device_connect)
1056 {
1057 USBRedirDevice *dev = priv;
1058 const char *speed;
1059
1060 if (qemu_timer_pending(dev->attach_timer) || dev->dev.attached) {
1061 ERROR("Received device connect while already connected\n");
1062 return;
1063 }
1064
1065 switch (device_connect->speed) {
1066 case usb_redir_speed_low:
1067 speed = "low speed";
1068 dev->dev.speed = USB_SPEED_LOW;
1069 break;
1070 case usb_redir_speed_full:
1071 speed = "full speed";
1072 dev->dev.speed = USB_SPEED_FULL;
1073 break;
1074 case usb_redir_speed_high:
1075 speed = "high speed";
1076 dev->dev.speed = USB_SPEED_HIGH;
1077 break;
1078 case usb_redir_speed_super:
1079 speed = "super speed";
1080 dev->dev.speed = USB_SPEED_SUPER;
1081 break;
1082 default:
1083 speed = "unknown speed";
1084 dev->dev.speed = USB_SPEED_FULL;
1085 }
1086
1087 if (usbredirparser_peer_has_cap(dev->parser,
1088 usb_redir_cap_connect_device_version)) {
1089 INFO("attaching %s device %04x:%04x version %d.%d class %02x\n",
1090 speed, device_connect->vendor_id, device_connect->product_id,
1091 ((device_connect->device_version_bcd & 0xf000) >> 12) * 10 +
1092 ((device_connect->device_version_bcd & 0x0f00) >> 8),
1093 ((device_connect->device_version_bcd & 0x00f0) >> 4) * 10 +
1094 ((device_connect->device_version_bcd & 0x000f) >> 0),
1095 device_connect->device_class);
1096 } else {
1097 INFO("attaching %s device %04x:%04x class %02x\n", speed,
1098 device_connect->vendor_id, device_connect->product_id,
1099 device_connect->device_class);
1100 }
1101
1102 dev->dev.speedmask = (1 << dev->dev.speed);
1103 dev->device_info = *device_connect;
1104
1105 if (usbredir_check_filter(dev)) {
1106 WARNING("Device %04x:%04x rejected by device filter, not attaching\n",
1107 device_connect->vendor_id, device_connect->product_id);
1108 return;
1109 }
1110
1111 qemu_mod_timer(dev->attach_timer, dev->next_attach_time);
1112 }
1113
1114 static void usbredir_device_disconnect(void *priv)
1115 {
1116 USBRedirDevice *dev = priv;
1117 int i;
1118
1119 /* Stop any pending attaches */
1120 qemu_del_timer(dev->attach_timer);
1121
1122 if (dev->dev.attached) {
1123 usb_device_detach(&dev->dev);
1124 /*
1125 * Delay next usb device attach to give the guest a chance to see
1126 * see the detach / attach in case of quick close / open succession
1127 */
1128 dev->next_attach_time = qemu_get_clock_ms(vm_clock) + 200;
1129 }
1130
1131 /* Reset state so that the next dev connected starts with a clean slate */
1132 usbredir_cleanup_device_queues(dev);
1133 memset(dev->endpoint, 0, sizeof(dev->endpoint));
1134 for (i = 0; i < MAX_ENDPOINTS; i++) {
1135 QTAILQ_INIT(&dev->endpoint[i].bufpq);
1136 }
1137 usb_ep_init(&dev->dev);
1138 dev->interface_info.interface_count = NO_INTERFACE_INFO;
1139 dev->dev.addr = 0;
1140 dev->dev.speed = 0;
1141 }
1142
1143 static void usbredir_interface_info(void *priv,
1144 struct usb_redir_interface_info_header *interface_info)
1145 {
1146 USBRedirDevice *dev = priv;
1147
1148 dev->interface_info = *interface_info;
1149
1150 /*
1151 * If we receive interface info after the device has already been
1152 * connected (ie on a set_config), re-check the filter.
1153 */
1154 if (qemu_timer_pending(dev->attach_timer) || dev->dev.attached) {
1155 if (usbredir_check_filter(dev)) {
1156 ERROR("Device no longer matches filter after interface info "
1157 "change, disconnecting!\n");
1158 }
1159 }
1160 }
1161
1162 static void usbredir_ep_info(void *priv,
1163 struct usb_redir_ep_info_header *ep_info)
1164 {
1165 USBRedirDevice *dev = priv;
1166 struct USBEndpoint *usb_ep;
1167 int i;
1168
1169 for (i = 0; i < MAX_ENDPOINTS; i++) {
1170 dev->endpoint[i].type = ep_info->type[i];
1171 dev->endpoint[i].interval = ep_info->interval[i];
1172 dev->endpoint[i].interface = ep_info->interface[i];
1173 switch (dev->endpoint[i].type) {
1174 case usb_redir_type_invalid:
1175 break;
1176 case usb_redir_type_iso:
1177 case usb_redir_type_interrupt:
1178 if (dev->endpoint[i].interval == 0) {
1179 ERROR("Received 0 interval for isoc or irq endpoint\n");
1180 usbredir_device_disconnect(dev);
1181 }
1182 /* Fall through */
1183 case usb_redir_type_control:
1184 case usb_redir_type_bulk:
1185 DPRINTF("ep: %02X type: %d interface: %d\n", I2EP(i),
1186 dev->endpoint[i].type, dev->endpoint[i].interface);
1187 break;
1188 default:
1189 ERROR("Received invalid endpoint type\n");
1190 usbredir_device_disconnect(dev);
1191 return;
1192 }
1193 usb_ep = usb_ep_get(&dev->dev,
1194 (i & 0x10) ? USB_TOKEN_IN : USB_TOKEN_OUT,
1195 i & 0x0f);
1196 usb_ep->type = dev->endpoint[i].type;
1197 usb_ep->ifnum = dev->endpoint[i].interface;
1198 }
1199 }
1200
1201 static void usbredir_configuration_status(void *priv, uint32_t id,
1202 struct usb_redir_configuration_status_header *config_status)
1203 {
1204 USBRedirDevice *dev = priv;
1205 AsyncURB *aurb;
1206 int len = 0;
1207
1208 DPRINTF("set config status %d config %d id %u\n", config_status->status,
1209 config_status->configuration, id);
1210
1211 aurb = async_find(dev, id);
1212 if (!aurb) {
1213 return;
1214 }
1215 if (aurb->packet) {
1216 if (dev->dev.setup_buf[0] & USB_DIR_IN) {
1217 dev->dev.data_buf[0] = config_status->configuration;
1218 len = 1;
1219 }
1220 aurb->packet->result =
1221 usbredir_handle_status(dev, config_status->status, len);
1222 usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1223 }
1224 async_free(dev, aurb);
1225 }
1226
1227 static void usbredir_alt_setting_status(void *priv, uint32_t id,
1228 struct usb_redir_alt_setting_status_header *alt_setting_status)
1229 {
1230 USBRedirDevice *dev = priv;
1231 AsyncURB *aurb;
1232 int len = 0;
1233
1234 DPRINTF("alt status %d intf %d alt %d id: %u\n",
1235 alt_setting_status->status,
1236 alt_setting_status->interface,
1237 alt_setting_status->alt, id);
1238
1239 aurb = async_find(dev, id);
1240 if (!aurb) {
1241 return;
1242 }
1243 if (aurb->packet) {
1244 if (dev->dev.setup_buf[0] & USB_DIR_IN) {
1245 dev->dev.data_buf[0] = alt_setting_status->alt;
1246 len = 1;
1247 }
1248 aurb->packet->result =
1249 usbredir_handle_status(dev, alt_setting_status->status, len);
1250 usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1251 }
1252 async_free(dev, aurb);
1253 }
1254
1255 static void usbredir_iso_stream_status(void *priv, uint32_t id,
1256 struct usb_redir_iso_stream_status_header *iso_stream_status)
1257 {
1258 USBRedirDevice *dev = priv;
1259 uint8_t ep = iso_stream_status->endpoint;
1260
1261 DPRINTF("iso status %d ep %02X id %u\n", iso_stream_status->status,
1262 ep, id);
1263
1264 if (!dev->dev.attached || !dev->endpoint[EP2I(ep)].iso_started) {
1265 return;
1266 }
1267
1268 dev->endpoint[EP2I(ep)].iso_error = iso_stream_status->status;
1269 if (iso_stream_status->status == usb_redir_stall) {
1270 DPRINTF("iso stream stopped by peer ep %02X\n", ep);
1271 dev->endpoint[EP2I(ep)].iso_started = 0;
1272 }
1273 }
1274
1275 static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
1276 struct usb_redir_interrupt_receiving_status_header
1277 *interrupt_receiving_status)
1278 {
1279 USBRedirDevice *dev = priv;
1280 uint8_t ep = interrupt_receiving_status->endpoint;
1281
1282 DPRINTF("interrupt recv status %d ep %02X id %u\n",
1283 interrupt_receiving_status->status, ep, id);
1284
1285 if (!dev->dev.attached || !dev->endpoint[EP2I(ep)].interrupt_started) {
1286 return;
1287 }
1288
1289 dev->endpoint[EP2I(ep)].interrupt_error =
1290 interrupt_receiving_status->status;
1291 if (interrupt_receiving_status->status == usb_redir_stall) {
1292 DPRINTF("interrupt receiving stopped by peer ep %02X\n", ep);
1293 dev->endpoint[EP2I(ep)].interrupt_started = 0;
1294 }
1295 }
1296
1297 static void usbredir_bulk_streams_status(void *priv, uint32_t id,
1298 struct usb_redir_bulk_streams_status_header *bulk_streams_status)
1299 {
1300 }
1301
1302 static void usbredir_control_packet(void *priv, uint32_t id,
1303 struct usb_redir_control_packet_header *control_packet,
1304 uint8_t *data, int data_len)
1305 {
1306 USBRedirDevice *dev = priv;
1307 int len = control_packet->length;
1308 AsyncURB *aurb;
1309
1310 DPRINTF("ctrl-in status %d len %d id %u\n", control_packet->status,
1311 len, id);
1312
1313 aurb = async_find(dev, id);
1314 if (!aurb) {
1315 free(data);
1316 return;
1317 }
1318
1319 if (aurb->packet) {
1320 len = usbredir_handle_status(dev, control_packet->status, len);
1321 if (len > 0) {
1322 usbredir_log_data(dev, "ctrl data in:", data, data_len);
1323 if (data_len <= sizeof(dev->dev.data_buf)) {
1324 memcpy(dev->dev.data_buf, data, data_len);
1325 } else {
1326 ERROR("ctrl buffer too small (%d > %zu)\n",
1327 data_len, sizeof(dev->dev.data_buf));
1328 len = USB_RET_STALL;
1329 }
1330 }
1331 aurb->packet->result = len;
1332 usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1333 }
1334 async_free(dev, aurb);
1335 free(data);
1336 }
1337
1338 static void usbredir_bulk_packet(void *priv, uint32_t id,
1339 struct usb_redir_bulk_packet_header *bulk_packet,
1340 uint8_t *data, int data_len)
1341 {
1342 USBRedirDevice *dev = priv;
1343 uint8_t ep = bulk_packet->endpoint;
1344 int len = bulk_packet->length;
1345 AsyncURB *aurb;
1346
1347 DPRINTF("bulk-in status %d ep %02X len %d id %u\n", bulk_packet->status,
1348 ep, len, id);
1349
1350 aurb = async_find(dev, id);
1351 if (!aurb) {
1352 free(data);
1353 return;
1354 }
1355
1356 if (aurb->packet) {
1357 len = usbredir_handle_status(dev, bulk_packet->status, len);
1358 if (len > 0) {
1359 usbredir_log_data(dev, "bulk data in:", data, data_len);
1360 if (data_len <= aurb->packet->iov.size) {
1361 usb_packet_copy(aurb->packet, data, data_len);
1362 } else {
1363 ERROR("bulk buffer too small (%d > %zd)\n", data_len,
1364 aurb->packet->iov.size);
1365 len = USB_RET_STALL;
1366 }
1367 }
1368 aurb->packet->result = len;
1369 usb_packet_complete(&dev->dev, aurb->packet);
1370 }
1371 async_free(dev, aurb);
1372 free(data);
1373 }
1374
1375 static void usbredir_iso_packet(void *priv, uint32_t id,
1376 struct usb_redir_iso_packet_header *iso_packet,
1377 uint8_t *data, int data_len)
1378 {
1379 USBRedirDevice *dev = priv;
1380 uint8_t ep = iso_packet->endpoint;
1381
1382 DPRINTF2("iso-in status %d ep %02X len %d id %u\n", iso_packet->status, ep,
1383 data_len, id);
1384
1385 if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_ISOC) {
1386 ERROR("received iso packet for non iso endpoint %02X\n", ep);
1387 free(data);
1388 return;
1389 }
1390
1391 if (dev->endpoint[EP2I(ep)].iso_started == 0) {
1392 DPRINTF("received iso packet for non started stream ep %02X\n", ep);
1393 free(data);
1394 return;
1395 }
1396
1397 /* bufp_alloc also adds the packet to the ep queue */
1398 bufp_alloc(dev, data, data_len, iso_packet->status, ep);
1399 }
1400
1401 static void usbredir_interrupt_packet(void *priv, uint32_t id,
1402 struct usb_redir_interrupt_packet_header *interrupt_packet,
1403 uint8_t *data, int data_len)
1404 {
1405 USBRedirDevice *dev = priv;
1406 uint8_t ep = interrupt_packet->endpoint;
1407
1408 DPRINTF("interrupt-in status %d ep %02X len %d id %u\n",
1409 interrupt_packet->status, ep, data_len, id);
1410
1411 if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_INT) {
1412 ERROR("received int packet for non interrupt endpoint %02X\n", ep);
1413 free(data);
1414 return;
1415 }
1416
1417 if (ep & USB_DIR_IN) {
1418 if (dev->endpoint[EP2I(ep)].interrupt_started == 0) {
1419 DPRINTF("received int packet while not started ep %02X\n", ep);
1420 free(data);
1421 return;
1422 }
1423
1424 /* bufp_alloc also adds the packet to the ep queue */
1425 bufp_alloc(dev, data, data_len, interrupt_packet->status, ep);
1426 } else {
1427 int len = interrupt_packet->length;
1428
1429 AsyncURB *aurb = async_find(dev, id);
1430 if (!aurb) {
1431 return;
1432 }
1433
1434 if (aurb->packet) {
1435 aurb->packet->result = usbredir_handle_status(dev,
1436 interrupt_packet->status, len);
1437 usb_packet_complete(&dev->dev, aurb->packet);
1438 }
1439 async_free(dev, aurb);
1440 }
1441 }
1442
1443 static Property usbredir_properties[] = {
1444 DEFINE_PROP_CHR("chardev", USBRedirDevice, cs),
1445 DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, 0),
1446 DEFINE_PROP_STRING("filter", USBRedirDevice, filter_str),
1447 DEFINE_PROP_INT32("bootindex", USBRedirDevice, bootindex, -1),
1448 DEFINE_PROP_END_OF_LIST(),
1449 };
1450
1451 static void usbredir_class_initfn(ObjectClass *klass, void *data)
1452 {
1453 USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
1454 DeviceClass *dc = DEVICE_CLASS(klass);
1455
1456 uc->init = usbredir_initfn;
1457 uc->product_desc = "USB Redirection Device";
1458 uc->handle_destroy = usbredir_handle_destroy;
1459 uc->cancel_packet = usbredir_cancel_packet;
1460 uc->handle_reset = usbredir_handle_reset;
1461 uc->handle_data = usbredir_handle_data;
1462 uc->handle_control = usbredir_handle_control;
1463 dc->props = usbredir_properties;
1464 }
1465
1466 static TypeInfo usbredir_dev_info = {
1467 .name = "usb-redir",
1468 .parent = TYPE_USB_DEVICE,
1469 .instance_size = sizeof(USBRedirDevice),
1470 .class_init = usbredir_class_initfn,
1471 };
1472
1473 static void usbredir_register_types(void)
1474 {
1475 type_register_static(&usbredir_dev_info);
1476 }
1477
1478 type_init(usbredir_register_types)