Statistics
| Branch: | Revision:

root / usb-redir.c @ 02021812

History | View | Annotate | Download (47.1 kB)

1
/*
2
 * USB redirector usb-guest
3
 *
4
 * Copyright (c) 2011 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 EP2I(ep_address) (((ep_address & 0x80) >> 3) | (ep_address & 0x0f))
43
#define I2EP(i) (((i & 0x10) << 3) | (i & 0x0f))
44

    
45
typedef struct AsyncURB AsyncURB;
46
typedef struct USBRedirDevice USBRedirDevice;
47

    
48
/* Struct to hold buffered packets (iso or int input packets) */
49
struct buf_packet {
50
    uint8_t *data;
51
    int len;
52
    int status;
53
    QTAILQ_ENTRY(buf_packet)next;
54
};
55

    
56
struct endp_data {
57
    uint8_t type;
58
    uint8_t interval;
59
    uint8_t interface; /* bInterfaceNumber this ep belongs to */
60
    uint8_t iso_started;
61
    uint8_t iso_error; /* For reporting iso errors to the HC */
62
    uint8_t interrupt_started;
63
    uint8_t interrupt_error;
64
    uint8_t bufpq_prefilled;
65
    uint8_t bufpq_dropping_packets;
66
    QTAILQ_HEAD(, buf_packet) bufpq;
67
    int bufpq_size;
68
    int bufpq_target_size;
69
};
70

    
71
struct USBRedirDevice {
72
    USBDevice dev;
73
    /* Properties */
74
    CharDriverState *cs;
75
    uint8_t debug;
76
    char *filter_str;
77
    /* Data passed from chardev the fd_read cb to the usbredirparser read cb */
78
    const uint8_t *read_buf;
79
    int read_buf_size;
80
    /* For async handling of open/close */
81
    QEMUBH *open_close_bh;
82
    /* To delay the usb attach in case of quick chardev close + open */
83
    QEMUTimer *attach_timer;
84
    int64_t next_attach_time;
85
    struct usbredirparser *parser;
86
    struct endp_data endpoint[MAX_ENDPOINTS];
87
    uint32_t packet_id;
88
    QTAILQ_HEAD(, AsyncURB) asyncq;
89
    /* Data for device filtering */
90
    struct usb_redir_device_connect_header device_info;
91
    struct usb_redir_interface_info_header interface_info;
92
    struct usbredirfilter_rule *filter_rules;
93
    int filter_rules_count;
94
};
95

    
96
struct AsyncURB {
97
    USBRedirDevice *dev;
98
    USBPacket *packet;
99
    uint32_t packet_id;
100
    int get;
101
    union {
102
        struct usb_redir_control_packet_header control_packet;
103
        struct usb_redir_bulk_packet_header bulk_packet;
104
        struct usb_redir_interrupt_packet_header interrupt_packet;
105
    };
106
    QTAILQ_ENTRY(AsyncURB)next;
107
};
108

    
109
static void usbredir_hello(void *priv, struct usb_redir_hello_header *h);
110
static void usbredir_device_connect(void *priv,
111
    struct usb_redir_device_connect_header *device_connect);
112
static void usbredir_device_disconnect(void *priv);
113
static void usbredir_interface_info(void *priv,
114
    struct usb_redir_interface_info_header *interface_info);
115
static void usbredir_ep_info(void *priv,
116
    struct usb_redir_ep_info_header *ep_info);
117
static void usbredir_configuration_status(void *priv, uint32_t id,
118
    struct usb_redir_configuration_status_header *configuration_status);
119
static void usbredir_alt_setting_status(void *priv, uint32_t id,
120
    struct usb_redir_alt_setting_status_header *alt_setting_status);
121
static void usbredir_iso_stream_status(void *priv, uint32_t id,
122
    struct usb_redir_iso_stream_status_header *iso_stream_status);
123
static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
124
    struct usb_redir_interrupt_receiving_status_header
125
    *interrupt_receiving_status);
126
static void usbredir_bulk_streams_status(void *priv, uint32_t id,
127
    struct usb_redir_bulk_streams_status_header *bulk_streams_status);
128
static void usbredir_control_packet(void *priv, uint32_t id,
129
    struct usb_redir_control_packet_header *control_packet,
130
    uint8_t *data, int data_len);
131
static void usbredir_bulk_packet(void *priv, uint32_t id,
132
    struct usb_redir_bulk_packet_header *bulk_packet,
133
    uint8_t *data, int data_len);
134
static void usbredir_iso_packet(void *priv, uint32_t id,
135
    struct usb_redir_iso_packet_header *iso_packet,
136
    uint8_t *data, int data_len);
137
static void usbredir_interrupt_packet(void *priv, uint32_t id,
138
    struct usb_redir_interrupt_packet_header *interrupt_header,
139
    uint8_t *data, int data_len);
140

    
141
static int usbredir_handle_status(USBRedirDevice *dev,
142
                                       int status, int actual_len);
143

    
144
#define VERSION "qemu usb-redir guest " QEMU_VERSION
145

    
146
/*
147
 * Logging stuff
148
 */
149

    
150
#define ERROR(...) \
151
    do { \
152
        if (dev->debug >= usbredirparser_error) { \
153
            error_report("usb-redir error: " __VA_ARGS__); \
154
        } \
155
    } while (0)
156
#define WARNING(...) \
157
    do { \
158
        if (dev->debug >= usbredirparser_warning) { \
159
            error_report("usb-redir warning: " __VA_ARGS__); \
160
        } \
161
    } while (0)
162
#define INFO(...) \
163
    do { \
164
        if (dev->debug >= usbredirparser_info) { \
165
            error_report("usb-redir: " __VA_ARGS__); \
166
        } \
167
    } while (0)
168
#define DPRINTF(...) \
169
    do { \
170
        if (dev->debug >= usbredirparser_debug) { \
171
            error_report("usb-redir: " __VA_ARGS__); \
172
        } \
173
    } while (0)
174
#define DPRINTF2(...) \
175
    do { \
176
        if (dev->debug >= usbredirparser_debug_data) { \
177
            error_report("usb-redir: " __VA_ARGS__); \
178
        } \
179
    } while (0)
180

    
181
static void usbredir_log(void *priv, int level, const char *msg)
182
{
183
    USBRedirDevice *dev = priv;
184

    
185
    if (dev->debug < level) {
186
        return;
187
    }
188

    
189
    error_report("%s", msg);
190
}
191

    
192
static void usbredir_log_data(USBRedirDevice *dev, const char *desc,
193
    const uint8_t *data, int len)
194
{
195
    int i, j, n;
196

    
197
    if (dev->debug < usbredirparser_debug_data) {
198
        return;
199
    }
200

    
201
    for (i = 0; i < len; i += j) {
202
        char buf[128];
203

    
204
        n = sprintf(buf, "%s", desc);
205
        for (j = 0; j < 8 && i + j < len; j++) {
206
            n += sprintf(buf + n, " %02X", data[i + j]);
207
        }
208
        error_report("%s", buf);
209
    }
210
}
211

    
212
/*
213
 * usbredirparser io functions
214
 */
