qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [5342] Add a "null" bluetooth HCI and a header file for blu


From: Andrzej Zaborowski
Subject: [Qemu-devel] [5342] Add a "null" bluetooth HCI and a header file for bluetooth.
Date: Sun, 28 Sep 2008 23:19:48 +0000

Revision: 5342
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=5342
Author:   balrog
Date:     2008-09-28 23:19:47 +0000 (Sun, 28 Sep 2008)

Log Message:
-----------
Add a "null" bluetooth HCI and a header file for bluetooth.

Modified Paths:
--------------
    trunk/Makefile
    trunk/hw/nseries.c
    trunk/net.h
    trunk/qemu-common.h
    trunk/vl.c

Added Paths:
-----------
    trunk/hw/bt.c
    trunk/hw/bt.h

Modified: trunk/Makefile
===================================================================
--- trunk/Makefile      2008-09-28 22:02:30 UTC (rev 5341)
+++ trunk/Makefile      2008-09-28 23:19:47 UTC (rev 5342)
@@ -81,6 +81,7 @@
 OBJS+=usb.o usb-hub.o usb-linux.o usb-hid.o usb-msd.o usb-wacom.o
 OBJS+=usb-serial.o usb-net.o
 OBJS+=sd.o ssi-sd.o
+OBJS+=bt.o
 
 ifdef CONFIG_BRLAPI
 OBJS+= baum.o

Added: trunk/hw/bt.c
===================================================================
--- trunk/hw/bt.c                               (rev 0)
+++ trunk/hw/bt.c       2008-09-28 23:19:47 UTC (rev 5342)
@@ -0,0 +1,123 @@
+/*
+ * Convenience functions for bluetooth.
+ *
+ * Copyright (C) 2008 Andrzej Zaborowski  <address@hidden>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 or
+ * (at your option) version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include "qemu-common.h"
+#include "net.h"
+#include "bt.h"
+
+/* Slave implementations can ignore this */
+static void bt_dummy_lmp_mode_change(struct bt_link_s *link)
+{
+}
+
+/* Slaves should never receive these PDUs */
+static void bt_dummy_lmp_connection_complete(struct bt_link_s *link)
+{
+    if (link->slave->reject_reason)
+        fprintf(stderr, "%s: stray LMP_not_accepted received, fixme\n",
+                        __FUNCTION__);
+    else
+        fprintf(stderr, "%s: stray LMP_accepted received, fixme\n",
+                        __FUNCTION__);
+    exit(-1);
+}
+
+static void bt_dummy_lmp_disconnect_master(struct bt_link_s *link)
+{
+    fprintf(stderr, "%s: stray LMP_detach received, fixme\n", __FUNCTION__);
+    exit(-1);
+}
+
+static void bt_dummy_lmp_acl_resp(struct bt_link_s *link,
+                const uint8_t *data, int start, int len)
+{
+    fprintf(stderr, "%s: stray ACL response PDU, fixme\n", __FUNCTION__);
+    exit(-1);
+}
+
+/* Slaves that don't hold any additional per link state can use these */
+static void bt_dummy_lmp_connection_request(struct bt_link_s *req)
+{
+    struct bt_link_s *link = qemu_mallocz(sizeof(struct bt_link_s));
+
+    link->slave = req->slave;
+    link->host = req->host;
+
+    req->host->reject_reason = 0;
+    req->host->lmp_connection_complete(link);
+}
+
+static void bt_dummy_lmp_disconnect_slave(struct bt_link_s *link)
+{
+    qemu_free(link);
+}
+
+static void bt_dummy_destroy(struct bt_device_s *device)
+{
+    bt_device_done(device);
+    qemu_free(device);
+}
+
+static int bt_dev_idx = 0;
+
+void bt_device_init(struct bt_device_s *dev, struct bt_scatternet_s *net)
+{
+    memset(dev, 0, sizeof(*dev));
+    dev->inquiry_scan = 1;
+    dev->page_scan = 1;
+
+    dev->bd_addr.b[0] = bt_dev_idx & 0xff;
+    dev->bd_addr.b[1] = bt_dev_idx >> 8;
+    dev->bd_addr.b[2] = 0xd0;
+    dev->bd_addr.b[3] = 0xba;
+    dev->bd_addr.b[4] = 0xbe;
+    dev->bd_addr.b[5] = 0xba;
+    bt_dev_idx ++;
+
+    /* Simple slave-only devices need to implement only .lmp_acl_data */
+    dev->lmp_connection_complete = bt_dummy_lmp_connection_complete;
+    dev->lmp_disconnect_master = bt_dummy_lmp_disconnect_master;
+    dev->lmp_acl_resp = bt_dummy_lmp_acl_resp;
+    dev->lmp_mode_change = bt_dummy_lmp_mode_change;
+    dev->lmp_connection_request = bt_dummy_lmp_connection_request;
+    dev->lmp_disconnect_slave = bt_dummy_lmp_disconnect_slave;
+
+    dev->handle_destroy = bt_dummy_destroy;
+
+    dev->net = net;
+    dev->next = net->slave;
+    net->slave = dev;
+}
+
+void bt_device_done(struct bt_device_s *dev)
+{
+    struct bt_device_s **p = &dev->net->slave;
+
+    while (*p && *p != dev)
+        p = &(*p)->next;
+    if (*p != dev) {
+        fprintf(stderr, "%s: bad bt device \"%s\"\n", __FUNCTION__,
+                        dev->lmp_name ?: "(null)");
+        exit(-1);
+    }
+
+    *p = dev->next;
+}

