Commit 1ae26a18a33263330e1551abf5244d68f8aa825a

Authored by balrog
1 parent c0d82995

Add a "null" bluetooth HCI and a header file for bluetooth.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5342 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile
... ... @@ -81,6 +81,7 @@ OBJS+=scsi-generic.o
81 81 OBJS+=usb.o usb-hub.o usb-linux.o usb-hid.o usb-msd.o usb-wacom.o
82 82 OBJS+=usb-serial.o usb-net.o
83 83 OBJS+=sd.o ssi-sd.o
  84 +OBJS+=bt.o
84 85  
85 86 ifdef CONFIG_BRLAPI
86 87 OBJS+= baum.o
... ...
hw/bt.c 0 → 100644
  1 +/*
  2 + * Convenience functions for bluetooth.
  3 + *
  4 + * Copyright (C) 2008 Andrzej Zaborowski <balrog@zabor.org>
  5 + *
  6 + * This program is free software; you can redistribute it and/or
  7 + * modify it under the terms of the GNU General Public License as
  8 + * published by the Free Software Foundation; either version 2 or
  9 + * (at your option) version 3 of the License.
  10 + *
  11 + * This program is distributed in the hope that it will be useful,
  12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + * GNU General Public License for more details.
  15 + *
  16 + * You should have received a copy of the GNU General Public License
  17 + * along with this program; if not, write to the Free Software
  18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  19 + * MA 02111-1307 USA
  20 + */
  21 +
  22 +#include "qemu-common.h"
  23 +#include "net.h"
  24 +#include "bt.h"
  25 +
  26 +/* Slave implementations can ignore this */
  27 +static void bt_dummy_lmp_mode_change(struct bt_link_s *link)
  28 +{
  29 +}
  30 +
  31 +/* Slaves should never receive these PDUs */
  32 +static void bt_dummy_lmp_connection_complete(struct bt_link_s *link)
  33 +{
  34 + if (link->slave->reject_reason)
  35 + fprintf(stderr, "%s: stray LMP_not_accepted received, fixme\n",
  36 + __FUNCTION__);
  37 + else
  38 + fprintf(stderr, "%s: stray LMP_accepted received, fixme\n",
  39 + __FUNCTION__);
  40 + exit(-1);
  41 +}
  42 +
  43 +static void bt_dummy_lmp_disconnect_master(struct bt_link_s *link)
  44 +{
  45 + fprintf(stderr, "%s: stray LMP_detach received, fixme\n", __FUNCTION__);
  46 + exit(-1);
  47 +}
  48 +
  49 +static void bt_dummy_lmp_acl_resp(struct bt_link_s *link,
  50 + const uint8_t *data, int start, int len)
  51 +{
  52 + fprintf(stderr, "%s: stray ACL response PDU, fixme\n", __FUNCTION__);
  53 + exit(-1);
  54 +}
  55 +
  56 +/* Slaves that don't hold any additional per link state can use these */
  57 +static void bt_dummy_lmp_connection_request(struct bt_link_s *req)
  58 +{
  59 + struct bt_link_s *link = qemu_mallocz(sizeof(struct bt_link_s));
  60 +
  61 + link->slave = req->slave;
  62 + link->host = req->host;
  63 +
  64 + req->host->reject_reason = 0;
  65 + req->host->lmp_connection_complete(link);
  66 +}
  67 +
  68 +static void bt_dummy_lmp_disconnect_slave(struct bt_link_s *link)
  69 +{
  70 + qemu_free(link);
  71 +}
  72 +
  73 +static void bt_dummy_destroy(struct bt_device_s *device)
  74 +{
  75 + bt_device_done(device);
  76 + qemu_free(device);
  77 +}
  78 +
  79 +static int bt_dev_idx = 0;
  80 +
  81 +void bt_device_init(struct bt_device_s *dev, struct bt_scatternet_s *net)
  82 +{
  83 + memset(dev, 0, sizeof(*dev));
  84 + dev->inquiry_scan = 1;
  85 + dev->page_scan = 1;
  86 +
  87 + dev->bd_addr.b[0] = bt_dev_idx & 0xff;
  88 + dev->bd_addr.b[1] = bt_dev_idx >> 8;
  89 + dev->bd_addr.b[2] = 0xd0;
  90 + dev->bd_addr.b[3] = 0xba;
  91 + dev->bd_addr.b[4] = 0xbe;
  92 + dev->bd_addr.b[5] = 0xba;
  93 + bt_dev_idx ++;
  94 +
  95 + /* Simple slave-only devices need to implement only .lmp_acl_data */
  96 + dev->lmp_connection_complete = bt_dummy_lmp_connection_complete;
  97 + dev->lmp_disconnect_master = bt_dummy_lmp_disconnect_master;
  98 + dev->lmp_acl_resp = bt_dummy_lmp_acl_resp;
  99 + dev->lmp_mode_change = bt_dummy_lmp_mode_change;
  100 + dev->lmp_connection_request = bt_dummy_lmp_connection_request;
  101 + dev->lmp_disconnect_slave = bt_dummy_lmp_disconnect_slave;
  102 +
  103 + dev->handle_destroy = bt_dummy_destroy;
  104 +
  105 + dev->net = net;
  106 + dev->next = net->slave;
  107 + net->slave = dev;
  108 +}
  109 +
  110 +void bt_device_done(struct bt_device_s *dev)
  111 +{
  112 + struct bt_device_s **p = &dev->net->slave;
  113 +
  114 + while (*p && *p != dev)
  115 + p = &(*p)->next;
  116 + if (*p != dev) {
  117 + fprintf(stderr, "%s: bad bt device \"%s\"\n", __FUNCTION__,
  118 + dev->lmp_name ?: "(null)");
  119 + exit(-1);
  120 + }
  121 +
  122 + *p = dev->next;
  123 +}
... ...
hw/bt.h 0 → 100644
  1 +/*
  2 + * QEMU Bluetooth HCI helpers.
  3 + *
  4 + * Copyright (C) 2007 OpenMoko, Inc.
  5 + * Written by Andrzej Zaborowski <andrew@openedhand.com>
  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 of
  10 + * the License, or (at your option) any later version.
  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
  18 + * along with this program; if not, write to the Free Software
  19 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
  20 + * MA 02110-1301 USA
  21 + */
  22 +
  23 +/* BD Address */
  24 +typedef struct {
  25 + uint8_t b[6];
  26 +} __attribute__((packed)) bdaddr_t;
  27 +
  28 +#define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}})
  29 +#define BDADDR_ALL (&(bdaddr_t) {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}})
  30 +#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}})
  31 +
  32 +/* Copy, swap, convert BD Address */
  33 +static inline int bacmp(const bdaddr_t *ba1, const bdaddr_t *ba2)
  34 +{
  35 + return memcmp(ba1, ba2, sizeof(bdaddr_t));
  36 +}
  37 +static inline void bacpy(bdaddr_t *dst, const bdaddr_t *src)
  38 +{
  39 + memcpy(dst, src, sizeof(bdaddr_t));
  40 +}
  41 +
  42 +#define BAINIT(orig) { .b = { \
  43 + (orig)->b[0], (orig)->b[1], (orig)->b[2], \
  44 + (orig)->b[3], (orig)->b[4], (orig)->b[5], \
  45 +}, }
  46 +
  47 +/* The twisted structures of a bluetooth environment */
  48 +struct bt_device_s;
  49 +struct bt_scatternet_s;
  50 +struct bt_piconet_s;
  51 +struct bt_link_s;
  52 +
  53 +struct bt_scatternet_s {
  54 + struct bt_device_s *slave;
  55 +};
  56 +
  57 +struct bt_link_s {
  58 + struct bt_device_s *slave, *host;
  59 + uint16_t handle; /* Master (host) side handle */
  60 + uint16_t acl_interval;
  61 + enum {
  62 + acl_active,
  63 + acl_hold,
  64 + acl_sniff,
  65 + acl_parked,
  66 + } acl_mode;
  67 +};
  68 +
  69 +struct bt_device_s {
  70 + int lt_addr;
  71 + bdaddr_t bd_addr;
  72 + int mtu;
  73 + int setup;
  74 + struct bt_scatternet_s *net;
  75 +
  76 + uint8_t key[16];
  77 + int key_present;
  78 + uint8_t class[3];
  79 +
  80 + uint8_t reject_reason;
  81 +
  82 + uint64_t lmp_caps;
  83 + const char *lmp_name;
  84 + void (*lmp_connection_request)(struct bt_link_s *link);
  85 + void (*lmp_connection_complete)(struct bt_link_s *link);
  86 + void (*lmp_disconnect_master)(struct bt_link_s *link);
  87 + void (*lmp_disconnect_slave)(struct bt_link_s *link);
  88 + void (*lmp_acl_data)(struct bt_link_s *link, const uint8_t *data,
  89 + int start, int len);
  90 + void (*lmp_acl_resp)(struct bt_link_s *link, const uint8_t *data,
  91 + int start, int len);
  92 + void (*lmp_mode_change)(struct bt_link_s *link);
  93 +
  94 + void (*handle_destroy)(struct bt_device_s *device);
  95 + struct bt_device_s *next; /* Next in the piconet/scatternet */
  96 +
  97 + int inquiry_scan;
  98 + int page_scan;
  99 +
  100 + uint16_t clkoff; /* Note: Always little-endian */
  101 +};
  102 +
  103 +/* bt.c */
  104 +void bt_device_init(struct bt_device_s *dev, struct bt_scatternet_s *net);
  105 +void bt_device_done(struct bt_device_s *dev);
... ...
hw/nseries.c
... ... @@ -31,6 +31,7 @@
31 31 #include "devices.h"
32 32 #include "flash.h"
33 33 #include "hw.h"
  34 +#include "bt.h"