215

    
216
static int usbredir_read(void *priv, uint8_t *data, int count)
217
{
218
    USBRedirDevice *dev = priv;
219

    
220
    if (dev->read_buf_size < count) {
221
        count = dev->read_buf_size;
222
    }
223

    
224
    memcpy(data, dev->read_buf, count);
225

    
226
    dev->read_buf_size -= count;
227
    if (dev->read_buf_size) {
228
        dev->read_buf += count;
229
    } else {
230
        dev->read_buf = NULL;
231
    }
232

    
233
    return count;
234
}
235

    
236
static int usbredir_write(void *priv, uint8_t *data, int count)
237
{
238
    USBRedirDevice *dev = priv;
239

    
240
    if (!dev->cs->opened) {
241
        return 0;
242
    }
243

    
244
    return qemu_chr_fe_write(dev->cs, data, count);
245
}
246

    
247
/*
248
 * Async and buffered packets helpers
249
 */
250

    
251
static AsyncURB *async_alloc(USBRedirDevice *dev, USBPacket *p)
252
{
253
    AsyncURB *aurb = (AsyncURB *) g_malloc0(sizeof(AsyncURB));
254
    aurb->dev = dev;
255
    aurb->packet = p;
256
    aurb->packet_id = dev->packet_id;
257
    QTAILQ_INSERT_TAIL(&dev->asyncq, aurb, next);
258
    dev->packet_id++;
259

    
260
    return aurb;
261
}
262

    
263
static void async_free(USBRedirDevice *dev, AsyncURB *aurb)
264
{
265
    QTAILQ_REMOVE(&dev->asyncq, aurb, next);
266
    g_free(aurb);
267
}
268

    
269
static AsyncURB *async_find(USBRedirDevice *dev, uint32_t packet_id)
270
{
271
    AsyncURB *aurb;
272

    
273
    QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
274
        if (aurb->packet_id == packet_id) {
275
            return aurb;
276
        }
277
    }
278
    ERROR("could not find async urb for packet_id %u\n", packet_id);
279
    return NULL;
280
}
281

    
282
static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p)
283
{
284
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
285
    AsyncURB *aurb;
286

    
287
    QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
288
        if (p != aurb->packet) {
289
            continue;
290
        }
291

    
292
        DPRINTF("async cancel id %u\n", aurb->packet_id);
293
        usbredirparser_send_cancel_data_packet(dev->parser, aurb->packet_id);
294
        usbredirparser_do_write(dev->parser);
295

    
296
        /* Mark it as dead */
297
        aurb->packet = NULL;
298
        break;
299
    }
300
}
301

    
302
static void bufp_alloc(USBRedirDevice *dev,
303
    uint8_t *data, int len, int status, uint8_t ep)
304
{
305
    struct buf_packet *bufp;
306

    
307
    if (!dev->endpoint[EP2I(ep)].bufpq_dropping_packets &&
308
        dev->endpoint[EP2I(ep)].bufpq_size >
309
            2 * dev->endpoint[EP2I(ep)].bufpq_target_size) {
310
        DPRINTF("bufpq overflow, dropping packets ep %02X\n", ep);
311
        dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 1;
312
    }
313
    /* Since we're interupting the stream anyways, drop enough packets to get
314
       back to our target buffer size */
315
    if (dev->endpoint[EP2I(ep)].bufpq_dropping_packets) {
316
        if (dev->endpoint[EP2I(ep)].bufpq_size >
317
                dev->endpoint[EP2I(ep)].bufpq_target_size) {
318
            free(data);
319
            return;
320
        }
321
        dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
322
    }
323

    
324
    bufp = g_malloc(sizeof(struct buf_packet));
325
    bufp->data   = data;
326
    bufp->len    = len;
327
    bufp->status = status;
328
    QTAILQ_INSERT_TAIL(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
329
    dev->endpoint[EP2I(ep)].bufpq_size++;
330
}
331

    
332
static void bufp_free(USBRedirDevice *dev, struct buf_packet *bufp,
333
    uint8_t ep)
334
{
335
    QTAILQ_REMOVE(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
336
    dev->endpoint[EP2I(ep)].bufpq_size--;
337
    free(bufp->data);
338
    g_free(bufp);
339
}
340

    
341
static void usbredir_free_bufpq(USBRedirDevice *dev, uint8_t ep)
342
{
343
    struct buf_packet *buf, *buf_next;
344

    
345
    QTAILQ_FOREACH_SAFE(buf, &dev->endpoint[EP2I(ep)].bufpq, next, buf_next) {
346
        bufp_free(dev, buf, ep);
347
    }
348
}
349

    
350
/*
351
 * USBDevice callbacks
352
 */
353

    
354
static void usbredir_handle_reset(USBDevice *udev)
355
{
356
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
357

    
358
    DPRINTF("reset device\n");
359
    usbredirparser_send_reset(dev->parser);
360
    usbredirparser_do_write(dev->parser);
361
}
362

    
363
static int usbredir_handle_iso_data(USBRedirDevice *dev, USBPacket *p,
364
                                     uint8_t ep)
365
{
366
    int status, len;
367
    if (!dev->endpoint[EP2I(ep)].iso_started &&
368
            !dev->endpoint[EP2I(ep)].iso_error) {
369
        struct usb_redir_start_iso_stream_header start_iso = {
370
            .endpoint = ep,
371
        };
372
        int pkts_per_sec;
373

    
374
        if (dev->dev.speed == USB_SPEED_HIGH) {
375
            pkts_per_sec = 8000 / dev->endpoint[EP2I(ep)].interval;
376
        } else {
377
            pkts_per_sec = 1000 / dev->endpoint[EP2I(ep)].interval;
378
        }
379
        /* Testing has shown that we need circa 60 ms buffer */
380
        dev->endpoint[EP2I(ep)].bufpq_target_size = (pkts_per_sec * 60) / 1000;
381

    
382
        /* Aim for approx 100 interrupts / second on the client to
383
           balance latency and interrupt load */
384
        start_iso.pkts_per_urb = pkts_per_sec / 100;
385
        if (start_iso.pkts_per_urb < 1) {
386
            start_iso.pkts_per_urb = 1;
387
        } else if (start_iso.pkts_per_urb > 32) {
388
            start_iso.pkts_per_urb = 32;
389
        }
390

    
391
        start_iso.no_urbs = (dev->endpoint[EP2I(ep)].bufpq_target_size +
392
                             start_iso.pkts_per_urb - 1) /
393
                            start_iso.pkts_per_urb;
394
        /* Output endpoints pre-fill only 1/2 of the packets, keeping the rest
395
           as overflow buffer. Also see the usbredir protocol documentation */
396
        if (!(ep & USB_DIR_IN)) {
397
            start_iso.no_urbs *= 2;
398
        }
399
        if (start_iso.no_urbs > 16) {
400
            start_iso.no_urbs = 16;
401
        }
402

    
403
        /* No id, we look at the ep when receiving a status back */
404
        usbredirparser_send_start_iso_stream(dev->parser, 0, &start_iso);
405
        usbredirparser_do_write(dev->parser);
406
        DPRINTF("iso stream started pkts/sec %d pkts/urb %d urbs %d ep %02X\n",
407
                pkts_per_sec, start_iso.pkts_per_urb, start_iso.no_urbs, ep);
408
        dev->endpoint[EP2I(ep)].iso_started = 1;
409
        dev->endpoint[EP2I(ep)].bufpq_prefilled = 0;
410
        dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
411
    }
412

    
413
    if (ep & USB_DIR_IN) {
414
        struct buf_packet *isop;
415

    
416
        if (dev->endpoint[EP2I(ep)].iso_started &&
417
                !dev->endpoint[EP2I(ep)].bufpq_prefilled) {
418
            if (dev->endpoint[EP2I(ep)].bufpq_size <
419
                    dev->endpoint[EP2I(ep)].bufpq_target_size) {
420
                return usbredir_handle_status(dev, 0, 0);
421
            }
422
            dev->endpoint[EP2I(ep)].bufpq_prefilled = 1;
423
        }
424

    
425
        isop = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
426
        if (isop == NULL) {
427
            DPRINTF("iso-token-in ep %02X, no isop, iso_error: %d\n",
428
                    ep, dev->endpoint[EP2I(ep)].iso_error);
429
            /* Re-fill the buffer */
430
            dev->endpoint[EP2I(ep)].bufpq_prefilled = 0;
431
            /* Check iso_error for stream errors, otherwise its an underrun */
432
            status = dev->endpoint[EP2I(ep)].iso_error;
433
            dev->endpoint[EP2I(ep)].iso_error = 0;
434
            return status ? USB_RET_NAK : 0;
435
        }
436
        DPRINTF2("iso-token-in ep %02X status %d len %d queue-size: %d\n", ep,
437
                 isop->status, isop->len, dev->endpoint[EP2I(ep)].bufpq_size);
438

    
439
        status = isop->status;
440
        if (status != usb_redir_success) {
441
            bufp_free(dev, isop, ep);
442
            return USB_RET_NAK;
443
        }
444

    
445
        len = isop->len;
446
        if (len > p->iov.size) {
447
            ERROR("received iso data is larger then packet ep %02X (%d > %d)\n",
448
                  ep, len, (int)p->iov.size);
449
            bufp_free(dev, isop, ep);
450
            return USB_RET_NAK;
451
        }
452
        usb_packet_copy(p, isop->data, len);
453
        bufp_free(dev, isop, ep);
454
        return len;
455
    } else {
456
        /* If the stream was not started because of a pending error don't
457
           send the packet to the usb-host */
458
        if (dev->endpoint[EP2I(ep)].iso_started) {
459
            struct usb_redir_iso_packet_header iso_packet = {
460
                .endpoint = ep,
461
                .length = p->iov.size
462
            };
463
            uint8_t buf[p->iov.size];
464
            /* No id, we look at the ep when receiving a status back */
465
            usb_packet_copy(p, buf, p->iov.size);
466
            usbredirparser_send_iso_packet(dev->parser, 0, &iso_packet,
467
                                           buf, p->iov.size);
468
            usbredirparser_do_write(dev->parser);
469
        }
470
        status = dev->endpoint[EP2I(ep)].iso_error;
471
        dev->endpoint[EP2I(ep)].iso_error = 0;
472
        DPRINTF2("iso-token-out ep %02X status %d len %zd\n", ep, status,
473
                 p->iov.size);
474
        return usbredir_handle_status(dev, status, p->iov.size);
475
    }
476
}
477

    
478
static void usbredir_stop_iso_stream(USBRedirDevice *dev, uint8_t ep)
479
{
480
    struct usb_redir_stop_iso_stream_header stop_iso_stream = {
481
        .endpoint = ep
482
    };
483
    if (dev->endpoint[EP2I(ep)].iso_started) {
484
        usbredirparser_send_stop_iso_stream(dev->parser, 0, &stop_iso_stream);
485
        DPRINTF("iso stream stopped ep %02X\n", ep);
486
        dev->endpoint[EP2I(ep)].iso_started = 0;
487
    }
488
    dev->endpoint[EP2I(ep)].iso_error = 0;
489
    usbredir_free_bufpq(dev, ep);
490
}
491

    
492
static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
493
                                      uint8_t ep)
494
{
495
    AsyncURB *aurb = async_alloc(dev, p);
496
    struct usb_redir_bulk_packet_header bulk_packet;
497

    
498
    DPRINTF("bulk-out ep %02X len %zd id %u\n", ep,
499
            p->iov.size, aurb->packet_id);
500

    
501
    bulk_packet.endpoint  = ep;
502
    bulk_packet.length    = p->iov.size;
503
    bulk_packet.stream_id = 0;
504
    aurb->bulk_packet = bulk_packet;
505

    
506
    if (ep & USB_DIR_IN) {
507
        usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
508
                                        &bulk_packet, NULL, 0);
509
    } else {
510
        uint8_t buf[p->iov.size];
511
        usb_packet_copy(p, buf, p->iov.size);
512
        usbredir_log_data(dev, "bulk data out:", buf, p->iov.size);
513
        usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
514
                                        &bulk_packet, buf, p->iov.size);
515
    }
516
    usbredirparser_do_write(dev->parser);
517
    return USB_RET_ASYNC;
518
}
519

    
520
static int usbredir_handle_interrupt_data(USBRedirDevice *dev,
521
                                           USBPacket *p, uint8_t ep)
522
{
523
    if (ep & USB_DIR_IN) {
524
        /* Input interrupt endpoint, buffered packet input */
525
        struct buf_packet *intp;
526
        int status, len;
527

    
528
        if (!dev->endpoint[EP2I(ep)].interrupt_started &&
529
                !dev->endpoint[EP2I(ep)].interrupt_error) {
530
            struct usb_redir_start_interrupt_receiving_header start_int = {
531
                .endpoint = ep,
532
            };
533
            /* No id, we look at the ep when receiving a status back */
534
            usbredirparser_send_start_interrupt_receiving(dev->parser, 0,
535
                                                          &start_int);
536
            usbredirparser_do_write(dev->parser);
537
            DPRINTF("interrupt recv started ep %02X\n", ep);
538
            dev->endpoint[EP2I(ep)].interrupt_started = 1;
539
            /* We don't really want to drop interrupt packets ever, but
540
               having some upper limit to how much we buffer is good. */
541
            dev->endpoint[EP2I(ep)].bufpq_target_size = 1000;
542
            dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
543
        }
544

    
545
        intp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
546
        if (intp == NULL) {
547
            DPRINTF2("interrupt-token-in ep %02X, no intp\n", ep);
548
            /* Check interrupt_error for stream errors */
549
            status = dev->endpoint[EP2I(ep)].interrupt_error;
550
            dev->endpoint[EP2I(ep)].interrupt_error = 0;
551
            if (status) {
552
                return usbredir_handle_status(dev, status, 0);
553
            }
554
            return USB_RET_NAK;
555
        }
556
        DPRINTF("interrupt-token-in ep %02X status %d len %d\n", ep,
557
                intp->status, intp->len);
558

    
559
        status = intp->status;
560
        if (status != usb_redir_success) {
561
            bufp_free(dev, intp, ep);
562
            return usbredir_handle_status(dev, status, 0);
563
        }
564

    
565
        len = intp->len;
566
        if (len > p->iov.size) {
567
            ERROR("received int data is larger then packet ep %02X\n", ep);
568
            bufp_free(dev, intp, ep);
569
            return USB_RET_NAK;
570
        }
571
        usb_packet_copy(p, intp->data, len);
572
        bufp_free(dev, intp, ep);
573
        return len;
574
    } else {
575
        /* Output interrupt endpoint, normal async operation */
576
        AsyncURB *aurb = async_alloc(dev, p);
577
        struct usb_redir_interrupt_packet_header interrupt_packet;
578
        uint8_t buf[p->iov.size];
579

    
580
        DPRINTF("interrupt-out ep %02X len %zd id %u\n", ep, p->iov.size,
581
                aurb->packet_id);
582

    
583
        interrupt_packet.endpoint  = ep;
584
        interrupt_packet.length    = p->iov.size;
585
        aurb->interrupt_packet     = interrupt_packet;
586

    
587
        usb_packet_copy(p, buf, p->iov.size);
588
        usbredir_log_data(dev, "interrupt data out:", buf, p->iov.size);
589
        usbredirparser_send_interrupt_packet(dev->parser, aurb->packet_id,
590
                                        &interrupt_packet, buf, p->iov.size);
591
        usbredirparser_do_write(dev->parser);
592
        return USB_RET_ASYNC;
593
    }
594
}
595

    
596
static void usbredir_stop_interrupt_receiving(USBRedirDevice *dev,
597
    uint8_t ep)
