* [PATCH 0/3] android: add support for hidhost to haltest
From: Jerzy Kasenberg @ 2013-10-22 11:02 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Jerzy Kasenberg
- adds support for hidhost
- adds tab completion for hidhost
- adds help for hidhost
- magic number to #define change for buffer sizes
Jerzy Kasenberg (3):
android: Add definition of buffer sizes to haltest
android: Add calls to hidhost interface to haltest
android: Add help to hidhost in haltest
Makefile.android | 2 +
android/Android.mk | 1 +
android/client/haltest.c | 1 +
android/client/if-bt.c | 10 +-
android/client/if-hh.c | 431 +++++++++++++++++++++++++++++++++++++++++++++
android/client/if-main.h | 2 +
android/client/textconv.c | 2 +-
android/client/textconv.h | 2 +
8 files changed, 445 insertions(+), 6 deletions(-)
create mode 100644 android/client/if-hh.c
--
1.7.9.5
^ permalink raw reply
* [PATCH 2/2] android/hal: Add initial support for handling adapter notifications
From: Szymon Janc @ 2013-10-22 10:59 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382439549-18281-1-git-send-email-szymon.janc@tieto.com>
Only adapter state callback is handled for now.
---
android/hal-bluetooth.c | 24 ++++++++++++++++++++++++
android/hal-ipc.c | 6 ++++++
android/hal.h | 2 ++
3 files changed, 32 insertions(+)
diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 5b07070..37edb41 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -32,6 +32,30 @@
bt_callbacks_t *bt_hal_cbacks = NULL;
+static void handle_adapter_state_changed(void *buf)
+{
+ struct hal_msg_ev_bt_adapter_state_changed *ev = buf;
+
+ if (bt_hal_cbacks->adapter_state_changed_cb)
+ bt_hal_cbacks->adapter_state_changed_cb(ev->state);
+}
+
+/* will be called from notification thread context */
+void bt_notify_adapter(uint16_t opcode, void *buf, uint16_t len, int fd)
+{
+ if (!bt_hal_cbacks)
+ return;
+
+ switch (opcode) {
+ case HAL_MSG_EV_BT_ADAPTER_STATE_CHANGED:
+ handle_adapter_state_changed(buf);
+ break;
+ default:
+ DBG("Unhandled callback opcode=0x%x", opcode);
+ break;
+ }
+}
+
static bool interface_ready(void)
{
return bt_hal_cbacks != NULL;
diff --git a/android/hal-ipc.c b/android/hal-ipc.c
index ef58a7c..ccdcb9f 100644
--- a/android/hal-ipc.c
+++ b/android/hal-ipc.c
@@ -27,6 +27,9 @@
#include <cutils/properties.h>
+#include <hardware/bluetooth.h>
+#include "hal.h"
+
#include "hal-msg.h"
#include "hal-log.h"
#include "hal-ipc.h"
@@ -44,6 +47,9 @@ static pthread_t notif_th = 0;
static void notification_dispatch(struct hal_msg_hdr *msg, int fd)
{
switch (msg->service_id) {
+ case HAL_SERVICE_ID_BLUETOOTH:
+ bt_notify_adapter(msg->opcode, msg + 1, msg->len, fd);
+ break;
default:
DBG("Unhandled notification service=%d opcode=0x%x",
msg->service_id, msg->opcode);
diff --git a/android/hal.h b/android/hal.h
index d984336..889fce6 100644
--- a/android/hal.h
+++ b/android/hal.h
@@ -24,3 +24,5 @@ btsock_interface_t *bt_get_sock_interface(void);
bthh_interface_t *bt_get_hidhost_interface(void);
btpan_interface_t *bt_get_pan_interface(void);
btav_interface_t *bt_get_av_interface(void);
+
+void bt_notify_adapter(uint16_t opcode, void *buf, uint16_t len, int fd);
--
1.8.4
^ permalink raw reply related
* [PATCH 1/2] android/hal: Add initial code for notification handling
From: Szymon Janc @ 2013-10-22 10:59 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
This adds a dedicated thread that will read from notification sockets
and dispatch it to appropriate service notification function.
---
Makefile.android | 2 +
android/hal-ipc.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 107 insertions(+), 2 deletions(-)
diff --git a/Makefile.android b/Makefile.android
index aebc715..889b36e 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -54,6 +54,8 @@ 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/log.c android/device.c \
diff --git a/android/hal-ipc.c b/android/hal-ipc.c
index 8d40271..ef58a7c 100644
--- a/android/hal-ipc.c
+++ b/android/hal-ipc.c
@@ -39,6 +39,95 @@ static int notif_sk = -1;
static pthread_mutex_t cmd_sk_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_t notif_th = 0;
+
+static void notification_dispatch(struct hal_msg_hdr *msg, int fd)
+{
+ switch (msg->service_id) {
+ default:
+ DBG("Unhandled notification service=%d opcode=0x%x",
+ msg->service_id, msg->opcode);
+ break;
+ }
+}
+
+static void *notification_handler(void *data)
+{
+ struct msghdr msg;
+ struct iovec iv;
+ struct cmsghdr *cmsg;
+ char cmsgbuf[CMSG_SPACE(sizeof(int))];
+ char buf[BLUEZ_HAL_MTU];
+ struct hal_msg_hdr *hal_msg = (void *) buf;
+ ssize_t ret;
+ int fd;
+
+ while (true) {
+ memset(&msg, 0, sizeof(msg));
+ memset(buf, 0, sizeof(buf));
+ memset(cmsgbuf, 0, sizeof(cmsgbuf));
+
+ iv.iov_base = hal_msg;
+ iv.iov_len = sizeof(buf);
+
+ msg.msg_iov = &iv;
+ msg.msg_iovlen = 1;
+
+ msg.msg_control = cmsgbuf;
+ msg.msg_controllen = sizeof(cmsgbuf);
+
+ ret = recvmsg(notif_sk, &msg, 0);
+ if (ret < 0) {
+ error("Receiving notifications failed, aborting :%s",
+ strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ /* socket was shutdown */
+ if (ret == 0)
+ break;
+
+ if (ret < (ssize_t) sizeof(*hal_msg)) {
+ error("Too small notification (%zd bytes), aborting",
+ ret);
+ exit(EXIT_FAILURE);
+ }
+
+ if (hal_msg->opcode < HAL_MSG_EV_BT_ERROR) {
+ error("Invalid notification (0x%x), aborting",
+ hal_msg->opcode);
+ exit(EXIT_FAILURE);
+ }
+
+ if (ret != (ssize_t) (sizeof(*hal_msg) + hal_msg->len)) {
+ error("Malformed notification(%zd bytes), aborting",
+ ret);
+ exit(EXIT_FAILURE);
+ }
+
+ fd = -1;
+
+ /* Receive auxiliary data in msg */
+ for (cmsg = CMSG_FIRSTHDR(&msg); !cmsg;
+ cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ if (cmsg->cmsg_level == SOL_SOCKET
+ && cmsg->cmsg_type == SCM_RIGHTS) {
+ memcpy(&fd, CMSG_DATA(cmsg), sizeof(int));
+ break;
+ }
+ }
+
+ notification_dispatch(hal_msg, fd);
+ }
+
+ close(notif_sk);
+ notif_sk = -1;
+
+ DBG("exit");
+
+ return NULL;
+}
+
static int accept_connection(int sk)
{
int err;
@@ -126,6 +215,18 @@ bool hal_ipc_init(void)
close(sk);
+ err = pthread_create(¬if_th, NULL, notification_handler, NULL);
+ if (err < 0) {
+ notif_th = 0;
+ error("Failed to start notification thread: %d (%s)", -err,
+ strerror(-err));
+ close(cmd_sk);
+ cmd_sk = -1;
+ close(notif_sk);
+ notif_sk = -1;
+ return false;
+ }
+
return true;
}
@@ -134,8 +235,10 @@ void hal_ipc_cleanup(void)
close(cmd_sk);
cmd_sk = -1;
- close(notif_sk);
- notif_sk = -1;
+ shutdown(notif_sk, SHUT_RD);
+
+ pthread_join(notif_th, NULL);
+ notif_th = 0;
}
int hal_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len, void *param,
--
1.8.4
^ permalink raw reply related
* Re: [PATCH] android: Fix compilation error for Android 4.2.2
From: Johan Hedberg @ 2013-10-22 10:44 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1382436600-8598-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On Tue, Oct 22, 2013, Andrei Emeltchenko wrote:
> ---
> android/client/if-bt.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/android/client/if-bt.c b/android/client/if-bt.c
> index 5447e0c..330a3fa 100644
> --- a/android/client/if-bt.c
> +++ b/android/client/if-bt.c
> @@ -364,11 +364,13 @@ static void dut_mode_recv_cb(uint16_t opcode, uint8_t *buf, uint8_t len)
> haltest_info("%s\n", __func__);
> }
>
> +#if PLATFORM_SDK_VERSION > 17
> static void le_test_mode_cb(bt_status_t status, uint16_t num_packets)
> {
> haltest_info("%s %s %d\n", __func__, bt_state_t2str(status),
> num_packets);
> }
> +#endif
>
> static bt_callbacks_t bt_callbacks = {
> .size = sizeof(bt_callbacks),
Seems like you're missing a matching conditional for the bt_callbacks
part.
Johan
^ permalink raw reply
* [PATCH] android: HID host
From: Andrei Emeltchenko @ 2013-10-22 10:43 UTC (permalink / raw)
To: linux-bluetooth
From: Frederic Danis <frederic.danis@linux.intel.com>
Basic implementation of HID host for Android.
---
android/hidhost-device.c | 975 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 975 insertions(+)
create mode 100644 android/hidhost-device.c
diff --git a/android/hidhost-device.c b/android/hidhost-device.c
new file mode 100644
index 0000000..eb3849d
--- /dev/null
+++ b/android/hidhost-device.c
@@ -0,0 +1,975 @@
+/*
+ *
+ * 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
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <glib.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/sdp.h>
+#include <bluetooth/sdp_lib.h>
+#include <btio/btio.h>
+
+#include <linux/uhid.h>
+
+#include "log.h"
+#include "src/shared/mgmt.h"
+#include "adapter.h"
+#include "device.h"
+
+#define L2CAP_PSM_HIDP_CTRL 0x11
+#define L2CAP_PSM_HIDP_INTR 0x13
+
+#define UHID_DEVICE_FILE "/dev/uhid"
+
+#define REPORT_MAP_MAX_SIZE 512
+
+enum reconnect_mode_t {
+ RECONNECT_NONE = 0,
+ RECONNECT_DEVICE,
+ RECONNECT_HOST,
+ RECONNECT_ANY
+};
+
+struct input_device {
+/* struct btd_service *service;
+*/
+ struct bt_device *device;
+/* char *path;
+*/
+ bdaddr_t src;
+ bdaddr_t dst;
+/* uint32_t handle;
+*/
+ GIOChannel *ctrl_io;
+ GIOChannel *intr_io;
+ guint ctrl_watch;
+ guint intr_watch;
+/* guint sec_watch;
+*/
+ guint uhid_watch_id;
+/* struct hidp_connadd_req *req;
+*/
+ guint dc_id;
+/* bool disable_sdp;
+ char *name;
+*/
+ enum reconnect_mode_t reconnect_mode;
+ guint reconnect_timer;
+ uint32_t reconnect_attempt;
+ int uhid_fd;
+};
+
+static GSList *conns = NULL;
+
+static struct input_device *find_conn(GSList *list,
+ const bdaddr_t *bd_addr)
+{
+ for (; list; list = list->next) {
+ struct input_device *idev = list->data;
+
+ if (bacmp(bd_addr, bt_device_get_address(idev->device)))
+ return idev;
+ }
+
+ return NULL;
+}
+
+static void input_device_enter_reconnect_mode(struct input_device *idev);
+
+static gboolean intr_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 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);
+
+ bt_device_remove_disconnect_watch(idev->device, idev->dc_id);
+ idev->dc_id = 0;
+
+ 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);
+
+ /* TODO:
+ btd_service_disconnecting_complete(idev->service, 0);
+ */
+
+ /* Enter the auto-reconnect mode if needed */
+ input_device_enter_reconnect_mode(idev);
+
+ return FALSE;
+}
+
+static void ctrl_disconnected(struct input_device *idev, GIOChannel *chan,
+ GIOCondition cond)
+{
+ 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;
+ }
+
+ /* Close interrupt channel */
+ if (idev->intr_io && !(cond & G_IO_NVAL))
+ g_io_channel_shutdown(idev->intr_io, TRUE, NULL);
+}
+
+static gboolean ctrl_watch_cb(GIOChannel *chan, GIOCondition cond,
+ gpointer data)
+{
+ struct input_device *idev = data;
+#if 0
+ 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;
+ }
+
+ /* Close interrupt channel */
+ if (idev->intr_io && !(cond & G_IO_NVAL))
+ g_io_channel_shutdown(idev->intr_io, TRUE, NULL);
+
+ return FALSE;
+#else
+ if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
+ /* TODO: */
+ ;
+ }
+
+ return TRUE;
+#endif
+}
+
+#ifndef STORAGEDIR
+#define STORAGEDIR "/var/lib/bluetooth"
+#endif
+
+sdp_record_t *record_from_string(const char *str)
+{
+ sdp_record_t *rec;
+ int size, i, len;
+ uint8_t *pdata;
+ char tmp[3];
+
+ size = strlen(str)/2;
+ pdata = g_malloc0(size);
+
+ tmp[2] = 0;
+ for (i = 0; i < size; i++) {
+ memcpy(tmp, str + (i * 2), 2);
+ pdata[i] = (uint8_t) strtol(tmp, NULL, 16);
+ }
+
+ rec = sdp_extract_pdu(pdata, size, &len);
+ g_free(pdata);
+
+ return rec;
+}
+
+#define HIDP_VIRTUAL_CABLE_UNPLUG 0
+#define HIDP_BOOT_PROTOCOL_MODE 1
+#define HIDP_BLUETOOTH_VENDOR_ID 9
+
+struct uhid_connadd_req {
+/* int ctrl_sock; /* Connected control socket */
+/* int intr_sock; /* Connected interrupt socket */
+ uint16_t parser; /* Parser version */
+ uint16_t rd_size; /* Report descriptor size */
+ uint8_t *rd_data; /* Report descriptor data */
+ uint8_t country;
+ uint8_t subclass;
+ uint16_t vendor;
+ uint16_t product;
+/* uint16_t version;
+*/
+ uint32_t flags;
+/* uint32_t idle_to;
+*/
+ char name[128]; /* Device name */
+};
+
+static void epox_endian_quirk(unsigned char *data, int size)
+{
+ /* USAGE_PAGE (Keyboard) 05 07
+ * USAGE_MINIMUM (0) 19 00
+ * USAGE_MAXIMUM (65280) 2A 00 FF <= must be FF 00
+ * LOGICAL_MINIMUM (0) 15 00
+ * LOGICAL_MAXIMUM (65280) 26 00 FF <= must be FF 00
+ */
+ unsigned char pattern[] = { 0x05, 0x07, 0x19, 0x00, 0x2a, 0x00, 0xff,
+ 0x15, 0x00, 0x26, 0x00, 0xff };
+ unsigned int i;
+
+ if (!data)
+ return;
+
+ for (i = 0; i < size - sizeof(pattern); i++) {
+ if (!memcmp(data + i, pattern, sizeof(pattern))) {
+ data[i + 5] = 0xff;
+ data[i + 6] = 0x00;
+ data[i + 10] = 0xff;
+ data[i + 11] = 0x00;
+ }
+ }
+}
+
+static int create_hid_dev_name(sdp_record_t *rec, struct uhid_connadd_req *req)
+{
+ char sdesc[sizeof(req->name)];
+
+ if (sdp_get_service_desc(rec, sdesc, sizeof(sdesc)) == 0) {
+ char pname[sizeof(req->name)];
+
+ if (sdp_get_provider_name(rec, pname, sizeof(pname)) == 0 &&
+ strncmp(sdesc, pname, 5) != 0)
+ snprintf(req->name, sizeof(req->name), "%s %s", pname,
+ sdesc);
+ else
+ snprintf(req->name, sizeof(req->name), "%s", sdesc);
+ } else {
+ return sdp_get_service_name(rec, req->name, sizeof(req->name));
+ }
+
+ return 0;
+}
+
+/* See HID profile specification v1.0, "7.11.6 HIDDescriptorList" for details
+ * on the attribute format. */
+static int extract_hid_desc_data(sdp_record_t *rec,
+ struct uhid_connadd_req *req)
+{
+ sdp_data_t *d;
+
+ d = sdp_data_get(rec, SDP_ATTR_HID_DESCRIPTOR_LIST);
+ if (!d)
+ goto invalid_desc;
+
+ if (!SDP_IS_SEQ(d->dtd))
+ goto invalid_desc;
+
+ /* First HIDDescriptor */
+ d = d->val.dataseq;
+ if (!SDP_IS_SEQ(d->dtd))
+ goto invalid_desc;
+
+ /* ClassDescriptorType */
+ d = d->val.dataseq;
+ if (d->dtd != SDP_UINT8)
+ goto invalid_desc;
+
+ /* ClassDescriptorData */
+ d = d->next;
+ if (!d || !SDP_IS_TEXT_STR(d->dtd))
+ goto invalid_desc;
+
+ req->rd_data = g_try_malloc0(d->unitSize);
+ if (req->rd_data) {
+ memcpy(req->rd_data, d->val.str, d->unitSize);
+ req->rd_size = d->unitSize;
+ epox_endian_quirk(req->rd_data, req->rd_size);
+ }
+
+ return 0;
+
+invalid_desc:
+ error("Missing or invalid HIDDescriptorList SDP attribute");
+ return -EINVAL;
+}
+
+static int extract_hid_record(sdp_record_t *rec, struct uhid_connadd_req *req)
+{
+ sdp_data_t *pdlist;
+ uint8_t attr_val;
+ int err;
+
+ err = create_hid_dev_name(rec, req);
+ if (err < 0)
+ DBG("No valid Service Name or Service Description found");
+
+ pdlist = sdp_data_get(rec, SDP_ATTR_HID_PARSER_VERSION);
+ req->parser = pdlist ? pdlist->val.uint16 : 0x0100;
+
+ pdlist = sdp_data_get(rec, SDP_ATTR_HID_DEVICE_SUBCLASS);
+ req->subclass = pdlist ? pdlist->val.uint8 : 0;
+
+ pdlist = sdp_data_get(rec, SDP_ATTR_HID_COUNTRY_CODE);
+ req->country = pdlist ? pdlist->val.uint8 : 0;
+
+ pdlist = sdp_data_get(rec, SDP_ATTR_HID_VIRTUAL_CABLE);
+ attr_val = pdlist ? pdlist->val.uint8 : 0;
+ if (attr_val)
+ req->flags |= (1 << HIDP_VIRTUAL_CABLE_UNPLUG);
+
+ pdlist = sdp_data_get(rec, SDP_ATTR_HID_BOOT_DEVICE);
+ attr_val = pdlist ? pdlist->val.uint8 : 0;
+ if (attr_val)
+ req->flags |= (1 << HIDP_BOOT_PROTOCOL_MODE);
+
+ err = extract_hid_desc_data(rec, req);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+static int uhid_add_connection(struct input_device *idev)
+{
+ struct uhid_connadd_req *req;
+ sdp_record_t *rec;
+ char src_addr[18], dst_addr[18];
+ char filename[PATH_MAX + 1];
+ GKeyFile *key_file;
+ char handle[11], *str;
+ uint8_t value[REPORT_MAP_MAX_SIZE];
+ struct uhid_event ev;
+ int i;
+ int err;
+
+ /* TODO: */
+#if 1
+ req = g_new0(struct uhid_connadd_req, 1);
+
+ ba2str(&idev->src, src_addr);
+ ba2str(&idev->dst, dst_addr);
+
+ snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", src_addr,
+ dst_addr);
+ filename[PATH_MAX] = '\0';
+#if 0
+ sprintf(handle, "0x%8.8X", idev->handle);
+#else
+ sprintf(handle, "0x00010000");
+#endif
+
+ key_file = g_key_file_new();
+ g_key_file_load_from_file(key_file, filename, 0, NULL);
+ str = g_key_file_get_string(key_file, "ServiceRecords", handle, NULL);
+ g_key_file_free(key_file);
+
+ if (!str) {
+ error("Rejected connection from unknown device %s", dst_addr);
+#if 0
+ err = -EPERM;
+ goto cleanup;
+#else
+ return -1;
+#endif
+ }
+
+ rec = record_from_string(str);
+ g_free(str);
+
+ err = extract_hid_record(rec, req);
+ sdp_record_free(rec);
+ if (err < 0) {
+ error("Could not parse HID SDP record: %s (%d)", strerror(-err),
+ -err);
+#if 0
+ goto cleanup;
+#else
+ return -1;
+#endif
+ }
+#endif
+
+ DBG("Report MAP:");
+ for (i = 0; i < req->rd_size; i++) {
+#if 0
+ switch (value[i]) {
+ case 0x85:
+ case 0x86:
+ case 0x87:
+ hogdev->has_report_id = TRUE;
+ }
+#endif
+
+ if (i % 2 == 0) {
+ if (i + 1 == req->rd_size)
+ DBG("\t %02x", req->rd_data[i]);
+ else
+ DBG("\t %02x %02x", req->rd_data[i],
+ req->rd_data[i + 1]);
+ }
+ }
+
+#if 0
+ vendor_src = btd_device_get_vendor_src(idev->device);
+ vendor = btd_device_get_vendor(idev->device);
+ product = btd_device_get_product(idev->device);
+ version = btd_device_get_version(idev->device);
+/* DBG("DIS information: vendor_src=0x%X, vendor=0x%X, product=0x%X, "
+ "version=0x%X", vendor_src, vendor, product, version);
+*/
+#else
+ DBG("DIS information: vendor=0x%X, product=0x%X, version=0x%X",
+ req->vendor, req->product, req->parser);
+#endif
+
+ /* create uHID device */
+ memset(&ev, 0, sizeof(ev));
+ ev.type = UHID_CREATE;
+ strcpy((char *) ev.u.create.name, "bluez-hid-device");
+#if 0
+ ev.u.create.vendor = vendor;
+ ev.u.create.product = product;
+ ev.u.create.version = version;
+ ev.u.create.country = hogdev->bcountrycode;
+#else
+ ev.u.create.vendor = req->vendor;
+ ev.u.create.product = req->product;
+ ev.u.create.version = req->parser;
+ ev.u.create.country = req->country;
+#endif
+ ev.u.create.bus = BUS_BLUETOOTH;
+ ev.u.create.rd_data = req->rd_data;
+ ev.u.create.rd_size = req->rd_size;
+
+ if (write(idev->uhid_fd, &ev, sizeof(ev)) < 0)
+ error("Failed to create uHID device: %s", strerror(errno));
+
+ return 0;
+}
+
+static int is_connected(struct input_device *idev)
+{
+ /* TODO: */
+#if 0
+ struct hidp_conninfo ci;
+ int ctl;
+
+ /* Standard HID */
+ ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HIDP);
+ if (ctl < 0)
+ return 0;
+
+ memset(&ci, 0, sizeof(ci));
+ bacpy(&ci.bdaddr, &idev->dst);
+ if (ioctl(ctl, HIDPGETCONNINFO, &ci) < 0) {
+ close(ctl);
+ return 0;
+ }
+
+ close(ctl);
+
+ if (ci.state != BT_CONNECTED)
+ return 0;
+ else
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+static void disconnect_cb(struct bt_device *device, gboolean removal,
+ void *user_data)
+{
+ /* TODO: */
+#if 0
+ struct input_device *idev = user_data;
+ int flags;
+
+ info("Input: disconnect %s", idev->path);
+
+ flags = removal ? (1 << HIDP_VIRTUAL_CABLE_UNPLUG) : 0;
+
+ connection_disconnect(idev, flags);
+#endif
+}
+
+static int input_device_connected(struct input_device *idev)
+{
+ int err;
+
+ if (idev->intr_io == NULL || idev->ctrl_io == NULL)
+ return -ENOTCONN;
+
+ err = uhid_add_connection(idev);
+ if (err < 0)
+ return err;
+
+ idev->dc_id = bt_device_add_disconnect_watch(idev->device,
+ disconnect_cb,
+ idev, NULL);
+
+ /* TODO:
+ btd_service_connecting_complete(idev->service, 0);
+ */
+
+ return 0;
+}
+
+static void interrupt_connect_cb(GIOChannel *chan, GError *conn_err,
+ gpointer user_data)
+{
+ struct input_device *idev = user_data;
+ int err;
+
+ if (conn_err) {
+ err = -EIO;
+ goto failed;
+ }
+
+ err = input_device_connected(idev);
+ if (err < 0)
+ goto failed;
+
+ idev->intr_watch = g_io_add_watch(idev->intr_io,
+ G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+ intr_watch_cb, idev);
+
+ return;
+
+failed:
+ /* TODO:
+ btd_service_connecting_complete(idev->service, err);
+ */
+
+ /* 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;
+ GIOChannel *io;
+ GError *err = NULL;
+
+ if (conn_err) {
+ error("%s", conn_err->message);
+ goto failed;
+ }
+
+ /* Connect to the HID interrupt channel */
+ 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 (!io) {
+ error("%s", err->message);
+ g_error_free(err);
+ goto failed;
+ }
+
+ idev->intr_io = io;
+
+ 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:
+ /* TODO:
+ btd_service_connecting_complete(idev->service, -EIO);
+ */
+ g_io_channel_unref(idev->ctrl_io);
+ idev->ctrl_io = NULL;
+}
+
+static int dev_connect(struct input_device *idev)
+{
+ GError *err = NULL;
+ GIOChannel *io;
+
+ /* TODO: */
+#if 0
+ if (idev->disable_sdp)
+ bt_clear_cached_session(&idev->src, &idev->dst);
+#endif
+
+ 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);
+ idev->ctrl_io = io;
+
+ if (err == NULL)
+ return 0;
+
+ error("%s", err->message);
+ g_error_free(err);
+
+ return -EIO;
+}
+
+static gboolean input_device_auto_reconnect(gpointer user_data)
+{
+ struct input_device *idev = user_data;
+
+ /* TODO: */
+#if 0
+ DBG("path=%s, attempt=%d", idev->path, idev->reconnect_attempt);
+
+ /* Stop the recurrent reconnection attempts if the device is reconnected
+ * or is marked for removal. */
+ if (device_is_temporary(idev->device) ||
+ device_is_connected(idev->device))
+ return FALSE;
+#else
+ DBG("attempt=%d", idev->reconnect_attempt);
+#endif
+
+ /* Only attempt an auto-reconnect for at most 3 minutes (6 * 30s). */
+ if (idev->reconnect_attempt >= 6)
+ return FALSE;
+
+ /* Check if the profile is already connected. */
+ if (idev->ctrl_io)
+ return FALSE;
+
+ if (is_connected(idev))
+ return FALSE;
+
+ idev->reconnect_attempt++;
+ dev_connect(idev);
+
+ return TRUE;
+}
+
+static const char * const _reconnect_mode_str[] = {
+ "none",
+ "device",
+ "host",
+ "any"
+};
+
+static const char *reconnect_mode_to_string(const enum reconnect_mode_t mode)
+{
+ return _reconnect_mode_str[mode];
+}
+
+static void input_device_enter_reconnect_mode(struct input_device *idev)
+{
+#if 0
+ DBG("path=%s reconnect_mode=%s", idev->path,
+ reconnect_mode_to_string(idev->reconnect_mode));
+#else
+ DBG("reconnect_mode=%s",
+ reconnect_mode_to_string(idev->reconnect_mode));
+#endif
+
+ /* Only attempt an auto-reconnect when the device is required to accept
+ * reconnections from the host. */
+ if (idev->reconnect_mode != RECONNECT_ANY &&
+ idev->reconnect_mode != RECONNECT_HOST)
+ return;
+
+ /* TODO: */
+#if 0
+ /* If the device is temporary we are not required to reconnect with the
+ * device. This is likely the case of a removing device. */
+ if (device_is_temporary(idev->device) ||
+ device_is_connected(idev->device))
+ return;
+#endif
+
+ if (idev->reconnect_timer > 0)
+ g_source_remove(idev->reconnect_timer);
+
+ DBG("registering auto-reconnect");
+ idev->reconnect_attempt = 0;
+ idev->reconnect_timer = g_timeout_add_seconds(30,
+ input_device_auto_reconnect, idev);
+
+}
+
+int input_device_connect(bdaddr_t *bd_addr)
+{
+ struct input_device *idev;
+
+ DBG("");
+
+ idev = find_conn(conns, bd_addr);
+
+ if (idev->ctrl_io)
+ return -EBUSY;
+
+ if (is_connected(idev))
+ return -EALREADY;
+
+ return dev_connect(idev);
+}
+
+static void forward_report(struct input_device *idev,
+ struct uhid_event *ev)
+{
+ /* TODO: */
+#if 0
+ struct report *report;
+ GSList *l;
+ void *data;
+ int size;
+ guint type;
+
+ if (idev->has_report_id) {
+ data = ev->u.output.data + 1;
+ size = ev->u.output.size - 1;
+ } else {
+ data = ev->u.output.data;
+ size = ev->u.output.size;
+ }
+
+ switch (ev->type) {
+ case UHID_OUTPUT:
+ type = HOG_REPORT_TYPE_OUTPUT;
+ break;
+ case UHID_FEATURE:
+ type = HOG_REPORT_TYPE_FEATURE;
+ break;
+ default:
+ return;
+ }
+
+ l = g_slist_find_custom(hogdev->reports, GUINT_TO_POINTER(type),
+ report_type_cmp);
+ if (!l)
+ return;
+
+ report = l->data;
+
+ DBG("Sending report type %d to device 0x%04X handle 0x%X", type,
+ idev->id, report->decl->value_handle);
+
+ if (idev->attrib == NULL)
+ return;
+
+ if (report->decl->properties & ATT_CHAR_PROPER_WRITE)
+ gatt_write_char(idev->attrib, report->decl->value_handle,
+ data, size, output_written_cb, idev);
+ else if (report->decl->properties & ATT_CHAR_PROPER_WRITE_WITHOUT_RESP)
+ gatt_write_cmd(idev->attrib, report->decl->value_handle,
+ data, size, NULL, NULL);
+#endif
+}
+
+static gboolean uhid_event_cb(GIOChannel *io, GIOCondition cond,
+ gpointer user_data)
+{
+ struct input_device *idev = user_data;
+ struct uhid_event ev;
+ ssize_t bread;
+ int fd;
+
+ if (cond & (G_IO_ERR | G_IO_NVAL))
+ goto failed;
+
+ fd = g_io_channel_unix_get_fd(io);
+ memset(&ev, 0, sizeof(ev));
+
+ bread = read(fd, &ev, sizeof(ev));
+ if (bread < 0) {
+ int err = -errno;
+ DBG("uhid-dev read: %s(%d)", strerror(-err), -err);
+ goto failed;
+ }
+
+ DBG("uHID event type %d received", ev.type);
+
+ switch (ev.type) {
+ case UHID_START:
+ case UHID_STOP:
+ /* These are called to start and stop the underlying hardware.
+ * For HoG we open the channels before creating the device so
+ * the hardware is always ready. No need to handle these.
+ * Note that these are also called when the kernel switches
+ * between device-drivers loaded on the HID device. But we can
+ * simply keep the hardware alive during transitions and it
+ * works just fine.
+ * The kernel never destroys a device itself! Only an explicit
+ * UHID_DESTROY request can remove a device. */
+ break;
+ case UHID_OPEN:
+ case UHID_CLOSE:
+ /* OPEN/CLOSE are sent whenever user-space opens any interface
+ * provided by the kernel HID device. Whenever the open-count
+ * is non-zero we must be ready for I/O. As long as it is zero,
+ * we can decide to drop all I/O and put the device
+ * asleep This is optional, though. Moreover, some
+ * special device drivers are buggy in that regard, so
+ * maybe we just keep I/O always awake like HIDP in the
+ * kernel does. */
+ break;
+ case UHID_OUTPUT:
+ case UHID_FEATURE:
+ forward_report(idev, &ev);
+ break;
+ case UHID_OUTPUT_EV:
+ /* This is only sent by kernels prior to linux-3.11. It
+ * requires us to parse HID-descriptors in user-space to
+ * properly handle it. This is redundant as the kernel
+ * does it already. That's why newer kernels assemble
+ * the output-reports and send it to us via UHID_OUTPUT.
+ * We never implemented this, so we rely on users to use
+ * recent-enough kernels if they want this feature. No reason
+ * to implement this for older kernels. */
+ DBG("Unsupported uHID output event: type %d code %d value %d",
+ ev.u.output_ev.type, ev.u.output_ev.code,
+ ev.u.output_ev.value);
+ break;
+ default:
+ warn("unexpected uHID event");
+ break;
+ }
+
+ return TRUE;
+
+failed:
+ idev->uhid_watch_id = 0;
+ return FALSE;
+}
+
+static struct input_device *input_new_device(struct bt_device *device)
+{
+ struct input_device *idev;
+
+ idev = g_try_new0(struct input_device, 1);
+ if (!idev)
+ return NULL;
+
+ idev->device = bt_device_ref(device);
+
+ return idev;
+}
+
+static void input_free_device(struct input_device *idev)
+{
+ bt_device_unref(idev->device);
+/* g_slist_free_full(idev->reports, report_free);
+*/ g_free(idev);
+}
+
+struct input_device *input_register_device(struct bt_device *device)
+{
+ struct input_device *idev;
+ GIOCondition cond = G_IO_IN | G_IO_ERR | G_IO_NVAL;
+ GIOChannel *io;
+
+ idev = input_new_device(device);
+ if (!idev)
+ return NULL;
+
+ idev->uhid_fd = open(UHID_DEVICE_FILE, O_RDWR | O_CLOEXEC);
+ if (idev->uhid_fd < 0) {
+ error("Failed to open uHID device: %s(%d)", strerror(errno),
+ errno);
+ input_free_device(idev);
+ return NULL;
+ }
+
+ io = g_io_channel_unix_new(idev->uhid_fd);
+ g_io_channel_set_encoding(io, NULL, NULL);
+ idev->uhid_watch_id = g_io_add_watch(io, cond, uhid_event_cb, idev);
+ g_io_channel_unref(io);
+
+ return idev;
+}
+
+int input_unregister_device(struct input_device *idev)
+{
+ struct uhid_event ev;
+
+ if (idev->uhid_watch_id) {
+ g_source_remove(idev->uhid_watch_id);
+ idev->uhid_watch_id = 0;
+ }
+
+ memset(&ev, 0, sizeof(ev));
+ ev.type = UHID_DESTROY;
+ if (write(idev->uhid_fd, &ev, sizeof(ev)) < 0)
+ error("Failed to destroy uHID device: %s", strerror(errno));
+
+ close(idev->uhid_fd);
+ idev->uhid_fd = -1;
+
+ input_free_device(idev);
+
+ return 0;
+}
--
1.8.1.2
^ permalink raw reply related
* Re: [PATCH BlueZ] core: Fix crash while processing SDP records
From: Johan Hedberg @ 2013-10-22 10:38 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1382432600-6101-1-git-send-email-luiz.dentz@gmail.com>
Hi Luiz,
On Tue, Oct 22, 2013, Luiz Augusto von Dentz wrote:
> This was introduced by commit 073714c3ff70379131be3e19d9ccb8b85fe3f0d9
> which attempted to treat the return of sdp_process but caused the crash
> bellow because sdp_process actually calls search_completed_cb if it
> fails:
> Invalid read of size 8
> at 0x44FC93: search_process_cb (sdp-client.c:214)
> by 0x3D46047E05: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3600.3)
> by 0x3D46048157: ??? (in /usr/lib64/libglib-2.0.so.0.3600.3)
> by 0x3D46048559: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3600.3)
> by 0x40A2DF: main (main.c:587)
> Address 0x59febd0 is 16 bytes inside a block of size 72 free'd
> at 0x4A074C4: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
> by 0x3D4604D9AE: g_free (in /usr/lib64/libglib-2.0.so.0.3600.3)
> by 0x44FE44: search_completed_cb (sdp-client.c:192)
> by 0x4732E7: sdp_process (sdp.c:4341)
> by 0x44FCD8: search_process_cb (sdp-client.c:206)
> by 0x3D46047E05: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3600.3)
> by 0x3D46048157: ??? (in /usr/lib64/libglib-2.0.so.0.3600.3)
> by 0x3D46048559: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3600.3)
> by 0x40A2DF: main (main.c:587)
> ---
> src/sdp-client.c | 22 +++++++---------------
> 1 file changed, 7 insertions(+), 15 deletions(-)
Applied. Thanks.
Johan
^ permalink raw reply
* [PATCH] android: Fix compilation error for Android 4.2.2
From: Andrei Emeltchenko @ 2013-10-22 10:37 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1382436600-8598-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
On our current target the tools cannot be compiled.
---
android/Android.mk | 2 ++
android/client/if-bt.c | 6 ++++++
android/client/if-main.h | 3 +++
android/client/textconv.c | 2 ++
4 files changed, 13 insertions(+)
diff --git a/android/Android.mk b/android/Android.mk
index 679c12b..657ab3e 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -84,6 +84,8 @@ LOCAL_SRC_FILES := \
client/tabcompletion.c \
client/if-bt.c \
+LOCAL_CFLAGS := -DPLATFORM_SDK_VERSION=$(PLATFORM_SDK_VERSION)
+
LOCAL_SHARED_LIBRARIES := libhardware
LOCAL_MODULE_TAGS := optional
diff --git a/android/client/if-bt.c b/android/client/if-bt.c
index 30b41cd..330a3fa 100644
--- a/android/client/if-bt.c
+++ b/android/client/if-bt.c
@@ -364,11 +364,13 @@ static void dut_mode_recv_cb(uint16_t opcode, uint8_t *buf, uint8_t len)
haltest_info("%s\n", __func__);
}
+#if PLATFORM_SDK_VERSION > 17
static void le_test_mode_cb(bt_status_t status, uint16_t num_packets)
{
haltest_info("%s %s %d\n", __func__, bt_state_t2str(status),
num_packets);
}
+#endif
static bt_callbacks_t bt_callbacks = {
.size = sizeof(bt_callbacks),
@@ -383,7 +385,9 @@ static bt_callbacks_t bt_callbacks = {
.acl_state_changed_cb = acl_state_changed_cb,
.thread_evt_cb = thread_evt_cb,
.dut_mode_recv_cb = dut_mode_recv_cb,
+#if PLATFORM_SDK_VERSION > 17
.le_test_mode_cb = le_test_mode_cb
+#endif
};
static void init_p(int argc, const char **argv)
@@ -808,8 +812,10 @@ static void get_profile_interface_p(int argc, const char **argv)
pif = &dummy; /* TODO: change when if_hh is there */
else if (strcmp(BT_PROFILE_PAN_ID, id) == 0)
pif = &dummy; /* TODO: change when if_pan is there */
+#if PLATFORM_SDK_VERSION > 17
else if (strcmp(BT_PROFILE_AV_RC_ID, id) == 0)
pif = &dummy; /* TODO: change when if_rc is there */
+#endif
else
haltest_error("%s is not correct for get_profile_interface\n",
id);
diff --git a/android/client/if-main.h b/android/client/if-main.h
index 6d2b0cb..5f4a434 100644
--- a/android/client/if-main.h
+++ b/android/client/if-main.h
@@ -35,7 +35,10 @@
#include <hardware/bt_sock.h>
#include <hardware/bt_hf.h>
#include <hardware/bt_hl.h>
+
+#if PLATFORM_SDK_VERSION > 17
#include <hardware/bt_rc.h>
+#endif
#include "textconv.h"
diff --git a/android/client/textconv.c b/android/client/textconv.c
index 3493b1c..cdd443e 100644
--- a/android/client/textconv.c
+++ b/android/client/textconv.c
@@ -94,7 +94,9 @@ INTMAP(bt_property_type_t, -1, "(unknown)")
DELEMENT(BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT),
DELEMENT(BT_PROPERTY_REMOTE_FRIENDLY_NAME),
DELEMENT(BT_PROPERTY_REMOTE_RSSI),
+#if PLATFORM_SDK_VERSION > 17
DELEMENT(BT_PROPERTY_REMOTE_VERSION_INFO),
+#endif
DELEMENT(BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP),
ENDMAP
--
1.8.1.2
^ permalink raw reply related
* Re: [PATCH] android: Add hidhost defines and structures to header file
From: Johan Hedberg @ 2013-10-22 10:34 UTC (permalink / raw)
To: Ravi kumar Veeramally; +Cc: linux-bluetooth
In-Reply-To: <1382431088-14122-1-git-send-email-ravikumar.veeramally@linux.intel.com>
Hi Ravi,
On Tue, Oct 22, 2013, Ravi kumar Veeramally wrote:
> ---
> android/hal-msg.h | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 67 insertions(+)
Applied. Thanks.
Johan
^ permalink raw reply
* [PATCH] android: Fix compilation error for Android 4.2.2
From: Andrei Emeltchenko @ 2013-10-22 10:10 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
android/client/if-bt.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/android/client/if-bt.c b/android/client/if-bt.c
index 5447e0c..330a3fa 100644
--- a/android/client/if-bt.c
+++ b/android/client/if-bt.c
@@ -364,11 +364,13 @@ static void dut_mode_recv_cb(uint16_t opcode, uint8_t *buf, uint8_t len)
haltest_info("%s\n", __func__);
}
+#if PLATFORM_SDK_VERSION > 17
static void le_test_mode_cb(bt_status_t status, uint16_t num_packets)
{
haltest_info("%s %s %d\n", __func__, bt_state_t2str(status),
num_packets);
}
+#endif
static bt_callbacks_t bt_callbacks = {
.size = sizeof(bt_callbacks),
--
1.8.1.2
^ permalink raw reply related
* [PATCH_v2] android: Add hidhost defines and structures to header file
From: Ravi kumar Veeramally @ 2013-10-22 9:07 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
v2: Changed 2 byte arrays to uint16_t as per Luiz comments
---
android/hal-msg.h | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 67 insertions(+)
diff --git a/android/hal-msg.h b/android/hal-msg.h
index 6266903..9dcfbf6 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -179,6 +179,73 @@ struct hal_msg_cmd_bt_le_test_mode {
uint8_t data[0];
} __attribute__((packed));
+#define HAL_MSG_OP_BT_HID_CONNECT 0x01
+struct hal_msg_cmd_bt_hid_connect {
+ uint8_t bdaddr[6];
+} __attribute__((packed));
+
+#define HAL_MSG_OP_BT_HID_DISCONNECT 0x02
+struct hal_msg_cmd_bt_hid_disconnect {
+ uint8_t bdaddr[6];
+} __attribute__((packed));
+
+#define HAL_MSG_OP_BT_HID_VP 0x03
+struct hal_msg_cmd_bt_hid_vp {
+ uint8_t bdaddr[6];
+} __attribute__((packed));
+
+#define HAL_MSG_OP_BT_HID_SET_INFO 0x04
+struct hal_msg_cmd_bt_hid_set_info {
+ uint8_t bdaddr[6];
+ uint8_t attr;
+ uint8_t subclass;
+ uint8_t app_id;
+ uint16_t vendor;
+ uint16_t product;
+ uint16_t country;
+ uint16_t descr_len;
+ uint8_t descr[0];
+} __attribute__((packed));
+
+#define HAL_MSG_BT_HID_REPORT_PROTOCOL 0x00
+#define HAL_MSG_BT_HID_BOOT_PROTOCOL 0x01
+#define HAL_MSG_BT_HID_UNSUPPORTED_PROTOCOL 0xff
+
+#define HAL_MSG_OP_BT_HID_GET_PROTOCOL 0x05
+struct hal_msg_cmd_bt_hid_get_protocol {
+ uint8_t bdaddr[6];
+ uint8_t mode;
+} __attribute__((packed));
+
+#define HAL_MSG_OP_BT_HID_SET_PROTOCOL 0x06
+struct hal_msg_cmd_bt_hid_set_protocol {
+ uint8_t bdaddr[6];
+ uint8_t mode;
+} __attribute__((packed));
+
+#define HAL_MSG_BT_HID_INPUT_REPORT 0x01
+#define HAL_MSG_BT_HID_OUTPUT_REPORT 0x02
+#define HAL_MSG_BT_HID_FEATURE_REPORT 0x03
+
+#define HAL_MSG_OP_BT_HID_GET_REPORT 0x07
+struct hal_msg_cmd_bt_hid_get_report {
+ uint8_t bdaddr[6];
+ uint8_t type;
+ uint8_t id;
+ uint16_t buf;
+} __attribute__((packed));
+
+#define HAL_MSG_OP_BT_HID_SET_REPORT 0x08
+struct hal_msg_cmd_bt_hid_set_report {
+ uint8_t bdaddr[6];
+ uint8_t type;
+} __attribute__((packed));
+
+#define HAL_MSG_OP_BT_HID_SEND_DATA 0x09
+struct hal_msg_cmd_bt_hid_send_data {
+ uint8_t bdaddr[6];
+} __attribute__((packed));
+
/* Notifications and confirmations */
#define HAL_MSG_EV_BT_ERROR 0x80
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ] core: Fix crash while processing SDP records
From: Luiz Augusto von Dentz @ 2013-10-22 9:03 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This was introduced by commit 073714c3ff70379131be3e19d9ccb8b85fe3f0d9
which attempted to treat the return of sdp_process but caused the crash
bellow because sdp_process actually calls search_completed_cb if it
fails:
Invalid read of size 8
at 0x44FC93: search_process_cb (sdp-client.c:214)
by 0x3D46047E05: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x3D46048157: ??? (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x3D46048559: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x40A2DF: main (main.c:587)
Address 0x59febd0 is 16 bytes inside a block of size 72 free'd
at 0x4A074C4: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x3D4604D9AE: g_free (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x44FE44: search_completed_cb (sdp-client.c:192)
by 0x4732E7: sdp_process (sdp.c:4341)
by 0x44FCD8: search_process_cb (sdp-client.c:206)
by 0x3D46047E05: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x3D46048157: ??? (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x3D46048559: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x40A2DF: main (main.c:587)
---
src/sdp-client.c | 22 +++++++---------------
1 file changed, 7 insertions(+), 15 deletions(-)
diff --git a/src/sdp-client.c b/src/sdp-client.c
index 1221f5e..51f3048 100644
--- a/src/sdp-client.c
+++ b/src/sdp-client.c
@@ -196,31 +196,23 @@ static gboolean search_process_cb(GIOChannel *chan, GIOCondition cond,
gpointer user_data)
{
struct search_context *ctxt = user_data;
- int err;
if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
- err = -EIO;
- goto failed;
- }
-
- err = sdp_process(ctxt->session);
- if (err < 0)
- goto failed;
-
- return TRUE;
-
-failed:
- if (err) {
sdp_close(ctxt->session);
ctxt->session = NULL;
if (ctxt->cb)
- ctxt->cb(NULL, err, ctxt->user_data);
+ ctxt->cb(NULL, -EIO, ctxt->user_data);
search_context_cleanup(ctxt);
+ return FALSE;
}
- return FALSE;
+ /* If sdp_process fails it calls search_completed_cb */
+ if (sdp_process(ctxt->session) < 0)
+ return FALSE;
+
+ return TRUE;
}
static gboolean connect_watch(GIOChannel *chan, GIOCondition cond,
--
1.8.3.1
^ permalink raw reply related
* [PATCH] android: Add hidhost defines and structures to header file
From: Ravi kumar Veeramally @ 2013-10-22 8:38 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
---
android/hal-msg.h | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 67 insertions(+)
diff --git a/android/hal-msg.h b/android/hal-msg.h
index 6266903..8dadd64 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -179,6 +179,73 @@ struct hal_msg_cmd_bt_le_test_mode {
uint8_t data[0];
} __attribute__((packed));
+#define HAL_MSG_OP_BT_HID_CONNECT 0x01
+struct hal_msg_cmd_bt_hid_connect {
+ uint8_t bdaddr[6];
+} __attribute__((packed));
+
+#define HAL_MSG_OP_BT_HID_DISCONNECT 0x02
+struct hal_msg_cmd_bt_hid_disconnect {
+ uint8_t bdaddr[6];
+} __attribute__((packed));
+
+#define HAL_MSG_OP_BT_HID_VP 0x03
+struct hal_msg_cmd_bt_hid_vp {
+ uint8_t bdaddr[6];
+} __attribute__((packed));
+
+#define HAL_MSG_OP_BT_HID_SET_INFO 0x04
+struct hal_msg_cmd_bt_hid_set_info {
+ uint8_t bdaddr[6];
+ uint8_t attr;
+ uint8_t subclass;
+ uint8_t app_id;
+ uint8_t vendor[2];
+ uint8_t product[2];
+ uint8_t country[2];
+ uint8_t descr_len[2];
+ uint8_t descr[0];
+} __attribute__((packed));
+
+#define HAL_MSG_BT_HID_REPORT_PROTOCOL 0x00
+#define HAL_MSG_BT_HID_BOOT_PROTOCOL 0x01
+#define HAL_MSG_BT_HID_UNSUPPORTED_PROTOCOL 0xff
+
+#define HAL_MSG_OP_BT_HID_GET_PROTOCOL 0x05
+struct hal_msg_cmd_bt_hid_get_protocol {
+ uint8_t bdaddr[6];
+ uint8_t mode;
+} __attribute__((packed));
+
+#define HAL_MSG_OP_BT_HID_SET_PROTOCOL 0x06
+struct hal_msg_cmd_bt_hid_set_protocol {
+ uint8_t bdaddr[6];
+ uint8_t mode;
+} __attribute__((packed));
+
+#define HAL_MSG_BT_HID_INPUT_REPORT 0x01
+#define HAL_MSG_BT_HID_OUTPUT_REPORT 0x02
+#define HAL_MSG_BT_HID_FEATURE_REPORT 0x03
+
+#define HAL_MSG_OP_BT_HID_GET_REPORT 0x07
+struct hal_msg_cmd_bt_hid_get_report {
+ uint8_t bdaddr[6];
+ uint8_t type;
+ uint8_t id;
+ uint8_t buf[2];
+} __attribute__((packed));
+
+#define HAL_MSG_OP_BT_HID_SET_REPORT 0x08
+struct hal_msg_cmd_bt_hid_set_report {
+ uint8_t bdaddr[6];
+ uint8_t type;
+} __attribute__((packed));
+
+#define HAL_MSG_OP_BT_HID_SEND_DATA 0x09
+struct hal_msg_cmd_bt_hid_send_data {
+ uint8_t bdaddr[6];
+} __attribute__((packed));
+
/* Notifications and confirmations */
#define HAL_MSG_EV_BT_ERROR 0x80
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH 0/3] Add basic commands to haltest
From: Johan Hedberg @ 2013-10-22 7:59 UTC (permalink / raw)
To: Jerzy Kasenberg; +Cc: linux-bluetooth
In-Reply-To: <CAHCYCoyszrDFjxZA8yini=QY4A0zOP6msZPGG3WHs0C2mfjUHg@mail.gmail.com>
Hi Jerzy,
On Tue, Oct 22, 2013, Jerzy Kasenberg wrote:
> On 21 October 2013 18:18, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> > Hi Jerzy,
> >
> > On Mon, Oct 21, 2013, Jerzy Kasenberg wrote:
> >> - Adds handling of Ctrl-c Ctrl-d as requested
> >> - Prompted changed to includ space
> >> - Added commands: quit exit help
> >> - Added completion for help
> >> - Terminal settings restored on exit
> >>
> >> Jerzy Kasenberg (3):
> >> android: Add space in prompt in haltest
> >> android: Add handling of Ctrl-c to haltest
> >> android: Add help and quit to haltest
> >>
> >> android/client/haltest.c | 151 ++++++++++++++++++++++++++++++++++------
> >> android/client/if-main.h | 6 ++
> >> android/client/tabcompletion.c | 151 ++++++++++++++++++++++++++++------------
> >> android/client/terminal.c | 100 ++++++++++++++++++--------
> >> 4 files changed, 312 insertions(+), 96 deletions(-)
> >
> > Patches 1 and 3 have been applied. It seems we had a bit of a
> > misunderstanding about 2 though. I was looking for ctrl-d (i.e. EOF)
> > support. Sorry for not being more precise here. Right now when I try
> > it the following just happens:
> >
> > jh@x220:bluez{master}$ android/haltest
> >> char-0x04
>
> Patch 2 handles Ctrl-c and Ctrl-d.
> When I tried on two terminals in bash Ctrl-d act like delete if line
> is not empty.
Seems you're right. Anyway, this was part of the same request as adding
basic "exit" or "quit" commands. When a user ends up in an unknown shell
and wants to get out from it those are usually the first things tried
(including ctrl-d).
> You or Szymon asked me to add Ctrl-c to clear current line like in
> other tools.
It wasn't me since ctrl-c was already getting me out from the tool.
> So maybe it wold be better to put Ctrl-d in patch title instead of
> Ctrl-c
Ctrl-d should be generating an EOF indicator just like feeding a file to
the program through stdin does. So in this sense "ctrl-d" isn't really
the best description as there are more ways of accomplishing the same.
> This is what patch 2 handles by setting atexit() cleanup function
> that restore terminal settings.
Sounds like this should have been split into a separate patch then.
Johan
^ permalink raw reply
* Re: [PATCH 0/3] Add basic commands to haltest
From: Jerzy Kasenberg @ 2013-10-22 7:42 UTC (permalink / raw)
To: Jerzy Kasenberg, linux-bluetooth
In-Reply-To: <20131021161859.GA9153@x220.p-661hnu-f1>
Hi Johan,
On 21 October 2013 18:18, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Hi Jerzy,
>
> On Mon, Oct 21, 2013, Jerzy Kasenberg wrote:
>> - Adds handling of Ctrl-c Ctrl-d as requested
>> - Prompted changed to includ space
>> - Added commands: quit exit help
>> - Added completion for help
>> - Terminal settings restored on exit
>>
>> Jerzy Kasenberg (3):
>> android: Add space in prompt in haltest
>> android: Add handling of Ctrl-c to haltest
>> android: Add help and quit to haltest
>>
>> android/client/haltest.c | 151 ++++++++++++++++++++++++++++++++++------
>> android/client/if-main.h | 6 ++
>> android/client/tabcompletion.c | 151 ++++++++++++++++++++++++++++------------
>> android/client/terminal.c | 100 ++++++++++++++++++--------
>> 4 files changed, 312 insertions(+), 96 deletions(-)
>
> Patches 1 and 3 have been applied. It seems we had a bit of a
> misunderstanding about 2 though. I was looking for ctrl-d (i.e. EOF)
> support. Sorry for not being more precise here. Right now when I try
> it the following just happens:
>
> jh@x220:bluez{master}$ android/haltest
>> char-0x04
Patch 2 handles Ctrl-c and Ctrl-d.
When I tried on two terminals in bash Ctrl-d act like delete if line
is not empty.
(this is emax style). When line is empty it terminates.
You or Szymon asked me to add Ctrl-c to clear current line like in other tools.
So maybe it wold be better to put Ctrl-d in patch title instead of Ctrl-c
>
> I wouldn't have expected this to be an issue if stdin is processed
> properly, but it seems even something like the following doesn't result
> in the expected behavior right now (to run all commands in the file and
> then exit the tool):
>
> $ tools/haltest < my-script.txt
This I haven't tried yet so this will probably not work.
But I can handle it some other way not related to Ctrl-d (later :)).
>
> Another thing I'd like to see fixed is getting the terminal back to a
> sane state when exiting. Right now even after a clean exit I seem to
> have to do a hard terminal reset to get normal behavior back. As an
> example, the following is what I get after cleanly exiting using "exit"
> and then pressing enter a couple of times:
>
> jh@x220:bluez{master}$ android/haltest
>> exit
This is what patch 2 handles by setting atexit() cleanup function that restore
terminal settings. Before there was exit command, ctrl-c did it automatically.
> jh@x220:bluez{master}$ jh@x220:bluez{master}$ jh@x220:bluez{master}$
>
> Johan
--
Jerzy Kasenberg
^ permalink raw reply
* Re: [PATCH] android: Improve hal_ipc_cmd helper
From: Johan Hedberg @ 2013-10-22 7:34 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1382426248-10793-1-git-send-email-szymon.janc@tieto.com>
Hi Szymon,
On Tue, Oct 22, 2013, Szymon Janc wrote:
> Handle error response inside helper so that users don't expecting any
> response don't need to provide dummy buffer only for error (which is
> already return value of helper).
> ---
> android/hal-bluetooth.c | 7 ++-----
> android/hal-ipc.c | 6 ++++++
> 2 files changed, 8 insertions(+), 5 deletions(-)
Applied. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH] Bluetooth: Add function name to debug prints
From: Johan Hedberg @ 2013-10-22 7:29 UTC (permalink / raw)
To: Jukka Rissanen; +Cc: linux-bluetooth
In-Reply-To: <1382425751-9018-1-git-send-email-jukka.rissanen@linux.intel.com>
Hi Jukka,
On Tue, Oct 22, 2013, Jukka Rissanen wrote:
> the debug prints are quite useless without the function name.
> Without this patch one sees lot of "hci0" lines which is not
> very helpful.
>
> Cheers,
> Jukka
>
> include/net/bluetooth/bluetooth.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
> index bf2ddff..0b1eacd 100644
> --- a/include/net/bluetooth/bluetooth.h
> +++ b/include/net/bluetooth/bluetooth.h
> @@ -122,7 +122,7 @@ int bt_err(const char *fmt, ...);
>
> #define BT_INFO(fmt, ...) bt_info(fmt "\n", ##__VA_ARGS__)
> #define BT_ERR(fmt, ...) bt_err(fmt "\n", ##__VA_ARGS__)
> -#define BT_DBG(fmt, ...) pr_debug(fmt "\n", ##__VA_ARGS__)
> +#define BT_DBG(fmt, ...) pr_debug("%s():" fmt "\n", __FUNCTION__, ##__VA_ARGS__)
This shouldn't be necessary since you can ask the function name to be
printed using standard dynamic debug control syntax, e.g:
echo "file hci_event.c +pf" > /sys/kernel/debug/dynamic_debug/control
Johan
^ permalink raw reply
* [PATCH] android: Improve hal_ipc_cmd helper
From: Szymon Janc @ 2013-10-22 7:17 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
Handle error response inside helper so that users don't expecting any
response don't need to provide dummy buffer only for error (which is
already return value of helper).
---
android/hal-bluetooth.c | 7 ++-----
android/hal-ipc.c | 6 ++++++
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index f408a7d..5b07070 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -40,7 +40,6 @@ static bool interface_ready(void)
static int init(bt_callbacks_t *callbacks)
{
struct hal_msg_cmd_register_module cmd;
- struct hal_msg_rsp_error rsp;
DBG("");
@@ -55,8 +54,7 @@ static int init(bt_callbacks_t *callbacks)
cmd.service_id = HAL_SERVICE_ID_BLUETOOTH;
if (hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_MSG_OP_REGISTER_MODULE,
- sizeof(cmd), &cmd,
- sizeof(rsp), &rsp, NULL) < 0) {
+ sizeof(cmd), &cmd, 0, NULL, NULL) < 0) {
error("Failed to register 'bluetooth' service");
goto fail;
}
@@ -64,8 +62,7 @@ static int init(bt_callbacks_t *callbacks)
cmd.service_id = HAL_SERVICE_ID_SOCK;
if (hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_MSG_OP_REGISTER_MODULE,
- sizeof(cmd), &cmd,
- sizeof(rsp), &rsp, NULL) < 0) {
+ sizeof(cmd), &cmd, 0, NULL, NULL) < 0) {
error("Failed to register 'socket' service");
goto fail;
}
diff --git a/android/hal-ipc.c b/android/hal-ipc.c
index 5b77adf..8d40271 100644
--- a/android/hal-ipc.c
+++ b/android/hal-ipc.c
@@ -146,10 +146,16 @@ int hal_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len, void *param,
struct iovec iv[2];
struct hal_msg_hdr hal_msg;
char cmsgbuf[CMSG_SPACE(sizeof(int))];
+ struct hal_msg_rsp_error err;
if (cmd_sk < 0)
return -EBADF;
+ if (!rsp || rsp_len == 0) {
+ memset(&err, 0, sizeof(err));
+ rsp = &err;
+ }
+
memset(&msg, 0, sizeof(msg));
memset(&hal_msg, 0, sizeof(hal_msg));
--
1.8.4
^ permalink raw reply related
* [PATCH] Bluetooth: Add function name to debug prints
From: Jukka Rissanen @ 2013-10-22 7:09 UTC (permalink / raw)
To: linux-bluetooth
---
Hi,
the debug prints are quite useless without the function name.
Without this patch one sees lot of "hci0" lines which is not
very helpful.
Cheers,
Jukka
include/net/bluetooth/bluetooth.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index bf2ddff..0b1eacd 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -122,7 +122,7 @@ int bt_err(const char *fmt, ...);
#define BT_INFO(fmt, ...) bt_info(fmt "\n", ##__VA_ARGS__)
#define BT_ERR(fmt, ...) bt_err(fmt "\n", ##__VA_ARGS__)
-#define BT_DBG(fmt, ...) pr_debug(fmt "\n", ##__VA_ARGS__)
+#define BT_DBG(fmt, ...) pr_debug("%s():" fmt "\n", __FUNCTION__, ##__VA_ARGS__)
/* Connection and socket states */
enum {
--
1.7.11.7
^ permalink raw reply related
* Re: [PATCH] android: Add missing HAL IPC error status definitions
From: Johan Hedberg @ 2013-10-22 7:03 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1382424852-8049-1-git-send-email-szymon.janc@tieto.com>
Hi Szymon,
On Tue, Oct 22, 2013, Szymon Janc wrote:
> ---
> android/hal-msg.h | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/android/hal-msg.h b/android/hal-msg.h
> index 1f77586..7d91ed1 100644
> --- a/android/hal-msg.h
> +++ b/android/hal-msg.h
> @@ -47,6 +47,15 @@ struct hal_msg_hdr {
> /* Core Service */
>
> #define HAL_ERROR_FAILED 0x01
> +#define HAL_ERROR_NOT_READY 0x02
> +#define HAL_ERROR_NOMEM 0x03
> +#define HAL_ERROR_BUSY 0x04
> +#define HAL_ERROR_DONE 0x05
> +#define HAL_ERROR_UNSUPPORTED 0x06
> +#define HAL_ERROR_INVALID 0x07
> +#define HAL_ERROR_UNHANDLED 0x08
> +#define HAL_ERROR_AUTH_FAILURE 0x09
> +#define HAL_ERROR_REMOTE_DEVICE_DOWN 0x0A
Applied after a minor s/0A/0a/ change to make this consistent with the
rest of the header file.
Johan
^ permalink raw reply
* [PATCH] android: Add missing HAL IPC error status definitions
From: Szymon Janc @ 2013-10-22 6:54 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
---
android/hal-msg.h | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/android/hal-msg.h b/android/hal-msg.h
index 1f77586..7d91ed1 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -47,6 +47,15 @@ struct hal_msg_hdr {
/* Core Service */
#define HAL_ERROR_FAILED 0x01
+#define HAL_ERROR_NOT_READY 0x02
+#define HAL_ERROR_NOMEM 0x03
+#define HAL_ERROR_BUSY 0x04
+#define HAL_ERROR_DONE 0x05
+#define HAL_ERROR_UNSUPPORTED 0x06
+#define HAL_ERROR_INVALID 0x07
+#define HAL_ERROR_UNHANDLED 0x08
+#define HAL_ERROR_AUTH_FAILURE 0x09
+#define HAL_ERROR_REMOTE_DEVICE_DOWN 0x0A
#define HAL_MSG_OP_ERROR 0x00
struct hal_msg_rsp_error {
--
1.8.4
^ permalink raw reply related
* [PATCH] android: Add capabilities and set userid
From: Andrei Emeltchenko @ 2013-10-22 6:35 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
The patch set UID as standard Bluetooth user for Android (AID_BLUETOOTH).
It also sets the same capability needed for systemd service (found
in src/bluetooth.service.
---
android/main.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
configure.ac | 4 ++++
2 files changed, 57 insertions(+)
diff --git a/android/main.c b/android/main.c
index fac1003..e7f842e 100644
--- a/android/main.c
+++ b/android/main.c
@@ -33,10 +33,17 @@
#include <stdbool.h>
#include <string.h>
#include <errno.h>
+#include <unistd.h>
+
#include <sys/signalfd.h>
#include <sys/socket.h>
#include <sys/un.h>
+#if defined(ANDROID)
+#include <sys/prctl.h>
+#include <private/android_filesystem_config.h>
+#endif
+
#include <glib.h>
#include "log.h"
@@ -409,6 +416,49 @@ static void cleanup_hal_connection(void)
}
}
+static bool set_capabilities(void)
+{
+#if defined(ANDROID)
+ struct __user_cap_header_struct header;
+ struct __user_cap_data_struct cap;
+
+ DBG("pid %d uid %d gid %d", getpid(), getuid(), getgid());
+
+ header.version = _LINUX_CAPABILITY_VERSION;
+
+ prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
+
+ if (setgid(AID_BLUETOOTH) < 0)
+ warn("%s: setgid(): %s", __func__, strerror(errno));
+
+ if (setuid(AID_BLUETOOTH) < 0)
+ warn("%s: setuid(): %s", __func__, strerror(errno));
+
+ header.version = _LINUX_CAPABILITY_VERSION;
+ header.pid = 0;
+
+ cap.effective = cap.permitted =
+ CAP_TO_MASK(CAP_NET_RAW) |
+ CAP_TO_MASK(CAP_NET_ADMIN) |
+ CAP_TO_MASK(CAP_NET_BIND_SERVICE);
+ cap.inheritable = 0;
+
+ if (capset(&header, &cap) < 0) {
+ error("%s: capset(): %s", __func__, strerror(errno));
+ return false;
+ }
+
+ if (capget(&header, &cap) < 0)
+ error("%s: capget(): %s", __func__, strerror(errno));
+ else
+ DBG("Caps: eff: 0x%x, perm: 0x%x, inh: 0x%x", cap.effective,
+ cap.permitted, cap.inheritable);
+
+ DBG("pid %d uid %d gid %d", getpid(), getuid(), getgid());
+#endif
+ return true;
+}
+
int main(int argc, char *argv[])
{
GOptionContext *context;
@@ -442,6 +492,9 @@ int main(int argc, char *argv[])
__btd_log_init("*", 0);
+ if (!set_capabilities())
+ return EXIT_FAILURE;
+
if (!init_mgmt_interface())
return EXIT_FAILURE;
diff --git a/configure.ac b/configure.ac
index b4d3998..e3b5220 100644
--- a/configure.ac
+++ b/configure.ac
@@ -247,4 +247,8 @@ AC_ARG_ENABLE(android, AC_HELP_STRING([--enable-android],
[enable_android=${enableval}])
AM_CONDITIONAL(ANDROID, test "${enable_android}" = "yes")
+if (test "${enable_android}" = "yes"); then
+ AC_CHECK_LIB(cap, capget, dummy=yes, AC_MSG_ERROR(libcap is required))
+fi
+
AC_OUTPUT(Makefile src/bluetoothd.8 lib/bluez.pc)
--
1.8.1.2
^ permalink raw reply related
* [PATCH] android: Add capabilities and set userid
From: Andrei Emeltchenko @ 2013-10-22 6:28 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
The patch set UID as standard Bluetooth user for Android (AID_BLUETOOTH).
It also sets the same capability needed for systemd service (found
in src/bluetooth.service.
---
android/main.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
configure.ac | 4 ++++
2 files changed, 57 insertions(+)
diff --git a/android/main.c b/android/main.c
index fac1003..e7f842e 100644
--- a/android/main.c
+++ b/android/main.c
@@ -33,10 +33,17 @@
#include <stdbool.h>
#include <string.h>
#include <errno.h>
+#include <unistd.h>
+
#include <sys/signalfd.h>
#include <sys/socket.h>
#include <sys/un.h>
+#if defined(ANDROID)
+#include <sys/prctl.h>
+#include <private/android_filesystem_config.h>
+#endif
+
#include <glib.h>
#include "log.h"
@@ -409,6 +416,49 @@ static void cleanup_hal_connection(void)
}
}
+static bool set_capabilities(void)
+{
+#if defined(ANDROID)
+ struct __user_cap_header_struct header;
+ struct __user_cap_data_struct cap;
+
+ DBG("pid %d uid %d gid %d", getpid(), getuid(), getgid());
+
+ header.version = _LINUX_CAPABILITY_VERSION;
+
+ prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
+
+ if (setgid(AID_BLUETOOTH) < 0)
+ warn("%s: setgid(): %s", __func__, strerror(errno));
+
+ if (setuid(AID_BLUETOOTH) < 0)
+ warn("%s: setuid(): %s", __func__, strerror(errno));
+
+ header.version = _LINUX_CAPABILITY_VERSION;
+ header.pid = 0;
+
+ cap.effective = cap.permitted =
+ CAP_TO_MASK(CAP_NET_RAW) |
+ CAP_TO_MASK(CAP_NET_ADMIN) |
+ CAP_TO_MASK(CAP_NET_BIND_SERVICE);
+ cap.inheritable = 0;
+
+ if (capset(&header, &cap) < 0) {
+ error("%s: capset(): %s", __func__, strerror(errno));
+ return false;
+ }
+
+ if (capget(&header, &cap) < 0)
+ error("%s: capget(): %s", __func__, strerror(errno));
+ else
+ DBG("Caps: eff: 0x%x, perm: 0x%x, inh: 0x%x", cap.effective,
+ cap.permitted, cap.inheritable);
+
+ DBG("pid %d uid %d gid %d", getpid(), getuid(), getgid());
+#endif
+ return true;
+}
+
int main(int argc, char *argv[])
{
GOptionContext *context;
@@ -442,6 +492,9 @@ int main(int argc, char *argv[])
__btd_log_init("*", 0);
+ if (!set_capabilities())
+ return EXIT_FAILURE;
+
if (!init_mgmt_interface())
return EXIT_FAILURE;
diff --git a/configure.ac b/configure.ac
index b4d3998..e3b5220 100644
--- a/configure.ac
+++ b/configure.ac
@@ -247,4 +247,8 @@ AC_ARG_ENABLE(android, AC_HELP_STRING([--enable-android],
[enable_android=${enableval}])
AM_CONDITIONAL(ANDROID, test "${enable_android}" = "yes")
+if (test "${enable_android}" = "yes"); then
+ AC_CHECK_LIB(cap, capget, dummy=yes, AC_MSG_ERROR(libcap is required))
+fi
+
AC_OUTPUT(Makefile src/bluetoothd.8 lib/bluez.pc)
--
1.8.1.2
^ permalink raw reply related
* Re: GATT - How to mark an attribute as requiring encryption
From: Anderson Lizardo @ 2013-10-22 1:31 UTC (permalink / raw)
To: Scott James Remnant; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <CAHZ1yC=vh0PUS7ZgZ_zUff_gPzLwjYx8EABxbT71uU5zQAChTQ@mail.gmail.com>
Hi Scott,
On Mon, Oct 21, 2013 at 9:01 PM, Scott James Remnant <keybuk@google.com> wrote:
> While there is a way to mark an attribute as needing authentication
> and/or authorization, there does not seem to be a way to mark an
> attribute as requiring encryption (or a particular key size), and I
> couldn't find any code that would return the ATT_ECODE_INSUFF_ENC or
> ATT_ECODE_INSUFF_ENCR_KEY_SIZE responses.
There is a FIXME for this on function att_check_reqs()
(src/attrib-server.c). Feel free to fix it :)
Note that, as part of the ongoing implementation of a D-Bus API for
implementing external GATT services, we have patches (currently being
cleaned up for upstream submission) that will refactor the internal C
API for creating GATT services. If you are interested, take a look at
(note that it is work-in-progress code):
git://git.infradead.org/users/cktakahasi/bluez.git (branch gatt-api-devel)
Also take a look at the API document sent by Claudio a few days ago:
"[RFC BlueZ v0] doc: Add GATT API"
Best Regards,
--
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil
^ permalink raw reply
* GATT - How to mark an attribute as requiring encryption
From: Scott James Remnant @ 2013-10-22 1:01 UTC (permalink / raw)
To: linux-bluetooth@vger.kernel.org
While there is a way to mark an attribute as needing authentication
and/or authorization, there does not seem to be a way to mark an
attribute as requiring encryption (or a particular key size), and I
couldn't find any code that would return the ATT_ECODE_INSUFF_ENC or
ATT_ECODE_INSUFF_ENCR_KEY_SIZE responses.
There is an explicit test case in the GATT TS for this:
TP/GAR/SR/BI-05-C [Read Characteristic Value - Insufficient
Encryption Key Size]
The TRCL maps this:
(GATT:3/8 AND ATT:5/2)
OR
(ATT:3/1 AND ATT:3/10 AND ATT:5/2)
GATT:3/8 [Read Characteristic Value] is Mandatory
ATT:5/2 - [LE Security Mode 1] is Optional, but without it none of the
authentication or authorization stuff makes sense either
Reference:
GATT 4.8.1
ATT 3.4.11, 3.4.4.3
Thoughts?
Scott
--
Scott James Remnant | Chrome OS Systems | keybuk@google.com | Google
^ permalink raw reply
* pull request: bluetooth-next 2013-10-21
From: Gustavo Padovan @ 2013-10-21 22:37 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, linux-bluetooth, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 8588 bytes --]
Hi John,
One more big pull request for 3.13. These are the patches we queued during
last week. Here you will find a lot of improvements to the HCI and L2CAP and
MGMT layers with the main ones being a better debugfs support and end of work
of splitting L2CAP into Core and Socket parts.
Please pull!
Gustavo
---
The following changes since commit 4b836f393bd8ed111857a6ee1865e44627266ec6:
Bluetooth: Read current IAC LAP on controller setup (2013-10-14 19:31:18 -0300)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next for-upstream
for you to fetch changes up to d78a32a8fcf775111ccc9ba611a08ca5c29784b6:
Bluetooth: Remove sk member from struct l2cap_chan (2013-10-21 13:50:56 -0700)
----------------------------------------------------------------
Gustavo Padovan (14):
Bluetooth: Extend state_change() call to report errors too
Bluetooth: Add l2cap_state_change_and_error()
Bluetooth: Access sk_sndtimeo indirectly in l2cap_core.c
Bluetooth: Add chan->ops->set_shutdown()
Bluetooth: Move l2cap_wait_ack() to l2cap_sock.c
Bluetooth: use l2cap_chan_ready() instead of duplicate code
Bluetooth: Remove not used struct sock
Bluetooth: Do not access chan->sk directly
Bluetooth: Hold socket in defer callback in L2CAP socket
Bluetooth: Remove socket lock from l2cap_state_change()
Bluetooth: Remove parent socket usage from l2cap_core.c
Bluetooth: Add L2CAP channel to skb private data
Bluetooth: Use bt_cb(skb)->chan to send raw data back
Bluetooth: Remove sk member from struct l2cap_chan
Johan Hedberg (20):
Bluetooth: Fix L2CAP "Command Reject: Invalid CID" response
Bluetooth: Remove unused command reject mapping for EMSGSIZE
Bluetooth: Remove useless l2cap_err_to_reason function
Bluetooth: Ignore A2MP data on non-BR/EDR links
Bluetooth: Ignore SMP data on non-LE links
Bluetooth: Fix updating the right variable in update_scan_rsp_data()
Bluetooth: Reintroduce socket restrictions for LE sockets
Bluetooth: Convert auto accept timer to use delayed work
Bluetooth: Convert idle timer to use delayed work
Bluetooth: Fix ATT socket backwards compatibility with user space
Bluetooth: Check for flag instead of features in update_scan_rsp_data()
Bluetooth: Check for flag instead of features in update_adv_data()
Bluetooth: Add missing check for BREDR_ENABLED flag in update_class()
Bluetooth: Refactor set_connectable settings update to separate function
Bluetooth: Fix updating settings when there are no HCI commands to send
Bluetooth: Move mgmt_pending_find to avoid forward declarations
Bluetooth: Fix sending write_scan_enable when BR/EDR is disabled
Bluetooth: Move HCI_LIMITED_DISCOVERABLE changes to a general place
Bluetooth: Update Set Discoverable to support LE
Bluetooth: Fix enabling fast connectable on LE-only controllers
Marcel Holtmann (71):
Bluetooth: Fix minor coding style issue in set_connectable()
Bluetooth: Use hci_request for discoverable timeout handling
Bluetooth: Update advertising data based on management commands
Bluetooth: Introduce flag for limited discoverable mode
Bluetooth: Make mgmt_discoverable() return void
Bluetooth: Make mgmt_connectable() return void
Bluetooth: Make mgmt_write_scan_failed() return void
Bluetooth: Update class of device after changing discoverable mode
Bluetooth: Move arming of discoverable timeout to complete handler
Bluetooth: Simplify the code for re-arming discoverable timeout
Bluetooth: Add HCI command structure for writing current IAC LAP
Bluetooth: Add support for entering limited discoverable mode
Bluetooth: Make mgmt_new_link_key() return void
Bluetooth: Move eir_append_data() function into mgmt.c
Bluetooth: Move eir_get_length() function into hci_event.c
Bluetooth: Update class of device on discoverable timeout
Bluetooth: Add l2cap_chan_no_resume stub for A2MP
Bluetooth: Make mgmt_pin_code_request() return void
Bluetooth: Make mgmt_pin_code_reply_complete() return void
Bluetooth: Make mgmt_pin_code_neg_reply_complete() return void
Bluetooth: Make mgmt_auth_failed() return void
Bluetooth: Make mgmt_auth_enable_complete() return void
Bluetooth: Make mgmt_ssp_enable_complete() return void
Bluetooth: Make mgmt_set_class_of_dev_complete() return void
Bluetooth: Make mgmt_set_local_name_complete() return void
Bluetooth: Make mgmt_read_local_oob_data_reply_complete() return void
Bluetooth: Make mgmt_new_ltk() return void
Bluetooth: Rename create_ad into create_adv_data
Bluetooth: Store scan response data in HCI device
Bluetooth: Set the scan response data when needed
Bluetooth: Store device name in scan response data
Bluetooth: Rename update_ad into update_adv_data
Bluetooth: Remove duplicate definitions for advertising event types
Bluetooth: Remove enable_hs declaration
Bluetooth: Socket address parameter for CID is in little endian
Bluetooth: Expose inquiry_cache debugfs only on BR/EDR controllers
Bluetooth: Expose auto_accept_delay debugfs only when SSP is supported
Bluetooth: Expose static address value for LE capable controllers
Bluetooth: Expose current voice setting in debugfs
Bluetooth: Add address type to device blacklist table
Bluetooth: Move blacklist debugfs entry creation into hci_core.c
Bluetooth: Move uuids debugfs entry creation into hci_core.c
Bluetooth: Use IS_ERR_OR_NULL for checking bt_debugfs
Bluetooth: Create HCI device debugfs directory in hci_register_dev
Bluetooth: Create root debugfs directory during module init
Bluetooth: Move device_add handling into hci_register_dev
Bluetooth: Include address type in blacklist debugfs data
Bluetooth: Move idle_timeout and sniff_{min,max}_interval to hci_core.c
Bluetooth: Use BDADDR_BREDR type for old blacklist ioctl interface
Bluetooth: Use hcon directly instead of conn->hcon where possible
Bluetooth: Block ATT connection on LE when device is blocked
Bluetooth: Move HCI device features into hci_core.c
Bluetooth: Add workaround for buggy max_page features page value
Bluetooth: Remove debug entry for connection features
Bluetooth: Move manufacturer, hci_ver and hci_rev into hci_core.c
Bluetooth: Store local version information only during setup phase
Bluetooth: Move export of class of device information into hci_core.c
Bluetooth: Expose current list of link keys via debugfs
Bluetooth: Remove bus attribute in favor of hierarchy
Bluetooth: Expose white list size information in debugfs
Bluetooth: Expose current list of long term keys via debugfs
Bluetooth: Select the own address type during initial setup phase
Bluetooth: Expose debugfs entry read/write own address type
Bluetooth: Expose setting if debug keys are used or not
Bluetooth: Add LE features to debugfs if available
Bluetooth: Remove interval parameter from HCI connection
Bluetooth: Add support for setting SSP debug mode
Bluetooth: Expose debugfs settings for LE connection interval
Bluetooth: Add support for setting DUT mode
Bluetooth: Fix UUID values in debugfs file
Bluetooth: Fix minor coding style issue in hci_core.c
include/net/bluetooth/bluetooth.h | 1 +
include/net/bluetooth/hci.h | 35 ++-
include/net/bluetooth/hci_core.h | 89 +++----
include/net/bluetooth/l2cap.h | 20 +-
net/bluetooth/a2mp.c | 9 +-
net/bluetooth/af_bluetooth.c | 9 +-
net/bluetooth/hci_conn.c | 48 ++--
net/bluetooth/hci_core.c | 803 +++++++++++++++++++++++++++++++++++++++++++++++++--------
net/bluetooth/hci_event.c | 59 +++--
net/bluetooth/hci_sock.c | 4 +-
net/bluetooth/hci_sysfs.c | 373 ---------------------------
net/bluetooth/l2cap_core.c | 227 ++++++----------
net/bluetooth/l2cap_sock.c | 120 ++++++++-
net/bluetooth/mgmt.c | 637 ++++++++++++++++++++++++++++++++-------------
net/bluetooth/rfcomm/core.c | 14 +-
net/bluetooth/rfcomm/sock.c | 14 +-
net/bluetooth/sco.c | 13 +-
net/bluetooth/smp.c | 4 +-
18 files changed, 1506 insertions(+), 973 deletions(-)
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
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