Added: trunk/hw/bt.h
===================================================================
--- trunk/hw/bt.h                               (rev 0)
+++ trunk/hw/bt.h       2008-09-28 23:19:47 UTC (rev 5342)
@@ -0,0 +1,105 @@
+/*
+ * QEMU Bluetooth HCI helpers.
+ *
+ * Copyright (C) 2007 OpenMoko, Inc.
+ * Written by Andrzej Zaborowski <address@hidden>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA  02110-1301  USA
+ */
+
+/* BD Address */
+typedef struct {
+    uint8_t b[6];
+} __attribute__((packed)) bdaddr_t;
+
+#define BDADDR_ANY     (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}})
+#define BDADDR_ALL     (&(bdaddr_t) {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}})
+#define BDADDR_LOCAL   (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}})
+
+/* Copy, swap, convert BD Address */
+static inline int bacmp(const bdaddr_t *ba1, const bdaddr_t *ba2)
+{
+    return memcmp(ba1, ba2, sizeof(bdaddr_t));
+}
+static inline void bacpy(bdaddr_t *dst, const bdaddr_t *src)
+{
+    memcpy(dst, src, sizeof(bdaddr_t));
+}
+
+#define BAINIT(orig)   { .b = {                \
+    (orig)->b[0], (orig)->b[1], (orig)->b[2],  \
+    (orig)->b[3], (orig)->b[4], (orig)->b[5],  \
+}, }
+
+/* The twisted structures of a bluetooth environment */
+struct bt_device_s;
+struct bt_scatternet_s;
+struct bt_piconet_s;
+struct bt_link_s;
+
+struct bt_scatternet_s {
+    struct bt_device_s *slave;
+};
+
+struct bt_link_s {
+    struct bt_device_s *slave, *host;
+    uint16_t handle;           /* Master (host) side handle */
+    uint16_t acl_interval;
+    enum {
+        acl_active,
+        acl_hold,
+        acl_sniff,
+        acl_parked,
+    } acl_mode;
+};
+
+struct bt_device_s {
+    int lt_addr;
+    bdaddr_t bd_addr;
+    int mtu;
+    int setup;
+    struct bt_scatternet_s *net;
+
+    uint8_t key[16];
+    int key_present;
+    uint8_t class[3];
+
+    uint8_t reject_reason;
+
+    uint64_t lmp_caps;
+    const char *lmp_name;
+    void (*lmp_connection_request)(struct bt_link_s *link);
+    void (*lmp_connection_complete)(struct bt_link_s *link);
+    void (*lmp_disconnect_master)(struct bt_link_s *link);
+    void (*lmp_disconnect_slave)(struct bt_link_s *link);
+    void (*lmp_acl_data)(struct bt_link_s *link, const uint8_t *data,
+                    int start, int len);
+    void (*lmp_acl_resp)(struct bt_link_s *link, const uint8_t *data,
+                    int start, int len);
+    void (*lmp_mode_change)(struct bt_link_s *link);
+
+    void (*handle_destroy)(struct bt_device_s *device);
+    struct bt_device_s *next;  /* Next in the piconet/scatternet */
+
+    int inquiry_scan;
+    int page_scan;
+
+    uint16_t clkoff;   /* Note: Always little-endian */
+};
+
+/* bt.c */
+void bt_device_init(struct bt_device_s *dev, struct bt_scatternet_s *net);
+void bt_device_done(struct bt_device_s *dev);

Modified: trunk/hw/nseries.c
===================================================================
--- trunk/hw/nseries.c  2008-09-28 22:02:30 UTC (rev 5341)
+++ trunk/hw/nseries.c  2008-09-28 23:19:47 UTC (rev 5342)
@@ -31,6 +31,7 @@
 #include "devices.h"
 #include "flash.h"
 #include "hw.h"