598
{
599
    struct usb_redir_stop_interrupt_receiving_header stop_interrupt_recv = {
600
        .endpoint = ep
601
    };
602
    if (dev->endpoint[EP2I(ep)].interrupt_started) {
603
        usbredirparser_send_stop_interrupt_receiving(dev->parser, 0,
604
                                                     &stop_interrupt_recv);
605
        DPRINTF("interrupt recv stopped ep %02X\n", ep);
606
        dev->endpoint[EP2I(ep)].interrupt_started = 0;
607
    }
608
    dev->endpoint[EP2I(ep)].interrupt_error = 0;
609
    usbredir_free_bufpq(dev, ep);
610
}
611

    
612
static int usbredir_handle_data(USBDevice *udev, USBPacket *p)
613
{
614
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
615
    uint8_t ep;
616

    
617
    ep = p->ep->nr;
618
    if (p->pid == USB_TOKEN_IN) {
619
        ep |= USB_DIR_IN;
620
    }
621

    
622
    switch (dev->endpoint[EP2I(ep)].type) {
623
    case USB_ENDPOINT_XFER_CONTROL:
624
        ERROR("handle_data called for control transfer on ep %02X\n", ep);
625
        return USB_RET_NAK;
626
    case USB_ENDPOINT_XFER_ISOC:
627
        return usbredir_handle_iso_data(dev, p, ep);
628
    case USB_ENDPOINT_XFER_BULK:
629
        return usbredir_handle_bulk_data(dev, p, ep);
630
    case USB_ENDPOINT_XFER_INT:
631
        return usbredir_handle_interrupt_data(dev, p, ep);
632
    default:
633
        ERROR("handle_data ep %02X has unknown type %d\n", ep,
634
              dev->endpoint[EP2I(ep)].type);
635
        return USB_RET_NAK;
636
    }
637
}
638

    
639
static int usbredir_set_config(USBRedirDevice *dev, USBPacket *p,
640
                                int config)
641
{
642
    struct usb_redir_set_configuration_header set_config;
643
    AsyncURB *aurb = async_alloc(dev, p);
644
    int i;
645

    
646
    DPRINTF("set config %d id %u\n", config, aurb->packet_id);
647

    
648
    for (i = 0; i < MAX_ENDPOINTS; i++) {
649
        switch (dev->endpoint[i].type) {
650
        case USB_ENDPOINT_XFER_ISOC:
651
            usbredir_stop_iso_stream(dev, I2EP(i));
652
            break;
653
        case USB_ENDPOINT_XFER_INT:
654
            if (i & 0x10) {
655
                usbredir_stop_interrupt_receiving(dev, I2EP(i));
656
            }
657
            break;
658
        }
659
        usbredir_free_bufpq(dev, I2EP(i));
660
    }
661

    
662
    set_config.configuration = config;
663
    usbredirparser_send_set_configuration(dev->parser, aurb->packet_id,
664
                                          &set_config);
665
    usbredirparser_do_write(dev->parser);
666
    return USB_RET_ASYNC;
667
}
668

    
669
static int usbredir_get_config(USBRedirDevice *dev, USBPacket *p)
670
{
671
    AsyncURB *aurb = async_alloc(dev, p);
672

    
673
    DPRINTF("get config id %u\n", aurb->packet_id);
674

    
675
    aurb->get = 1;
676
    usbredirparser_send_get_configuration(dev->parser, aurb->packet_id);
677
    usbredirparser_do_write(dev->parser);
678
    return USB_RET_ASYNC;
679
}
680

    
681
static int usbredir_set_interface(USBRedirDevice *dev, USBPacket *p,
682
                                   int interface, int alt)
683
{
684
    struct usb_redir_set_alt_setting_header set_alt;
685
    AsyncURB *aurb = async_alloc(dev, p);
686
    int i;
687

    
688
    DPRINTF("set interface %d alt %d id %u\n", interface, alt,
689
            aurb->packet_id);
690

    
691
    for (i = 0; i < MAX_ENDPOINTS; i++) {
692
        if (dev->endpoint[i].interface == interface) {
693
            switch (dev->endpoint[i].type) {
694
            case USB_ENDPOINT_XFER_ISOC:
695
                usbredir_stop_iso_stream(dev, I2EP(i));
696
                break;
697
            case USB_ENDPOINT_XFER_INT:
698
                if (i & 0x10) {
699
                    usbredir_stop_interrupt_receiving(dev, I2EP(i));
700
                }
701
                break;
702
            }
703
            usbredir_free_bufpq(dev, I2EP(i));
704
        }
705
    }
706

    
707
    set_alt.interface = interface;
708
    set_alt.alt = alt;
709
    usbredirparser_send_set_alt_setting(dev->parser, aurb->packet_id,
710
                                        &set_alt);
711
    usbredirparser_do_write(dev->parser);
712
    return USB_RET_ASYNC;
713
}
714

    
715
static int usbredir_get_interface(USBRedirDevice *dev, USBPacket *p,
716
                                   int interface)
717
{
718
    struct usb_redir_get_alt_setting_header get_alt;
719
    AsyncURB *aurb = async_alloc(dev, p);
720

    
721
    DPRINTF("get interface %d id %u\n", interface, aurb->packet_id);
722

    
723
    get_alt.interface = interface;
724
    aurb->get = 1;
725
    usbredirparser_send_get_alt_setting(dev->parser, aurb->packet_id,
726
                                        &get_alt);
727
    usbredirparser_do_write(dev->parser);
728
    return USB_RET_ASYNC;
729
}
730

    
731
static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
732
        int request, int value, int index, int length, uint8_t *data)
