* [PATCH 1/2] android: Add helper functions for converting bdaddr transmitted over IPC
From: Szymon Janc @ 2013-10-28 13:45 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
Android holds Bluetooth address in reverse order comparing to
bluetoothd. Add convenient functions for converting to and from that
format.
Convertion will done on daemon side to keep HAL library simple.
---
android/utils.h | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
create mode 100644 android/utils.h
diff --git a/android/utils.h b/android/utils.h
new file mode 100644
index 0000000..5b009bc
--- /dev/null
+++ b/android/utils.h
@@ -0,0 +1,33 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2013 Intel Corporation. All rights reserved.
+ *
+ *
+ * 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
+ *
+ */
+
+
+static inline void android2bdaddr(const void *buf, bdaddr_t *dst)
+{
+ baswap(dst, buf);
+}
+
+static inline void bdaddr2android(const bdaddr_t *src, void *buf)
+{
+ baswap(buf, src);
+}
--
1.8.4.1
^ permalink raw reply related
* [PATCH 2/2] android: Use helper function to convert bdaddr to android format
From: Szymon Janc @ 2013-10-28 13:45 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382967914-11102-1-git-send-email-szymon.janc@tieto.com>
This will make easier to understand why swap is needed.
---
Makefile.android | 1 +
android/adapter.c | 3 ++-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/Makefile.android b/Makefile.android
index fd8043c..2b57daa 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -4,6 +4,7 @@ noinst_PROGRAMS += android/bluetoothd
android_bluetoothd_SOURCES = android/main.c \
src/log.c \
android/hal-msg.h \
+ android/utils.h \
src/sdpd-database.c src/sdpd-server.c \
src/sdpd-service.c src/sdpd-request.c \
src/shared/util.h src/shared/util.c \
diff --git a/android/adapter.c b/android/adapter.c
index f393c49..15b65e5 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -31,6 +31,7 @@
#include "log.h"
#include "hal-msg.h"
#include "ipc.h"
+#include "utils.h"
#include "adapter.h"
static GIOChannel *notification_io = NULL;
@@ -384,7 +385,7 @@ static void send_adapter_address(void)
ev->props[0].type = HAL_PROP_ADAPTER_ADDR;
ev->props[0].len = sizeof(bdaddr_t);
- baswap((bdaddr_t *) ev->props[0].val, &adapter->bdaddr);
+ bdaddr2android(&adapter->bdaddr, ev->props[0].val);
ipc_send(notification_io, HAL_SERVICE_ID_BLUETOOTH,
HAL_EV_ADAPTER_PROPS_CHANGED, len, ev, -1);
--
1.8.4.1
^ permalink raw reply related
* Re: [PATCH 5/5] android: Add and remove uuids in mgmt interface
From: Marcel Holtmann @ 2013-10-28 13:47 UTC (permalink / raw)
To: Johan Hedberg; +Cc: Marcin Kraglak, linux-bluetooth@vger.kernel.org development
In-Reply-To: <20131028132354.GA13148@x220.p-661hnu-f1>
Hi Johan,
>> +static int uuid_cmp(const void *a, const void *b)
>> +{
>> + const sdp_record_t *rec = a;
>> + const uuid_t *uuid = b;
>> +
>> + return sdp_uuid_cmp(&rec->svclass, uuid);
>> +}
>> +
>> +static void uuid_to_uuid128(uuid_t *uuid128, const uuid_t *uuid)
>> +{
>> + if (uuid->type == SDP_UUID16)
>> + sdp_uuid16_to_uuid128(uuid128, uuid);
>> + else if (uuid->type == SDP_UUID32)
>> + sdp_uuid32_to_uuid128(uuid128, uuid);
>> + else
>> + memcpy(uuid128, uuid, sizeof(*uuid));
>> +}
>> +
>> +static uint8_t get_uuid_mask(const uuid_t *uuid)
>> +{
>> + if (uuid->type != SDP_UUID16)
>> + return 0;
>> +
>> + switch (uuid->value.uuid16) {
>> + case DIALUP_NET_SVCLASS_ID:
>> + case CIP_SVCLASS_ID:
>> + return 0x42; /* Telephony & Networking */
>> + case IRMC_SYNC_SVCLASS_ID:
>> + case OBEX_OBJPUSH_SVCLASS_ID:
>> + case OBEX_FILETRANS_SVCLASS_ID:
>> + case IRMC_SYNC_CMD_SVCLASS_ID:
>> + case PBAP_PSE_SVCLASS_ID:
>> + return 0x10; /* Object Transfer */
>> + case HEADSET_SVCLASS_ID:
>> + case HANDSFREE_SVCLASS_ID:
>> + return 0x20; /* Audio */
>> + case CORDLESS_TELEPHONY_SVCLASS_ID:
>> + case INTERCOM_SVCLASS_ID:
>> + case FAX_SVCLASS_ID:
>> + case SAP_SVCLASS_ID:
>> + /*
>> + * Setting the telephony bit for the handsfree audio gateway
>> + * role is not required by the HFP specification, but the
>> + * Nokia 616 carkit is just plain broken! It will refuse
>> + * pairing without this bit set.
>> + */
>> + case HANDSFREE_AGW_SVCLASS_ID:
>> + return 0x40; /* Telephony */
>> + case AUDIO_SOURCE_SVCLASS_ID:
>> + case VIDEO_SOURCE_SVCLASS_ID:
>> + return 0x08; /* Capturing */
>> + case AUDIO_SINK_SVCLASS_ID:
>> + case VIDEO_SINK_SVCLASS_ID:
>> + return 0x04; /* Rendering */
>> + case PANU_SVCLASS_ID:
>> + case NAP_SVCLASS_ID:
>> + case GN_SVCLASS_ID:
>> + return 0x02; /* Networking */
>> + default:
>> + return 0;
>> + }
>> +}
>
> I don't think it makes sense to duplicate this code in bluez.git,
> especially not the last function. Instead, I think it should be
> refactored to the appropriate common place (lib/sdp.c maybe? Or maybe
> not if we don't want to pollute the already deprecated libbluetooth - in
> which case I'd expect a proposal where to put this).
I was actually thinking that we just make this static. In Android all SDP records are normally registered ahead of time. They even did this when they used BlueZ. It was essentially a sdptool add for all the records they needed.
This is also means we can just use the service class hint as a static value.
>> +static int add_uuid(uuid_t *uuid, uint8_t svc_hint)
>> +{
>> + struct mgmt_cp_add_uuid cp;
>> + uuid_t uuid128;
>> + uint128_t uint128;
>> +
>> + uuid_to_uuid128(&uuid128, uuid);
>> +
>> + ntoh128((uint128_t *) uuid128.value.uuid128.data, &uint128);
>> + htob128(&uint128, (uint128_t *) cp.uuid);
>> + cp.svc_hint = svc_hint;
>> +
>> + if (mgmt_send(adapter->mgmt, MGMT_OP_ADD_UUID,
>> + 0, sizeof(cp), &cp,
>> + add_uuid_complete, adapter, NULL) > 0)
>> + return 0;
>
> Since you're skipping the "is_supported_uuid" check that we're doing in
> the normal bluetoothd I suppose we at least have a proper check for a
> minimum mgmt version when initializing the android bluetoothd? Otherwise
> your patch is broken.
We should require a minimum mgmt version for Android. One that has all the bugs fixed. There is no point in planning on supporting older kernels anyway.
Regards
Marcel
^ permalink raw reply
* [RFC 0/2] Make HAL debug thread-safe
From: Andrei Emeltchenko @ 2013-10-28 14:06 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Since HAL is threaded this makes it safe to print properties and bdaddr.
This is slightly modified bionic thread-safe code.
Please comment.
Andrei Emeltchenko (2):
android: Add thread-safe helpers
android: Use thread-safe helpers
android/client/textconv.c | 15 ++++++++-----
android/pthread-local.h | 51 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+), 5 deletions(-)
create mode 100644 android/pthread-local.h
--
1.7.10.4
^ permalink raw reply
* [RFC 1/2] android: Add thread-safe helpers
From: Andrei Emeltchenko @ 2013-10-28 14:06 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1382969211-7402-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Add thread safe helpers to make HAL debug printing thread-safe. The code
is inherited from Android bionic and it is used for strerror, strsignal,
etc.
---
android/pthread-local.h | 51 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 51 insertions(+)
create mode 100644 android/pthread-local.h
diff --git a/android/pthread-local.h b/android/pthread-local.h
new file mode 100644
index 0000000..07012f3
--- /dev/null
+++ b/android/pthread-local.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ * Copyright (C) 2013 Intel Corp.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include <pthread.h>
+
+#define GLOBAL_INIT_THREAD_LOCAL_BUFFER(name) \
+ static pthread_key_t __bionic_tls_ ## name ## _key; \
+ static void __bionic_tls_ ## name ## _key_destroy(void* buffer) { \
+ free(buffer); \
+ } \
+ __attribute__((constructor)) static void __bionic_tls_ ## name ## _key_init() { \
+ pthread_key_create(&__bionic_tls_ ## name ## _key, __bionic_tls_ ## name ## _key_destroy); \
+ }
+
+// Leaves "name_tls_buffer" and "name_tls_buffer_size" defined and initialized.
+#define LOCAL_INIT_THREAD_LOCAL_BUFFER(type, name, byte_count) \
+ type name ## _tls_buffer = \
+ (pthread_getspecific(__bionic_tls_ ## name ## _key)); \
+ if (name ## _tls_buffer == NULL) { \
+ name ## _tls_buffer = (calloc(1, byte_count)); \
+ pthread_setspecific(__bionic_tls_ ## name ## _key, name ## _tls_buffer); \
+ } \
+ const size_t name ## _tls_buffer_size __attribute__((unused)) = byte_count
--
1.7.10.4
^ permalink raw reply related
* [RFC 2/2] android: Use thread-safe helpers
From: Andrei Emeltchenko @ 2013-10-28 14:06 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1382969211-7402-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Make use of thread-safe helpers.
---
android/client/textconv.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/android/client/textconv.c b/android/client/textconv.c
index 16392c2..6e75c28 100644
--- a/android/client/textconv.c
+++ b/android/client/textconv.c
@@ -19,6 +19,8 @@
#include <stdio.h>
#include <hardware/bluetooth.h>
+#include "../pthread-local.h"
+
#include "textconv.h"
/*
@@ -227,11 +229,12 @@ const char *enum_one_string(void *v, int i)
return (i == 0) && (m[0] != 0) ? m : NULL;
}
+GLOBAL_INIT_THREAD_LOCAL_BUFFER(bdaddr_buf);
char *bdaddr2str(const bt_bdaddr_t *bd_addr)
{
- static char buf[MAX_ADDR_STR_LEN];
+ LOCAL_INIT_THREAD_LOCAL_BUFFER(char*, bdaddr_buf, MAX_ADDR_STR_LEN);
- return bt_bdaddr_t2str(bd_addr, buf);
+ return bt_bdaddr_t2str(bd_addr, bdaddr_buf_tls_buffer);
}
char *btuuid2str(const bt_uuid_t *uuid)
@@ -241,12 +244,14 @@ char *btuuid2str(const bt_uuid_t *uuid)
return bt_uuid_t2str(uuid, buf);
}
+GLOBAL_INIT_THREAD_LOCAL_BUFFER(property_buf);
char *btproperty2str(const bt_property_t *property)
{
- static char buf[4096];
+ LOCAL_INIT_THREAD_LOCAL_BUFFER(char*, property_buf, 4096);
char *p;
- p = buf + sprintf(buf, "type=%s len=%d val=",
+ p = property_buf_tls_buffer + sprintf(property_buf_tls_buffer,
+ "type=%s len=%d val=",
bt_property_type_t2str(property->type),
property->len);
@@ -334,5 +339,5 @@ char *btproperty2str(const bt_property_t *property)
sprintf(p, "%p", property->val);
}
- return buf;
+ return property_buf_tls_buffer;
}
--
1.7.10.4
^ permalink raw reply related
* [PATCH 0/2] Initial HID connect disconnect methods
From: Ravi kumar Veeramally @ 2013-10-28 14:47 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
Patchset adds hid connect and disconnect mechanisms at
L2CAP level. It opens the control channel and interrupt
channel and listens on io events. UHID, hid server and
reconnect related features not yet done.
Ravi kumar Veeramally (2):
android: Add initial HID connect implementation
android: Add initial HID disconnect implementation.
Makefile.android | 3 +-
android/Android.mk | 1 +
android/hid.c | 260 ++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 263 insertions(+), 1 deletion(-)
--
1.7.9.5
^ permalink raw reply
* [PATCH 1/2] android: Add initial HID connect implementation
From: Ravi kumar Veeramally @ 2013-10-28 14:47 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1382971653-11727-1-git-send-email-ravikumar.veeramally@linux.intel.com>
Implemented basic HID connect method. Host connects to
bt device at L2CAP level.
---
Makefile.android | 3 +-
android/Android.mk | 1 +
android/hid.c | 237 ++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 240 insertions(+), 1 deletion(-)
diff --git a/Makefile.android b/Makefile.android
index 2b57daa..22002be 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -12,7 +12,8 @@ android_bluetoothd_SOURCES = android/main.c \
android/adapter.h android/adapter.c \
android/hid.h android/hid.c \
android/ipc.h android/ipc.c \
- android/socket.h android/socket.c
+ android/socket.h android/socket.c \
+ btio/btio.h btio/btio.c
android_bluetoothd_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
diff --git a/android/Android.mk b/android/Android.mk
index 22208e0..28ec465 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -28,6 +28,7 @@ LOCAL_SRC_FILES := \
../lib/sdp.c \
../lib/bluetooth.c \
../lib/hci.c \
+ ../btio/btio.c
LOCAL_C_INCLUDES := \
$(call include-path-for, glib) \
diff --git a/android/hid.c b/android/hid.c
index f2da0d3..b7bdc07 100644
--- a/android/hid.c
+++ b/android/hid.c
@@ -23,16 +23,252 @@
#include <stdint.h>
#include <stdbool.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
#include <glib.h>
+#include "btio/btio.h"
#include "lib/bluetooth.h"
+#include "src/shared/mgmt.h"
+
#include "log.h"
#include "hal-msg.h"
#include "ipc.h"
#include "hid.h"
+#include "adapter.h"
+#include "utils.h"
+
+#define L2CAP_PSM_HIDP_CTRL 0x11
+#define L2CAP_PSM_HIDP_INTR 0x13
+#define MAX_READ_BUFFER 4096
static GIOChannel *notification_io = NULL;
+static GSList *devices = NULL;
+
+struct input_device {
+ bdaddr_t src;
+ bdaddr_t dst;
+ GIOChannel *ctrl_io;
+ GIOChannel *intr_io;
+ guint ctrl_watch;
+ guint intr_watch;
+};
+
+static int device_cmp(gconstpointer s, gconstpointer user_data)
+{
+ const struct input_device *idev = s;
+ const bdaddr_t *dst = user_data;
+
+ return bacmp(&idev->dst, dst);
+}
+
+static void input_device_free(struct input_device *idev)
+{
+ if (idev->ctrl_watch > 0)
+ g_source_remove(idev->ctrl_watch);
+
+ if (idev->intr_watch > 0)
+ g_source_remove(idev->intr_watch);
+
+ if (idev->intr_io)
+ g_io_channel_unref(idev->intr_io);
+
+ if (idev->ctrl_io)
+ g_io_channel_unref(idev->ctrl_io);
+
+ devices = g_slist_remove(devices, idev);
+ g_free(idev);
+}
+
+static gboolean intr_io_watch_cb(GIOChannel *chan, gpointer data)
+{
+ char buf[MAX_READ_BUFFER];
+ int fd, bread;
+
+ fd = g_io_channel_unix_get_fd(chan);
+ bread = read(fd, buf, sizeof(buf));
+ if (bread < 0) {
+ error("read: %s(%d)", strerror(-errno), -errno);
+ return TRUE;
+ }
+
+ DBG("bytes read %d", bread);
+
+ /* TODO: At this moment only baseband is connected, i.e. mouse
+ * movements keyboard events doesn't effect on UI. Have to send
+ * this data to uhid fd for profile connection. */
+
+ return TRUE;
+}
+
+static gboolean intr_watch_cb(GIOChannel *chan, GIOCondition cond,
+ gpointer data)
+{
+ struct input_device *idev = data;
+ char address[18];
+
+ if (cond & G_IO_IN)
+ return intr_io_watch_cb(chan, data);
+
+ ba2str(&idev->dst, address);
+ DBG("Device %s disconnected", address);
+
+ /* Checking for ctrl_watch avoids a double g_io_channel_shutdown since
+ * it's likely that ctrl_watch_cb has been queued for dispatching in
+ * this mainloop iteration */
+ if ((cond & (G_IO_HUP | G_IO_ERR)) && idev->ctrl_watch)
+ g_io_channel_shutdown(chan, TRUE, NULL);
+
+ idev->intr_watch = 0;
+
+ if (idev->intr_io) {
+ g_io_channel_unref(idev->intr_io);
+ idev->intr_io = NULL;
+ }
+
+ /* Close control channel */
+ if (idev->ctrl_io && !(cond & G_IO_NVAL))
+ g_io_channel_shutdown(idev->ctrl_io, TRUE, NULL);
+
+ return FALSE;
+}
+
+static gboolean ctrl_watch_cb(GIOChannel *chan, GIOCondition cond,
+ gpointer data)
+{
+ struct input_device *idev = data;
+ char address[18];
+
+ ba2str(&idev->dst, address);
+ DBG("Device %s disconnected", address);
+
+ /* Checking for intr_watch avoids a double g_io_channel_shutdown since
+ * it's likely that intr_watch_cb has been queued for dispatching in
+ * this mainloop iteration */
+ if ((cond & (G_IO_HUP | G_IO_ERR)) && idev->intr_watch)
+ g_io_channel_shutdown(chan, TRUE, NULL);
+
+ idev->ctrl_watch = 0;
+
+ if (idev->ctrl_io) {
+ g_io_channel_unref(idev->ctrl_io);
+ idev->ctrl_io = NULL;
+ }
+
+ if (idev->intr_io && !(cond & G_IO_NVAL))
+ g_io_channel_shutdown(idev->intr_io, TRUE, NULL);
+
+ return FALSE;
+}
+
+static void interrupt_connect_cb(GIOChannel *chan, GError *conn_err,
+ gpointer user_data)
+{
+ struct input_device *idev = user_data;
+
+ DBG("");
+
+ if (conn_err)
+ goto failed;
+
+ /*TODO: Get device details through SDP and create UHID fd and start
+ * listening on uhid events */
+ idev->intr_watch = g_io_add_watch(idev->intr_io,
+ G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+ intr_watch_cb, idev);
+
+ return;
+
+failed:
+ /* So we guarantee the interrupt channel is closed before the
+ * control channel (if we only do unref GLib will close it only
+ * after returning control to the mainloop */
+ if (!conn_err)
+ g_io_channel_shutdown(idev->intr_io, FALSE, NULL);
+
+ g_io_channel_unref(idev->intr_io);
+ idev->intr_io = NULL;
+
+ if (idev->ctrl_io) {
+ g_io_channel_unref(idev->ctrl_io);
+ idev->ctrl_io = NULL;
+ }
+}
+
+static void control_connect_cb(GIOChannel *chan, GError *conn_err,
+ gpointer user_data)
+{
+ struct input_device *idev = user_data;
+ GError *err = NULL;
+
+ DBG("");
+
+ if (conn_err) {
+ error("%s", conn_err->message);
+ goto failed;
+ }
+
+ /* Connect to the HID interrupt channel */
+ idev->intr_io = bt_io_connect(interrupt_connect_cb, idev, NULL, &err,
+ BT_IO_OPT_SOURCE_BDADDR, &idev->src,
+ BT_IO_OPT_DEST_BDADDR, &idev->dst,
+ BT_IO_OPT_PSM, L2CAP_PSM_HIDP_INTR,
+ BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+ BT_IO_OPT_INVALID);
+ if (!idev->intr_io) {
+ error("%s", err->message);
+ g_error_free(err);
+ goto failed;
+ }
+
+ idev->ctrl_watch = g_io_add_watch(idev->ctrl_io,
+ G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+ ctrl_watch_cb, idev);
+
+ return;
+
+failed:
+ g_io_channel_unref(idev->ctrl_io);
+ idev->ctrl_io = NULL;
+}
+
+static uint8_t dev_connect(struct hal_cmd_hid_connect *cmd, uint16_t len)
+{
+ struct input_device *idev;
+ char addr[18];
+ GError *err = NULL;
+
+ DBG("");
+
+ if (len < sizeof(*cmd))
+ return HAL_STATUS_INVALID;
+
+ idev = g_new0(struct input_device, 1);
+ bacpy(&idev->src, bt_adapter_get_address());
+ android2bdaddr((bdaddr_t *)&cmd->bdaddr, &idev->dst);
+ ba2str(&idev->dst, addr);
+
+ DBG("connecting to %s", addr);
+
+ idev->ctrl_io = bt_io_connect(control_connect_cb, idev, NULL, &err,
+ BT_IO_OPT_SOURCE_BDADDR, &idev->src,
+ BT_IO_OPT_DEST_BDADDR, &idev->dst,
+ BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL,
+ BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+ BT_IO_OPT_INVALID);
+ if (err) {
+ error("%s", err->message);
+ g_error_free(err);
+ input_device_free(idev);
+ return HAL_STATUS_FAILED;
+ }
+
+ devices = g_slist_append(devices, idev);
+
+ return HAL_STATUS_SUCCESS;
+}
void bt_hid_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf, uint16_t len)
{
@@ -40,6 +276,7 @@ void bt_hid_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf, uint16_t len)
switch (opcode) {
case HAL_OP_HID_CONNECT:
+ status = dev_connect((struct hal_cmd_hid_connect *) buf, len);
break;
case HAL_OP_HID_DISCONNECT:
break;
--
1.7.9.5
^ permalink raw reply related
* [PATCH 2/2] android: Add initial HID disconnect implementation.
From: Ravi kumar Veeramally @ 2013-10-28 14:47 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1382971653-11727-1-git-send-email-ravikumar.veeramally@linux.intel.com>
Implemented basic HID disconnect method. Host disconnects
with bt device at L2CAP level.
---
android/hid.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/android/hid.c b/android/hid.c
index b7bdc07..3e7ac0d 100644
--- a/android/hid.c
+++ b/android/hid.c
@@ -270,6 +270,27 @@ static uint8_t dev_connect(struct hal_cmd_hid_connect *cmd, uint16_t len)
return HAL_STATUS_SUCCESS;
}
+static uint8_t dev_disconnect(struct hal_cmd_hid_disconnect *cmd, uint16_t len)
+{
+ GSList *l;
+ bdaddr_t dst;
+
+ DBG("");
+
+ if (len < sizeof(*cmd))
+ return HAL_STATUS_INVALID;
+
+ android2bdaddr((bdaddr_t *)&cmd->bdaddr, &dst);
+
+ l = g_slist_find_custom(devices, &dst, device_cmp);
+ if (!l)
+ return HAL_STATUS_FAILED;
+
+ input_device_free(l->data);
+
+ return HAL_STATUS_SUCCESS;
+}
+
void bt_hid_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf, uint16_t len)
{
uint8_t status = HAL_STATUS_FAILED;
@@ -279,6 +300,8 @@ void bt_hid_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf, uint16_t len)
status = dev_connect((struct hal_cmd_hid_connect *) buf, len);
break;
case HAL_OP_HID_DISCONNECT:
+ status = dev_disconnect((struct hal_cmd_hid_disconnect *) buf,
+ len);
break;
default:
DBG("Unhandled command, opcode 0x%x", opcode);
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH 2/2] android: Add initial HID disconnect implementation.
From: Luiz Augusto von Dentz @ 2013-10-28 14:53 UTC (permalink / raw)
To: Ravi kumar Veeramally; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1382971653-11727-3-git-send-email-ravikumar.veeramally@linux.intel.com>
Hi Ravi,
On Mon, Oct 28, 2013 at 4:47 PM, Ravi kumar Veeramally
<ravikumar.veeramally@linux.intel.com> wrote:
> Implemented basic HID disconnect method. Host disconnects
> with bt device at L2CAP level.
> ---
> android/hid.c | 23 +++++++++++++++++++++++
> 1 file changed, 23 insertions(+)
>
> diff --git a/android/hid.c b/android/hid.c
> index b7bdc07..3e7ac0d 100644
> --- a/android/hid.c
> +++ b/android/hid.c
> @@ -270,6 +270,27 @@ static uint8_t dev_connect(struct hal_cmd_hid_connect *cmd, uint16_t len)
> return HAL_STATUS_SUCCESS;
> }
>
> +static uint8_t dev_disconnect(struct hal_cmd_hid_disconnect *cmd, uint16_t len)
> +{
> + GSList *l;
> + bdaddr_t dst;
> +
> + DBG("");
> +
> + if (len < sizeof(*cmd))
> + return HAL_STATUS_INVALID;
> +
> + android2bdaddr((bdaddr_t *)&cmd->bdaddr, &dst);
> +
> + l = g_slist_find_custom(devices, &dst, device_cmp);
> + if (!l)
> + return HAL_STATUS_FAILED;
> +
> + input_device_free(l->data);
> +
> + return HAL_STATUS_SUCCESS;
> +}
> +
> void bt_hid_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf, uint16_t len)
> {
> uint8_t status = HAL_STATUS_FAILED;
> @@ -279,6 +300,8 @@ void bt_hid_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf, uint16_t len)
> status = dev_connect((struct hal_cmd_hid_connect *) buf, len);
> break;
> case HAL_OP_HID_DISCONNECT:
> + status = dev_disconnect((struct hal_cmd_hid_disconnect *) buf,
> + len);
Look at the other files, we are not doing the casts upfront but in the
function itself.
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: [PATCH] Regression fix revert: "Bluetooth: Add missing reset_resume dev_pm_ops"
From: Hans de Goede @ 2013-10-28 14:54 UTC (permalink / raw)
To: Gustavo Padovan
Cc: USB list, linux-bluetooth, Shuah Khan, Gustavo Padovan, stable
In-Reply-To: <508150F6-D142-4406-8CC9-57DDE754F391@holtmann.org>
Hi Gustavo,
> Patch has been applied to bluetooth.git. Thanks.
Hmm, I'm not seeing this in 3.12 yet, not only should this be added
to 3.12 asap, it should also really get added to 3.11.x soon.
The regression this patch fixes is breaking btusb for lots of users, see:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1213239
https://bugzilla.redhat.com/show_bug.cgi?id=988481
Where lots of people are adding me too comments (and some are building
their own kernels with the revert and confirming it fixes things for
them).
Regards,
Hans
^ permalink raw reply
* Re: [PATCH 1/2] android: Add initial HID connect implementation
From: Luiz Augusto von Dentz @ 2013-10-28 15:06 UTC (permalink / raw)
To: Ravi kumar Veeramally; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1382971653-11727-2-git-send-email-ravikumar.veeramally@linux.intel.com>
Hi Ravi,
On Mon, Oct 28, 2013 at 4:47 PM, Ravi kumar Veeramally
<ravikumar.veeramally@linux.intel.com> wrote:
> Implemented basic HID connect method. Host connects to
> bt device at L2CAP level.
> ---
> Makefile.android | 3 +-
> android/Android.mk | 1 +
> android/hid.c | 237 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 240 insertions(+), 1 deletion(-)
>
> diff --git a/Makefile.android b/Makefile.android
> index 2b57daa..22002be 100644
> --- a/Makefile.android
> +++ b/Makefile.android
> @@ -12,7 +12,8 @@ android_bluetoothd_SOURCES = android/main.c \
> android/adapter.h android/adapter.c \
> android/hid.h android/hid.c \
> android/ipc.h android/ipc.c \
> - android/socket.h android/socket.c
> + android/socket.h android/socket.c \
> + btio/btio.h btio/btio.c
>
> android_bluetoothd_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
>
> diff --git a/android/Android.mk b/android/Android.mk
> index 22208e0..28ec465 100644
> --- a/android/Android.mk
> +++ b/android/Android.mk
> @@ -28,6 +28,7 @@ LOCAL_SRC_FILES := \
> ../lib/sdp.c \
> ../lib/bluetooth.c \
> ../lib/hci.c \
> + ../btio/btio.c
>
> LOCAL_C_INCLUDES := \
> $(call include-path-for, glib) \
> diff --git a/android/hid.c b/android/hid.c
> index f2da0d3..b7bdc07 100644
> --- a/android/hid.c
> +++ b/android/hid.c
> @@ -23,16 +23,252 @@
>
> #include <stdint.h>
> #include <stdbool.h>
> +#include <errno.h>
> +#include <unistd.h>
> +#include <fcntl.h>
>
> #include <glib.h>
>
> +#include "btio/btio.h"
> #include "lib/bluetooth.h"
> +#include "src/shared/mgmt.h"
> +
> #include "log.h"
> #include "hal-msg.h"
> #include "ipc.h"
> #include "hid.h"
> +#include "adapter.h"
> +#include "utils.h"
> +
> +#define L2CAP_PSM_HIDP_CTRL 0x11
> +#define L2CAP_PSM_HIDP_INTR 0x13
> +#define MAX_READ_BUFFER 4096
>
> static GIOChannel *notification_io = NULL;
> +static GSList *devices = NULL;
> +
> +struct input_device {
> + bdaddr_t src;
> + bdaddr_t dst;
> + GIOChannel *ctrl_io;
> + GIOChannel *intr_io;
> + guint ctrl_watch;
> + guint intr_watch;
> +};
You probably don't need the address of the adapter as there could be
only one in android you can always query its value via
bt_adapter_get_address.
> +static uint8_t dev_connect(struct hal_cmd_hid_connect *cmd, uint16_t len)
> +{
> + struct input_device *idev;
> + char addr[18];
> + GError *err = NULL;
> +
> + DBG("");
> +
> + if (len < sizeof(*cmd))
> + return HAL_STATUS_INVALID;
> +
> + idev = g_new0(struct input_device, 1);
> + bacpy(&idev->src, bt_adapter_get_address());
> + android2bdaddr((bdaddr_t *)&cmd->bdaddr, &idev->dst);
> + ba2str(&idev->dst, addr);
Might be worth checking if there a connection ongoing before you
create a new data, I would also avoid having the same struct names
from our input plugin, just use something else like hid_data.
> +
> + DBG("connecting to %s", addr);
> +
> + idev->ctrl_io = bt_io_connect(control_connect_cb, idev, NULL, &err,
> + BT_IO_OPT_SOURCE_BDADDR, &idev->src,
> + BT_IO_OPT_DEST_BDADDR, &idev->dst,
> + BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL,
> + BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
> + BT_IO_OPT_INVALID);
> + if (err) {
> + error("%s", err->message);
> + g_error_free(err);
> + input_device_free(idev);
> + return HAL_STATUS_FAILED;
> + }
> +
> + devices = g_slist_append(devices, idev);
> +
> + return HAL_STATUS_SUCCESS;
> +}
>
> void bt_hid_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf, uint16_t len)
> {
> @@ -40,6 +276,7 @@ void bt_hid_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf, uint16_t len)
>
> switch (opcode) {
> case HAL_OP_HID_CONNECT:
> + status = dev_connect((struct hal_cmd_hid_connect *) buf, len);
Call it hid_connect or bt_hid_connect.
--
Luiz Augusto von Dentz
^ permalink raw reply
* [PATCH 1/2] android: Add thread-safe helpers
From: Andrei Emeltchenko @ 2013-10-28 15:30 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1382969211-7402-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Add thread safe helpers to make HAL debug printing thread-safe. The code
is inherited from Android bionic and it is used for strerror, strsignal,
etc.
---
android/pthread-local.h | 53 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
create mode 100644 android/pthread-local.h
diff --git a/android/pthread-local.h b/android/pthread-local.h
new file mode 100644
index 0000000..4bf22f3
--- /dev/null
+++ b/android/pthread-local.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ * Copyright (C) 2013 Intel Corp.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <pthread.h>
+#include <stdlib.h>
+
+#define GLOBAL_INIT_THREAD_LOCAL_BUFFER(name) \
+ static pthread_key_t __bionic_tls_ ## name ## _key; \
+ static void __bionic_tls_ ## name ## _key_destroy(void* buffer) { \
+ free(buffer); \
+ } \
+ __attribute__((constructor)) static void __bionic_tls_ ## name ## _key_init() { \
+ pthread_key_create(&__bionic_tls_ ## name ## _key, __bionic_tls_ ## name ## _key_destroy); \
+ }
+
+/*
+ * Leaves "name_tls_buffer" and "name_tls_buffer_size" defined and initialized.
+ */
+#define LOCAL_INIT_THREAD_LOCAL_BUFFER(type, name, byte_count) \
+ const size_t name ## _tls_buffer_size __attribute__((unused)) = byte_count; \
+ type name ## _tls_buffer = \
+ (pthread_getspecific(__bionic_tls_ ## name ## _key)); \
+ if (name ## _tls_buffer == NULL) { \
+ name ## _tls_buffer = (calloc(1, byte_count)); \
+ pthread_setspecific(__bionic_tls_ ## name ## _key, name ## _tls_buffer); \
+ }
--
1.7.10.4
^ permalink raw reply related
* [PATCH 2/2] android: Use thread-safe helpers
From: Andrei Emeltchenko @ 2013-10-28 15:30 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1382974225-13855-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Make use of thread-safe helpers.
---
android/client/textconv.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/android/client/textconv.c b/android/client/textconv.c
index 1dc6ad0..c09f47d 100644
--- a/android/client/textconv.c
+++ b/android/client/textconv.c
@@ -19,6 +19,8 @@
#include <stdio.h>
#include <hardware/bluetooth.h>
+#include "../pthread-local.h"
+
#include "textconv.h"
/*
@@ -227,11 +229,12 @@ const char *enum_one_string(void *v, int i)
return (i == 0) && (m[0] != 0) ? m : NULL;
}
+GLOBAL_INIT_THREAD_LOCAL_BUFFER(bdaddr_buf);
char *bdaddr2str(const bt_bdaddr_t *bd_addr)
{
- static char buf[MAX_ADDR_STR_LEN];
+ LOCAL_INIT_THREAD_LOCAL_BUFFER(char*, bdaddr_buf, MAX_ADDR_STR_LEN);
- return bt_bdaddr_t2str(bd_addr, buf);
+ return bt_bdaddr_t2str(bd_addr, bdaddr_buf_tls_buffer);
}
static char *btuuid2str(const bt_uuid_t *uuid)
@@ -241,12 +244,14 @@ static char *btuuid2str(const bt_uuid_t *uuid)
return bt_uuid_t2str(uuid, buf);
}
+GLOBAL_INIT_THREAD_LOCAL_BUFFER(property_buf);
char *btproperty2str(const bt_property_t *property)
{
- static char buf[4096];
char *p;
+ LOCAL_INIT_THREAD_LOCAL_BUFFER(char*, property_buf, 4096);
- p = buf + sprintf(buf, "type=%s len=%d val=",
+ p = property_buf_tls_buffer + sprintf(property_buf_tls_buffer,
+ "type=%s len=%d val=",
bt_property_type_t2str(property->type),
property->len);
@@ -334,5 +339,5 @@ char *btproperty2str(const bt_property_t *property)
sprintf(p, "%p", property->val);
}
- return buf;
+ return property_buf_tls_buffer;
}
--
1.7.10.4
^ permalink raw reply related
* [PATCH] android/hal: Set callbacks before initializing IPC
From: Szymon Janc @ 2013-10-28 15:45 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
Notification thread is started on IPC init and it can be scheduled
before main thread.
Fix following crash on HAL init:
pid: 3392, tid: 3492, name: droid.bluetooth >>> com.android.bluetooth <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000028
eax 00000000 ebx ce047f64 ecx ce0405d0 edx f7763724
esi cdf3af00 edi f837fb90
xcs 00000023 xds 0000002b xes 0000002b xfs 00000000 xss 0000002b
eip ce042289 ebp cdf3a9f8 esp cdf3a9e0 flags 00010292
backtrace:
#00 pc 00003289 /system/lib/hw/bluetooth.default.so (bt_thread_associate+25)
#01 pc 000015f8 /system/lib/hw/bluetooth.default.so (notification_handler+40)
#02 pc 0000f804 /system/lib/libc.so (__thread_entry+276)
#03 pc 0002999d /system/lib/libc.so
#04 pc 00082ae7 /system/lib/libdvm.so (dvmThreadSelf()+39)
#05 pc 00010db9 /system/lib/libc.so (pthread_mutex_unlock+25)
---
android/hal-bluetooth.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 5929fff..5f6dcbe 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -114,11 +114,13 @@ static int init(bt_callbacks_t *callbacks)
if (interface_ready())
return BT_STATUS_SUCCESS;
- if (!hal_ipc_init())
- return BT_STATUS_FAIL;
-
bt_hal_cbacks = callbacks;
+ if (!hal_ipc_init()) {
+ bt_hal_cbacks = NULL;
+ return BT_STATUS_FAIL;
+ }
+
cmd.service_id = HAL_SERVICE_ID_BLUETOOTH;
status = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
--
1.8.4.1
^ permalink raw reply related
* [PATCH] build: Move Makefile.android to android/Makefile.am
From: Szymon Janc @ 2013-10-28 16:37 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
This will keep all Android related changes within android directory.
---
Will also fix messing with Marcel's tab completion habits :-)
Makefile.am | 2 +-
Makefile.android | 113 ----------------------------------------------------
android/Makefile.am | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 114 insertions(+), 114 deletions(-)
delete mode 100644 Makefile.android
create mode 100644 android/Makefile.am
diff --git a/Makefile.am b/Makefile.am
index 8aed6f7..69a2805 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -179,7 +179,7 @@ test_scripts =
include Makefile.tools
include Makefile.obexd
-include Makefile.android
+include android/Makefile.am
if HID2HCI
rulesdir = @UDEV_DIR@/rules.d
diff --git a/Makefile.android b/Makefile.android
deleted file mode 100644
index 2b57daa..0000000
--- a/Makefile.android
+++ /dev/null
@@ -1,113 +0,0 @@
-if ANDROID
-noinst_PROGRAMS += android/bluetoothd
-
-android_bluetoothd_SOURCES = android/main.c \
- src/log.c \
- android/hal-msg.h \
- android/utils.h \
- src/sdpd-database.c src/sdpd-server.c \
- src/sdpd-service.c src/sdpd-request.c \
- src/shared/util.h src/shared/util.c \
- src/shared/mgmt.h src/shared/mgmt.c \
- android/adapter.h android/adapter.c \
- android/hid.h android/hid.c \
- android/ipc.h android/ipc.c \
- android/socket.h android/socket.c
-
-android_bluetoothd_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
-
-noinst_LTLIBRARIES += android/libhal-internal.la
-
-android_libhal_internal_la_SOURCES = android/hal.h android/hal-bluetooth.c \
- android/hal-sock.c \
- android/hal-hidhost.c \
- android/hal-pan.c \
- android/hal-av.c \
- android/hardware/bluetooth.h \
- android/hardware/bt_av.h \
- android/hardware/bt_gatt.h \
- android/hardware/bt_gatt_client.h \
- android/hardware/bt_gatt_server.h \
- android/hardware/bt_gatt_types.h \
- android/hardware/bt_hf.h \
- android/hardware/bt_hh.h \
- android/hardware/bt_hl.h \
- android/hardware/bt_pan.h \
- android/hardware/bt_rc.h \
- android/hardware/bt_sock.h \
- android/hardware/hardware.h \
- android/cutils/properties.h \
- android/hal-log.h \
- android/hal-ipc.h android/hal-ipc.c
-
-android_libhal_internal_la_CPPFLAGS = -I$(srcdir)/android
-
-noinst_PROGRAMS += android/haltest
-
-android_haltest_SOURCES = android/client/haltest.c \
- android/client/pollhandler.c \
- android/client/terminal.c \
- android/client/history.c \
- android/client/textconv.c \
- android/client/tabcompletion.c \
- android/client/if-av.c \
- android/client/if-bt.c \
- android/client/if-hf.c \
- android/client/if-hh.c \
- android/client/if-pan.c \
- android/client/if-sock.c \
- android/client/hwmodule.c
-
-android_haltest_LDADD = android/libhal-internal.la
-
-android_haltest_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/android
-
-android_haltest_LDFLAGS = -pthread
-
-endif
-
-EXTRA_DIST += android/Android.mk android/device.c android/adapter.c\
- android/main.c android/hal-msg.h android/hal.h
-
-EXTRA_DIST += android/hal-bluetooth.c \
- android/hal-sock.c \
- android/hal-hidhost.c \
- android/hal-pan.c \
- android/hal-av.c \
- android/hal-log.h
-
-EXTRA_DIST += android/client/terminal.c \
- android/client/haltest.c \
- android/client/hwmodule.c \
- android/client/pollhandler.c \
- android/client/history.c \
- android/client/if-av.c \
- android/client/if-bt.c \
- android/client/if-hf.c \
- android/client/if-hh.c \
- android/client/if-pan.c \
- android/client/if-sock.c \
- android/client/textconv.c \
- android/client/tabcompletion.c \
- android/client/textconv.h \
- android/client/if-main.h \
- android/client/pollhandler.h \
- android/client/history.h \
- android/client/terminal.h
-
-EXTRA_DIST += android/hal-ipc-api.txt
-
-EXTRA_DIST += android/hardware/bluetooth.h \
- android/hardware/bt_av.h \
- android/hardware/bt_gatt.h \
- android/hardware/bt_gatt_client.h \
- android/hardware/bt_gatt_server.h \
- android/hardware/bt_gatt_types.h \
- android/hardware/bt_hf.h \
- android/hardware/bt_hh.h \
- android/hardware/bt_hl.h \
- android/hardware/bt_pan.h \
- android/hardware/bt_rc.h \
- android/hardware/bt_sock.h \
- android/hardware/hardware.h \
- android/cutils/properties.h
diff --git a/android/Makefile.am b/android/Makefile.am
new file mode 100644
index 0000000..2b57daa
--- /dev/null
+++ b/android/Makefile.am
@@ -0,0 +1,113 @@
+if ANDROID
+noinst_PROGRAMS += android/bluetoothd
+
+android_bluetoothd_SOURCES = android/main.c \
+ src/log.c \
+ android/hal-msg.h \
+ android/utils.h \
+ src/sdpd-database.c src/sdpd-server.c \
+ src/sdpd-service.c src/sdpd-request.c \
+ src/shared/util.h src/shared/util.c \
+ src/shared/mgmt.h src/shared/mgmt.c \
+ android/adapter.h android/adapter.c \
+ android/hid.h android/hid.c \
+ android/ipc.h android/ipc.c \
+ android/socket.h android/socket.c
+
+android_bluetoothd_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
+
+noinst_LTLIBRARIES += android/libhal-internal.la
+
+android_libhal_internal_la_SOURCES = android/hal.h android/hal-bluetooth.c \
+ android/hal-sock.c \
+ android/hal-hidhost.c \
+ android/hal-pan.c \
+ android/hal-av.c \
+ android/hardware/bluetooth.h \
+ android/hardware/bt_av.h \
+ android/hardware/bt_gatt.h \
+ android/hardware/bt_gatt_client.h \
+ android/hardware/bt_gatt_server.h \
+ android/hardware/bt_gatt_types.h \
+ android/hardware/bt_hf.h \
+ android/hardware/bt_hh.h \
+ android/hardware/bt_hl.h \
+ android/hardware/bt_pan.h \
+ android/hardware/bt_rc.h \
+ android/hardware/bt_sock.h \
+ android/hardware/hardware.h \
+ android/cutils/properties.h \
+ android/hal-log.h \
+ android/hal-ipc.h android/hal-ipc.c
+
+android_libhal_internal_la_CPPFLAGS = -I$(srcdir)/android
+
+noinst_PROGRAMS += android/haltest
+
+android_haltest_SOURCES = android/client/haltest.c \
+ android/client/pollhandler.c \
+ android/client/terminal.c \
+ android/client/history.c \
+ android/client/textconv.c \
+ android/client/tabcompletion.c \
+ android/client/if-av.c \
+ android/client/if-bt.c \
+ android/client/if-hf.c \
+ android/client/if-hh.c \
+ android/client/if-pan.c \
+ android/client/if-sock.c \
+ android/client/hwmodule.c
+
+android_haltest_LDADD = android/libhal-internal.la
+
+android_haltest_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/android
+
+android_haltest_LDFLAGS = -pthread
+
+endif
+
+EXTRA_DIST += android/Android.mk android/device.c android/adapter.c\
+ android/main.c android/hal-msg.h android/hal.h
+
+EXTRA_DIST += android/hal-bluetooth.c \
+ android/hal-sock.c \
+ android/hal-hidhost.c \
+ android/hal-pan.c \
+ android/hal-av.c \
+ android/hal-log.h
+
+EXTRA_DIST += android/client/terminal.c \
+ android/client/haltest.c \
+ android/client/hwmodule.c \
+ android/client/pollhandler.c \
+ android/client/history.c \
+ android/client/if-av.c \
+ android/client/if-bt.c \
+ android/client/if-hf.c \
+ android/client/if-hh.c \
+ android/client/if-pan.c \
+ android/client/if-sock.c \
+ android/client/textconv.c \
+ android/client/tabcompletion.c \
+ android/client/textconv.h \
+ android/client/if-main.h \
+ android/client/pollhandler.h \
+ android/client/history.h \
+ android/client/terminal.h
+
+EXTRA_DIST += android/hal-ipc-api.txt
+
+EXTRA_DIST += android/hardware/bluetooth.h \
+ android/hardware/bt_av.h \
+ android/hardware/bt_gatt.h \
+ android/hardware/bt_gatt_client.h \
+ android/hardware/bt_gatt_server.h \
+ android/hardware/bt_gatt_types.h \
+ android/hardware/bt_hf.h \
+ android/hardware/bt_hh.h \
+ android/hardware/bt_hl.h \
+ android/hardware/bt_pan.h \
+ android/hardware/bt_rc.h \
+ android/hardware/bt_sock.h \
+ android/hardware/hardware.h \
+ android/cutils/properties.h
--
1.8.4.1
^ permalink raw reply related
* Re: Bluetooth tools
From: Vinicius Costa Gomes @ 2013-10-28 19:18 UTC (permalink / raw)
To: Kevin Wilson; +Cc: linux-bluetooth
In-Reply-To: <CAGXs5wULS_dYYCCyimg3y9Fv6smMp8kOQbN3BfYJ+=bBhbhHxQ@mail.gmail.com>
Hi Kevin,
On 09:40 Sat 26 Oct, Kevin Wilson wrote:
> Hello,
>
> I saw that bluetoothctl and btmon are the newer tool of Bluetooth.
>
> What are the advantages of bluetoothctl over hciconfig/hcitool?
I would not say advantages, as they have very different aims, bluetoothctl is
meant to be used in the day-to-day (think scanning for a device, pairing
with it, changing the discoverability, etc); hciconfig/hcitool are more for
development/debugging (think disabling SSP mode, enabling periodic inquiry,
etc), they are more similar to btmgmt than to bluetoothctl.
>
> What are the advantages of btmon over hcidump ?
btmon also tracks events from the Management interface. And colors ;-)
>
>
> Regards,
> Kevin
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
Cheers,
--
Vinicius
^ permalink raw reply
* [PATCH_v2 1/2] android: Add initial HID connect implementation
From: Ravi kumar Veeramally @ 2013-10-29 8:38 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
Implemented basic HID connect method. Host connects to
bt device at L2CAP level.
---
v2: Updated patches as per Luiz comments
v1: Patchset adds hid connect and disconnect mechanisms at
L2CAP level. It opens the control channel and interrupt
channel and listens on io events. UHID, hid server and
reconnect related features not yet done.
---
Makefile.android | 3 +-
android/Android.mk | 1 +
android/hid.c | 245 ++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 248 insertions(+), 1 deletion(-)
diff --git a/Makefile.android b/Makefile.android
index 2b57daa..22002be 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -12,7 +12,8 @@ android_bluetoothd_SOURCES = android/main.c \
android/adapter.h android/adapter.c \
android/hid.h android/hid.c \
android/ipc.h android/ipc.c \
- android/socket.h android/socket.c
+ android/socket.h android/socket.c \
+ btio/btio.h btio/btio.c
android_bluetoothd_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
diff --git a/android/Android.mk b/android/Android.mk
index 22208e0..28ec465 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -28,6 +28,7 @@ LOCAL_SRC_FILES := \
../lib/sdp.c \
../lib/bluetooth.c \
../lib/hci.c \
+ ../btio/btio.c
LOCAL_C_INCLUDES := \
$(call include-path-for, glib) \
diff --git a/android/hid.c b/android/hid.c
index f2da0d3..7f9e386 100644
--- a/android/hid.c
+++ b/android/hid.c
@@ -23,16 +23,260 @@
#include <stdint.h>
#include <stdbool.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
#include <glib.h>
+#include "btio/btio.h"
#include "lib/bluetooth.h"
+#include "src/shared/mgmt.h"
+
#include "log.h"
#include "hal-msg.h"
#include "ipc.h"
#include "hid.h"
+#include "adapter.h"
+#include "utils.h"
+
+#define L2CAP_PSM_HIDP_CTRL 0x11
+#define L2CAP_PSM_HIDP_INTR 0x13
+#define MAX_READ_BUFFER 4096
static GIOChannel *notification_io = NULL;
+static GSList *devices = NULL;
+
+struct hid_device {
+ bdaddr_t dst;
+ GIOChannel *ctrl_io;
+ GIOChannel *intr_io;
+ guint ctrl_watch;
+ guint intr_watch;
+};
+
+static int device_cmp(gconstpointer s, gconstpointer user_data)
+{
+ const struct hid_device *hdev = s;
+ const bdaddr_t *dst = user_data;
+
+ return bacmp(&hdev->dst, dst);
+}
+
+static void hid_device_free(struct hid_device *hdev)
+{
+ if (hdev->ctrl_watch > 0)
+ g_source_remove(hdev->ctrl_watch);
+
+ if (hdev->intr_watch > 0)
+ g_source_remove(hdev->intr_watch);
+
+ if (hdev->intr_io)
+ g_io_channel_unref(hdev->intr_io);
+
+ if (hdev->ctrl_io)
+ g_io_channel_unref(hdev->ctrl_io);
+
+ devices = g_slist_remove(devices, hdev);
+ g_free(hdev);
+}
+
+static gboolean intr_io_watch_cb(GIOChannel *chan, gpointer data)
+{
+ char buf[MAX_READ_BUFFER];
+ int fd, bread;
+
+ fd = g_io_channel_unix_get_fd(chan);
+ bread = read(fd, buf, sizeof(buf));
+ if (bread < 0) {
+ error("read: %s(%d)", strerror(-errno), -errno);
+ return TRUE;
+ }
+
+ DBG("bytes read %d", bread);
+
+ /* TODO: At this moment only baseband is connected, i.e. mouse
+ * movements keyboard events doesn't effect on UI. Have to send
+ * this data to uhid fd for profile connection. */
+
+ return TRUE;
+}
+
+static gboolean intr_watch_cb(GIOChannel *chan, GIOCondition cond,
+ gpointer data)
+{
+ struct hid_device *hdev = data;
+ char address[18];
+
+ if (cond & G_IO_IN)
+ return intr_io_watch_cb(chan, data);
+
+ ba2str(&hdev->dst, address);
+ DBG("Device %s disconnected", address);
+
+ /* Checking for ctrl_watch avoids a double g_io_channel_shutdown since
+ * it's likely that ctrl_watch_cb has been queued for dispatching in
+ * this mainloop iteration */
+ if ((cond & (G_IO_HUP | G_IO_ERR)) && hdev->ctrl_watch)
+ g_io_channel_shutdown(chan, TRUE, NULL);
+
+ hdev->intr_watch = 0;
+
+ if (hdev->intr_io) {
+ g_io_channel_unref(hdev->intr_io);
+ hdev->intr_io = NULL;
+ }
+
+ /* Close control channel */
+ if (hdev->ctrl_io && !(cond & G_IO_NVAL))
+ g_io_channel_shutdown(hdev->ctrl_io, TRUE, NULL);
+
+ return FALSE;
+}
+
+static gboolean ctrl_watch_cb(GIOChannel *chan, GIOCondition cond,
+ gpointer data)
+{
+ struct hid_device *hdev = data;
+ char address[18];
+
+ ba2str(&hdev->dst, address);
+ DBG("Device %s disconnected", address);
+
+ /* Checking for intr_watch avoids a double g_io_channel_shutdown since
+ * it's likely that intr_watch_cb has been queued for dispatching in
+ * this mainloop iteration */
+ if ((cond & (G_IO_HUP | G_IO_ERR)) && hdev->intr_watch)
+ g_io_channel_shutdown(chan, TRUE, NULL);
+
+ hdev->ctrl_watch = 0;
+
+ if (hdev->ctrl_io) {
+ g_io_channel_unref(hdev->ctrl_io);
+ hdev->ctrl_io = NULL;
+ }
+
+ if (hdev->intr_io && !(cond & G_IO_NVAL))
+ g_io_channel_shutdown(hdev->intr_io, TRUE, NULL);
+
+ return FALSE;
+}
+
+static void interrupt_connect_cb(GIOChannel *chan, GError *conn_err,
+ gpointer user_data)
+{
+ struct hid_device *hdev = user_data;
+
+ DBG("");
+
+ if (conn_err)
+ goto failed;
+
+ /*TODO: Get device details through SDP and create UHID fd and start
+ * listening on uhid events */
+ hdev->intr_watch = g_io_add_watch(hdev->intr_io,
+ G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+ intr_watch_cb, hdev);
+
+ return;
+
+failed:
+ /* So we guarantee the interrupt channel is closed before the
+ * control channel (if we only do unref GLib will close it only
+ * after returning control to the mainloop */
+ if (!conn_err)
+ g_io_channel_shutdown(hdev->intr_io, FALSE, NULL);
+
+ g_io_channel_unref(hdev->intr_io);
+ hdev->intr_io = NULL;
+
+ if (hdev->ctrl_io) {
+ g_io_channel_unref(hdev->ctrl_io);
+ hdev->ctrl_io = NULL;
+ }
+}
+
+static void control_connect_cb(GIOChannel *chan, GError *conn_err,
+ gpointer user_data)
+{
+ struct hid_device *hdev = user_data;
+ GError *err = NULL;
+ const bdaddr_t *src = bt_adapter_get_address();
+
+ DBG("");
+
+ if (conn_err) {
+ error("%s", conn_err->message);
+ goto failed;
+ }
+
+ /* Connect to the HID interrupt channel */
+ hdev->intr_io = bt_io_connect(interrupt_connect_cb, hdev, NULL, &err,
+ BT_IO_OPT_SOURCE_BDADDR, src,
+ BT_IO_OPT_DEST_BDADDR, &hdev->dst,
+ BT_IO_OPT_PSM, L2CAP_PSM_HIDP_INTR,
+ BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+ BT_IO_OPT_INVALID);
+ if (!hdev->intr_io) {
+ error("%s", err->message);
+ g_error_free(err);
+ goto failed;
+ }
+
+ hdev->ctrl_watch = g_io_add_watch(hdev->ctrl_io,
+ G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+ ctrl_watch_cb, hdev);
+
+ return;
+
+failed:
+ g_io_channel_unref(hdev->ctrl_io);
+ hdev->ctrl_io = NULL;
+}
+
+static uint8_t bt_hid_connect(struct hal_cmd_hid_connect *cmd, uint16_t len)
+{
+ struct hid_device *hdev;
+ char addr[18];
+ bdaddr_t dst;
+ GSList *l;
+ GError *err = NULL;
+ const bdaddr_t *src = bt_adapter_get_address();
+
+ DBG("");
+
+ if (len < sizeof(*cmd))
+ return HAL_STATUS_INVALID;
+
+ android2bdaddr((bdaddr_t *)&cmd->bdaddr, &dst);
+
+ l = g_slist_find_custom(devices, &dst, device_cmp);
+ if (l)
+ return HAL_STATUS_FAILED;
+
+ hdev = g_new0(struct hid_device, 1);
+ android2bdaddr((bdaddr_t *)&cmd->bdaddr, &hdev->dst);
+ ba2str(&hdev->dst, addr);
+
+ DBG("connecting to %s", addr);
+
+ hdev->ctrl_io = bt_io_connect(control_connect_cb, hdev, NULL, &err,
+ BT_IO_OPT_SOURCE_BDADDR, src,
+ BT_IO_OPT_DEST_BDADDR, &hdev->dst,
+ BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL,
+ BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+ BT_IO_OPT_INVALID);
+ if (err) {
+ error("%s", err->message);
+ g_error_free(err);
+ hid_device_free(hdev);
+ return HAL_STATUS_FAILED;
+ }
+
+ devices = g_slist_append(devices, hdev);
+
+ return HAL_STATUS_SUCCESS;
+}
void bt_hid_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf, uint16_t len)
{
@@ -40,6 +284,7 @@ void bt_hid_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf, uint16_t len)
switch (opcode) {
case HAL_OP_HID_CONNECT:
+ status = bt_hid_connect(buf, len);
break;
case HAL_OP_HID_DISCONNECT:
break;
--
1.7.9.5
^ permalink raw reply related
* [PATCH_v2 2/2] android: Add initial HID disconnect implementation.
From: Ravi kumar Veeramally @ 2013-10-29 8:38 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1383035920-21599-1-git-send-email-ravikumar.veeramally@linux.intel.com>
Implemented basic HID disconnect method. Host disconnects
with bt device at L2CAP level.
---
android/hid.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/android/hid.c b/android/hid.c
index 7f9e386..0a26bfe 100644
--- a/android/hid.c
+++ b/android/hid.c
@@ -278,6 +278,28 @@ static uint8_t bt_hid_connect(struct hal_cmd_hid_connect *cmd, uint16_t len)
return HAL_STATUS_SUCCESS;
}
+static uint8_t bt_hid_disconnect(struct hal_cmd_hid_disconnect *cmd,
+ uint16_t len)
+{
+ GSList *l;
+ bdaddr_t dst;
+
+ DBG("");
+
+ if (len < sizeof(*cmd))
+ return HAL_STATUS_INVALID;
+
+ android2bdaddr((bdaddr_t *)&cmd->bdaddr, &dst);
+
+ l = g_slist_find_custom(devices, &dst, device_cmp);
+ if (!l)
+ return HAL_STATUS_FAILED;
+
+ hid_device_free(l->data);
+
+ return HAL_STATUS_SUCCESS;
+}
+
void bt_hid_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf, uint16_t len)
{
uint8_t status = HAL_STATUS_FAILED;
@@ -287,6 +309,7 @@ void bt_hid_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf, uint16_t len)
status = bt_hid_connect(buf, len);
break;
case HAL_OP_HID_DISCONNECT:
+ status = bt_hid_disconnect(buf, len);
break;
default:
DBG("Unhandled command, opcode 0x%x", opcode);
--
1.7.9.5
^ permalink raw reply related
* [PATCH_v3 1/2] android: Add initial HID connect implementation
From: Ravi kumar Veeramally @ 2013-10-29 9:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
Implemented basic HID connect method. Host connects to
bt device at L2CAP level.
---
v3: Updated patches as per Luiz comments (remove unnecessary
type cast and tabs)
v2: Updated patches as per Luiz comments
v1: Patchset adds hid connect and disconnect mechanisms at
L2CAP level. It opens the control channel and interrupt
channel and listens on io events. UHID, hid server and
---
Makefile.android | 3 +-
android/Android.mk | 1 +
android/hid.c | 245 ++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 248 insertions(+), 1 deletion(-)
diff --git a/Makefile.android b/Makefile.android
index 2b57daa..22002be 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -12,7 +12,8 @@ android_bluetoothd_SOURCES = android/main.c \
android/adapter.h android/adapter.c \
android/hid.h android/hid.c \
android/ipc.h android/ipc.c \
- android/socket.h android/socket.c
+ android/socket.h android/socket.c \
+ btio/btio.h btio/btio.c
android_bluetoothd_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
diff --git a/android/Android.mk b/android/Android.mk
index 22208e0..28ec465 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -28,6 +28,7 @@ LOCAL_SRC_FILES := \
../lib/sdp.c \
../lib/bluetooth.c \
../lib/hci.c \
+ ../btio/btio.c
LOCAL_C_INCLUDES := \
$(call include-path-for, glib) \
diff --git a/android/hid.c b/android/hid.c
index f2da0d3..913dab4 100644
--- a/android/hid.c
+++ b/android/hid.c
@@ -23,16 +23,260 @@
#include <stdint.h>
#include <stdbool.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
#include <glib.h>
+#include "btio/btio.h"
#include "lib/bluetooth.h"
+#include "src/shared/mgmt.h"
+
#include "log.h"
#include "hal-msg.h"
#include "ipc.h"
#include "hid.h"
+#include "adapter.h"
+#include "utils.h"
+
+#define L2CAP_PSM_HIDP_CTRL 0x11
+#define L2CAP_PSM_HIDP_INTR 0x13
+#define MAX_READ_BUFFER 4096
static GIOChannel *notification_io = NULL;
+static GSList *devices = NULL;
+
+struct hid_device {
+ bdaddr_t dst;
+ GIOChannel *ctrl_io;
+ GIOChannel *intr_io;
+ guint ctrl_watch;
+ guint intr_watch;
+};
+
+static int device_cmp(gconstpointer s, gconstpointer user_data)
+{
+ const struct hid_device *hdev = s;
+ const bdaddr_t *dst = user_data;
+
+ return bacmp(&hdev->dst, dst);
+}
+
+static void hid_device_free(struct hid_device *hdev)
+{
+ if (hdev->ctrl_watch > 0)
+ g_source_remove(hdev->ctrl_watch);
+
+ if (hdev->intr_watch > 0)
+ g_source_remove(hdev->intr_watch);
+
+ if (hdev->intr_io)
+ g_io_channel_unref(hdev->intr_io);
+
+ if (hdev->ctrl_io)
+ g_io_channel_unref(hdev->ctrl_io);
+
+ devices = g_slist_remove(devices, hdev);
+ g_free(hdev);
+}
+
+static gboolean intr_io_watch_cb(GIOChannel *chan, gpointer data)
+{
+ char buf[MAX_READ_BUFFER];
+ int fd, bread;
+
+ fd = g_io_channel_unix_get_fd(chan);
+ bread = read(fd, buf, sizeof(buf));
+ if (bread < 0) {
+ error("read: %s(%d)", strerror(errno), -errno);
+ return TRUE;
+ }
+
+ DBG("bytes read %d", bread);
+
+ /* TODO: At this moment only baseband is connected, i.e. mouse
+ * movements keyboard events doesn't effect on UI. Have to send
+ * this data to uhid fd for profile connection. */
+
+ return TRUE;
+}
+
+static gboolean intr_watch_cb(GIOChannel *chan, GIOCondition cond,
+ gpointer data)
+{
+ struct hid_device *hdev = data;
+ char address[18];
+
+ if (cond & G_IO_IN)
+ return intr_io_watch_cb(chan, data);
+
+ ba2str(&hdev->dst, address);
+ DBG("Device %s disconnected", address);
+
+ /* Checking for ctrl_watch avoids a double g_io_channel_shutdown since
+ * it's likely that ctrl_watch_cb has been queued for dispatching in
+ * this mainloop iteration */
+ if ((cond & (G_IO_HUP | G_IO_ERR)) && hdev->ctrl_watch)
+ g_io_channel_shutdown(chan, TRUE, NULL);
+
+ hdev->intr_watch = 0;
+
+ if (hdev->intr_io) {
+ g_io_channel_unref(hdev->intr_io);
+ hdev->intr_io = NULL;
+ }
+
+ /* Close control channel */
+ if (hdev->ctrl_io && !(cond & G_IO_NVAL))
+ g_io_channel_shutdown(hdev->ctrl_io, TRUE, NULL);
+
+ return FALSE;
+}
+
+static gboolean ctrl_watch_cb(GIOChannel *chan, GIOCondition cond,
+ gpointer data)
+{
+ struct hid_device *hdev = data;
+ char address[18];
+
+ ba2str(&hdev->dst, address);
+ DBG("Device %s disconnected", address);
+
+ /* Checking for intr_watch avoids a double g_io_channel_shutdown since
+ * it's likely that intr_watch_cb has been queued for dispatching in
+ * this mainloop iteration */
+ if ((cond & (G_IO_HUP | G_IO_ERR)) && hdev->intr_watch)
+ g_io_channel_shutdown(chan, TRUE, NULL);
+
+ hdev->ctrl_watch = 0;
+
+ if (hdev->ctrl_io) {
+ g_io_channel_unref(hdev->ctrl_io);
+ hdev->ctrl_io = NULL;
+ }
+
+ if (hdev->intr_io && !(cond & G_IO_NVAL))
+ g_io_channel_shutdown(hdev->intr_io, TRUE, NULL);
+
+ return FALSE;
+}
+
+static void interrupt_connect_cb(GIOChannel *chan, GError *conn_err,
+ gpointer user_data)
+{
+ struct hid_device *hdev = user_data;
+
+ DBG("");
+
+ if (conn_err)
+ goto failed;
+
+ /*TODO: Get device details through SDP and create UHID fd and start
+ * listening on uhid events */
+ hdev->intr_watch = g_io_add_watch(hdev->intr_io,
+ G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+ intr_watch_cb, hdev);
+
+ return;
+
+failed:
+ /* So we guarantee the interrupt channel is closed before the
+ * control channel (if we only do unref GLib will close it only
+ * after returning control to the mainloop */
+ if (!conn_err)
+ g_io_channel_shutdown(hdev->intr_io, FALSE, NULL);
+
+ g_io_channel_unref(hdev->intr_io);
+ hdev->intr_io = NULL;
+
+ if (hdev->ctrl_io) {
+ g_io_channel_unref(hdev->ctrl_io);
+ hdev->ctrl_io = NULL;
+ }
+}
+
+static void control_connect_cb(GIOChannel *chan, GError *conn_err,
+ gpointer user_data)
+{
+ struct hid_device *hdev = user_data;
+ GError *err = NULL;
+ const bdaddr_t *src = bt_adapter_get_address();
+
+ DBG("");
+
+ if (conn_err) {
+ error("%s", conn_err->message);
+ goto failed;
+ }
+
+ /* Connect to the HID interrupt channel */
+ hdev->intr_io = bt_io_connect(interrupt_connect_cb, hdev, NULL, &err,
+ BT_IO_OPT_SOURCE_BDADDR, src,
+ BT_IO_OPT_DEST_BDADDR, &hdev->dst,
+ BT_IO_OPT_PSM, L2CAP_PSM_HIDP_INTR,
+ BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+ BT_IO_OPT_INVALID);
+ if (!hdev->intr_io) {
+ error("%s", err->message);
+ g_error_free(err);
+ goto failed;
+ }
+
+ hdev->ctrl_watch = g_io_add_watch(hdev->ctrl_io,
+ G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+ ctrl_watch_cb, hdev);
+
+ return;
+
+failed:
+ g_io_channel_unref(hdev->ctrl_io);
+ hdev->ctrl_io = NULL;
+}
+
+static uint8_t bt_hid_connect(struct hal_cmd_hid_connect *cmd, uint16_t len)
+{
+ struct hid_device *hdev;
+ char addr[18];
+ bdaddr_t dst;
+ GSList *l;
+ GError *err = NULL;
+ const bdaddr_t *src = bt_adapter_get_address();
+
+ DBG("");
+
+ if (len < sizeof(*cmd))
+ return HAL_STATUS_INVALID;
+
+ android2bdaddr(&cmd->bdaddr, &dst);
+
+ l = g_slist_find_custom(devices, &dst, device_cmp);
+ if (l)
+ return HAL_STATUS_FAILED;
+
+ hdev = g_new0(struct hid_device, 1);
+ android2bdaddr(&cmd->bdaddr, &hdev->dst);
+ ba2str(&hdev->dst, addr);
+
+ DBG("connecting to %s", addr);
+
+ hdev->ctrl_io = bt_io_connect(control_connect_cb, hdev, NULL, &err,
+ BT_IO_OPT_SOURCE_BDADDR, src,
+ BT_IO_OPT_DEST_BDADDR, &hdev->dst,
+ BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL,
+ BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+ BT_IO_OPT_INVALID);
+ if (err) {
+ error("%s", err->message);
+ g_error_free(err);
+ hid_device_free(hdev);
+ return HAL_STATUS_FAILED;
+ }
+
+ devices = g_slist_append(devices, hdev);
+
+ return HAL_STATUS_SUCCESS;
+}
void bt_hid_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf, uint16_t len)
{
@@ -40,6 +284,7 @@ void bt_hid_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf, uint16_t len)
switch (opcode) {
case HAL_OP_HID_CONNECT:
+ status = bt_hid_connect(buf, len);
break;
case HAL_OP_HID_DISCONNECT:
break;
--
1.7.9.5
^ permalink raw reply related
* [PATCH_v3 2/2] android: Add initial HID disconnect implementation.
From: Ravi kumar Veeramally @ 2013-10-29 9:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1383040097-15475-1-git-send-email-ravikumar.veeramally@linux.intel.com>
Implemented basic HID disconnect method. Host disconnects
with bt device at L2CAP level.
---
android/hid.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/android/hid.c b/android/hid.c
index 913dab4..3479f80 100644
--- a/android/hid.c
+++ b/android/hid.c
@@ -278,6 +278,28 @@ static uint8_t bt_hid_connect(struct hal_cmd_hid_connect *cmd, uint16_t len)
return HAL_STATUS_SUCCESS;
}
+static uint8_t bt_hid_disconnect(struct hal_cmd_hid_disconnect *cmd,
+ uint16_t len)
+{
+ GSList *l;
+ bdaddr_t dst;
+
+ DBG("");
+
+ if (len < sizeof(*cmd))
+ return HAL_STATUS_INVALID;
+
+ android2bdaddr(&cmd->bdaddr, &dst);
+
+ l = g_slist_find_custom(devices, &dst, device_cmp);
+ if (!l)
+ return HAL_STATUS_FAILED;
+
+ hid_device_free(l->data);
+
+ return HAL_STATUS_SUCCESS;
+}
+
void bt_hid_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf, uint16_t len)
{
uint8_t status = HAL_STATUS_FAILED;
@@ -287,6 +309,7 @@ void bt_hid_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf, uint16_t len)
status = bt_hid_connect(buf, len);
break;
case HAL_OP_HID_DISCONNECT:
+ status = bt_hid_disconnect(buf, len);
break;
default:
DBG("Unhandled command, opcode 0x%x", opcode);
--
1.7.9.5
^ permalink raw reply related
* Intel 7260 bluetooth malfunction when it is connected to EHCI bus
From: Hui Wang @ 2013-10-29 10:03 UTC (permalink / raw)
To: tedd.an, johan.hedberg, marcel, xiong.y.zhang, gustavo.padovan
Cc: linux-bluetooth
The problem is:
On the machine which has Intel 7260 BT module, i use it to connect a
bluetooth headset,
it can successfully scan and connect to the headset, when i play sound
to the bt headset,
the problem comes, if the bt module is connected to the XHCI, it can
work very well.
u@u-Lenovo-B4400:~$ lsusb -t
1-7:1.0: No such file or directory
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/14p, 480M
|__ Port 6: Dev 8, If 0, Class=HID, Driver=usbhid, 1.5M
|__ Port 7: Dev 2, If 0, Class=vend., Driver=, 12M
|__ Port 11: Dev 3, If 0, Class='bInterfaceClass 0xe0 not yet
handled', Driver=btusb, 12M
|__ Port 11: Dev 3, If 1, Class='bInterfaceClass 0xe0 not yet
handled', Driver=btusb, 12M
But if the bt module is connected to the EHCI, it always fails to play
sound.
u@u-Lenovo-B4400:~$ lsusb -t
/: Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M
/: Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/14p, 480M
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=ehci_hcd/3p, 480M
|__ Port 1: Dev 2, If 0, Class=hub, Driver=hub/8p, 480M
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci_hcd/3p, 480M
|__ Port 1: Dev 2, If 0, Class=hub, Driver=hub/6p, 480M
|__ Port 5: Dev 3, If 0, Class='bInterfaceClass 0xe0 not yet
handled', Driver=btusb, 12M
|__ Port 5: Dev 3, If 1, Class='bInterfaceClass 0xe0 not yet
handled', Driver=btusb, 12M
|__ Port 6: Dev 4, If 0, Class='bInterfaceClass 0x0e not yet
handled', Driver=uvcvideo, 480M
|__ Port 6: Dev 4, If 1, Class='bInterfaceClass 0x0e not yet
handled', Driver=uvcvideo, 480M
---------------------------------------------------------------------------------------------------------
The BT moudle version, firmware version and linux kernel version:
dmesg snippet,
[ 2.164386] Bluetooth: hci0: read Intel version: 370710018002030d00
[ 2.200701] Bluetooth: hci0: Intel Bluetooth firmware file:
intel/ibt-hw-37.7.10-fw-1.80.2.3.d.bseq
And the firmware was got from
http://permalink.gmane.org/gmane.linux.bluez.kernel/37580.
To verify the firmware is the latest, i execute following commands,
u@u-Lenovo-B4400:~$ sudo hcitool cmd 0x3f 0x005 0x00
< HCI Command: ogf 0x3f, ocf 0x0005, plen 1
00
> HCI Event: 0x0e plen 13
01 05 FC 00 37 07 10 01 80 02 03 0D 2E
On the machine, i installed ubuntu-12.04 (kernel is 3.5), then i
replaced the kernel to the linux-3.8 and
the latest upstream kernel linux-3.12.0-rc6, the situation had no
difference, the problem still can be
reproduced on very linux kernel version.
----------------------------------------------------------------------------------------------------------
My investigation:
I did the test on dozens of laptops on which all installed intel 7260
wifi+bt combo, in case the bt module
is connected to EHCI bus, it will 100% fail to play sound to the bt
headset. If the bt module is connected
to the XHCI bus, it will work very well, including play audio to a bt
headset.
And more investigation show, if the bt module is on the EHCI bus, it
can't receive any SCO packet like this,
u@u-Lenovo-B4400:~$ hciconfig
hci0: Type: BR/EDR Bus: USB
BD Address: 00:15:00:CC:2D:D2 ACL MTU: 1021:5 SCO MTU: 96:5
UP RUNNING PSCAN
RX bytes:6687 acl:61 sco:0 events:308 errors:0
TX bytes:19367 acl:70 sco:3 commands:179 errors:0
if the bt module is on the XHCI bus, it can transmit and receive SCO
packets very well,
u@u-Lenovo-B4400:~$ hciconfig
hci0: Type: BR/EDR Bus: USB
BD Address: 00:15:00:CC:2D:D2 ACL MTU: 1021:5 SCO MTU: 96:5
UP RUNNING PSCAN
RX bytes:572756 acl:47 sco:11173 events:221 errors:0
TX bytes:586261 acl:55 sco:11137 commands:137 errors:0
----------------------------------------------------------------------------------------------------------
So could anybody be kindly help to confirm this problem, and could the
maintainer of intel 7260 bt driver/firmware
be kindly to solve this problem?
Thanks in advance.
Hui.
^ permalink raw reply
* [PATCH 1/5] android: Define class of device as four bytes in IPC doc
From: Szymon Janc @ 2013-10-29 10:07 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
For PIN and SSP requests callback define CoD as 4 bytes. This will
allow HAL library to pass CoD direclty to callback. Will also match
how CoD is passed as property.
---
android/hal-ipc-api.txt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/android/hal-ipc-api.txt b/android/hal-ipc-api.txt
index dc0d067..e7af8a3 100644
--- a/android/hal-ipc-api.txt
+++ b/android/hal-ipc-api.txt
@@ -354,13 +354,13 @@ Notifications:
Notification parameters: Remote address (6 octets)
Remote name (249 octets)
- Class of device (3 octets)
+ Class of device (4 octets)
Opcode 0x87 - SSP Request notification
Notification parameters: Remote address (6 octets)
Remote name (249 octets)
- Class of device (3 octets)
+ Class of device (4 octets)
Pairing variant (1 octet)
Passkey (4 octets)
--
1.8.4.1
^ permalink raw reply related
* [PATCH 2/5] android: Update IPC headers to match SSP and PIN requests events
From: Szymon Janc @ 2013-10-29 10:07 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1383041255-26549-1-git-send-email-szymon.janc@tieto.com>
Name should be 249 bytes so it is always NULL terminated string.
Class of device is send as uint32. This will allow to make simple
passing of data in HAL library without need of copying data.
---
android/hal-msg.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/android/hal-msg.h b/android/hal-msg.h
index a4eb2a8..80b47d6 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -356,15 +356,15 @@ struct hal_ev_discovery_state_changed {
#define HAL_EV_PIN_REQUEST 0x86
struct hal_ev_pin_request {
uint8_t bdaddr[6];
- uint8_t name[249 - 1];
- uint8_t class_of_dev[3];
+ uint8_t name[249];
+ uint32_t class_of_dev;
} __attribute__((packed));
#define HAL_EV_SSP_REQUEST 0x87
struct hal_ev_ssp_request {
uint8_t bdaddr[6];
- uint8_t name[249 - 1];
- uint8_t class_of_dev[3];
+ uint8_t name[249];
+ uint32_t class_of_dev;
uint8_t pairing_variant;
uint32_t passkey;
} __attribute__((packed));
--
1.8.4.1
^ permalink raw reply related
* [PATCH 3/5] android/hal: Add support for handling bond state change event
From: Szymon Janc @ 2013-10-29 10:07 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1383041255-26549-1-git-send-email-szymon.janc@tieto.com>
---
android/hal-bluetooth.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 5f6dcbe..067f420 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -68,6 +68,17 @@ static void handle_adapter_props_changed(void *buf, uint16_t len)
bt_hal_cbacks->adapter_properties_cb(ev->status, ev->num_props, props);
}
+static void handle_bond_state_change(void *buf)
+{
+ struct hal_ev_bond_state_changed *ev = buf;
+ bt_bdaddr_t *addr = (bt_bdaddr_t *) ev->bdaddr;
+
+ if (!bt_hal_cbacks->bond_state_changed_cb)
+ return;
+
+ bt_hal_cbacks->bond_state_changed_cb(ev->status, addr, ev->state);
+}
+
void bt_thread_associate(void)
{
if (bt_hal_cbacks->thread_evt_cb)
@@ -98,6 +109,9 @@ void bt_notify_adapter(uint16_t opcode, void *buf, uint16_t len)
case HAL_EV_ADAPTER_PROPS_CHANGED:
handle_adapter_props_changed(buf, len);
break;
+ case HAL_EV_BOND_STATE_CHANGED:
+ handle_bond_state_change(buf);
+ break;
default:
DBG("Unhandled callback opcode=0x%x", opcode);
break;
--
1.8.4.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox