qemu/hw/usb/dev-bluetooth.c
<<
>>
Prefs
   1/*
   2 * QEMU Bluetooth HCI USB Transport Layer v1.0
   3 *
   4 * Copyright (C) 2007 OpenMoko, Inc.
   5 * Copyright (C) 2008 Andrzej Zaborowski  <balrog@zabor.org>
   6 *
   7 * This program is free software; you can redistribute it and/or
   8 * modify it under the terms of the GNU General Public License as
   9 * published by the Free Software Foundation; either version 2 or
  10 * (at your option) version 3 of the License.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License along
  18 * with this program; if not, see <http://www.gnu.org/licenses/>.
  19 */
  20
  21#include "qemu/osdep.h"
  22#include "qemu-common.h"
  23#include "qemu/error-report.h"
  24#include "hw/usb.h"
  25#include "hw/usb/desc.h"
  26#include "sysemu/bt.h"
  27#include "hw/bt.h"
  28
  29struct USBBtState {
  30    USBDevice dev;
  31    struct HCIInfo *hci;
  32    USBEndpoint *intr;
  33
  34    int config;
  35
  36#define CFIFO_LEN_MASK  255
  37#define DFIFO_LEN_MASK  4095
  38    struct usb_hci_in_fifo_s {
  39        uint8_t data[(DFIFO_LEN_MASK + 1) * 2];
  40        struct {
  41            uint8_t *data;
  42            int len;
  43        } fifo[CFIFO_LEN_MASK + 1];
  44        int dstart, dlen, dsize, start, len;
  45    } evt, acl, sco;
  46
  47    struct usb_hci_out_fifo_s {
  48        uint8_t data[4096];
  49        int len;
  50    } outcmd, outacl, outsco;
  51};
  52
  53#define TYPE_USB_BT "usb-bt-dongle"
  54#define USB_BT(obj) OBJECT_CHECK(struct USBBtState, (obj), TYPE_USB_BT)
  55
  56#define USB_EVT_EP      1
  57#define USB_ACL_EP      2
  58#define USB_SCO_EP      3
  59
  60enum {
  61    STR_MANUFACTURER = 1,
  62    STR_SERIALNUMBER,
  63};
  64
  65static const USBDescStrings desc_strings = {
  66    [STR_MANUFACTURER]     = "QEMU",
  67    [STR_SERIALNUMBER]     = "1",
  68};
  69
  70static const USBDescIface desc_iface_bluetooth[] = {
  71    {
  72        .bInterfaceNumber              = 0,
  73        .bNumEndpoints                 = 3,
  74        .bInterfaceClass               = 0xe0, /* Wireless */
  75        .bInterfaceSubClass            = 0x01, /* Radio Frequency */
  76        .bInterfaceProtocol            = 0x01, /* Bluetooth */
  77        .eps = (USBDescEndpoint[]) {
  78            {
  79                .bEndpointAddress      = USB_DIR_IN | USB_EVT_EP,
  80                .bmAttributes          = USB_ENDPOINT_XFER_INT,
  81                .wMaxPacketSize        = 0x10,
  82                .bInterval             = 0x02,
  83            },
  84            {
  85                .bEndpointAddress      = USB_DIR_OUT | USB_ACL_EP,
  86                .bmAttributes          = USB_ENDPOINT_XFER_BULK,
  87                .wMaxPacketSize        = 0x40,
  88                .bInterval             = 0x0a,
  89            },
  90            {
  91                .bEndpointAddress      = USB_DIR_IN | USB_ACL_EP,
  92                .bmAttributes          = USB_ENDPOINT_XFER_BULK,
  93                .wMaxPacketSize        = 0x40,
  94                .bInterval             = 0x0a,
  95            },
  96        },
  97    },{
  98        .bInterfaceNumber              = 1,
  99        .bAlternateSetting             = 0,
 100        .bNumEndpoints                 = 2,
 101        .bInterfaceClass               = 0xe0, /* Wireless */
 102        .bInterfaceSubClass            = 0x01, /* Radio Frequency */
 103        .bInterfaceProtocol            = 0x01, /* Bluetooth */
 104        .eps = (USBDescEndpoint[]) {
 105            {
 106                .bEndpointAddress      = USB_DIR_OUT | USB_SCO_EP,
 107                .bmAttributes          = USB_ENDPOINT_XFER_ISOC,
 108                .wMaxPacketSize        = 0,
 109                .bInterval             = 0x01,
 110            },
 111            {
 112                .bEndpointAddress      = USB_DIR_IN | USB_SCO_EP,
 113                .bmAttributes          = USB_ENDPOINT_XFER_ISOC,
 114                .wMaxPacketSize        = 0,
 115                .bInterval             = 0x01,
 116            },
 117        },
 118    },{
 119        .bInterfaceNumber              = 1,
 120        .bAlternateSetting             = 1,
 121        .bNumEndpoints                 = 2,
 122        .bInterfaceClass               = 0xe0, /* Wireless */
 123        .bInterfaceSubClass            = 0x01, /* Radio Frequency */
 124        .bInterfaceProtocol            = 0x01, /* Bluetooth */
 125        .eps = (USBDescEndpoint[]) {
 126            {
 127                .bEndpointAddress      = USB_DIR_OUT | USB_SCO_EP,
 128                .bmAttributes          = USB_ENDPOINT_XFER_ISOC,
 129                .wMaxPacketSize        = 0x09,
 130                .bInterval             = 0x01,
 131            },
 132            {
 133                .bEndpointAddress      = USB_DIR_IN | USB_SCO_EP,
 134                .bmAttributes          = USB_ENDPOINT_XFER_ISOC,
 135                .wMaxPacketSize        = 0x09,
 136                .bInterval             = 0x01,
 137            },
 138        },
 139    },{
 140        .bInterfaceNumber              = 1,
 141        .bAlternateSetting             = 2,
 142        .bNumEndpoints                 = 2,
 143        .bInterfaceClass               = 0xe0, /* Wireless */
 144        .bInterfaceSubClass            = 0x01, /* Radio Frequency */
 145        .bInterfaceProtocol            = 0x01, /* Bluetooth */
 146        .eps = (USBDescEndpoint[]) {
 147            {
 148                .bEndpointAddress      = USB_DIR_OUT | USB_SCO_EP,
 149                .bmAttributes          = USB_ENDPOINT_XFER_ISOC,
 150                .wMaxPacketSize        = 0x11,
 151                .bInterval             = 0x01,
 152            },
 153            {
 154                .bEndpointAddress      = USB_DIR_IN | USB_SCO_EP,
 155                .bmAttributes          = USB_ENDPOINT_XFER_ISOC,
 156                .wMaxPacketSize        = 0x11,
 157                .bInterval             = 0x01,
 158            },
 159        },
 160    },{
 161        .bInterfaceNumber              = 1,
 162        .bAlternateSetting             = 3,
 163        .bNumEndpoints                 = 2,
 164        .bInterfaceClass               = 0xe0, /* Wireless */
 165        .bInterfaceSubClass            = 0x01, /* Radio Frequency */
 166        .bInterfaceProtocol            = 0x01, /* Bluetooth */
 167        .eps = (USBDescEndpoint[]) {
 168            {
 169                .bEndpointAddress      = USB_DIR_OUT | USB_SCO_EP,
 170                .bmAttributes          = USB_ENDPOINT_XFER_ISOC,
 171                .wMaxPacketSize        = 0x19,
 172                .bInterval             = 0x01,
 173            },
 174            {
 175                .bEndpointAddress      = USB_DIR_IN | USB_SCO_EP,
 176                .bmAttributes          = USB_ENDPOINT_XFER_ISOC,
 177                .wMaxPacketSize        = 0x19,
 178                .bInterval             = 0x01,
 179            },
 180        },
 181    },{
 182        .bInterfaceNumber              = 1,
 183        .bAlternateSetting             = 4,
 184        .bNumEndpoints                 = 2,
 185        .bInterfaceClass               = 0xe0, /* Wireless */
 186        .bInterfaceSubClass            = 0x01, /* Radio Frequency */
 187        .bInterfaceProtocol            = 0x01, /* Bluetooth */
 188        .eps = (USBDescEndpoint[]) {
 189            {
 190                .bEndpointAddress      = USB_DIR_OUT | USB_SCO_EP,
 191                .bmAttributes          = USB_ENDPOINT_XFER_ISOC,
 192                .wMaxPacketSize        = 0x21,
 193                .bInterval             = 0x01,
 194            },
 195            {
 196                .bEndpointAddress      = USB_DIR_IN | USB_SCO_EP,
 197                .bmAttributes          = USB_ENDPOINT_XFER_ISOC,
 198                .wMaxPacketSize        = 0x21,
 199                .bInterval             = 0x01,
 200            },
 201        },
 202    },{
 203        .bInterfaceNumber              = 1,
 204        .bAlternateSetting             = 5,
 205        .bNumEndpoints                 = 2,
 206        .bInterfaceClass               = 0xe0, /* Wireless */
 207        .bInterfaceSubClass            = 0x01, /* Radio Frequency */
 208        .bInterfaceProtocol            = 0x01, /* Bluetooth */
 209        .eps = (USBDescEndpoint[]) {
 210            {
 211                .bEndpointAddress      = USB_DIR_OUT | USB_SCO_EP,
 212                .bmAttributes          = USB_ENDPOINT_XFER_ISOC,
 213                .wMaxPacketSize        = 0x31,
 214                .bInterval             = 0x01,
 215            },
 216            {
 217                .bEndpointAddress      = USB_DIR_IN | USB_SCO_EP,
 218                .bmAttributes          = USB_ENDPOINT_XFER_ISOC,
 219                .wMaxPacketSize        = 0x31,
 220                .bInterval             = 0x01,
 221            },
 222        },
 223    }
 224};
 225
 226static const USBDescDevice desc_device_bluetooth = {
 227    .bcdUSB                        = 0x0110,
 228    .bDeviceClass                  = 0xe0, /* Wireless */
 229    .bDeviceSubClass               = 0x01, /* Radio Frequency */
 230    .bDeviceProtocol               = 0x01, /* Bluetooth */
 231    .bMaxPacketSize0               = 64,
 232    .bNumConfigurations            = 1,
 233    .confs = (USBDescConfig[]) {
 234        {
 235            .bNumInterfaces        = 2,
 236            .bConfigurationValue   = 1,
 237            .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
 238            .bMaxPower             = 0,
 239            .nif = ARRAY_SIZE(desc_iface_bluetooth),
 240            .ifs = desc_iface_bluetooth,
 241        },
 242    },
 243};
 244
 245static const USBDesc desc_bluetooth = {
 246    .id = {
 247        .idVendor          = 0x0a12,
 248        .idProduct         = 0x0001,
 249        .bcdDevice         = 0x1958,
 250        .iManufacturer     = STR_MANUFACTURER,
 251        .iProduct          = 0,
 252        .iSerialNumber     = STR_SERIALNUMBER,
 253    },
 254    .full = &desc_device_bluetooth,
 255    .str  = desc_strings,
 256};
 257
 258static void usb_bt_fifo_reset(struct usb_hci_in_fifo_s *fifo)
 259{
 260    fifo->dstart = 0;
 261    fifo->dlen = 0;
 262    fifo->dsize = DFIFO_LEN_MASK + 1;
 263    fifo->start = 0;
 264    fifo->len = 0;
 265}
 266
 267static void usb_bt_fifo_enqueue(struct usb_hci_in_fifo_s *fifo,
 268                const uint8_t *data, int len)
 269{
 270    int off = fifo->dstart + fifo->dlen;
 271    uint8_t *buf;
 272
 273    fifo->dlen += len;
 274    if (off <= DFIFO_LEN_MASK) {
 275        if (off + len > DFIFO_LEN_MASK + 1 &&
 276                        (fifo->dsize = off + len) > (DFIFO_LEN_MASK + 1) * 2) {
 277            fprintf(stderr, "%s: can't alloc %i bytes\n", __FUNCTION__, len);
 278            exit(-1);
 279        }
 280        buf = fifo->data + off;
 281    } else {
 282        if (fifo->dlen > fifo->dsize) {
 283            fprintf(stderr, "%s: can't alloc %i bytes\n", __FUNCTION__, len);
 284            exit(-1);
 285        }
 286        buf = fifo->data + off - fifo->dsize;
 287    }
 288
 289    off = (fifo->start + fifo->len ++) & CFIFO_LEN_MASK;
 290    fifo->fifo[off].data = memcpy(buf, data, len);
 291    fifo->fifo[off].len = len;
 292}
 293
 294static inline void usb_bt_fifo_dequeue(struct usb_hci_in_fifo_s *fifo,
 295                USBPacket *p)
 296{
 297    int len;
 298
 299    assert(fifo->len != 0);
 300
 301    len = MIN(p->iov.size, fifo->fifo[fifo->start].len);
 302    usb_packet_copy(p, fifo->fifo[fifo->start].data, len);
 303    if (len == p->iov.size) {
 304        fifo->fifo[fifo->start].len -= len;
 305        fifo->fifo[fifo->start].data += len;
 306    } else {
 307        fifo->start ++;
 308        fifo->start &= CFIFO_LEN_MASK;
 309        fifo->len --;
 310    }
 311
 312    fifo->dstart += len;
 313    fifo->dlen -= len;
 314    if (fifo->dstart >= fifo->dsize) {
 315        fifo->dstart = 0;
 316        fifo->dsize = DFIFO_LEN_MASK + 1;
 317    }
 318}
 319
 320static inline void usb_bt_fifo_out_enqueue(struct USBBtState *s,
 321                struct usb_hci_out_fifo_s *fifo,
 322                void (*send)(struct HCIInfo *, const uint8_t *, int),
 323                int (*complete)(const uint8_t *, int),
 324                USBPacket *p)
 325{
 326    usb_packet_copy(p, fifo->data + fifo->len, p->iov.size);
 327    fifo->len += p->iov.size;
 328    if (complete(fifo->data, fifo->len)) {
 329        send(s->hci, fifo->data, fifo->len);
 330        fifo->len = 0;
 331    }
 332
 333    /* TODO: do we need to loop? */
 334}
 335
 336static int usb_bt_hci_cmd_complete(const uint8_t *data, int len)
 337{
 338    len -= HCI_COMMAND_HDR_SIZE;
 339    return len >= 0 &&
 340            len >= ((struct hci_command_hdr *) data)->plen;
 341}
 342
 343static int usb_bt_hci_acl_complete(const uint8_t *data, int len)
 344{
 345    len -= HCI_ACL_HDR_SIZE;
 346    return len >= 0 &&
 347            len >= le16_to_cpu(((struct hci_acl_hdr *) data)->dlen);
 348}
 349
 350static int usb_bt_hci_sco_complete(const uint8_t *data, int len)
 351{
 352    len -= HCI_SCO_HDR_SIZE;
 353    return len >= 0 &&
 354            len >= ((struct hci_sco_hdr *) data)->dlen;
 355}
 356
 357static void usb_bt_handle_reset(USBDevice *dev)
 358{
 359    struct USBBtState *s = (struct USBBtState *) dev->opaque;
 360
 361    usb_bt_fifo_reset(&s->evt);
 362    usb_bt_fifo_reset(&s->acl);
 363    usb_bt_fifo_reset(&s->sco);
 364    s->outcmd.len = 0;
 365    s->outacl.len = 0;
 366    s->outsco.len = 0;
 367}
 368
 369static void usb_bt_handle_control(USBDevice *dev, USBPacket *p,
 370               int request, int value, int index, int length, uint8_t *data)
 371{
 372    struct USBBtState *s = (struct USBBtState *) dev->opaque;
 373    int ret;
 374
 375    ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
 376    if (ret >= 0) {
 377        switch (request) {
 378        case DeviceRequest | USB_REQ_GET_CONFIGURATION:
 379            s->config = 0;
 380            break;
 381        case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
 382            s->config = 1;
 383            usb_bt_fifo_reset(&s->evt);
 384            usb_bt_fifo_reset(&s->acl);
 385            usb_bt_fifo_reset(&s->sco);
 386            break;
 387        }
 388        return;
 389    }
 390
 391    switch (request) {
 392    case InterfaceRequest | USB_REQ_GET_STATUS:
 393    case EndpointRequest | USB_REQ_GET_STATUS:
 394        data[0] = 0x00;
 395        data[1] = 0x00;
 396        p->actual_length = 2;
 397        break;
 398    case InterfaceOutRequest | USB_REQ_CLEAR_FEATURE:
 399    case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
 400        goto fail;
 401    case InterfaceOutRequest | USB_REQ_SET_FEATURE:
 402    case EndpointOutRequest | USB_REQ_SET_FEATURE:
 403        goto fail;
 404        break;
 405    case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_DEVICE) << 8):
 406        if (s->config)
 407            usb_bt_fifo_out_enqueue(s, &s->outcmd, s->hci->cmd_send,
 408                            usb_bt_hci_cmd_complete, p);
 409        break;
 410    default:
 411    fail:
 412        p->status = USB_RET_STALL;
 413        break;
 414    }
 415}
 416
 417static void usb_bt_handle_data(USBDevice *dev, USBPacket *p)
 418{
 419    struct USBBtState *s = (struct USBBtState *) dev->opaque;
 420
 421    if (!s->config)
 422        goto fail;
 423
 424    switch (p->pid) {
 425    case USB_TOKEN_IN:
 426        switch (p->ep->nr) {
 427        case USB_EVT_EP:
 428            if (s->evt.len == 0) {
 429                p->status = USB_RET_NAK;
 430                break;
 431            }
 432            usb_bt_fifo_dequeue(&s->evt, p);
 433            break;
 434
 435        case USB_ACL_EP:
 436            if (s->evt.len == 0) {
 437                p->status = USB_RET_STALL;
 438                break;
 439            }
 440            usb_bt_fifo_dequeue(&s->acl, p);
 441            break;
 442
 443        case USB_SCO_EP:
 444            if (s->evt.len == 0) {
 445                p->status = USB_RET_STALL;
 446                break;
 447            }
 448            usb_bt_fifo_dequeue(&s->sco, p);
 449            break;
 450
 451        default:
 452            goto fail;
 453        }
 454        break;
 455
 456    case USB_TOKEN_OUT:
 457        switch (p->ep->nr) {
 458        case USB_ACL_EP:
 459            usb_bt_fifo_out_enqueue(s, &s->outacl, s->hci->acl_send,
 460                            usb_bt_hci_acl_complete, p);
 461            break;
 462
 463        case USB_SCO_EP:
 464            usb_bt_fifo_out_enqueue(s, &s->outsco, s->hci->sco_send,
 465                            usb_bt_hci_sco_complete, p);
 466            break;
 467
 468        default:
 469            goto fail;
 470        }
 471        break;
 472
 473    default:
 474    fail:
 475        p->status = USB_RET_STALL;
 476        break;
 477    }
 478}
 479
 480static void usb_bt_out_hci_packet_event(void *opaque,
 481                const uint8_t *data, int len)
 482{
 483    struct USBBtState *s = (struct USBBtState *) opaque;
 484
 485    if (s->evt.len == 0) {
 486        usb_wakeup(s->intr, 0);
 487    }
 488    usb_bt_fifo_enqueue(&s->evt, data, len);
 489}
 490
 491static void usb_bt_out_hci_packet_acl(void *opaque,
 492                const uint8_t *data, int len)
 493{
 494    struct USBBtState *s = (struct USBBtState *) opaque;
 495
 496    usb_bt_fifo_enqueue(&s->acl, data, len);
 497}
 498
 499static void usb_bt_unrealize(USBDevice *dev, Error **errp)
 500{
 501    struct USBBtState *s = (struct USBBtState *) dev->opaque;
 502
 503    s->hci->opaque = NULL;
 504    s->hci->evt_recv = NULL;
 505    s->hci->acl_recv = NULL;
 506}
 507
 508static void usb_bt_realize(USBDevice *dev, Error **errp)
 509{
 510    struct USBBtState *s = USB_BT(dev);
 511
 512    usb_desc_create_serial(dev);
 513    usb_desc_init(dev);
 514    s->dev.opaque = s;
 515    if (!s->hci) {
 516        s->hci = bt_new_hci(qemu_find_bt_vlan(0));
 517    }
 518    s->hci->opaque = s;
 519    s->hci->evt_recv = usb_bt_out_hci_packet_event;
 520    s->hci->acl_recv = usb_bt_out_hci_packet_acl;
 521    usb_bt_handle_reset(&s->dev);
 522    s->intr = usb_ep_get(dev, USB_TOKEN_IN, USB_EVT_EP);
 523}
 524
 525static USBDevice *usb_bt_init(USBBus *bus, const char *cmdline)
 526{
 527    USBDevice *dev;
 528    struct USBBtState *s;
 529    HCIInfo *hci;
 530    const char *name = TYPE_USB_BT;
 531
 532    if (*cmdline) {
 533        hci = hci_init(cmdline);
 534    } else {
 535        hci = bt_new_hci(qemu_find_bt_vlan(0));
 536    }
 537    if (!hci)
 538        return NULL;
 539
 540    dev = usb_create(bus, name);
 541    s = USB_BT(dev);
 542    s->hci = hci;
 543    return dev;
 544}
 545
 546static const VMStateDescription vmstate_usb_bt = {
 547    .name = "usb-bt",
 548    .unmigratable = 1,
 549};
 550
 551static void usb_bt_class_initfn(ObjectClass *klass, void *data)
 552{
 553    DeviceClass *dc = DEVICE_CLASS(klass);
 554    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
 555
 556    uc->realize        = usb_bt_realize;
 557    uc->product_desc   = "QEMU BT dongle";
 558    uc->usb_desc       = &desc_bluetooth;
 559    uc->handle_reset   = usb_bt_handle_reset;
 560    uc->handle_control = usb_bt_handle_control;
 561    uc->handle_data    = usb_bt_handle_data;
 562    uc->unrealize      = usb_bt_unrealize;
 563    dc->vmsd = &vmstate_usb_bt;
 564    set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
 565}
 566
 567static const TypeInfo bt_info = {
 568    .name          = TYPE_USB_BT,
 569    .parent        = TYPE_USB_DEVICE,
 570    .instance_size = sizeof(struct USBBtState),
 571    .class_init    = usb_bt_class_initfn,
 572};
 573
 574static void usb_bt_register_types(void)
 575{
 576    type_register_static(&bt_info);
 577    usb_legacy_register(TYPE_USB_BT, "bt", usb_bt_init);
 578}
 579
 580type_init(usb_bt_register_types)
 581