733
{
734
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
735
    struct usb_redir_control_packet_header control_packet;
736
    AsyncURB *aurb;
737

    
738
    /* Special cases for certain standard device requests */
739
    switch (request) {
740
    case DeviceOutRequest | USB_REQ_SET_ADDRESS:
741
        DPRINTF("set address %d\n", value);
742
        dev->dev.addr = value;
743
        return 0;
744
    case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
745
        return usbredir_set_config(dev, p, value & 0xff);
746
    case DeviceRequest | USB_REQ_GET_CONFIGURATION:
747
        return usbredir_get_config(dev, p);
748
    case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
749
        return usbredir_set_interface(dev, p, index, value);
750
    case InterfaceRequest | USB_REQ_GET_INTERFACE:
751
        return usbredir_get_interface(dev, p, index);
752
    }
753

    
754
    /* "Normal" ctrl requests */
755
    aurb = async_alloc(dev, p);
756

    
757
    /* Note request is (bRequestType << 8) | bRequest */
758
    DPRINTF("ctrl-out type 0x%x req 0x%x val 0x%x index %d len %d id %u\n",
759
            request >> 8, request & 0xff, value, index, length,
760
            aurb->packet_id);
761

    
762
    control_packet.request     = request & 0xFF;
763
    control_packet.requesttype = request >> 8;
764
    control_packet.endpoint    = control_packet.requesttype & USB_DIR_IN;
765
    control_packet.value       = value;
766
    control_packet.index       = index;
767
    control_packet.length      = length;
768
    aurb->control_packet       = control_packet;
769

    
770
    if (control_packet.requesttype & USB_DIR_IN) {
771
        usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
772
                                           &control_packet, NULL, 0);
773
    } else {
774
        usbredir_log_data(dev, "ctrl data out:", data, length);
775
        usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
776
                                           &control_packet, data, length);
777
    }
778
    usbredirparser_do_write(dev->parser);
779
    return USB_RET_ASYNC;
780
}
781

    
782
/*
783
 * Close events can be triggered by usbredirparser_do_write which gets called
784
 * from within the USBDevice data / control packet callbacks and doing a
785
 * usb_detach from within these callbacks is not a good idea.
786
 *
787
 * So we use a bh handler to take care of close events. We also handle
788
 * open events from this callback to make sure that a close directly followed
789
 * by an open gets handled in the right order.
790
 */
791
static void usbredir_open_close_bh(void *opaque)
792
{
793
    USBRedirDevice *dev = opaque;
794
    uint32_t caps[USB_REDIR_CAPS_SIZE] = { 0, };
795

    
796
    usbredir_device_disconnect(dev);
797

    
798
    if (dev->parser) {
799
        usbredirparser_destroy(dev->parser);
800
        dev->parser = NULL;
801
    }
802

    
803
    if (dev->cs->opened) {
804
        dev->parser = qemu_oom_check(usbredirparser_create());
805
        dev->parser->priv = dev;
806
        dev->parser->log_func = usbredir_log;
807
        dev->parser->read_func = usbredir_read;
808
        dev->parser->write_func = usbredir_write;
809
        dev->parser->hello_func = usbredir_hello;
810
        dev->parser->device_connect_func = usbredir_device_connect;
811
        dev->parser->device_disconnect_func = usbredir_device_disconnect;
812
        dev->parser->interface_info_func = usbredir_interface_info;
813
        dev->parser->ep_info_func = usbredir_ep_info;
814
        dev->parser->configuration_status_func = usbredir_configuration_status;
815
        dev->parser->alt_setting_status_func = usbredir_alt_setting_status;
816
        dev->parser->iso_stream_status_func = usbredir_iso_stream_status;
817
        dev->parser->interrupt_receiving_status_func =
818
            usbredir_interrupt_receiving_status;
819
        dev->parser->bulk_streams_status_func = usbredir_bulk_streams_status;
820
        dev->parser->control_packet_func = usbredir_control_packet;
821
        dev->parser->bulk_packet_func = usbredir_bulk_packet;
822
        dev->parser->iso_packet_func = usbredir_iso_packet;
823
        dev->parser->interrupt_packet_func = usbredir_interrupt_packet;
824
        dev->read_buf = NULL;
825
        dev->read_buf_size = 0;
826

    
827
        usbredirparser_caps_set_cap(caps, usb_redir_cap_connect_device_version);
828
        usbredirparser_caps_set_cap(caps, usb_redir_cap_filter);
829
        usbredirparser_init(dev->parser, VERSION, caps, USB_REDIR_CAPS_SIZE, 0);
830
        usbredirparser_do_write(dev->parser);
831
    }
832
}
833

    
834
static void usbredir_do_attach(void *opaque)
835
{
836
    USBRedirDevice *dev = opaque;
837

    
838
    usb_device_attach(&dev->dev);
839
}
840

    
841
/*
842
 * chardev callbacks
843
 */
844

    
845
static int usbredir_chardev_can_read(void *opaque)
846
{
847
    USBRedirDevice *dev = opaque;
848

    
849
    if (dev->parser) {
850
        /* usbredir_parser_do_read will consume *all* data we give it */
851
        return 1024 * 1024;
852
    } else {
853
        /* usbredir_open_close_bh hasn't handled the open event yet */
854
        return 0;
855
    }
856
}
857

    
858
static void usbredir_chardev_read(void *opaque, const uint8_t *buf, int size)
859
{
860
    USBRedirDevice *dev = opaque;
861

    
862
    /* No recursion allowed! */
863
    assert(dev->read_buf == NULL);
864

    
865
    dev->read_buf = buf;
866
    dev->read_buf_size = size;
867

    
868
    usbredirparser_do_read(dev->parser);
869
    /* Send any acks, etc. which may be queued now */
870
    usbredirparser_do_write(dev->parser);
871
}
872

    
873
static void usbredir_chardev_event(void *opaque, int event)
874
{
875
    USBRedirDevice *dev = opaque;
876

    
877
    switch (event) {
878
    case CHR_EVENT_OPENED:
879
    case CHR_EVENT_CLOSED:
880
        qemu_bh_schedule(dev->open_close_bh);
881
        break;
882
    }
883
}
884

    
885
/*
886
 * init + destroy
887
 */
888

    
889
static int usbredir_initfn(USBDevice *udev)
890
{
891
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
892
    int i;
893

    
894
    if (dev->cs == NULL) {
895
        qerror_report(QERR_MISSING_PARAMETER, "chardev");
896
        return -1;
897
    }
898

    
899
    if (dev->filter_str) {
900
        i = usbredirfilter_string_to_rules(dev->filter_str, ":", "|",
901
                                           &dev->filter_rules,
902
                                           &dev->filter_rules_count);
903
        if (i) {
904
            qerror_report(QERR_INVALID_PARAMETER_VALUE, "filter",
905
                          "a usb device filter string");
906
            return -1;
907
        }
908
    }
909

    
910
    dev->open_close_bh = qemu_bh_new(usbredir_open_close_bh, dev);
911
    dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
912

    
913
    QTAILQ_INIT(&dev->asyncq);
914
    for (i = 0; i < MAX_ENDPOINTS; i++) {
915
        QTAILQ_INIT(&dev->endpoint[i].bufpq);
916
    }
917

    
918
    /* We'll do the attach once we receive the speed from the usb-host */
919
    udev->auto_attach = 0;
920

    
921
    /* Let the backend know we are ready */
922
    qemu_chr_fe_open(dev->cs);
923
    qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read,
924
                          usbredir_chardev_read, usbredir_chardev_event, dev);
925

    
926
    return 0;