+#include "bt.h"
 
 /* Nokia N8x0 support */
 struct n800_s {
@@ -122,10 +123,6 @@
 
 #define N8X0_BD_ADDR                   0x00, 0x1a, 0x89, 0x9e, 0x3e, 0x81
 
-typedef struct {
-    uint8_t b[6];
-} __attribute__((packed)) bdaddr_t;    /* XXX: move to BT headers */
-
 static void n800_mmc_cs_cb(void *opaque, int line, int level)
 {
     /* TODO: this seems to actually be connected to the menelaus, to

Modified: trunk/net.h
===================================================================
--- trunk/net.h 2008-09-28 22:02:30 UTC (rev 5341)
+++ trunk/net.h 2008-09-28 23:19:47 UTC (rev 5342)
@@ -48,6 +48,20 @@
 extern int nb_nics;
 extern NICInfo nd_table[MAX_NICS];
 
+/* BT HCI info */
+
+struct HCIInfo {
+    int (*bdaddr_set)(struct HCIInfo *hci, const uint8_t *bd_addr);
+    void (*cmd_send)(struct HCIInfo *hci, const uint8_t *data, int len);
+    void (*sco_send)(struct HCIInfo *hci, const uint8_t *data, int len);
+    void (*acl_send)(struct HCIInfo *hci, const uint8_t *data, int len);
+    void *opaque;
+    void (*evt_recv)(void *opaque, const uint8_t *data, int len);
+    void (*acl_recv)(void *opaque, const uint8_t *data, int len);
+};
+
+struct HCIInfo *qemu_next_hci(void);
+
 /* checksumming functions (net-checksum.c) */
 uint32_t net_checksum_add(int len, uint8_t *buf);
 uint16_t net_checksum_finish(uint32_t sum);

Modified: trunk/qemu-common.h
===================================================================
--- trunk/qemu-common.h 2008-09-28 22:02:30 UTC (rev 5341)
+++ trunk/qemu-common.h 2008-09-28 23:19:47 UTC (rev 5342)
@@ -116,6 +116,7 @@
 /* A load of opaque types so that device init declarations don't have to
    pull in all the real definitions.  */
 typedef struct NICInfo NICInfo;
+typedef struct HCIInfo HCIInfo;
 typedef struct AudioState AudioState;
 typedef struct BlockDriverState BlockDriverState;
 typedef struct DisplayState DisplayState;

Modified: trunk/vl.c
===================================================================
--- trunk/vl.c  2008-09-28 22:02:30 UTC (rev 5341)
+++ trunk/vl.c  2008-09-28 23:19:47 UTC (rev 5342)
@@ -29,6 +29,7 @@
 #include "hw/audiodev.h"
 #include "hw/isa.h"
 #include "hw/baum.h"
+#include "hw/bt.h"
 #include "net.h"
 #include "console.h"
 #include "sysemu.h"
@@ -5361,6 +5362,61 @@
     }
 }
 
+/***********************************************************/
+/* Bluetooth support */
+static int nb_hcis;
+static int cur_hci;
+static struct HCIInfo *hci_table[MAX_NICS];
+static struct bt_vlan_s {
+    struct bt_scatternet_s net;
+    int id;
+    struct bt_vlan_s *next;
+} *first_bt_vlan;
+
+/* find or alloc a new bluetooth "VLAN" */
+struct bt_scatternet_s *qemu_find_bt_vlan(int id)
+{
+    struct bt_vlan_s **pvlan, *vlan;
+    for (vlan = first_bt_vlan; vlan != NULL; vlan = vlan->next) {
+        if (vlan->id == id)
+            return &vlan->net;
+    }
+    vlan = qemu_mallocz(sizeof(struct bt_vlan_s));
+    vlan->id = id;
+    pvlan = &first_bt_vlan;
+    while (*pvlan != NULL)
+        pvlan = &(*pvlan)->next;
+    *pvlan = vlan;
+    return &vlan->net;
+}
+
+static void null_hci_send(struct HCIInfo *hci, const uint8_t *data, int len)
+{
+}
+
+static int null_hci_addr_set(struct HCIInfo *hci, const uint8_t *bd_addr)
+{
+    return -ENOTSUP;
+}
+
+static struct HCIInfo null_hci = {
+    .cmd_send = null_hci_send,
+    .sco_send = null_hci_send,
+    .acl_send = null_hci_send,
+    .bdaddr_set = null_hci_addr_set,
+};
+
+struct HCIInfo *qemu_next_hci(void)
+{
+    if (cur_hci == nb_hcis)
+        return &null_hci;
+
+    return hci_table[cur_hci++];
+}
+
+/***********************************************************/
+/* QEMU Block devices */
+
 #define HD_ALIAS "index=%d,media=disk"
 #ifdef TARGET_PPC
 #define CDROM_ALIAS "index=1,media=cdrom"






reply via email to

[Prev in Thread] Current Thread [Next in Thread]