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