927
}
928

    
929
static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
930
{
931
    AsyncURB *aurb, *next_aurb;
932
    int i;
933

    
934
    QTAILQ_FOREACH_SAFE(aurb, &dev->asyncq, next, next_aurb) {
935
        async_free(dev, aurb);
936
    }
937
    for (i = 0; i < MAX_ENDPOINTS; i++) {
938
        usbredir_free_bufpq(dev, I2EP(i));
939
    }
940
}
941

    
942
static void usbredir_handle_destroy(USBDevice *udev)
943
{
944
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
945

    
946
    qemu_chr_fe_close(dev->cs);
947
    qemu_chr_delete(dev->cs);
948
    /* Note must be done after qemu_chr_close, as that causes a close event */
949
    qemu_bh_delete(dev->open_close_bh);
950

    
951
    qemu_del_timer(dev->attach_timer);
952
    qemu_free_timer(dev->attach_timer);
953

    
954
    usbredir_cleanup_device_queues(dev);
955

    
956
    if (dev->parser) {
957
        usbredirparser_destroy(dev->parser);
958
    }
959

    
960
    free(dev->filter_rules);
961
}
962

    
963
static int usbredir_check_filter(USBRedirDevice *dev)
964
{
965
    if (dev->interface_info.interface_count == 0) {
966
        ERROR("No interface info for device\n");
967
        goto error;
968
    }
969

    
970
    if (dev->filter_rules) {
971
        if (!usbredirparser_peer_has_cap(dev->parser,
972
                                    usb_redir_cap_connect_device_version)) {
973
            ERROR("Device filter specified and peer does not have the "
974
                  "connect_device_version capability\n");
975
            goto error;
976
        }
977

    
978
        if (usbredirfilter_check(
979
                dev->filter_rules,
980
                dev->filter_rules_count,
981
                dev->device_info.device_class,
982
                dev->device_info.device_subclass,
983
                dev->device_info.device_protocol,
984
                dev->interface_info.interface_class,
985
                dev->interface_info.interface_subclass,
986
                dev->interface_info.interface_protocol,
987
                dev->interface_info.interface_count,
988
                dev->device_info.vendor_id,
989
                dev->device_info.product_id,
990
                dev->device_info.device_version_bcd,
991
                0) != 0) {
992
            goto error;
993
        }
994
    }
995

    
996
    return 0;
997

    
998
error:
999
    usbredir_device_disconnect(dev);
1000
    if (usbredirparser_peer_has_cap(dev->parser, usb_redir_cap_filter)) {
1001
        usbredirparser_send_filter_reject(dev->parser);
1002
        usbredirparser_do_write(dev->parser);
1003
    }
1004
    return -1;
1005
}
1006

    
1007
/*
1008
 * usbredirparser packet complete callbacks
1009
 */
1010

    
1011
static int usbredir_handle_status(USBRedirDevice *dev,
1012
                                       int status, int actual_len)
1013
{
1014
    switch (status) {
1015
    case usb_redir_success:
1016
        return actual_len;
1017
    case usb_redir_stall:
1018
        return USB_RET_STALL;
1019
    case usb_redir_cancelled:
1020
        WARNING("returning cancelled packet to HC?\n");
1021
    case usb_redir_inval:
1022
    case usb_redir_ioerror:
1023
    case usb_redir_timeout:
1024
    default:
1025
        return USB_RET_NAK;
1026
    }
1027
}
1028

    
1029
static void usbredir_hello(void *priv, struct usb_redir_hello_header *h)
1030
{
1031
    USBRedirDevice *dev = priv;
1032

    
1033
    /* Try to send the filter info now that we've the usb-host's caps */
1034
    if (usbredirparser_peer_has_cap(dev->parser, usb_redir_cap_filter) &&
1035
            dev->filter_rules) {
1036
        usbredirparser_send_filter_filter(dev->parser, dev->filter_rules,
1037
                                          dev->filter_rules_count);
1038
        usbredirparser_do_write(dev->parser);
1039
    }
1040
}
1041

    
1042
static void usbredir_device_connect(void *priv,
1043
    struct usb_redir_device_connect_header *device_connect)
1044
{
1045
    USBRedirDevice *dev = priv;
1046
    const char *speed;
1047

    
1048
    if (qemu_timer_pending(dev->attach_timer) || dev->dev.attached) {
1049
        ERROR("Received device connect while already connected\n");
1050
        return;
1051
    }
1052

    
1053
    switch (device_connect->speed) {
1054
    case usb_redir_speed_low:
1055
        speed = "low speed";
1056
        dev->dev.speed = USB_SPEED_LOW;
1057
        break;
1058
    case usb_redir_speed_full:
1059
        speed = "full speed";
1060
        dev->dev.speed = USB_SPEED_FULL;
1061
        break;
1062
    case usb_redir_speed_high:
1063
        speed = "high speed";
1064
        dev->dev.speed = USB_SPEED_HIGH;
1065
        break;
1066
    case usb_redir_speed_super:
1067
        speed = "super speed";
1068
        dev->dev.speed = USB_SPEED_SUPER;
1069
        break;
1070
    default:
1071
        speed = "unknown speed";
1072
        dev->dev.speed = USB_SPEED_FULL;
1073
    }
1074

    
1075
    if (usbredirparser_peer_has_cap(dev->parser,
1076
                                    usb_redir_cap_connect_device_version)) {
1077
        INFO("attaching %s device %04x:%04x version %d.%d class %02x\n",
1078
             speed, device_connect->vendor_id, device_connect->product_id,
1079
             ((device_connect->device_version_bcd & 0xf000) >> 12) * 10 +
1080
             ((device_connect->device_version_bcd & 0x0f00) >>  8),
1081
             ((device_connect->device_version_bcd & 0x00f0) >>  4) * 10 +
1082
             ((device_connect->device_version_bcd & 0x000f) >>  0),
1083
             device_connect->device_class);
1084
    } else {
1085
        INFO("attaching %s device %04x:%04x class %02x\n", speed,
1086
             device_connect->vendor_id, device_connect->product_id,
1087
             device_connect->device_class);
1088
    }
1089

    
1090
    dev->dev.speedmask = (1 << dev->dev.speed);
1091
    dev->device_info = *device_connect;
1092

    
1093
    if (usbredir_check_filter(dev)) {
1094
        WARNING("Device %04x:%04x rejected by device filter, not attaching\n",
1095
                device_connect->vendor_id, device_connect->product_id);
1096
        return;
1097
    }
1098

    
1099
    qemu_mod_timer(dev->attach_timer, dev->next_attach_time);
1100
}
1101

    
1102
static void usbredir_device_disconnect(void *priv)
1103
{
1104
    USBRedirDevice *dev = priv;
1105
    int i;
1106

    
1107
    /* Stop any pending attaches */
1108
    qemu_del_timer(dev->attach_timer);
1109

    
1110
    if (dev->dev.attached) {
1111
        usb_device_detach(&dev->dev);
1112
        /*
1113
         * Delay next usb device attach to give the guest a chance to see
1114
         * see the detach / attach in case of quick close / open succession
1115
         */
1116
        dev->next_attach_time = qemu_get_clock_ms(vm_clock) + 200;
1117
    }
1118

    
1119
    /* Reset state so that the next dev connected starts with a clean slate */
1120
    usbredir_cleanup_device_queues(dev);
1121
    memset(dev->endpoint, 0, sizeof(dev->endpoint));
1122
    for (i = 0; i < MAX_ENDPOINTS; i++) {
1123
        QTAILQ_INIT(&dev->endpoint[i].bufpq);
1124
    }
1125
    dev->interface_info.interface_count = 0;
1126
}
1127

    
1128
static void usbredir_interface_info(void *priv,
1129
    struct usb_redir_interface_info_header *interface_info)