34 35  
35 36 /* Nokia N8x0 support */
36 37 struct n800_s {
... ... @@ -122,10 +123,6 @@ struct n800_s {
122 123  
123 124 #define N8X0_BD_ADDR 0x00, 0x1a, 0x89, 0x9e, 0x3e, 0x81
124 125  
125   -typedef struct {
126   - uint8_t b[6];
127   -} __attribute__((packed)) bdaddr_t; /* XXX: move to BT headers */
128   -
129 126 static void n800_mmc_cs_cb(void *opaque, int line, int level)
130 127 {
131 128 /* TODO: this seems to actually be connected to the menelaus, to
... ...
... ... @@ -48,6 +48,20 @@ struct NICInfo {
48 48 extern int nb_nics;
49 49 extern NICInfo nd_table[MAX_NICS];
50 50  
  51 +/* BT HCI info */
  52 +
  53 +struct HCIInfo {
  54 + int (*bdaddr_set)(struct HCIInfo *hci, const uint8_t *bd_addr);
  55 + void (*cmd_send)(struct HCIInfo *hci, const uint8_t *data, int len);
  56 + void (*sco_send)(struct HCIInfo *hci, const uint8_t *data, int len);
  57 + void (*acl_send)(struct HCIInfo *hci, const uint8_t *data, int len);
  58 + void *opaque;
  59 + void (*evt_recv)(void *opaque, const uint8_t *data, int len);
  60 + void (*acl_recv)(void *opaque, const uint8_t *data, int len);
  61 +};
  62 +
  63 +struct HCIInfo *qemu_next_hci(void);
  64 +
51 65 /* checksumming functions (net-checksum.c) */
52 66 uint32_t net_checksum_add(int len, uint8_t *buf);
53 67 uint16_t net_checksum_finish(uint32_t sum);
... ...
qemu-common.h
... ... @@ -116,6 +116,7 @@ typedef int (*DMA_transfer_handler) (void *opaque, int nchan, int pos, int size)
116 116 /* A load of opaque types so that device init declarations don't have to
117 117 pull in all the real definitions. */
118 118 typedef struct NICInfo NICInfo;
  119 +typedef struct HCIInfo HCIInfo;
119 120 typedef struct AudioState AudioState;
120 121 typedef struct BlockDriverState BlockDriverState;
121 122 typedef struct DisplayState DisplayState;
... ...
... ... @@ -29,6 +29,7 @@
29 29 #include "hw/audiodev.h"
30 30 #include "hw/isa.h"
31 31 #include "hw/baum.h"
  32 +#include "hw/bt.h"
32 33 #include "net.h"
33 34 #include "console.h"
34 35 #include "sysemu.h"
... ... @@ -5361,6 +5362,61 @@ void do_info_network(void)
5361 5362 }
5362 5363 }
5363 5364  
  5365 +/***********************************************************/
  5366 +/* Bluetooth support */
  5367 +static int nb_hcis;
  5368 +static int cur_hci;
  5369 +static struct HCIInfo *hci_table[MAX_NICS];
  5370 +static struct bt_vlan_s {
  5371 + struct bt_scatternet_s net;
  5372 + int id;
  5373 + struct bt_vlan_s *next;
  5374 +} *first_bt_vlan;
  5375 +
  5376 +/* find or alloc a new bluetooth "VLAN" */
  5377 +struct bt_scatternet_s *qemu_find_bt_vlan(int id)
  5378 +{
  5379 + struct bt_vlan_s **pvlan, *vlan;
  5380 + for (vlan = first_bt_vlan; vlan != NULL; vlan = vlan->next) {
  5381 + if (vlan->id == id)
  5382 + return &vlan->net;
  5383 + }
  5384 + vlan = qemu_mallocz(sizeof(struct bt_vlan_s));
  5385 + vlan->id = id;
  5386 + pvlan = &first_bt_vlan;
  5387 + while (*pvlan != NULL)
  5388 + pvlan = &(*pvlan)->next;
  5389 + *pvlan = vlan;
  5390 + return &vlan->net;
  5391 +}
  5392 +
  5393 +static void null_hci_send(struct HCIInfo *hci, const uint8_t *data, int len)
  5394 +{
  5395 +}
  5396 +
  5397 +static int null_hci_addr_set(struct HCIInfo *hci, const uint8_t *bd_addr)
  5398 +{
  5399 + return -ENOTSUP;
  5400 +}
  5401 +
  5402 +static struct HCIInfo null_hci = {
  5403 + .cmd_send = null_hci_send,
  5404 + .sco_send = null_hci_send,
  5405 + .acl_send = null_hci_send,
  5406 + .bdaddr_set = null_hci_addr_set,
  5407 +};
  5408 +
  5409 +struct HCIInfo *qemu_next_hci(void)
  5410 +{
  5411 + if (cur_hci == nb_hcis)
  5412 + return &null_hci;
  5413 +
  5414 + return hci_table[cur_hci++];
  5415 +}
  5416 +
  5417 +/***********************************************************/
  5418 +/* QEMU Block devices */
  5419 +
5364 5420 #define HD_ALIAS "index=%d,media=disk"
5365 5421 #ifdef TARGET_PPC
5366 5422 #define CDROM_ALIAS "index=1,media=cdrom"
... ...