From patchwork Sun Mar 28 18:43:43 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Samuel Thibault X-Patchwork-Id: 48790 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 26959B7C06 for ; Mon, 29 Mar 2010 05:45:36 +1100 (EST) Received: from localhost ([127.0.0.1]:44296 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NvxUL-0007vg-1c for incoming@patchwork.ozlabs.org; Sun, 28 Mar 2010 14:45:33 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NvxSi-0007a7-3N for qemu-devel@nongnu.org; Sun, 28 Mar 2010 14:43:52 -0400 Received: from [140.186.70.92] (port=32820 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NvxSg-0007Z9-3G for qemu-devel@nongnu.org; Sun, 28 Mar 2010 14:43:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1NvxSd-00073C-24 for qemu-devel@nongnu.org; Sun, 28 Mar 2010 14:43:48 -0400 Received: from solo.fdn.fr ([80.67.169.19]:53968) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1NvxSc-000732-3o for qemu-devel@nongnu.org; Sun, 28 Mar 2010 14:43:46 -0400 Received: from const.ipv6 (youpi.is-a-geek.org [80.67.176.89]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by solo.fdn.fr (Postfix) with ESMTP id E235B4433B; Sun, 28 Mar 2010 20:43:44 +0200 (CEST) Received: from samy by const.ipv6 with local (Exim 4.71) (envelope-from ) id 1NvxSZ-000464-DL; Sun, 28 Mar 2010 20:43:43 +0200 Date: Sun, 28 Mar 2010 20:43:43 +0200 From: Samuel Thibault To: qemu-devel@nongnu.org, Andrzej Zaborowski Message-ID: <20100328184343.GO7497@const.famille.thibault.fr> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.12-2006-07-14 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) Cc: Subject: [Qemu-devel] BlueTooth RFCOMM? X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Hello, I am trying to add support for Bluetooth braille devices, but I seem to be missing something. Basically, it should be using the RFCOMM PSM, but running rfcomm connect 0 BA:BE:BA:D0:00:01 in the Linux guest hangs for some time and then the connect() system call returns EINPROGRESS. Am I perhaps missing some call to the qemu bt core? Samuel diff --git a/Makefile.objs b/Makefile.objs index e791dd5..b7c8fa6 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -78,7 +78,7 @@ common-obj-y += msmouse.o ps2.o common-obj-y += qdev.o qdev-properties.o common-obj-y += qemu-config.o block-migration.o -common-obj-$(CONFIG_BRLAPI) += baum.o +common-obj-$(CONFIG_BRLAPI) += baum.o bt-baum.o common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o diff --git a/hw/baum.h b/hw/baum.h index 8af710f..1fe30a7 100644 --- a/hw/baum.h +++ b/hw/baum.h @@ -22,5 +22,9 @@ * THE SOFTWARE. */ +#include "qemu-char.h" +#include "bt.h" /* char device */ CharDriverState *chr_baum_init(QemuOpts *opts); +/* bluetooth device */ +struct bt_device_s *bt_baum_init(struct bt_scatternet_s *net); diff --git a/hw/bt-baum.c b/hw/bt-baum.c new file mode 100644 index 0000000..568b8a1 --- /dev/null +++ b/hw/bt-baum.c @@ -0,0 +1,158 @@ +/* + * QEMU Bluetooth Baum driver. + * + * Copyright (C) 2010 Samuel Thibault + * + * 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, if not, see . + */ + +#include "qemu-common.h" +#include "baum.h" +#include "bt.h" + +#define BT_BAUM_MTU 1000 + +struct bt_baum_device_s { + struct bt_l2cap_device_s btdev; + struct bt_l2cap_conn_params_s *ch; + + CharDriverState *cdrv; +}; + +static int bt_baum_can_read(void *opaque) +{ + struct bt_baum_device_s *s = opaque; + /* Is there room in the bluetooth socket? */ + + if (!s->ch) + return 0; + + return s->ch->remote_mtu; +} + +static void bt_baum_read(void *opaque, const uint8_t *buf, int size) +{ + /* Got data from the Baum device to send over bluetooth to the guest */ + struct bt_baum_device_s *s = opaque; + uint8_t *pkt; + int len; + struct bt_l2cap_conn_params_s *ch = s->ch; + + if (!ch) + return; + + while (size) { + len = MIN(size, ch->remote_mtu); + pkt = ch->sdu_out(ch, size); + memcpy(pkt, buf, size); + ch->sdu_submit(ch); + size -= len; + buf += len; + }; +} + +static void bt_baum_sdu(void *opaque, const uint8_t *data, int len) +{ + /* Got data from bluetooth, to be sent to the Baum device */ + struct bt_baum_device_s *s = opaque; + qemu_chr_write(s->cdrv, data, len); +} + +static void bt_baum_close_ch(void *opaque) +{ + struct bt_baum_device_s *s = opaque; + + s->btdev.device.page_scan = 1; + s->btdev.device.inquiry_scan = 1; + + s->ch = NULL; + printf("close connection\n"); +} + +static int bt_baum_new_ch(struct bt_l2cap_device_s *dev, + struct bt_l2cap_conn_params_s *params) +{ + struct bt_baum_device_s *s = (struct bt_baum_device_s *) dev; + + if (s->ch) { + printf("already there: %p\n", s->ch); + return 1; + } + + printf("new connection\n"); + s->ch = params; + s->ch->opaque = s; + s->ch->close = bt_baum_close_ch; + s->ch->sdu_in = bt_baum_sdu; + + s->btdev.device.page_scan = 0; + s->btdev.device.inquiry_scan = 0; + + return 0; +} + +static void bt_baum_destroy(struct bt_device_s *dev) +{ + struct bt_baum_device_s *s = (struct bt_baum_device_s *) dev; + + bt_l2cap_device_done(&s->btdev); + + qemu_chr_close(s->cdrv); + + qemu_free(s); +} + +struct bt_device_s *bt_baum_init(struct bt_scatternet_s *net) +{ + struct bt_baum_device_s *s; + /* FIXME */ + uint32_t class = + /* Format type */ + (0 << 0) | + /* Device class */ + (0 << 2) | + (5 << 8) | /* "Peripheral" */ + /* Service classes */ + (1 << 13) | /* Limited discoverable mode */ + (1 << 19); /* Capturing device (?) */ + + s = qemu_mallocz(sizeof(*s)); + if (!s) + return NULL; + + s->cdrv = qemu_chr_open("braille", "braille", NULL); + + if (!s->cdrv) { + qemu_free(s); + return NULL; + } + + bt_l2cap_device_init(&s->btdev, net); + bt_l2cap_sdp_init(&s->btdev); + + s->btdev.device.lmp_name = "QEMU USB Braille"; + s->btdev.device.handle_destroy = bt_baum_destroy; + + printf("chan is %p\n", bt_baum_new_ch); + bt_l2cap_psm_register(&s->btdev, BT_PSM_RFCOMM, + BT_BAUM_MTU, bt_baum_new_ch); + + qemu_chr_add_handlers(s->cdrv, bt_baum_can_read, bt_baum_read, NULL, s); + + s->btdev.device.class[0] = (class >> 0) & 0xff; + s->btdev.device.class[1] = (class >> 8) & 0xff; + s->btdev.device.class[2] = (class >> 16) & 0xff; + + return &s->btdev.device; +} diff --git a/hw/bt.h b/hw/bt.h index 4a702ad..720b974 100644 --- a/hw/bt.h +++ b/hw/bt.h @@ -23,6 +23,9 @@ * along with this program; if not, see . */ +#ifndef BT_H +#define BT_H + /* BD Address */ typedef struct { uint8_t b[6]; @@ -2181,3 +2184,4 @@ enum bt_sdp_attribute_id { SDP_ATTR_NORMALLY_CONNECTABLE = 0x020d, SDP_ATTR_BOOT_DEVICE = 0x020e, }; +#endif diff --git a/vl.c b/vl.c index 10d8e34..2d89bfd 100644 --- a/vl.c +++ b/vl.c @@ -1741,6 +1741,9 @@ static struct bt_device_s *bt_device_add(const char *opt) if (!strcmp(devname, "keyboard")) return bt_keyboard_init(vlan); + if (!strcmp(devname, "braille")) + return bt_baum_init(vlan); + fprintf(stderr, "qemu: unsupported bluetooth device `%s'\n", devname); return 0; }