1130
{
1131
    USBRedirDevice *dev = priv;
1132

    
1133
    dev->interface_info = *interface_info;
1134

    
1135
    /*
1136
     * If we receive interface info after the device has already been
1137
     * connected (ie on a set_config), re-check the filter.
1138
     */
1139
    if (qemu_timer_pending(dev->attach_timer) || dev->dev.attached) {
1140
        if (usbredir_check_filter(dev)) {
1141
            ERROR("Device no longer matches filter after interface info "
1142
                  "change, disconnecting!\n");
1143
        }
1144
    }
1145
}
1146

    
1147
static void usbredir_ep_info(void *priv,
1148
    struct usb_redir_ep_info_header *ep_info)
1149
{
1150
    USBRedirDevice *dev = priv;
1151
    int i;
1152

    
1153
    for (i = 0; i < MAX_ENDPOINTS; i++) {
1154
        dev->endpoint[i].type = ep_info->type[i];
1155
        dev->endpoint[i].interval = ep_info->interval[i];
1156
        dev->endpoint[i].interface = ep_info->interface[i];
1157
        switch (dev->endpoint[i].type) {
1158
        case usb_redir_type_invalid:
1159
            break;
1160
        case usb_redir_type_iso:
1161
        case usb_redir_type_interrupt:
1162
            if (dev->endpoint[i].interval == 0) {
1163
                ERROR("Received 0 interval for isoc or irq endpoint\n");
1164
                usbredir_device_disconnect(dev);
1165
            }
1166
            /* Fall through */
1167
        case usb_redir_type_control:
1168
        case usb_redir_type_bulk:
1169
            DPRINTF("ep: %02X type: %d interface: %d\n", I2EP(i),
1170
                    dev->endpoint[i].type, dev->endpoint[i].interface);
1171
            break;
1172
        default:
1173
            ERROR("Received invalid endpoint type\n");
1174
            usbredir_device_disconnect(dev);
1175
        }
1176
    }
1177
}
1178

    
1179
static void usbredir_configuration_status(void *priv, uint32_t id,
1180
    struct usb_redir_configuration_status_header *config_status)
1181
{
1182
    USBRedirDevice *dev = priv;
1183
    AsyncURB *aurb;
1184
    int len = 0;
1185

    
1186
    DPRINTF("set config status %d config %d id %u\n", config_status->status,
1187
            config_status->configuration, id);
1188

    
1189
    aurb = async_find(dev, id);
1190
    if (!aurb) {
1191
        return;
1192
    }
1193
    if (aurb->packet) {
1194
        if (aurb->get) {
1195
            dev->dev.data_buf[0] = config_status->configuration;
1196
            len = 1;
1197
        }
1198
        aurb->packet->result =
1199
            usbredir_handle_status(dev, config_status->status, len);
1200
        usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1201
    }
1202
    async_free(dev, aurb);
1203
}
1204

    
1205
static void usbredir_alt_setting_status(void *priv, uint32_t id,
1206
    struct usb_redir_alt_setting_status_header *alt_setting_status)
1207
{
1208
    USBRedirDevice *dev = priv;
1209
    AsyncURB *aurb;
1210
    int len = 0;
1211

    
1212
    DPRINTF("alt status %d intf %d alt %d id: %u\n",
1213
            alt_setting_status->status,
1214
            alt_setting_status->interface,
1215
            alt_setting_status->alt, id);
1216

    
1217
    aurb = async_find(dev, id);
1218
    if (!aurb) {
1219
        return;
1220
    }
1221
    if (aurb->packet) {
1222
        if (aurb->get) {
1223
            dev->dev.data_buf[0] = alt_setting_status->alt;
1224
            len = 1;
1225
        }
1226
        aurb->packet->result =
1227
            usbredir_handle_status(dev, alt_setting_status->status, len);
1228
        usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1229
    }
1230
    async_free(dev, aurb);
1231
}
1232

    
1233
static void usbredir_iso_stream_status(void *priv, uint32_t id,
1234
    struct usb_redir_iso_stream_status_header *iso_stream_status)
1235
{
1236
    USBRedirDevice *dev = priv;
1237
    uint8_t ep = iso_stream_status->endpoint;
1238

    
1239
    DPRINTF("iso status %d ep %02X id %u\n", iso_stream_status->status,
1240
            ep, id);
1241

    
1242
    if (!dev->dev.attached || !dev->endpoint[EP2I(ep)].iso_started) {
1243
        return;
1244
    }
1245

    
1246
    dev->endpoint[EP2I(ep)].iso_error = iso_stream_status->status;
1247
    if (iso_stream_status->status == usb_redir_stall) {
1248
        DPRINTF("iso stream stopped by peer ep %02X\n", ep);
1249
        dev->endpoint[EP2I(ep)].iso_started = 0;
1250
    }
1251
}
1252

    
1253
static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
1254
    struct usb_redir_interrupt_receiving_status_header
1255
    *interrupt_receiving_status)
1256
{
1257
    USBRedirDevice *dev = priv;
1258
    uint8_t ep = interrupt_receiving_status->endpoint;
1259

    
1260
    DPRINTF("interrupt recv status %d ep %02X id %u\n",
1261
            interrupt_receiving_status->status, ep, id);
1262

    
1263
    if (!dev->dev.attached || !dev->endpoint[EP2I(ep)].interrupt_started) {
1264
        return;
1265
    }
1266

    
1267
    dev->endpoint[EP2I(ep)].interrupt_error =
1268
        interrupt_receiving_status->status;
1269
    if (interrupt_receiving_status->status == usb_redir_stall) {
1270
        DPRINTF("interrupt receiving stopped by peer ep %02X\n", ep);
1271
        dev->endpoint[EP2I(ep)].interrupt_started = 0;
1272
    }
1273
}
1274

    
1275
static void usbredir_bulk_streams_status(void *priv, uint32_t id,
1276
    struct usb_redir_bulk_streams_status_header *bulk_streams_status)
1277
{
1278
}
1279

    
1280
static void usbredir_control_packet(void *priv, uint32_t id,
1281
    struct usb_redir_control_packet_header *control_packet,
1282
    uint8_t *data, int data_len)
1283
{
1284
    USBRedirDevice *dev = priv;
1285
    int len = control_packet->length;
1286
    AsyncURB *aurb;
1287

    
1288
    DPRINTF("ctrl-in status %d len %d id %u\n", control_packet->status,
1289
            len, id);
1290

    
1291
    aurb = async_find(dev, id);
1292
    if (!aurb) {
1293
        free(data);
1294
        return;
1295
    }
1296

    
1297
    aurb->control_packet.status = control_packet->status;
1298
    aurb->control_packet.length = control_packet->length;
1299
    if (memcmp(&aurb->control_packet, control_packet,
1300
               sizeof(*control_packet))) {
1301
        ERROR("return control packet mismatch, please report this!\n");
1302
        len = USB_RET_NAK;
1303
    }
1304

    
1305
    if (aurb->packet) {
1306
        len = usbredir_handle_status(dev, control_packet->status, len);
1307
        if (len > 0) {
1308
            usbredir_log_data(dev, "ctrl data in:", data, data_len);
1309
            if (data_len <= sizeof(dev->dev.data_buf)) {
1310
                memcpy(dev->dev.data_buf, data, data_len);
1311
            } else {
1312
                ERROR("ctrl buffer too small (%d > %zu)\n",
1313
                      data_len, sizeof(dev->dev.data_buf));
1314
                len = USB_RET_STALL;
1315
            }
1316
        }
1317
        aurb->packet->result = len;
1318
        usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1319
    }
1320
    async_free(dev, aurb);
1321
    free(data);
1322
}
1323

    
1324
static void usbredir_bulk_packet(void *priv, uint32_t id,
1325
    struct usb_redir_bulk_packet_header *bulk_packet,
1326
    uint8_t *data, int data_len)
1327
{
1328
    USBRedirDevice *dev = priv;
1329
    uint8_t ep = bulk_packet->endpoint;
1330
    int len = bulk_packet->length;
1331
    AsyncURB *aurb;
1332

    
1333
    DPRINTF("bulk-in status %d ep %02X len %d id %u\n", bulk_packet->status,
1334
            ep, len, id);
1335

    
1336
    aurb = async_find(dev, id);
1337
    if (!aurb) {
1338
        free(data);
1339
        return;
1340
    }
1341

    
1342
    if (aurb->bulk_packet.endpoint != bulk_packet->endpoint ||
1343
            aurb->bulk_packet.stream_id != bulk_packet->stream_id) {
1344
        ERROR("return bulk packet mismatch, please report this!\n");
1345
        len = USB_RET_NAK;
1346
    }
1347

    
1348
    if (aurb->packet) {
1349
        len = usbredir_handle_status(dev, bulk_packet->status, len);
1350
        if (len > 0) {
1351
            usbredir_log_data(dev, "bulk data in:", data, data_len);
1352
            if (data_len <= aurb->packet->iov.size) {
1353
                usb_packet_copy(aurb->packet, data, data_len);
1354
            } else {
1355
                ERROR("bulk buffer too small (%d > %zd)\n", data_len,
1356
                      aurb->packet->iov.size);
1357
                len = USB_RET_STALL;
1358
            }
1359
        }
1360
        aurb->packet->result = len;
1361
        usb_packet_complete(&dev->dev, aurb->packet);
1362
    }
1363
    async_free(dev, aurb);
1364
    free(data);
1365
}
1366

    
1367
static void usbredir_iso_packet(void *priv, uint32_t id,
1368
    struct usb_redir_iso_packet_header *iso_packet,
1369
    uint8_t *data, int data_len)
1370
{
1371
    USBRedirDevice *dev = priv;
1372
    uint8_t ep = iso_packet->endpoint;
1373

    
1374
    DPRINTF2("iso-in status %d ep %02X len %d id %u\n", iso_packet->status, ep,
1375
             data_len, id);
1376

    
1377
    if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_ISOC) {
1378
        ERROR("received iso packet for non iso endpoint %02X\n", ep);
1379
        free(data);
1380
        return;
1381
    }
1382

    
1383
    if (dev->endpoint[EP2I(ep)].iso_started == 0) {
1384
        DPRINTF("received iso packet for non started stream ep %02X\n", ep);
1385
        free(data);
1386
        return;
1387
    }
1388

    
1389
    /* bufp_alloc also adds the packet to the ep queue */
1390
    bufp_alloc(dev, data, data_len, iso_packet->status, ep);
1391
}
1392

    
1393
static void usbredir_interrupt_packet(void *priv, uint32_t id,
1394
    struct usb_redir_interrupt_packet_header *interrupt_packet,
1395
    uint8_t *data, int data_len)
1396
{
1397
    USBRedirDevice *dev = priv;
1398
    uint8_t ep = interrupt_packet->endpoint;
1399

    
1400
    DPRINTF("interrupt-in status %d ep %02X len %d id %u\n",
1401
            interrupt_packet->status, ep, data_len, id);
1402

    
1403
    if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_INT) {
1404
        ERROR("received int packet for non interrupt endpoint %02X\n", ep);
1405
        free(data);
1406
        return;
1407
    }
1408

    
1409
    if (ep & USB_DIR_IN) {
1410
        if (dev->endpoint[EP2I(ep)].interrupt_started == 0) {
1411
            DPRINTF("received int packet while not started ep %02X\n", ep);
1412
            free(data);
1413
            return;
1414
        }
1415

    
1416
        /* bufp_alloc also adds the packet to the ep queue */
1417
        bufp_alloc(dev, data, data_len, interrupt_packet->status, ep);
1418
    } else {
1419
        int len = interrupt_packet->length;
1420

    
1421
        AsyncURB *aurb = async_find(dev, id);
1422
        if (!aurb) {
1423
            return;
1424
        }
1425

    
1426
        if (aurb->interrupt_packet.endpoint != interrupt_packet->endpoint) {
1427
            ERROR("return int packet mismatch, please report this!\n");
1428
            len = USB_RET_NAK;
1429
        }
1430

    
1431
        if (aurb->packet) {
1432
            aurb->packet->result = usbredir_handle_status(dev,
1433
                                               interrupt_packet->status, len);
1434
            usb_packet_complete(&dev->dev, aurb->packet);
1435
        }
1436
        async_free(dev, aurb);
1437
    }
1438
}
1439

    
1440
static Property usbredir_properties[] = {
1441
    DEFINE_PROP_CHR("chardev", USBRedirDevice, cs),
1442
    DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, 0),
1443
    DEFINE_PROP_STRING("filter", USBRedirDevice, filter_str),
1444
    DEFINE_PROP_END_OF_LIST(),
1445
};
1446

    
1447
static void usbredir_class_initfn(ObjectClass *klass, void *data)
1448
{
1449
    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
1450
    DeviceClass *dc = DEVICE_CLASS(klass);
1451

    
1452
    uc->init           = usbredir_initfn;
1453
    uc->product_desc   = "USB Redirection Device";
1454
    uc->handle_destroy = usbredir_handle_destroy;
1455
    uc->cancel_packet  = usbredir_cancel_packet;
1456
    uc->handle_reset   = usbredir_handle_reset;
1457
    uc->handle_data    = usbredir_handle_data;
1458
    uc->handle_control = usbredir_handle_control;
1459
    dc->props          = usbredir_properties;
1460
}
1461

    
1462
static TypeInfo usbredir_dev_info = {
1463
    .name          = "usb-redir",
1464
    .parent        = TYPE_USB_DEVICE,
1465
    .instance_size = sizeof(USBRedirDevice),
1466
    .class_init    = usbredir_class_initfn,
1467
};
1468

    
1469
static void usbredir_register_types(void)
1470
{
1471
    type_register_static(&usbredir_dev_info);
1472
}
1473

    
1474
type_init(usbredir_register_types)