Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [PATCH 1/3] android: Rename hidhost HAL related IPC API to match service name
From: Johan Hedberg @ 2013-11-07 16:47 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1383841024-11965-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

On Thu, Nov 07, 2013, Szymon Janc wrote:
> Use 'Android HAL name' string from IPC doc as base for names.
> ---
>  android/hal-hidhost.c | 72 +++++++++++++++++++++---------------------
>  android/hal-msg.h     | 80 +++++++++++++++++++++++------------------------
>  android/hid.c         | 86 ++++++++++++++++++++++++++-------------------------
>  3 files changed, 120 insertions(+), 118 deletions(-)

All three patches have been applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH v3] android: Add set/get for discovery timeout
From: Johan Hedberg @ 2013-11-07 16:44 UTC (permalink / raw)
  To: Lukasz Rymanowski; +Cc: linux-bluetooth, szymon.janc
In-Reply-To: <1383839864-5470-1-git-send-email-lukasz.rymanowski@tieto.com>

Hi Lukasz,

On Thu, Nov 07, 2013, Lukasz Rymanowski wrote:
> Android handles discoverable timeout in Settings app, however still
> expects BT stack to maintain this value so we should do it as well.
> Otherwise we will get some unexpected behaviour.
> For now we keep discovery_timeout only during runtime, but we need to move
> it to some local storage once we will have it.
> 
> Note: That since Android Settings up handles timer there is no reason to
> use discovery timer we have in kernel.
> ---
>  android/adapter.c | 38 +++++++++++++++++++++++++++++++++++---
>  1 file changed, 35 insertions(+), 3 deletions(-)

Applied, but I still had to tweak around the coding style a bit:

> +	memcpy(&ev->props[0].val, &adapter->discoverable_timeout,
> +						sizeof(uint32_t));

You can indent this second line more here. General rule is indent as
long as you stay under 80 characters.

> +	ipc_send(notification_sk, HAL_SERVICE_ID_BLUETOOTH,
> +				HAL_EV_ADAPTER_PROPS_CHANGED,
> +					sizeof(buf), ev, -1);

Here you're not only under-indented but the second continuation line
doesn't match the first continuation line (the coding style is to keep
lines 2-n with the same indentation).

Johan

^ permalink raw reply

* [PATCH 3/3] android/hal: Use hidhost instead of hh in hidhost HAL
From: Szymon Janc @ 2013-11-07 16:17 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1383841024-11965-1-git-send-email-szymon.janc@tieto.com>

Match functions names to HAL name. Where not needed hh prefix is
removed.
---
 android/hal-hidhost.c | 78 +++++++++++++++++++++++++--------------------------
 android/hal-ipc.c     |  2 +-
 android/hal.h         |  2 +-
 3 files changed, 41 insertions(+), 41 deletions(-)

diff --git a/android/hal-hidhost.c b/android/hal-hidhost.c
index ed730cf..3c147e8 100644
--- a/android/hal-hidhost.c
+++ b/android/hal-hidhost.c
@@ -24,19 +24,19 @@
 #include "hal-msg.h"
 #include "hal-ipc.h"
 
-static const bthh_callbacks_t *bt_hh_cbacks;
+static const bthh_callbacks_t *cbacks;
 
 static bool interface_ready(void)
 {
-	return bt_hh_cbacks != NULL;
+	return cbacks != NULL;
 }
 
 static void handle_conn_state(void *buf)
 {
 	struct hal_ev_hidhost_conn_state *ev = buf;
 
-	if (bt_hh_cbacks->connection_state_cb)
-		bt_hh_cbacks->connection_state_cb((bt_bdaddr_t *) ev->bdaddr,
+	if (cbacks->connection_state_cb)
+		cbacks->connection_state_cb((bt_bdaddr_t *) ev->bdaddr,
 								ev->state);
 }
 
@@ -55,16 +55,16 @@ static void handle_info(void *buf)
 	info.dl_len = ev->descr_len;
 	memcpy(info.dsc_list, ev->descr, info.dl_len);
 
-	if (bt_hh_cbacks->hid_info_cb)
-		bt_hh_cbacks->hid_info_cb((bt_bdaddr_t *) ev->bdaddr, info);
+	if (cbacks->hid_info_cb)
+		cbacks->hid_info_cb((bt_bdaddr_t *) ev->bdaddr, info);
 }
 
 static void handle_proto_mode(void *buf)
 {
 	struct hal_ev_hidhost_proto_mode *ev = buf;
 
-	if (bt_hh_cbacks->protocol_mode_cb)
-		bt_hh_cbacks->protocol_mode_cb((bt_bdaddr_t *) ev->bdaddr,
+	if (cbacks->protocol_mode_cb)
+		cbacks->protocol_mode_cb((bt_bdaddr_t *) ev->bdaddr,
 							ev->status, ev->mode);
 }
 
@@ -72,13 +72,13 @@ static void handle_get_report(void *buf)
 {
 	struct hal_ev_hidhost_get_report *ev = buf;
 
-	if (bt_hh_cbacks->get_report_cb)
-		bt_hh_cbacks->get_report_cb((bt_bdaddr_t *) ev->bdaddr,
-						ev->status, ev->data, ev->len);
+	if (cbacks->get_report_cb)
+		cbacks->get_report_cb((bt_bdaddr_t *) ev->bdaddr, ev->status,
+							ev->data, ev->len);
 }
 
 /* will be called from notification thread context */
-void bt_notify_hh(uint16_t opcode, void *buf, uint16_t len)
+void bt_notify_hidhost(uint16_t opcode, void *buf, uint16_t len)
 {
 	if (!interface_ready())
 		return;
@@ -102,7 +102,7 @@ void bt_notify_hh(uint16_t opcode, void *buf, uint16_t len)
 	}
 }
 
-static bt_status_t hh_connect(bt_bdaddr_t *bd_addr)
+static bt_status_t hidhost_connect(bt_bdaddr_t *bd_addr)
 {
 	struct hal_cmd_hidhost_connect cmd;
 
@@ -120,7 +120,7 @@ static bt_status_t hh_connect(bt_bdaddr_t *bd_addr)
 					sizeof(cmd), &cmd, 0, NULL, NULL);
 }
 
-static bt_status_t hh_disconnect(bt_bdaddr_t *bd_addr)
+static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
 {
 	struct hal_cmd_hidhost_disconnect cmd;
 
@@ -138,7 +138,7 @@ static bt_status_t hh_disconnect(bt_bdaddr_t *bd_addr)
 					sizeof(cmd), &cmd, 0, NULL, NULL);
 }
 
-static bt_status_t hh_virtual_unplug(bt_bdaddr_t *bd_addr)
+static bt_status_t virtual_unplug(bt_bdaddr_t *bd_addr)
 {
 	struct hal_cmd_hidhost_vp cmd;
 
@@ -156,7 +156,7 @@ static bt_status_t hh_virtual_unplug(bt_bdaddr_t *bd_addr)
 					sizeof(cmd), &cmd, 0, NULL, NULL);
 }
 
-static bt_status_t hh_set_info(bt_bdaddr_t *bd_addr, bthh_hid_info_t hid_info)
+static bt_status_t set_info(bt_bdaddr_t *bd_addr, bthh_hid_info_t hid_info)
 {
 	struct hal_cmd_hidhost_set_info cmd;
 
@@ -182,7 +182,7 @@ static bt_status_t hh_set_info(bt_bdaddr_t *bd_addr, bthh_hid_info_t hid_info)
 					sizeof(cmd), &cmd, 0, NULL, NULL);
 }
 
-static bt_status_t hh_get_protocol(bt_bdaddr_t *bd_addr,
+static bt_status_t get_protocol(bt_bdaddr_t *bd_addr,
 					bthh_protocol_mode_t protocol_mode)
 {
 	struct hal_cmd_hidhost_get_protocol cmd;
@@ -213,7 +213,7 @@ static bt_status_t hh_get_protocol(bt_bdaddr_t *bd_addr,
 				sizeof(cmd), &cmd, 0, NULL, NULL);
 }
 
-static bt_status_t hh_set_protocol(bt_bdaddr_t *bd_addr,
+static bt_status_t set_protocol(bt_bdaddr_t *bd_addr,
 					bthh_protocol_mode_t protocol_mode)
 {
 	struct hal_cmd_hidhost_set_protocol cmd;
@@ -244,7 +244,7 @@ static bt_status_t hh_set_protocol(bt_bdaddr_t *bd_addr,
 				sizeof(cmd), &cmd, 0, NULL, NULL);
 }
 
-static bt_status_t hh_get_report(bt_bdaddr_t *bd_addr,
+static bt_status_t get_report(bt_bdaddr_t *bd_addr,
 						bthh_report_type_t report_type,
 						uint8_t report_id,
 						int buffer_size)
@@ -281,7 +281,7 @@ static bt_status_t hh_get_report(bt_bdaddr_t *bd_addr,
 			sizeof(cmd), &cmd, 0, NULL, NULL);
 }
 
-static bt_status_t hh_set_report(bt_bdaddr_t *bd_addr,
+static bt_status_t set_report(bt_bdaddr_t *bd_addr,
 						bthh_report_type_t report_type,
 						char *report)
 {
@@ -317,7 +317,7 @@ static bt_status_t hh_set_report(bt_bdaddr_t *bd_addr,
 				sizeof(cmd), &cmd, 0, NULL, NULL);
 }
 
-static bt_status_t hh_send_data(bt_bdaddr_t *bd_addr, char *data)
+static bt_status_t send_data(bt_bdaddr_t *bd_addr, char *data)
 {
 	struct hal_cmd_hidhost_send_data cmd;
 
@@ -335,14 +335,14 @@ static bt_status_t hh_send_data(bt_bdaddr_t *bd_addr, char *data)
 					sizeof(cmd), &cmd, 0, NULL, NULL);
 }
 
-static bt_status_t hh_init(bthh_callbacks_t *callbacks)
+static bt_status_t init(bthh_callbacks_t *callbacks)
 {
 	struct hal_cmd_register_module cmd;
 
 	DBG("");
 
 	/* store reference to user callbacks */
-	bt_hh_cbacks = callbacks;
+	cbacks = callbacks;
 
 	cmd.service_id = HAL_SERVICE_ID_HIDHOST;
 
@@ -350,7 +350,7 @@ static bt_status_t hh_init(bthh_callbacks_t *callbacks)
 					sizeof(cmd), &cmd, 0, NULL, NULL);
 }
 
-static void hh_cleanup(void)
+static void cleanup(void)
 {
 	struct hal_cmd_unregister_module cmd;
 
@@ -359,7 +359,7 @@ static void hh_cleanup(void)
 	if (!interface_ready())
 		return;
 
-	bt_hh_cbacks = NULL;
+	cbacks = NULL;
 
 	cmd.service_id = HAL_SERVICE_ID_HIDHOST;
 
@@ -367,22 +367,22 @@ static void hh_cleanup(void)
 					sizeof(cmd), &cmd, 0, NULL, NULL);
 }
 
-static bthh_interface_t hh_if = {
-	.size = sizeof(hh_if),
-	.init = hh_init,
-	.connect = hh_connect,
-	.disconnect = hh_disconnect,
-	.virtual_unplug = hh_virtual_unplug,
-	.set_info = hh_set_info,
-	.get_protocol = hh_get_protocol,
-	.set_protocol = hh_set_protocol,
-	.get_report = hh_get_report,
-	.set_report = hh_set_report,
-	.send_data = hh_send_data,
-	.cleanup = hh_cleanup
+static bthh_interface_t hidhost_if = {
+	.size = sizeof(hidhost_if),
+	.init = init,
+	.connect = hidhost_connect,
+	.disconnect = disconnect,
+	.virtual_unplug = virtual_unplug,
+	.set_info = set_info,
+	.get_protocol = get_protocol,
+	.set_protocol = set_protocol,
+	.get_report = get_report,
+	.set_report = set_report,
+	.send_data = send_data,
+	.cleanup = cleanup
 };
 
 bthh_interface_t *bt_get_hidhost_interface(void)
 {
-	return &hh_if;
+	return &hidhost_if;
 }
diff --git a/android/hal-ipc.c b/android/hal-ipc.c
index a34061d..e1c8dd7 100644
--- a/android/hal-ipc.c
+++ b/android/hal-ipc.c
@@ -50,7 +50,7 @@ static void notification_dispatch(struct hal_hdr *msg, int fd)
 		bt_notify_adapter(msg->opcode, msg->payload, msg->len);
 		break;
 	case HAL_SERVICE_ID_HIDHOST:
-		bt_notify_hh(msg->opcode, msg->payload, msg->len);
+		bt_notify_hidhost(msg->opcode, msg->payload, msg->len);
 		break;
 	case HAL_SERVICE_ID_A2DP:
 		bt_notify_a2dp(msg->opcode, msg->payload, msg->len);
diff --git a/android/hal.h b/android/hal.h
index f47ec2a..2ce7932 100644
--- a/android/hal.h
+++ b/android/hal.h
@@ -29,5 +29,5 @@ btav_interface_t *bt_get_a2dp_interface(void);
 void bt_notify_adapter(uint16_t opcode, void *buf, uint16_t len);
 void bt_thread_associate(void);
 void bt_thread_disassociate(void);
-void bt_notify_hh(uint16_t opcode, void *buf, uint16_t len);
+void bt_notify_hidhost(uint16_t opcode, void *buf, uint16_t len);
 void bt_notify_a2dp(uint16_t opcode, void *buf, uint16_t len);
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH 2/3] android: Rename hid.c to hidhost.c
From: Szymon Janc @ 2013-11-07 16:17 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1383841024-11965-1-git-send-email-szymon.janc@tieto.com>

Name of daemon implementation will match Android HAL name. This will
make code navigation easier as daemon part and HAL library implementation
will be in foo.c and hal-foo.c respectively.
---
 android/Android.mk  |    2 +-
 android/Makefile.am |    2 +-
 android/hid.c       | 1095 ---------------------------------------------------
 android/hid.h       |   27 --
 android/hidhost.c   | 1095 +++++++++++++++++++++++++++++++++++++++++++++++++++
 android/hidhost.h   |   27 ++
 android/main.c      |    2 +-
 7 files changed, 1125 insertions(+), 1125 deletions(-)
 delete mode 100644 android/hid.c
 delete mode 100644 android/hid.h
 create mode 100644 android/hidhost.c
 create mode 100644 android/hidhost.h

diff --git a/android/Android.mk b/android/Android.mk
index f9bf070..51037a7 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -22,7 +22,7 @@ include $(CLEAR_VARS)
 LOCAL_SRC_FILES := \
 	main.c \
 	adapter.c \
-	hid.c \
+	hidhost.c \
 	socket.c \
 	ipc.c ipc.h \
 	a2dp.c \
diff --git a/android/Makefile.am b/android/Makefile.am
index 6790f24..073edc8 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -17,7 +17,7 @@ android_bluetoothd_SOURCES = android/main.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/hidhost.h android/hidhost.c \
 				android/ipc.h android/ipc.c \
 				android/a2dp.h android/a2dp.c \
 				android/socket.h android/socket.c \
diff --git a/android/hid.c b/android/hid.c
deleted file mode 100644
index 1089301..0000000
--- a/android/hid.c
+++ /dev/null
@@ -1,1095 +0,0 @@
-/*
- *
- *  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 <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 "lib/sdp.h"
-#include "lib/sdp_lib.h"
-#include "lib/uuid.h"
-#include "src/shared/mgmt.h"
-#include "src/sdp-client.h"
-#include "src/glib-helper.h"
-#include "profiles/input/uhid_copy.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 UHID_DEVICE_FILE	"/dev/uhid"
-
-/* HID message types */
-#define HID_MSG_GET_REPORT	0x40
-#define HID_MSG_SET_REPORT	0x50
-#define HID_MSG_GET_PROTOCOL	0x60
-#define HID_MSG_SET_PROTOCOL	0x70
-#define HID_MSG_DATA		0xa0
-
-/* HID data types */
-#define HID_DATA_TYPE_INPUT	0x01
-#define HID_DATA_TYPE_OUTPUT	0x02
-#define HID_DATA_TYPE_FEATURE	0x03
-
-/* HID protocol header parameters */
-#define HID_PROTO_BOOT		0x00
-#define HID_PROTO_REPORT	0x01
-
-/* HID GET REPORT Size Field */
-#define HID_GET_REPORT_SIZE_FIELD	0x08
-
-static int notification_sk = -1;
-static GIOChannel *ctrl_io = NULL;
-static GIOChannel *intr_io = NULL;
-static GSList *devices = NULL;
-
-struct hid_device {
-	bdaddr_t	dst;
-	uint8_t		state;
-	uint8_t		subclass;
-	uint16_t	vendor;
-	uint16_t	product;
-	uint16_t	version;
-	uint8_t		country;
-	int		rd_size;
-	void		*rd_data;
-	uint8_t		boot_dev;
-	GIOChannel	*ctrl_io;
-	GIOChannel	*intr_io;
-	guint		ctrl_watch;
-	guint		intr_watch;
-	int		uhid_fd;
-	guint		uhid_watch_id;
-	uint8_t		last_hid_msg;
-};
-
-static int device_cmp(gconstpointer s, gconstpointer user_data)
-{
-	const struct hid_device *dev = s;
-	const bdaddr_t *dst = user_data;
-
-	return bacmp(&dev->dst, dst);
-}
-
-static void uhid_destroy(int fd)
-{
-	struct uhid_event ev;
-
-	/* destroy uHID device */
-	memset(&ev, 0, sizeof(ev));
-	ev.type = UHID_DESTROY;
-
-	if (write(fd, &ev, sizeof(ev)) < 0)
-		error("Failed to destroy uHID device: %s (%d)",
-						strerror(errno), errno);
-
-	close(fd);
-}
-
-static void hid_device_free(struct hid_device *dev)
-{
-	if (dev->ctrl_watch > 0)
-		g_source_remove(dev->ctrl_watch);
-
-	if (dev->intr_watch > 0)
-		g_source_remove(dev->intr_watch);
-
-	if (dev->intr_io)
-		g_io_channel_unref(dev->intr_io);
-
-	if (dev->ctrl_io)
-		g_io_channel_unref(dev->ctrl_io);
-
-	if (dev->uhid_watch_id) {
-		g_source_remove(dev->uhid_watch_id);
-		dev->uhid_watch_id = 0;
-	}
-
-	if (dev->uhid_fd > 0)
-		uhid_destroy(dev->uhid_fd);
-
-	g_free(dev->rd_data);
-
-	devices = g_slist_remove(devices, dev);
-	g_free(dev);
-}
-
-static void handle_uhid_event(struct hid_device *dev, struct uhid_event *ev)
-{
-	DBG("UHID_OUTPUT UHID_FEATURE unsupported");
-}
-
-static gboolean uhid_event_cb(GIOChannel *io, GIOCondition cond,
-							gpointer user_data)
-{
-	struct hid_device *dev = user_data;
-	struct uhid_event ev;
-	ssize_t bread;
-	int fd;
-
-	DBG("");
-
-	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) {
-		DBG("read: %s (%d)", strerror(errno), errno);
-		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.
-		 * We open the channels before creating the device so the
-		 * hardware is always ready. No need to handle these.
-		 * 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. */
-		break;
-	case UHID_OUTPUT:
-	case UHID_FEATURE:
-		handle_uhid_event(dev, &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. */
-		DBG("UHID_OUTPUT_EV unsupported");
-		break;
-	default:
-		warn("unexpected uHID event");
-	}
-
-	return TRUE;
-
-failed:
-	dev->uhid_watch_id = 0;
-	return FALSE;
-}
-
-static gboolean intr_io_watch_cb(GIOChannel *chan, gpointer data)
-{
-	struct hid_device *dev = data;
-	uint8_t buf[UHID_DATA_MAX];
-	struct uhid_event ev;
-	int fd, bread;
-
-	/* Wait uHID if not ready */
-	if (dev->uhid_fd < 0)
-		return TRUE;
-
-	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;
-	}
-
-	/* Discard non-data packets */
-	if (bread == 0 || buf[0] != (HID_MSG_DATA | HID_DATA_TYPE_INPUT))
-		return TRUE;
-
-	/* send data to uHID device skipping HIDP header byte */
-	memset(&ev, 0, sizeof(ev));
-	ev.type = UHID_INPUT;
-	ev.u.input.size = bread - 1;
-	memcpy(ev.u.input.data, &buf[1], ev.u.input.size);
-
-	if (write(dev->uhid_fd, &ev, sizeof(ev)) < 0)
-		DBG("write: %s (%d)", strerror(errno), errno);
-
-	return TRUE;
-}
-
-static void bt_hid_notify_state(struct hid_device *dev, uint8_t state)
-{
-	struct hal_ev_hidhost_conn_state ev;
-	char address[18];
-
-	if (dev->state == state)
-		return;
-
-	dev->state = state;
-
-	ba2str(&dev->dst, address);
-	DBG("device %s state %u", address, state);
-
-	bdaddr2android(&dev->dst, ev.bdaddr);
-	ev.state = state;
-
-	ipc_send(notification_sk, HAL_SERVICE_ID_HIDHOST,
-			HAL_EV_HIDHOST_CONN_STATE, sizeof(ev), &ev, -1);
-}
-
-static gboolean intr_watch_cb(GIOChannel *chan, GIOCondition cond,
-								gpointer data)
-{
-	struct hid_device *dev = data;
-
-	if (cond & G_IO_IN)
-		return intr_io_watch_cb(chan, data);
-
-	/* 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)) && dev->ctrl_watch)
-		g_io_channel_shutdown(chan, TRUE, NULL);
-
-	dev->intr_watch = 0;
-
-	if (dev->intr_io) {
-		g_io_channel_unref(dev->intr_io);
-		dev->intr_io = NULL;
-	}
-
-	/* Close control channel */
-	if (dev->ctrl_io && !(cond & G_IO_NVAL))
-		g_io_channel_shutdown(dev->ctrl_io, TRUE, NULL);
-
-	return FALSE;
-}
-
-static void bt_hid_notify_proto_mode(struct hid_device *dev, uint8_t *buf,
-									int len)
-{
-	struct hal_ev_hidhost_proto_mode ev;
-	char address[18];
-
-	ba2str(&dev->dst, address);
-	DBG("device %s", address);
-
-	memset(&ev, 0, sizeof(ev));
-	bdaddr2android(&dev->dst, ev.bdaddr);
-
-	if (buf[0] == HID_MSG_DATA) {
-		ev.status = HAL_HIDHOST_STATUS_OK;
-		if (buf[1] == HID_PROTO_REPORT)
-			ev.mode = HAL_HIDHOST_REPORT_PROTOCOL;
-		else if (buf[1] == HID_PROTO_BOOT)
-			ev.mode = HAL_HIDHOST_BOOT_PROTOCOL;
-		else
-			ev.mode = HAL_HIDHOST_UNSUPPORTED_PROTOCOL;
-
-	} else {
-		ev.status = buf[0];
-		ev.mode = HAL_HIDHOST_UNSUPPORTED_PROTOCOL;
-	}
-
-	ipc_send(notification_sk, HAL_SERVICE_ID_HIDHOST,
-			HAL_EV_HIDHOST_PROTO_MODE, sizeof(ev), &ev, -1);
-}
-
-static void bt_hid_notify_get_report(struct hid_device *dev, uint8_t *buf,
-									int len)
-{
-	struct hal_ev_hidhost_get_report *ev;
-	int ev_len;
-	char address[18];
-
-	ba2str(&dev->dst, address);
-	DBG("device %s", address);
-
-	ev_len = sizeof(*ev) + sizeof(struct hal_ev_hidhost_get_report) + 1;
-
-	if (!((buf[0] == (HID_MSG_DATA | HID_DATA_TYPE_INPUT)) ||
-			(buf[0] == (HID_MSG_DATA | HID_DATA_TYPE_OUTPUT)) ||
-			(buf[0]	== (HID_MSG_DATA | HID_DATA_TYPE_FEATURE)))) {
-		ev = g_malloc0(ev_len);
-		ev->status = buf[0];
-		bdaddr2android(&dev->dst, ev->bdaddr);
-		goto send;
-	}
-
-	/* Report porotocol mode reply contains id after hdr, in boot
-	 * protocol mode id doesn't exist */
-	ev_len += (dev->boot_dev) ? (len - 1) : (len - 2);
-	ev = g_malloc0(ev_len);
-	ev->status = HAL_HIDHOST_STATUS_OK;
-	bdaddr2android(&dev->dst, ev->bdaddr);
-
-	/* Report porotocol mode reply contains id after hdr, in boot
-	 * protocol mode id doesn't exist */
-	if (dev->boot_dev) {
-		ev->len = len - 1;
-		memcpy(ev->data, buf + 1, ev->len);
-	} else {
-		ev->len = len - 2;
-		memcpy(ev->data, buf + 2, ev->len);
-	}
-
-send:
-	ipc_send(notification_sk, HAL_SERVICE_ID_HIDHOST,
-				HAL_EV_HIDHOST_GET_REPORT, ev_len, ev, -1);
-	g_free(ev);
-}
-
-static gboolean ctrl_io_watch_cb(GIOChannel *chan, gpointer data)
-{
-	struct hid_device *dev = data;
-	int fd, bread;
-	uint8_t buf[UHID_DATA_MAX];
-
-	DBG("");
-
-	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;
-	}
-
-	switch (dev->last_hid_msg) {
-	case HID_MSG_GET_PROTOCOL:
-	case HID_MSG_SET_PROTOCOL:
-		bt_hid_notify_proto_mode(dev, buf, bread);
-		break;
-	case HID_MSG_GET_REPORT:
-		bt_hid_notify_get_report(dev, buf, bread);
-		break;
-	}
-
-	/* reset msg type request */
-	dev->last_hid_msg = 0;
-
-	return TRUE;
-}
-
-static gboolean ctrl_watch_cb(GIOChannel *chan, GIOCondition cond,
-								gpointer data)
-{
-	struct hid_device *dev = data;
-	char address[18];
-
-	if (cond & G_IO_IN)
-		return ctrl_io_watch_cb(chan, data);
-
-	ba2str(&dev->dst, address);
-	bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED);
-
-	/* 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)) && dev->intr_watch)
-		g_io_channel_shutdown(chan, TRUE, NULL);
-
-	if (dev->intr_io && !(cond & G_IO_NVAL))
-		g_io_channel_shutdown(dev->intr_io, TRUE, NULL);
-
-	hid_device_free(dev);
-
-	return FALSE;
-}
-
-static void bt_hid_set_info(struct hid_device *dev)
-{
-	struct hal_ev_hidhost_info ev;
-
-	DBG("");
-
-	bdaddr2android(&dev->dst, ev.bdaddr);
-	ev.attr = 0; /* TODO: Check what is this field */
-	ev.subclass = dev->subclass;
-	ev.app_id = 0; /* TODO: Check what is this field */
-	ev.vendor = dev->vendor;
-	ev.product = dev->product;
-	ev.version = dev->version;
-	ev.country = dev->country;
-	ev.descr_len = dev->rd_size;
-	memset(ev.descr, 0, sizeof(ev.descr));
-	memcpy(ev.descr, dev->rd_data, ev.descr_len);
-
-	ipc_send(notification_sk, HAL_SERVICE_ID_HIDHOST, HAL_EV_HIDHOST_INFO,
-							sizeof(ev), &ev, -1);
-}
-
-static int uhid_create(struct hid_device *dev)
-{
-	GIOCondition cond = G_IO_IN | G_IO_ERR | G_IO_NVAL;
-	GIOChannel *io;
-	struct uhid_event ev;
-
-	dev->uhid_fd = open(UHID_DEVICE_FILE, O_RDWR | O_CLOEXEC);
-	if (dev->uhid_fd < 0) {
-		error("Failed to open uHID device: %s", strerror(errno));
-		bt_hid_notify_state(dev, HAL_HIDHOST_STATE_NO_HID);
-		return -errno;
-	}
-
-	memset(&ev, 0, sizeof(ev));
-	ev.type = UHID_CREATE;
-	strcpy((char *) ev.u.create.name, "bluez-input-device");
-	ev.u.create.bus = BUS_BLUETOOTH;
-	ev.u.create.vendor = dev->vendor;
-	ev.u.create.product = dev->product;
-	ev.u.create.version = dev->version;
-	ev.u.create.country = dev->country;
-	ev.u.create.rd_size = dev->rd_size;
-	ev.u.create.rd_data = dev->rd_data;
-
-	if (write(dev->uhid_fd, &ev, sizeof(ev)) < 0) {
-		error("Failed to create uHID device: %s", strerror(errno));
-		close(dev->uhid_fd);
-		dev->uhid_fd = -1;
-		return -errno;
-	}
-
-	io = g_io_channel_unix_new(dev->uhid_fd);
-	g_io_channel_set_encoding(io, NULL, NULL);
-	dev->uhid_watch_id = g_io_add_watch(io, cond, uhid_event_cb, dev);
-	g_io_channel_unref(io);
-
-	bt_hid_set_info(dev);
-
-	return 0;
-}
-
-static void interrupt_connect_cb(GIOChannel *chan, GError *conn_err,
-							gpointer user_data)
-{
-	struct hid_device *dev = user_data;
-
-	DBG("");
-
-	if (conn_err)
-		goto failed;
-
-	if (uhid_create(dev) < 0)
-		goto failed;
-
-	dev->intr_watch = g_io_add_watch(dev->intr_io,
-				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
-				intr_watch_cb, dev);
-
-	bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTED);
-
-	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(dev->intr_io, FALSE, NULL);
-
-	g_io_channel_unref(dev->intr_io);
-	dev->intr_io = NULL;
-
-	if (dev->ctrl_io) {
-		g_io_channel_unref(dev->ctrl_io);
-		dev->ctrl_io = NULL;
-	}
-}
-
-static void control_connect_cb(GIOChannel *chan, GError *conn_err,
-							gpointer user_data)
-{
-	struct hid_device *dev = user_data;
-	GError *err = NULL;
-	const bdaddr_t *src = bt_adapter_get_address();
-
-	DBG("");
-
-	if (conn_err) {
-		bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED);
-		error("%s", conn_err->message);
-		goto failed;
-	}
-
-	/* Connect to the HID interrupt channel */
-	dev->intr_io = bt_io_connect(interrupt_connect_cb, dev, NULL, &err,
-					BT_IO_OPT_SOURCE_BDADDR, src,
-					BT_IO_OPT_DEST_BDADDR, &dev->dst,
-					BT_IO_OPT_PSM, L2CAP_PSM_HIDP_INTR,
-					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
-					BT_IO_OPT_INVALID);
-	if (!dev->intr_io) {
-		error("%s", err->message);
-		g_error_free(err);
-		goto failed;
-	}
-
-	dev->ctrl_watch = g_io_add_watch(dev->ctrl_io,
-				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
-				ctrl_watch_cb, dev);
-
-	return;
-
-failed:
-	hid_device_free(dev);
-}
-
-static void hid_sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
-{
-	struct hid_device *dev = data;
-	sdp_list_t *list;
-	GError *gerr = NULL;
-	const bdaddr_t *src = bt_adapter_get_address();
-
-	DBG("");
-
-	if (err < 0) {
-		error("Unable to get SDP record: %s", strerror(-err));
-		goto fail;
-	}
-
-	if (!recs || !recs->data) {
-		error("No SDP records found");
-		goto fail;
-	}
-
-	for (list = recs; list != NULL; list = list->next) {
-		sdp_record_t *rec = list->data;
-		sdp_data_t *data;
-
-		data = sdp_data_get(rec, SDP_ATTR_VENDOR_ID);
-		if (data)
-			dev->vendor = data->val.uint16;
-
-		data = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID);
-		if (data)
-			dev->product = data->val.uint16;
-
-		data = sdp_data_get(rec, SDP_ATTR_VERSION);
-		if (data)
-			dev->version = data->val.uint16;
-
-		data = sdp_data_get(rec, SDP_ATTR_HID_COUNTRY_CODE);
-		if (data)
-			dev->country = data->val.uint8;
-
-		data = sdp_data_get(rec, SDP_ATTR_HID_DEVICE_SUBCLASS);
-		if (data)
-			dev->subclass = data->val.uint8;
-
-		data = sdp_data_get(rec, SDP_ATTR_HID_BOOT_DEVICE);
-		if (data)
-			dev->boot_dev = data->val.uint8;
-
-		data = sdp_data_get(rec, SDP_ATTR_HID_DESCRIPTOR_LIST);
-		if (data) {
-			if (!SDP_IS_SEQ(data->dtd))
-				goto fail;
-
-			/* First HIDDescriptor */
-			data = data->val.dataseq;
-			if (!SDP_IS_SEQ(data->dtd))
-				goto fail;
-
-			/* ClassDescriptorType */
-			data = data->val.dataseq;
-			if (data->dtd != SDP_UINT8)
-				goto fail;
-
-			/* ClassDescriptorData */
-			data = data->next;
-			if (!data || !SDP_IS_TEXT_STR(data->dtd))
-				goto fail;
-
-			dev->rd_size = data->unitSize;
-			dev->rd_data = g_memdup(data->val.str, data->unitSize);
-		}
-	}
-
-	if (dev->ctrl_io) {
-		if (uhid_create(dev) < 0)
-			goto fail;
-		return;
-	}
-
-	dev->ctrl_io = bt_io_connect(control_connect_cb, dev, NULL, &gerr,
-					BT_IO_OPT_SOURCE_BDADDR, src,
-					BT_IO_OPT_DEST_BDADDR, &dev->dst,
-					BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL,
-					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
-					BT_IO_OPT_INVALID);
-	if (gerr) {
-		error("%s", gerr->message);
-		g_error_free(gerr);
-		goto fail;
-	}
-
-	return;
-
-fail:
-	bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED);
-	hid_device_free(dev);
-}
-
-static uint8_t bt_hid_connect(struct hal_cmd_hidhost_connect *cmd,
-								uint16_t len)
-{
-	struct hid_device *dev;
-	char addr[18];
-	bdaddr_t dst;
-	GSList *l;
-	const bdaddr_t *src = bt_adapter_get_address();
-	uuid_t uuid;
-
-	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;
-
-	dev = g_new0(struct hid_device, 1);
-	bacpy(&dev->dst, &dst);
-	dev->uhid_fd = -1;
-
-	ba2str(&dev->dst, addr);
-	DBG("connecting to %s", addr);
-
-	bt_string2uuid(&uuid, HID_UUID);
-	if (bt_search_service(src, &dev->dst, &uuid, hid_sdp_search_cb, dev,
-								NULL) < 0) {
-		error("Failed to search sdp details");
-		hid_device_free(dev);
-		return HAL_STATUS_FAILED;
-	}
-
-	devices = g_slist_append(devices, dev);
-	bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTING);
-
-	return HAL_STATUS_SUCCESS;
-}
-
-static uint8_t bt_hid_disconnect(struct hal_cmd_hidhost_disconnect *cmd,
-								uint16_t len)
-{
-	struct hid_device *dev;
-	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;
-
-	dev = l->data;
-
-	/* Wait either channels to HUP */
-	if (dev->intr_io)
-		g_io_channel_shutdown(dev->intr_io, TRUE, NULL);
-
-	if (dev->ctrl_io)
-		g_io_channel_shutdown(dev->ctrl_io, TRUE, NULL);
-
-	bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTING);
-
-	return HAL_STATUS_SUCCESS;
-}
-
-static uint8_t bt_hid_virtual_unplug(struct hal_cmd_hidhost_vp *cmd,
-								uint16_t len)
-{
-	DBG("Not Implemented");
-
-	return HAL_STATUS_FAILED;
-}
-
-static uint8_t bt_hid_info(struct hal_cmd_hidhost_set_info *cmd, uint16_t len)
-{
-	DBG("Not Implemented");
-
-	return HAL_STATUS_FAILED;
-}
-
-static uint8_t bt_hid_get_protocol(struct hal_cmd_hidhost_get_protocol *cmd,
-								uint16_t len)
-{
-	struct hid_device *dev;
-	GSList *l;
-	bdaddr_t dst;
-	int fd;
-	uint8_t hdr;
-
-	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;
-
-	dev = l->data;
-
-	if (dev->boot_dev)
-		return HAL_STATUS_UNSUPPORTED;
-
-	hdr = HID_MSG_GET_PROTOCOL | cmd->mode;
-	fd = g_io_channel_unix_get_fd(dev->ctrl_io);
-
-	if (write(fd, &hdr, sizeof(hdr)) < 0) {
-		error("error while querying device protocol");
-		return HAL_STATUS_FAILED;
-	}
-
-	dev->last_hid_msg = HID_MSG_GET_PROTOCOL;
-	return HAL_STATUS_SUCCESS;
-}
-
-static uint8_t bt_hid_set_protocol(struct hal_cmd_hidhost_set_protocol *cmd,
-								uint16_t len)
-{
-	struct hid_device *dev;
-	GSList *l;
-	bdaddr_t dst;
-	int fd;
-	uint8_t hdr;
-
-	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;
-
-	dev = l->data;
-
-	if (dev->boot_dev)
-		return HAL_STATUS_UNSUPPORTED;
-
-	hdr = HID_MSG_SET_PROTOCOL | cmd->mode;
-	fd = g_io_channel_unix_get_fd(dev->ctrl_io);
-
-	if (write(fd, &hdr, sizeof(hdr)) < 0) {
-		error("error while setting device protocol");
-		return HAL_STATUS_FAILED;
-	}
-
-	dev->last_hid_msg = HID_MSG_SET_PROTOCOL;
-	return HAL_STATUS_SUCCESS;
-}
-
-static uint8_t bt_hid_get_report(struct hal_cmd_hidhost_get_report *cmd,
-								uint16_t len)
-{
-	struct hid_device *dev;
-	GSList *l;
-	bdaddr_t dst;
-	int fd;
-	uint8_t *req;
-	uint8_t req_size;
-
-	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;
-
-	dev = l->data;
-	req_size = (cmd->buf_size > 0) ? 4 : 2;
-	req = g_try_malloc0(req_size);
-	if (!req)
-		return HAL_STATUS_NOMEM;
-
-	req[0] = HID_MSG_GET_REPORT | cmd->type;
-	req[1] = cmd->id;
-
-	if (cmd->buf_size > 0) {
-		req[0] = req[0] | HID_GET_REPORT_SIZE_FIELD;
-		bt_put_le16(cmd->buf_size, &req[2]);
-	}
-
-	fd = g_io_channel_unix_get_fd(dev->ctrl_io);
-
-	if (write(fd, req, req_size) < 0) {
-		error("error while querying device protocol");
-		g_free(req);
-		return HAL_STATUS_FAILED;
-	}
-
-	dev->last_hid_msg = HID_MSG_GET_REPORT;
-	g_free(req);
-	return HAL_STATUS_SUCCESS;
-}
-
-static uint8_t bt_hid_set_report(struct hal_cmd_hidhost_set_report *cmd,
-								uint16_t len)
-{
-	struct hid_device *dev;
-	GSList *l;
-	bdaddr_t dst;
-	int fd;
-	uint8_t *req;
-	uint8_t req_size;
-
-	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;
-
-	dev = l->data;
-	req_size = 1 + cmd->len;
-	req = g_try_malloc0(req_size);
-	if (!req)
-		return HAL_STATUS_NOMEM;
-
-	req[0] = HID_MSG_SET_REPORT | cmd->type;
-	memcpy(req + 1, cmd->data, req_size - 1);
-
-	fd = g_io_channel_unix_get_fd(dev->ctrl_io);
-
-	if (write(fd, req, req_size) < 0) {
-		error("error while querying device protocol");
-		g_free(req);
-		return HAL_STATUS_FAILED;
-	}
-
-	dev->last_hid_msg = HID_MSG_SET_REPORT;
-	g_free(req);
-	return HAL_STATUS_SUCCESS;
-}
-
-static uint8_t bt_hid_send_data(struct hal_cmd_hidhost_send_data *cmd,
-								uint16_t len)
-{
-	DBG("Not Implemented");
-
-	return HAL_STATUS_FAILED;
-}
-
-void bt_hid_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
-{
-	uint8_t status = HAL_STATUS_FAILED;
-
-	switch (opcode) {
-	case HAL_OP_HIDHOST_CONNECT:
-		status = bt_hid_connect(buf, len);
-		break;
-	case HAL_OP_HIDHOST_DISCONNECT:
-		status = bt_hid_disconnect(buf, len);
-		break;
-	case HAL_OP_HIDHOST_VP:
-		status = bt_hid_virtual_unplug(buf, len);
-		break;
-	case HAL_OP_HIDHOST_SET_INFO:
-		status = bt_hid_info(buf, len);
-		break;
-	case HAL_OP_HIDHOST_GET_PROTOCOL:
-		status = bt_hid_get_protocol(buf, len);
-		break;
-	case HAL_OP_HIDHOST_SET_PROTOCOL:
-		status = bt_hid_set_protocol(buf, len);
-		break;
-	case HAL_OP_HIDHOST_GET_REPORT:
-		status = bt_hid_get_report(buf, len);
-		break;
-	case HAL_OP_HIDHOST_SET_REPORT:
-		status = bt_hid_set_report(buf, len);
-		break;
-	case HAL_OP_HIDHOST_SEND_DATA:
-		status = bt_hid_send_data(buf, len);
-		break;
-	default:
-		DBG("Unhandled command, opcode 0x%x", opcode);
-		break;
-	}
-
-	ipc_send_rsp(sk, HAL_SERVICE_ID_HIDHOST, status);
-}
-
-static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
-{
-	struct hid_device *dev;
-	bdaddr_t src, dst;
-	char address[18];
-	uint16_t psm;
-	GError *gerr = NULL;
-	GSList *l;
-	uuid_t uuid;
-
-	if (err) {
-		error("%s", err->message);
-		return;
-	}
-
-	bt_io_get(chan, &err,
-			BT_IO_OPT_SOURCE_BDADDR, &src,
-			BT_IO_OPT_DEST_BDADDR, &dst,
-			BT_IO_OPT_PSM, &psm,
-			BT_IO_OPT_INVALID);
-	if (err) {
-		error("%s", gerr->message);
-		g_io_channel_shutdown(chan, TRUE, NULL);
-		return;
-	}
-
-	ba2str(&dst, address);
-	DBG("Incoming connection from %s on PSM %d", address, psm);
-
-	switch (psm) {
-	case L2CAP_PSM_HIDP_CTRL:
-		l = g_slist_find_custom(devices, &dst, device_cmp);
-		if (l)
-			return;
-
-		dev = g_new0(struct hid_device, 1);
-		bacpy(&dev->dst, &dst);
-		dev->ctrl_io = g_io_channel_ref(chan);
-		dev->uhid_fd = -1;
-
-		bt_string2uuid(&uuid, HID_UUID);
-		if (bt_search_service(&src, &dev->dst, &uuid,
-					hid_sdp_search_cb, dev, NULL) < 0) {
-			error("failed to search sdp details");
-			hid_device_free(dev);
-			return;
-		}
-
-		devices = g_slist_append(devices, dev);
-
-		dev->ctrl_watch = g_io_add_watch(dev->ctrl_io,
-					G_IO_HUP | G_IO_ERR | G_IO_NVAL,
-					ctrl_watch_cb, dev);
-		bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTING);
-		break;
-
-	case L2CAP_PSM_HIDP_INTR:
-		l = g_slist_find_custom(devices, &dst, device_cmp);
-		if (!l)
-			return;
-
-		dev = l->data;
-		dev->intr_io = g_io_channel_ref(chan);
-		dev->intr_watch = g_io_add_watch(dev->intr_io,
-				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
-				intr_watch_cb, dev);
-		bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTED);
-		break;
-	}
-}
-
-bool bt_hid_register(int sk, const bdaddr_t *addr)
-{
-	GError *err = NULL;
-	const bdaddr_t *src = bt_adapter_get_address();
-
-	DBG("");
-
-	ctrl_io = bt_io_listen(connect_cb, NULL, NULL, NULL, &err,
-				BT_IO_OPT_SOURCE_BDADDR, src,
-				BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL,
-				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
-				BT_IO_OPT_INVALID);
-	if (!ctrl_io) {
-		error("Failed to listen on ctrl channel: %s", err->message);
-		g_error_free(err);
-		return false;
-	}
-
-	intr_io = bt_io_listen(connect_cb, NULL, NULL, NULL, &err,
-				BT_IO_OPT_SOURCE_BDADDR, src,
-				BT_IO_OPT_PSM, L2CAP_PSM_HIDP_INTR,
-				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
-				BT_IO_OPT_INVALID);
-	if (!intr_io) {
-		error("Failed to listen on intr channel: %s", err->message);
-		g_io_channel_unref(ctrl_io);
-		g_error_free(err);
-		return false;
-	}
-
-	notification_sk = sk;
-
-	return true;
-}
-
-void bt_hid_unregister(void)
-{
-	DBG("");
-
-	notification_sk = -1;
-
-	if (ctrl_io) {
-		g_io_channel_shutdown(ctrl_io, TRUE, NULL);
-		g_io_channel_unref(ctrl_io);
-		ctrl_io = NULL;
-	}
-
-	if (intr_io) {
-		g_io_channel_shutdown(intr_io, TRUE, NULL);
-		g_io_channel_unref(intr_io);
-		intr_io = NULL;
-	}
-}
diff --git a/android/hid.h b/android/hid.h
deleted file mode 100644
index 688086a..0000000
--- a/android/hid.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- *
- *  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
- *
- */
-
-void bt_hid_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len);
-
-bool bt_hid_register(int sk, const bdaddr_t *addr);
-void bt_hid_unregister(void);
diff --git a/android/hidhost.c b/android/hidhost.c
new file mode 100644
index 0000000..c7b4114
--- /dev/null
+++ b/android/hidhost.c
@@ -0,0 +1,1095 @@
+/*
+ *
+ *  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 <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 "lib/sdp.h"
+#include "lib/sdp_lib.h"
+#include "lib/uuid.h"
+#include "src/shared/mgmt.h"
+#include "src/sdp-client.h"
+#include "src/glib-helper.h"
+#include "profiles/input/uhid_copy.h"
+
+#include "log.h"
+#include "hal-msg.h"
+#include "ipc.h"
+#include "hidhost.h"
+#include "adapter.h"
+#include "utils.h"
+
+#define L2CAP_PSM_HIDP_CTRL	0x11
+#define L2CAP_PSM_HIDP_INTR	0x13
+#define UHID_DEVICE_FILE	"/dev/uhid"
+
+/* HID message types */
+#define HID_MSG_GET_REPORT	0x40
+#define HID_MSG_SET_REPORT	0x50
+#define HID_MSG_GET_PROTOCOL	0x60
+#define HID_MSG_SET_PROTOCOL	0x70
+#define HID_MSG_DATA		0xa0
+
+/* HID data types */
+#define HID_DATA_TYPE_INPUT	0x01
+#define HID_DATA_TYPE_OUTPUT	0x02
+#define HID_DATA_TYPE_FEATURE	0x03
+
+/* HID protocol header parameters */
+#define HID_PROTO_BOOT		0x00
+#define HID_PROTO_REPORT	0x01
+
+/* HID GET REPORT Size Field */
+#define HID_GET_REPORT_SIZE_FIELD	0x08
+
+static int notification_sk = -1;
+static GIOChannel *ctrl_io = NULL;
+static GIOChannel *intr_io = NULL;
+static GSList *devices = NULL;
+
+struct hid_device {
+	bdaddr_t	dst;
+	uint8_t		state;
+	uint8_t		subclass;
+	uint16_t	vendor;
+	uint16_t	product;
+	uint16_t	version;
+	uint8_t		country;
+	int		rd_size;
+	void		*rd_data;
+	uint8_t		boot_dev;
+	GIOChannel	*ctrl_io;
+	GIOChannel	*intr_io;
+	guint		ctrl_watch;
+	guint		intr_watch;
+	int		uhid_fd;
+	guint		uhid_watch_id;
+	uint8_t		last_hid_msg;
+};
+
+static int device_cmp(gconstpointer s, gconstpointer user_data)
+{
+	const struct hid_device *dev = s;
+	const bdaddr_t *dst = user_data;
+
+	return bacmp(&dev->dst, dst);
+}
+
+static void uhid_destroy(int fd)
+{
+	struct uhid_event ev;
+
+	/* destroy uHID device */
+	memset(&ev, 0, sizeof(ev));
+	ev.type = UHID_DESTROY;
+
+	if (write(fd, &ev, sizeof(ev)) < 0)
+		error("Failed to destroy uHID device: %s (%d)",
+						strerror(errno), errno);
+
+	close(fd);
+}
+
+static void hid_device_free(struct hid_device *dev)
+{
+	if (dev->ctrl_watch > 0)
+		g_source_remove(dev->ctrl_watch);
+
+	if (dev->intr_watch > 0)
+		g_source_remove(dev->intr_watch);
+
+	if (dev->intr_io)
+		g_io_channel_unref(dev->intr_io);
+
+	if (dev->ctrl_io)
+		g_io_channel_unref(dev->ctrl_io);
+
+	if (dev->uhid_watch_id) {
+		g_source_remove(dev->uhid_watch_id);
+		dev->uhid_watch_id = 0;
+	}
+
+	if (dev->uhid_fd > 0)
+		uhid_destroy(dev->uhid_fd);
+
+	g_free(dev->rd_data);
+
+	devices = g_slist_remove(devices, dev);
+	g_free(dev);
+}
+
+static void handle_uhid_event(struct hid_device *dev, struct uhid_event *ev)
+{
+	DBG("UHID_OUTPUT UHID_FEATURE unsupported");
+}
+
+static gboolean uhid_event_cb(GIOChannel *io, GIOCondition cond,
+							gpointer user_data)
+{
+	struct hid_device *dev = user_data;
+	struct uhid_event ev;
+	ssize_t bread;
+	int fd;
+
+	DBG("");
+
+	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) {
+		DBG("read: %s (%d)", strerror(errno), errno);
+		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.
+		 * We open the channels before creating the device so the
+		 * hardware is always ready. No need to handle these.
+		 * 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. */
+		break;
+	case UHID_OUTPUT:
+	case UHID_FEATURE:
+		handle_uhid_event(dev, &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. */
+		DBG("UHID_OUTPUT_EV unsupported");
+		break;
+	default:
+		warn("unexpected uHID event");
+	}
+
+	return TRUE;
+
+failed:
+	dev->uhid_watch_id = 0;
+	return FALSE;
+}
+
+static gboolean intr_io_watch_cb(GIOChannel *chan, gpointer data)
+{
+	struct hid_device *dev = data;
+	uint8_t buf[UHID_DATA_MAX];
+	struct uhid_event ev;
+	int fd, bread;
+
+	/* Wait uHID if not ready */
+	if (dev->uhid_fd < 0)
+		return TRUE;
+
+	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;
+	}
+
+	/* Discard non-data packets */
+	if (bread == 0 || buf[0] != (HID_MSG_DATA | HID_DATA_TYPE_INPUT))
+		return TRUE;
+
+	/* send data to uHID device skipping HIDP header byte */
+	memset(&ev, 0, sizeof(ev));
+	ev.type = UHID_INPUT;
+	ev.u.input.size = bread - 1;
+	memcpy(ev.u.input.data, &buf[1], ev.u.input.size);
+
+	if (write(dev->uhid_fd, &ev, sizeof(ev)) < 0)
+		DBG("write: %s (%d)", strerror(errno), errno);
+
+	return TRUE;
+}
+
+static void bt_hid_notify_state(struct hid_device *dev, uint8_t state)
+{
+	struct hal_ev_hidhost_conn_state ev;
+	char address[18];
+
+	if (dev->state == state)
+		return;
+
+	dev->state = state;
+
+	ba2str(&dev->dst, address);
+	DBG("device %s state %u", address, state);
+
+	bdaddr2android(&dev->dst, ev.bdaddr);
+	ev.state = state;
+
+	ipc_send(notification_sk, HAL_SERVICE_ID_HIDHOST,
+			HAL_EV_HIDHOST_CONN_STATE, sizeof(ev), &ev, -1);
+}
+
+static gboolean intr_watch_cb(GIOChannel *chan, GIOCondition cond,
+								gpointer data)
+{
+	struct hid_device *dev = data;
+
+	if (cond & G_IO_IN)
+		return intr_io_watch_cb(chan, data);
+
+	/* 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)) && dev->ctrl_watch)
+		g_io_channel_shutdown(chan, TRUE, NULL);
+
+	dev->intr_watch = 0;
+
+	if (dev->intr_io) {
+		g_io_channel_unref(dev->intr_io);
+		dev->intr_io = NULL;
+	}
+
+	/* Close control channel */
+	if (dev->ctrl_io && !(cond & G_IO_NVAL))
+		g_io_channel_shutdown(dev->ctrl_io, TRUE, NULL);
+
+	return FALSE;
+}
+
+static void bt_hid_notify_proto_mode(struct hid_device *dev, uint8_t *buf,
+									int len)
+{
+	struct hal_ev_hidhost_proto_mode ev;
+	char address[18];
+
+	ba2str(&dev->dst, address);
+	DBG("device %s", address);
+
+	memset(&ev, 0, sizeof(ev));
+	bdaddr2android(&dev->dst, ev.bdaddr);
+
+	if (buf[0] == HID_MSG_DATA) {
+		ev.status = HAL_HIDHOST_STATUS_OK;
+		if (buf[1] == HID_PROTO_REPORT)
+			ev.mode = HAL_HIDHOST_REPORT_PROTOCOL;
+		else if (buf[1] == HID_PROTO_BOOT)
+			ev.mode = HAL_HIDHOST_BOOT_PROTOCOL;
+		else
+			ev.mode = HAL_HIDHOST_UNSUPPORTED_PROTOCOL;
+
+	} else {
+		ev.status = buf[0];
+		ev.mode = HAL_HIDHOST_UNSUPPORTED_PROTOCOL;
+	}
+
+	ipc_send(notification_sk, HAL_SERVICE_ID_HIDHOST,
+			HAL_EV_HIDHOST_PROTO_MODE, sizeof(ev), &ev, -1);
+}
+
+static void bt_hid_notify_get_report(struct hid_device *dev, uint8_t *buf,
+									int len)
+{
+	struct hal_ev_hidhost_get_report *ev;
+	int ev_len;
+	char address[18];
+
+	ba2str(&dev->dst, address);
+	DBG("device %s", address);
+
+	ev_len = sizeof(*ev) + sizeof(struct hal_ev_hidhost_get_report) + 1;
+
+	if (!((buf[0] == (HID_MSG_DATA | HID_DATA_TYPE_INPUT)) ||
+			(buf[0] == (HID_MSG_DATA | HID_DATA_TYPE_OUTPUT)) ||
+			(buf[0]	== (HID_MSG_DATA | HID_DATA_TYPE_FEATURE)))) {
+		ev = g_malloc0(ev_len);
+		ev->status = buf[0];
+		bdaddr2android(&dev->dst, ev->bdaddr);
+		goto send;
+	}
+
+	/* Report porotocol mode reply contains id after hdr, in boot
+	 * protocol mode id doesn't exist */
+	ev_len += (dev->boot_dev) ? (len - 1) : (len - 2);
+	ev = g_malloc0(ev_len);
+	ev->status = HAL_HIDHOST_STATUS_OK;
+	bdaddr2android(&dev->dst, ev->bdaddr);
+
+	/* Report porotocol mode reply contains id after hdr, in boot
+	 * protocol mode id doesn't exist */
+	if (dev->boot_dev) {
+		ev->len = len - 1;
+		memcpy(ev->data, buf + 1, ev->len);
+	} else {
+		ev->len = len - 2;
+		memcpy(ev->data, buf + 2, ev->len);
+	}
+
+send:
+	ipc_send(notification_sk, HAL_SERVICE_ID_HIDHOST,
+				HAL_EV_HIDHOST_GET_REPORT, ev_len, ev, -1);
+	g_free(ev);
+}
+
+static gboolean ctrl_io_watch_cb(GIOChannel *chan, gpointer data)
+{
+	struct hid_device *dev = data;
+	int fd, bread;
+	uint8_t buf[UHID_DATA_MAX];
+
+	DBG("");
+
+	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;
+	}
+
+	switch (dev->last_hid_msg) {
+	case HID_MSG_GET_PROTOCOL:
+	case HID_MSG_SET_PROTOCOL:
+		bt_hid_notify_proto_mode(dev, buf, bread);
+		break;
+	case HID_MSG_GET_REPORT:
+		bt_hid_notify_get_report(dev, buf, bread);
+		break;
+	}
+
+	/* reset msg type request */
+	dev->last_hid_msg = 0;
+
+	return TRUE;
+}
+
+static gboolean ctrl_watch_cb(GIOChannel *chan, GIOCondition cond,
+								gpointer data)
+{
+	struct hid_device *dev = data;
+	char address[18];
+
+	if (cond & G_IO_IN)
+		return ctrl_io_watch_cb(chan, data);
+
+	ba2str(&dev->dst, address);
+	bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED);
+
+	/* 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)) && dev->intr_watch)
+		g_io_channel_shutdown(chan, TRUE, NULL);
+
+	if (dev->intr_io && !(cond & G_IO_NVAL))
+		g_io_channel_shutdown(dev->intr_io, TRUE, NULL);
+
+	hid_device_free(dev);
+
+	return FALSE;
+}
+
+static void bt_hid_set_info(struct hid_device *dev)
+{
+	struct hal_ev_hidhost_info ev;
+
+	DBG("");
+
+	bdaddr2android(&dev->dst, ev.bdaddr);
+	ev.attr = 0; /* TODO: Check what is this field */
+	ev.subclass = dev->subclass;
+	ev.app_id = 0; /* TODO: Check what is this field */
+	ev.vendor = dev->vendor;
+	ev.product = dev->product;
+	ev.version = dev->version;
+	ev.country = dev->country;
+	ev.descr_len = dev->rd_size;
+	memset(ev.descr, 0, sizeof(ev.descr));
+	memcpy(ev.descr, dev->rd_data, ev.descr_len);
+
+	ipc_send(notification_sk, HAL_SERVICE_ID_HIDHOST, HAL_EV_HIDHOST_INFO,
+							sizeof(ev), &ev, -1);
+}
+
+static int uhid_create(struct hid_device *dev)
+{
+	GIOCondition cond = G_IO_IN | G_IO_ERR | G_IO_NVAL;
+	GIOChannel *io;
+	struct uhid_event ev;
+
+	dev->uhid_fd = open(UHID_DEVICE_FILE, O_RDWR | O_CLOEXEC);
+	if (dev->uhid_fd < 0) {
+		error("Failed to open uHID device: %s", strerror(errno));
+		bt_hid_notify_state(dev, HAL_HIDHOST_STATE_NO_HID);
+		return -errno;
+	}
+
+	memset(&ev, 0, sizeof(ev));
+	ev.type = UHID_CREATE;
+	strcpy((char *) ev.u.create.name, "bluez-input-device");
+	ev.u.create.bus = BUS_BLUETOOTH;
+	ev.u.create.vendor = dev->vendor;
+	ev.u.create.product = dev->product;
+	ev.u.create.version = dev->version;
+	ev.u.create.country = dev->country;
+	ev.u.create.rd_size = dev->rd_size;
+	ev.u.create.rd_data = dev->rd_data;
+
+	if (write(dev->uhid_fd, &ev, sizeof(ev)) < 0) {
+		error("Failed to create uHID device: %s", strerror(errno));
+		close(dev->uhid_fd);
+		dev->uhid_fd = -1;
+		return -errno;
+	}
+
+	io = g_io_channel_unix_new(dev->uhid_fd);
+	g_io_channel_set_encoding(io, NULL, NULL);
+	dev->uhid_watch_id = g_io_add_watch(io, cond, uhid_event_cb, dev);
+	g_io_channel_unref(io);
+
+	bt_hid_set_info(dev);
+
+	return 0;
+}
+
+static void interrupt_connect_cb(GIOChannel *chan, GError *conn_err,
+							gpointer user_data)
+{
+	struct hid_device *dev = user_data;
+
+	DBG("");
+
+	if (conn_err)
+		goto failed;
+
+	if (uhid_create(dev) < 0)
+		goto failed;
+
+	dev->intr_watch = g_io_add_watch(dev->intr_io,
+				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+				intr_watch_cb, dev);
+
+	bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTED);
+
+	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(dev->intr_io, FALSE, NULL);
+
+	g_io_channel_unref(dev->intr_io);
+	dev->intr_io = NULL;
+
+	if (dev->ctrl_io) {
+		g_io_channel_unref(dev->ctrl_io);
+		dev->ctrl_io = NULL;
+	}
+}
+
+static void control_connect_cb(GIOChannel *chan, GError *conn_err,
+							gpointer user_data)
+{
+	struct hid_device *dev = user_data;
+	GError *err = NULL;
+	const bdaddr_t *src = bt_adapter_get_address();
+
+	DBG("");
+
+	if (conn_err) {
+		bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED);
+		error("%s", conn_err->message);
+		goto failed;
+	}
+
+	/* Connect to the HID interrupt channel */
+	dev->intr_io = bt_io_connect(interrupt_connect_cb, dev, NULL, &err,
+					BT_IO_OPT_SOURCE_BDADDR, src,
+					BT_IO_OPT_DEST_BDADDR, &dev->dst,
+					BT_IO_OPT_PSM, L2CAP_PSM_HIDP_INTR,
+					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+					BT_IO_OPT_INVALID);
+	if (!dev->intr_io) {
+		error("%s", err->message);
+		g_error_free(err);
+		goto failed;
+	}
+
+	dev->ctrl_watch = g_io_add_watch(dev->ctrl_io,
+				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+				ctrl_watch_cb, dev);
+
+	return;
+
+failed:
+	hid_device_free(dev);
+}
+
+static void hid_sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
+{
+	struct hid_device *dev = data;
+	sdp_list_t *list;
+	GError *gerr = NULL;
+	const bdaddr_t *src = bt_adapter_get_address();
+
+	DBG("");
+
+	if (err < 0) {
+		error("Unable to get SDP record: %s", strerror(-err));
+		goto fail;
+	}
+
+	if (!recs || !recs->data) {
+		error("No SDP records found");
+		goto fail;
+	}
+
+	for (list = recs; list != NULL; list = list->next) {
+		sdp_record_t *rec = list->data;
+		sdp_data_t *data;
+
+		data = sdp_data_get(rec, SDP_ATTR_VENDOR_ID);
+		if (data)
+			dev->vendor = data->val.uint16;
+
+		data = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID);
+		if (data)
+			dev->product = data->val.uint16;
+
+		data = sdp_data_get(rec, SDP_ATTR_VERSION);
+		if (data)
+			dev->version = data->val.uint16;
+
+		data = sdp_data_get(rec, SDP_ATTR_HID_COUNTRY_CODE);
+		if (data)
+			dev->country = data->val.uint8;
+
+		data = sdp_data_get(rec, SDP_ATTR_HID_DEVICE_SUBCLASS);
+		if (data)
+			dev->subclass = data->val.uint8;
+
+		data = sdp_data_get(rec, SDP_ATTR_HID_BOOT_DEVICE);
+		if (data)
+			dev->boot_dev = data->val.uint8;
+
+		data = sdp_data_get(rec, SDP_ATTR_HID_DESCRIPTOR_LIST);
+		if (data) {
+			if (!SDP_IS_SEQ(data->dtd))
+				goto fail;
+
+			/* First HIDDescriptor */
+			data = data->val.dataseq;
+			if (!SDP_IS_SEQ(data->dtd))
+				goto fail;
+
+			/* ClassDescriptorType */
+			data = data->val.dataseq;
+			if (data->dtd != SDP_UINT8)
+				goto fail;
+
+			/* ClassDescriptorData */
+			data = data->next;
+			if (!data || !SDP_IS_TEXT_STR(data->dtd))
+				goto fail;
+
+			dev->rd_size = data->unitSize;
+			dev->rd_data = g_memdup(data->val.str, data->unitSize);
+		}
+	}
+
+	if (dev->ctrl_io) {
+		if (uhid_create(dev) < 0)
+			goto fail;
+		return;
+	}
+
+	dev->ctrl_io = bt_io_connect(control_connect_cb, dev, NULL, &gerr,
+					BT_IO_OPT_SOURCE_BDADDR, src,
+					BT_IO_OPT_DEST_BDADDR, &dev->dst,
+					BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL,
+					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+					BT_IO_OPT_INVALID);
+	if (gerr) {
+		error("%s", gerr->message);
+		g_error_free(gerr);
+		goto fail;
+	}
+
+	return;
+
+fail:
+	bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED);
+	hid_device_free(dev);
+}
+
+static uint8_t bt_hid_connect(struct hal_cmd_hidhost_connect *cmd,
+								uint16_t len)
+{
+	struct hid_device *dev;
+	char addr[18];
+	bdaddr_t dst;
+	GSList *l;
+	const bdaddr_t *src = bt_adapter_get_address();
+	uuid_t uuid;
+
+	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;
+
+	dev = g_new0(struct hid_device, 1);
+	bacpy(&dev->dst, &dst);
+	dev->uhid_fd = -1;
+
+	ba2str(&dev->dst, addr);
+	DBG("connecting to %s", addr);
+
+	bt_string2uuid(&uuid, HID_UUID);
+	if (bt_search_service(src, &dev->dst, &uuid, hid_sdp_search_cb, dev,
+								NULL) < 0) {
+		error("Failed to search sdp details");
+		hid_device_free(dev);
+		return HAL_STATUS_FAILED;
+	}
+
+	devices = g_slist_append(devices, dev);
+	bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTING);
+
+	return HAL_STATUS_SUCCESS;
+}
+
+static uint8_t bt_hid_disconnect(struct hal_cmd_hidhost_disconnect *cmd,
+								uint16_t len)
+{
+	struct hid_device *dev;
+	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;
+
+	dev = l->data;
+
+	/* Wait either channels to HUP */
+	if (dev->intr_io)
+		g_io_channel_shutdown(dev->intr_io, TRUE, NULL);
+
+	if (dev->ctrl_io)
+		g_io_channel_shutdown(dev->ctrl_io, TRUE, NULL);
+
+	bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTING);
+
+	return HAL_STATUS_SUCCESS;
+}
+
+static uint8_t bt_hid_virtual_unplug(struct hal_cmd_hidhost_vp *cmd,
+								uint16_t len)
+{
+	DBG("Not Implemented");
+
+	return HAL_STATUS_FAILED;
+}
+
+static uint8_t bt_hid_info(struct hal_cmd_hidhost_set_info *cmd, uint16_t len)
+{
+	DBG("Not Implemented");
+
+	return HAL_STATUS_FAILED;
+}
+
+static uint8_t bt_hid_get_protocol(struct hal_cmd_hidhost_get_protocol *cmd,
+								uint16_t len)
+{
+	struct hid_device *dev;
+	GSList *l;
+	bdaddr_t dst;
+	int fd;
+	uint8_t hdr;
+
+	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;
+
+	dev = l->data;
+
+	if (dev->boot_dev)
+		return HAL_STATUS_UNSUPPORTED;
+
+	hdr = HID_MSG_GET_PROTOCOL | cmd->mode;
+	fd = g_io_channel_unix_get_fd(dev->ctrl_io);
+
+	if (write(fd, &hdr, sizeof(hdr)) < 0) {
+		error("error while querying device protocol");
+		return HAL_STATUS_FAILED;
+	}
+
+	dev->last_hid_msg = HID_MSG_GET_PROTOCOL;
+	return HAL_STATUS_SUCCESS;
+}
+
+static uint8_t bt_hid_set_protocol(struct hal_cmd_hidhost_set_protocol *cmd,
+								uint16_t len)
+{
+	struct hid_device *dev;
+	GSList *l;
+	bdaddr_t dst;
+	int fd;
+	uint8_t hdr;
+
+	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;
+
+	dev = l->data;
+
+	if (dev->boot_dev)
+		return HAL_STATUS_UNSUPPORTED;
+
+	hdr = HID_MSG_SET_PROTOCOL | cmd->mode;
+	fd = g_io_channel_unix_get_fd(dev->ctrl_io);
+
+	if (write(fd, &hdr, sizeof(hdr)) < 0) {
+		error("error while setting device protocol");
+		return HAL_STATUS_FAILED;
+	}
+
+	dev->last_hid_msg = HID_MSG_SET_PROTOCOL;
+	return HAL_STATUS_SUCCESS;
+}
+
+static uint8_t bt_hid_get_report(struct hal_cmd_hidhost_get_report *cmd,
+								uint16_t len)
+{
+	struct hid_device *dev;
+	GSList *l;
+	bdaddr_t dst;
+	int fd;
+	uint8_t *req;
+	uint8_t req_size;
+
+	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;
+
+	dev = l->data;
+	req_size = (cmd->buf_size > 0) ? 4 : 2;
+	req = g_try_malloc0(req_size);
+	if (!req)
+		return HAL_STATUS_NOMEM;
+
+	req[0] = HID_MSG_GET_REPORT | cmd->type;
+	req[1] = cmd->id;
+
+	if (cmd->buf_size > 0) {
+		req[0] = req[0] | HID_GET_REPORT_SIZE_FIELD;
+		bt_put_le16(cmd->buf_size, &req[2]);
+	}
+
+	fd = g_io_channel_unix_get_fd(dev->ctrl_io);
+
+	if (write(fd, req, req_size) < 0) {
+		error("error while querying device protocol");
+		g_free(req);
+		return HAL_STATUS_FAILED;
+	}
+
+	dev->last_hid_msg = HID_MSG_GET_REPORT;
+	g_free(req);
+	return HAL_STATUS_SUCCESS;
+}
+
+static uint8_t bt_hid_set_report(struct hal_cmd_hidhost_set_report *cmd,
+								uint16_t len)
+{
+	struct hid_device *dev;
+	GSList *l;
+	bdaddr_t dst;
+	int fd;
+	uint8_t *req;
+	uint8_t req_size;
+
+	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;
+
+	dev = l->data;
+	req_size = 1 + cmd->len;
+	req = g_try_malloc0(req_size);
+	if (!req)
+		return HAL_STATUS_NOMEM;
+
+	req[0] = HID_MSG_SET_REPORT | cmd->type;
+	memcpy(req + 1, cmd->data, req_size - 1);
+
+	fd = g_io_channel_unix_get_fd(dev->ctrl_io);
+
+	if (write(fd, req, req_size) < 0) {
+		error("error while querying device protocol");
+		g_free(req);
+		return HAL_STATUS_FAILED;
+	}
+
+	dev->last_hid_msg = HID_MSG_SET_REPORT;
+	g_free(req);
+	return HAL_STATUS_SUCCESS;
+}
+
+static uint8_t bt_hid_send_data(struct hal_cmd_hidhost_send_data *cmd,
+								uint16_t len)
+{
+	DBG("Not Implemented");
+
+	return HAL_STATUS_FAILED;
+}
+
+void bt_hid_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
+{
+	uint8_t status = HAL_STATUS_FAILED;
+
+	switch (opcode) {
+	case HAL_OP_HIDHOST_CONNECT:
+		status = bt_hid_connect(buf, len);
+		break;
+	case HAL_OP_HIDHOST_DISCONNECT:
+		status = bt_hid_disconnect(buf, len);
+		break;
+	case HAL_OP_HIDHOST_VP:
+		status = bt_hid_virtual_unplug(buf, len);
+		break;
+	case HAL_OP_HIDHOST_SET_INFO:
+		status = bt_hid_info(buf, len);
+		break;
+	case HAL_OP_HIDHOST_GET_PROTOCOL:
+		status = bt_hid_get_protocol(buf, len);
+		break;
+	case HAL_OP_HIDHOST_SET_PROTOCOL:
+		status = bt_hid_set_protocol(buf, len);
+		break;
+	case HAL_OP_HIDHOST_GET_REPORT:
+		status = bt_hid_get_report(buf, len);
+		break;
+	case HAL_OP_HIDHOST_SET_REPORT:
+		status = bt_hid_set_report(buf, len);
+		break;
+	case HAL_OP_HIDHOST_SEND_DATA:
+		status = bt_hid_send_data(buf, len);
+		break;
+	default:
+		DBG("Unhandled command, opcode 0x%x", opcode);
+		break;
+	}
+
+	ipc_send_rsp(sk, HAL_SERVICE_ID_HIDHOST, status);
+}
+
+static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
+{
+	struct hid_device *dev;
+	bdaddr_t src, dst;
+	char address[18];
+	uint16_t psm;
+	GError *gerr = NULL;
+	GSList *l;
+	uuid_t uuid;
+
+	if (err) {
+		error("%s", err->message);
+		return;
+	}
+
+	bt_io_get(chan, &err,
+			BT_IO_OPT_SOURCE_BDADDR, &src,
+			BT_IO_OPT_DEST_BDADDR, &dst,
+			BT_IO_OPT_PSM, &psm,
+			BT_IO_OPT_INVALID);
+	if (err) {
+		error("%s", gerr->message);
+		g_io_channel_shutdown(chan, TRUE, NULL);
+		return;
+	}
+
+	ba2str(&dst, address);
+	DBG("Incoming connection from %s on PSM %d", address, psm);
+
+	switch (psm) {
+	case L2CAP_PSM_HIDP_CTRL:
+		l = g_slist_find_custom(devices, &dst, device_cmp);
+		if (l)
+			return;
+
+		dev = g_new0(struct hid_device, 1);
+		bacpy(&dev->dst, &dst);
+		dev->ctrl_io = g_io_channel_ref(chan);
+		dev->uhid_fd = -1;
+
+		bt_string2uuid(&uuid, HID_UUID);
+		if (bt_search_service(&src, &dev->dst, &uuid,
+					hid_sdp_search_cb, dev, NULL) < 0) {
+			error("failed to search sdp details");
+			hid_device_free(dev);
+			return;
+		}
+
+		devices = g_slist_append(devices, dev);
+
+		dev->ctrl_watch = g_io_add_watch(dev->ctrl_io,
+					G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+					ctrl_watch_cb, dev);
+		bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTING);
+		break;
+
+	case L2CAP_PSM_HIDP_INTR:
+		l = g_slist_find_custom(devices, &dst, device_cmp);
+		if (!l)
+			return;
+
+		dev = l->data;
+		dev->intr_io = g_io_channel_ref(chan);
+		dev->intr_watch = g_io_add_watch(dev->intr_io,
+				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+				intr_watch_cb, dev);
+		bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTED);
+		break;
+	}
+}
+
+bool bt_hid_register(int sk, const bdaddr_t *addr)
+{
+	GError *err = NULL;
+	const bdaddr_t *src = bt_adapter_get_address();
+
+	DBG("");
+
+	ctrl_io = bt_io_listen(connect_cb, NULL, NULL, NULL, &err,
+				BT_IO_OPT_SOURCE_BDADDR, src,
+				BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL,
+				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+				BT_IO_OPT_INVALID);
+	if (!ctrl_io) {
+		error("Failed to listen on ctrl channel: %s", err->message);
+		g_error_free(err);
+		return false;
+	}
+
+	intr_io = bt_io_listen(connect_cb, NULL, NULL, NULL, &err,
+				BT_IO_OPT_SOURCE_BDADDR, src,
+				BT_IO_OPT_PSM, L2CAP_PSM_HIDP_INTR,
+				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+				BT_IO_OPT_INVALID);
+	if (!intr_io) {
+		error("Failed to listen on intr channel: %s", err->message);
+		g_io_channel_unref(ctrl_io);
+		g_error_free(err);
+		return false;
+	}
+
+	notification_sk = sk;
+
+	return true;
+}
+
+void bt_hid_unregister(void)
+{
+	DBG("");
+
+	notification_sk = -1;
+
+	if (ctrl_io) {
+		g_io_channel_shutdown(ctrl_io, TRUE, NULL);
+		g_io_channel_unref(ctrl_io);
+		ctrl_io = NULL;
+	}
+
+	if (intr_io) {
+		g_io_channel_shutdown(intr_io, TRUE, NULL);
+		g_io_channel_unref(intr_io);
+		intr_io = NULL;
+	}
+}
diff --git a/android/hidhost.h b/android/hidhost.h
new file mode 100644
index 0000000..688086a
--- /dev/null
+++ b/android/hidhost.h
@@ -0,0 +1,27 @@
+/*
+ *
+ *  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
+ *
+ */
+
+void bt_hid_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len);
+
+bool bt_hid_register(int sk, const bdaddr_t *addr);
+void bt_hid_unregister(void);
diff --git a/android/main.c b/android/main.c
index 71fc60b..057c2f7 100644
--- a/android/main.c
+++ b/android/main.c
@@ -50,7 +50,7 @@
 
 #include "adapter.h"
 #include "socket.h"
-#include "hid.h"
+#include "hidhost.h"
 #include "hal-msg.h"
 #include "ipc.h"
 #include "a2dp.h"
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH 1/3] android: Rename hidhost HAL related IPC API to match service name
From: Szymon Janc @ 2013-11-07 16:17 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

Use 'Android HAL name' string from IPC doc as base for names.
---
 android/hal-hidhost.c | 72 +++++++++++++++++++++---------------------
 android/hal-msg.h     | 80 +++++++++++++++++++++++------------------------
 android/hid.c         | 86 ++++++++++++++++++++++++++-------------------------
 3 files changed, 120 insertions(+), 118 deletions(-)

diff --git a/android/hal-hidhost.c b/android/hal-hidhost.c
index f1a2223..ed730cf 100644
--- a/android/hal-hidhost.c
+++ b/android/hal-hidhost.c
@@ -33,7 +33,7 @@ static bool interface_ready(void)
 
 static void handle_conn_state(void *buf)
 {
-	struct hal_ev_hid_conn_state *ev = buf;
+	struct hal_ev_hidhost_conn_state *ev = buf;
 
 	if (bt_hh_cbacks->connection_state_cb)
 		bt_hh_cbacks->connection_state_cb((bt_bdaddr_t *) ev->bdaddr,
@@ -42,7 +42,7 @@ static void handle_conn_state(void *buf)
 
 static void handle_info(void *buf)
 {
-	struct hal_ev_hid_info *ev = buf;
+	struct hal_ev_hidhost_info *ev = buf;
 	bthh_hid_info_t info;
 
 	info.attr_mask = ev->attr;
@@ -61,7 +61,7 @@ static void handle_info(void *buf)
 
 static void handle_proto_mode(void *buf)
 {
-	struct hal_ev_hid_proto_mode *ev = buf;
+	struct hal_ev_hidhost_proto_mode *ev = buf;
 
 	if (bt_hh_cbacks->protocol_mode_cb)
 		bt_hh_cbacks->protocol_mode_cb((bt_bdaddr_t *) ev->bdaddr,
@@ -70,7 +70,7 @@ static void handle_proto_mode(void *buf)
 
 static void handle_get_report(void *buf)
 {
-	struct hal_ev_hid_get_report *ev = buf;
+	struct hal_ev_hidhost_get_report *ev = buf;
 
 	if (bt_hh_cbacks->get_report_cb)
 		bt_hh_cbacks->get_report_cb((bt_bdaddr_t *) ev->bdaddr,
@@ -84,16 +84,16 @@ void bt_notify_hh(uint16_t opcode, void *buf, uint16_t len)
 		return;
 
 	switch (opcode) {
-	case HAL_EV_HID_CONN_STATE:
+	case HAL_EV_HIDHOST_CONN_STATE:
 		handle_conn_state(buf);
 		break;
-	case HAL_EV_HID_INFO:
+	case HAL_EV_HIDHOST_INFO:
 		handle_info(buf);
 		break;
-	case HAL_EV_HID_PROTO_MODE:
+	case HAL_EV_HIDHOST_PROTO_MODE:
 		handle_proto_mode(buf);
 		break;
-	case HAL_EV_HID_GET_REPORT:
+	case HAL_EV_HIDHOST_GET_REPORT:
 		handle_get_report(buf);
 		break;
 	default:
@@ -104,7 +104,7 @@ void bt_notify_hh(uint16_t opcode, void *buf, uint16_t len)
 
 static bt_status_t hh_connect(bt_bdaddr_t *bd_addr)
 {
-	struct hal_cmd_hid_connect cmd;
+	struct hal_cmd_hidhost_connect cmd;
 
 	DBG("");
 
@@ -116,13 +116,13 @@ static bt_status_t hh_connect(bt_bdaddr_t *bd_addr)
 
 	memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
 
-	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HID_CONNECT,
+	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_CONNECT,
 					sizeof(cmd), &cmd, 0, NULL, NULL);
 }
 
 static bt_status_t hh_disconnect(bt_bdaddr_t *bd_addr)
 {
-	struct hal_cmd_hid_disconnect cmd;
+	struct hal_cmd_hidhost_disconnect cmd;
 
 	DBG("");
 
@@ -134,13 +134,13 @@ static bt_status_t hh_disconnect(bt_bdaddr_t *bd_addr)
 
 	memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
 
-	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HID_DISCONNECT,
+	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_DISCONNECT,
 					sizeof(cmd), &cmd, 0, NULL, NULL);
 }
 
 static bt_status_t hh_virtual_unplug(bt_bdaddr_t *bd_addr)
 {
-	struct hal_cmd_hid_vp cmd;
+	struct hal_cmd_hidhost_vp cmd;
 
 	DBG("");
 
@@ -152,13 +152,13 @@ static bt_status_t hh_virtual_unplug(bt_bdaddr_t *bd_addr)
 
 	memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
 
-	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HID_VP,
+	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_VP,
 					sizeof(cmd), &cmd, 0, NULL, NULL);
 }
 
 static bt_status_t hh_set_info(bt_bdaddr_t *bd_addr, bthh_hid_info_t hid_info)
 {
-	struct hal_cmd_hid_set_info cmd;
+	struct hal_cmd_hidhost_set_info cmd;
 
 	DBG("");
 
@@ -178,14 +178,14 @@ static bt_status_t hh_set_info(bt_bdaddr_t *bd_addr, bthh_hid_info_t hid_info)
 	cmd.descr_len = hid_info.dl_len;
 	memcpy(cmd.descr, hid_info.dsc_list, cmd.descr_len);
 
-	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HID_SET_INFO,
+	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SET_INFO,
 					sizeof(cmd), &cmd, 0, NULL, NULL);
 }
 
 static bt_status_t hh_get_protocol(bt_bdaddr_t *bd_addr,
 					bthh_protocol_mode_t protocol_mode)
 {
-	struct hal_cmd_hid_get_protocol cmd;
+	struct hal_cmd_hidhost_get_protocol cmd;
 
 	DBG("");
 
@@ -199,24 +199,24 @@ static bt_status_t hh_get_protocol(bt_bdaddr_t *bd_addr,
 
 	switch (protocol_mode) {
 	case BTHH_REPORT_MODE:
-		cmd.mode = HAL_HID_REPORT_PROTOCOL;
+		cmd.mode = HAL_HIDHOST_REPORT_PROTOCOL;
 		break;
 	case BTHH_BOOT_MODE:
-		cmd.mode = HAL_HID_BOOT_PROTOCOL;
+		cmd.mode = HAL_HIDHOST_BOOT_PROTOCOL;
 		break;
 	default:
 		return BT_STATUS_PARM_INVALID;
 	}
 
 	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST,
-				HAL_OP_HID_GET_PROTOCOL,
+				HAL_OP_HIDHOST_GET_PROTOCOL,
 				sizeof(cmd), &cmd, 0, NULL, NULL);
 }
 
 static bt_status_t hh_set_protocol(bt_bdaddr_t *bd_addr,
 					bthh_protocol_mode_t protocol_mode)
 {
-	struct hal_cmd_hid_set_protocol cmd;
+	struct hal_cmd_hidhost_set_protocol cmd;
 
 	DBG("");
 
@@ -230,17 +230,17 @@ static bt_status_t hh_set_protocol(bt_bdaddr_t *bd_addr,
 
 	switch (protocol_mode) {
 	case BTHH_REPORT_MODE:
-		cmd.mode = HAL_HID_REPORT_PROTOCOL;
+		cmd.mode = HAL_HIDHOST_REPORT_PROTOCOL;
 		break;
 	case BTHH_BOOT_MODE:
-		cmd.mode = HAL_HID_BOOT_PROTOCOL;
+		cmd.mode = HAL_HIDHOST_BOOT_PROTOCOL;
 		break;
 	default:
 		return BT_STATUS_PARM_INVALID;
 	}
 
 	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST,
-				HAL_OP_HID_SET_PROTOCOL,
+				HAL_OP_HIDHOST_SET_PROTOCOL,
 				sizeof(cmd), &cmd, 0, NULL, NULL);
 }
 
@@ -249,7 +249,7 @@ static bt_status_t hh_get_report(bt_bdaddr_t *bd_addr,
 						uint8_t report_id,
 						int buffer_size)
 {
-	struct hal_cmd_hid_get_report cmd;
+	struct hal_cmd_hidhost_get_report cmd;
 
 	DBG("");
 
@@ -265,19 +265,19 @@ static bt_status_t hh_get_report(bt_bdaddr_t *bd_addr,
 
 	switch (report_type) {
 	case BTHH_INPUT_REPORT:
-		cmd.type = HAL_HID_INPUT_REPORT;
+		cmd.type = HAL_HIDHOST_INPUT_REPORT;
 		break;
 	case BTHH_OUTPUT_REPORT:
-		cmd.type = HAL_HID_OUTPUT_REPORT;
+		cmd.type = HAL_HIDHOST_OUTPUT_REPORT;
 		break;
 	case BTHH_FEATURE_REPORT:
-		cmd.type = HAL_HID_FEATURE_REPORT;
+		cmd.type = HAL_HIDHOST_FEATURE_REPORT;
 		break;
 	default:
 		return BT_STATUS_PARM_INVALID;
 	}
 
-	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HID_GET_REPORT,
+	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_GET_REPORT,
 			sizeof(cmd), &cmd, 0, NULL, NULL);
 }
 
@@ -285,7 +285,7 @@ static bt_status_t hh_set_report(bt_bdaddr_t *bd_addr,
 						bthh_report_type_t report_type,
 						char *report)
 {
-	struct hal_cmd_hid_set_report cmd;
+	struct hal_cmd_hidhost_set_report cmd;
 
 	DBG("");
 
@@ -301,25 +301,25 @@ static bt_status_t hh_set_report(bt_bdaddr_t *bd_addr,
 
 	switch (report_type) {
 	case BTHH_INPUT_REPORT:
-		cmd.type = HAL_HID_INPUT_REPORT;
+		cmd.type = HAL_HIDHOST_INPUT_REPORT;
 		break;
 	case BTHH_OUTPUT_REPORT:
-		cmd.type = HAL_HID_OUTPUT_REPORT;
+		cmd.type = HAL_HIDHOST_OUTPUT_REPORT;
 		break;
 	case BTHH_FEATURE_REPORT:
-		cmd.type = HAL_HID_FEATURE_REPORT;
+		cmd.type = HAL_HIDHOST_FEATURE_REPORT;
 		break;
 	default:
 		return BT_STATUS_PARM_INVALID;
 	}
 
-	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HID_SET_REPORT,
+	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SET_REPORT,
 				sizeof(cmd), &cmd, 0, NULL, NULL);
 }
 
 static bt_status_t hh_send_data(bt_bdaddr_t *bd_addr, char *data)
 {
-	struct hal_cmd_hid_send_data cmd;
+	struct hal_cmd_hidhost_send_data cmd;
 
 	DBG("");
 
@@ -331,7 +331,7 @@ static bt_status_t hh_send_data(bt_bdaddr_t *bd_addr, char *data)
 
 	memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
 
-	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HID_SEND_DATA,
+	return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SEND_DATA,
 					sizeof(cmd), &cmd, 0, NULL, NULL);
 }
 
diff --git a/android/hal-msg.h b/android/hal-msg.h
index e1feb19..7045c8c 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -232,23 +232,23 @@ struct hal_cmd_sock_connect {
 	uint8_t  flags;
 } __attribute__((packed));
 
-#define HAL_OP_HID_CONNECT		0x01
-struct hal_cmd_hid_connect {
+#define HAL_OP_HIDHOST_CONNECT		0x01
+struct hal_cmd_hidhost_connect {
 	uint8_t bdaddr[6];
 } __attribute__((packed));
 
-#define HAL_OP_HID_DISCONNECT		0x02
-struct hal_cmd_hid_disconnect {
+#define HAL_OP_HIDHOST_DISCONNECT		0x02
+struct hal_cmd_hidhost_disconnect {
 	uint8_t bdaddr[6];
 } __attribute__((packed));
 
-#define HAL_OP_HID_VP			0x03
-struct hal_cmd_hid_vp {
+#define HAL_OP_HIDHOST_VP			0x03
+struct hal_cmd_hidhost_vp {
 	uint8_t bdaddr[6];
 } __attribute__((packed));
 
-#define HAL_OP_HID_SET_INFO		0x04
-struct hal_cmd_hid_set_info {
+#define HAL_OP_HIDHOST_SET_INFO		0x04
+struct hal_cmd_hidhost_set_info {
 	uint8_t  bdaddr[6];
 	uint8_t  attr;
 	uint8_t  subclass;
@@ -260,44 +260,44 @@ struct hal_cmd_hid_set_info {
 	uint8_t  descr[0];
 } __attribute__((packed));
 
-#define HAL_HID_REPORT_PROTOCOL		0x00
-#define HAL_HID_BOOT_PROTOCOL		0x01
-#define HAL_HID_UNSUPPORTED_PROTOCOL	0xff
+#define HAL_HIDHOST_REPORT_PROTOCOL		0x00
+#define HAL_HIDHOST_BOOT_PROTOCOL		0x01
+#define HAL_HIDHOST_UNSUPPORTED_PROTOCOL	0xff
 
-#define HAL_OP_HID_GET_PROTOCOL	0x05
-struct hal_cmd_hid_get_protocol {
+#define HAL_OP_HIDHOST_GET_PROTOCOL	0x05
+struct hal_cmd_hidhost_get_protocol {
 	uint8_t bdaddr[6];
 	uint8_t mode;
 } __attribute__((packed));
 
-#define HAL_OP_HID_SET_PROTOCOL	0x06
-struct hal_cmd_hid_set_protocol {
+#define HAL_OP_HIDHOST_SET_PROTOCOL	0x06
+struct hal_cmd_hidhost_set_protocol {
 	uint8_t bdaddr[6];
 	uint8_t mode;
 } __attribute__((packed));
 
-#define HAL_HID_INPUT_REPORT		0x01
-#define HAL_HID_OUTPUT_REPORT		0x02
-#define HAL_HID_FEATURE_REPORT		0x03
+#define HAL_HIDHOST_INPUT_REPORT		0x01
+#define HAL_HIDHOST_OUTPUT_REPORT		0x02
+#define HAL_HIDHOST_FEATURE_REPORT		0x03
 
-#define HAL_OP_HID_GET_REPORT		0x07
-struct hal_cmd_hid_get_report {
+#define HAL_OP_HIDHOST_GET_REPORT		0x07
+struct hal_cmd_hidhost_get_report {
 	uint8_t  bdaddr[6];
 	uint8_t  type;
 	uint8_t  id;
 	uint16_t buf_size;
 } __attribute__((packed));
 
-#define HAL_OP_HID_SET_REPORT		0x08
-struct hal_cmd_hid_set_report {
+#define HAL_OP_HIDHOST_SET_REPORT		0x08
+struct hal_cmd_hidhost_set_report {
 	uint8_t  bdaddr[6];
 	uint8_t  type;
 	uint16_t len;
 	uint8_t  data[670];
 } __attribute__((packed));
 
-#define HAL_OP_HID_SEND_DATA		0x09
-struct hal_cmd_hid_send_data {
+#define HAL_OP_HIDHOST_SEND_DATA		0x09
+struct hal_cmd_hidhost_send_data {
 	uint8_t bdaddr[6];
 } __attribute__((packed));
 
@@ -432,24 +432,24 @@ struct hal_ev_le_test_mode {
 	uint16_t num_packets;
 } __attribute__((packed));
 
-#define HAL_HID_STATE_CONNECTED		0x00
-#define HAL_HID_STATE_CONNECTING	0x01
-#define HAL_HID_STATE_DISCONNECTED	0x02
-#define HAL_HID_STATE_DISCONNECTING	0x03
-#define HAL_HID_STATE_NO_HID		0x07
-#define HAL_HID_STATE_FAILED		0x08
-#define HAL_HID_STATE_UNKNOWN		0x09
+#define HAL_HIDHOST_STATE_CONNECTED		0x00
+#define HAL_HIDHOST_STATE_CONNECTING	0x01
+#define HAL_HIDHOST_STATE_DISCONNECTED	0x02
+#define HAL_HIDHOST_STATE_DISCONNECTING	0x03
+#define HAL_HIDHOST_STATE_NO_HID		0x07
+#define HAL_HIDHOST_STATE_FAILED		0x08
+#define HAL_HIDHOST_STATE_UNKNOWN		0x09
 
-#define HAL_EV_HID_CONN_STATE		0x81
-struct hal_ev_hid_conn_state {
+#define HAL_EV_HIDHOST_CONN_STATE		0x81
+struct hal_ev_hidhost_conn_state {
 	uint8_t bdaddr[6];
 	uint8_t state;
 } __attribute__((packed));
 
-#define HAL_HID_STATUS_OK		0x00
+#define HAL_HIDHOST_STATUS_OK		0x00
 
-#define HAL_EV_HID_INFO			0x82
-struct hal_ev_hid_info {
+#define HAL_EV_HIDHOST_INFO			0x82
+struct hal_ev_hidhost_info {
 	uint8_t  bdaddr[6];
 	uint8_t  attr;
 	uint8_t  subclass;
@@ -462,15 +462,15 @@ struct hal_ev_hid_info {
 	uint8_t  descr[884];
 } __attribute__((packed));
 
-#define HAL_EV_HID_PROTO_MODE		0x83
-struct hal_ev_hid_proto_mode {
+#define HAL_EV_HIDHOST_PROTO_MODE		0x83
+struct hal_ev_hidhost_proto_mode {
 	uint8_t bdaddr[6];
 	uint8_t status;
 	uint8_t mode;
 } __attribute__((packed));
 
-#define HAL_EV_HID_GET_REPORT		0x85
-struct hal_ev_hid_get_report {
+#define HAL_EV_HIDHOST_GET_REPORT		0x85
+struct hal_ev_hidhost_get_report {
 	uint8_t  bdaddr[6];
 	uint8_t  status;
 	uint16_t len;
diff --git a/android/hid.c b/android/hid.c
index 93b828c..1089301 100644
--- a/android/hid.c
+++ b/android/hid.c
@@ -255,7 +255,7 @@ static gboolean intr_io_watch_cb(GIOChannel *chan, gpointer data)
 
 static void bt_hid_notify_state(struct hid_device *dev, uint8_t state)
 {
-	struct hal_ev_hid_conn_state ev;
+	struct hal_ev_hidhost_conn_state ev;
 	char address[18];
 
 	if (dev->state == state)
@@ -270,7 +270,7 @@ static void bt_hid_notify_state(struct hid_device *dev, uint8_t state)
 	ev.state = state;
 
 	ipc_send(notification_sk, HAL_SERVICE_ID_HIDHOST,
-				HAL_EV_HID_CONN_STATE, sizeof(ev), &ev, -1);
+			HAL_EV_HIDHOST_CONN_STATE, sizeof(ev), &ev, -1);
 }
 
 static gboolean intr_watch_cb(GIOChannel *chan, GIOCondition cond,
@@ -304,7 +304,7 @@ static gboolean intr_watch_cb(GIOChannel *chan, GIOCondition cond,
 static void bt_hid_notify_proto_mode(struct hid_device *dev, uint8_t *buf,
 									int len)
 {
-	struct hal_ev_hid_proto_mode ev;
+	struct hal_ev_hidhost_proto_mode ev;
 	char address[18];
 
 	ba2str(&dev->dst, address);
@@ -314,34 +314,34 @@ static void bt_hid_notify_proto_mode(struct hid_device *dev, uint8_t *buf,
 	bdaddr2android(&dev->dst, ev.bdaddr);
 
 	if (buf[0] == HID_MSG_DATA) {
-		ev.status = HAL_HID_STATUS_OK;
+		ev.status = HAL_HIDHOST_STATUS_OK;
 		if (buf[1] == HID_PROTO_REPORT)
-			ev.mode = HAL_HID_REPORT_PROTOCOL;
+			ev.mode = HAL_HIDHOST_REPORT_PROTOCOL;
 		else if (buf[1] == HID_PROTO_BOOT)
-			ev.mode = HAL_HID_BOOT_PROTOCOL;
+			ev.mode = HAL_HIDHOST_BOOT_PROTOCOL;
 		else
-			ev.mode = HAL_HID_UNSUPPORTED_PROTOCOL;
+			ev.mode = HAL_HIDHOST_UNSUPPORTED_PROTOCOL;
 
 	} else {
 		ev.status = buf[0];
-		ev.mode = HAL_HID_UNSUPPORTED_PROTOCOL;
+		ev.mode = HAL_HIDHOST_UNSUPPORTED_PROTOCOL;
 	}
 
 	ipc_send(notification_sk, HAL_SERVICE_ID_HIDHOST,
-				HAL_EV_HID_PROTO_MODE, sizeof(ev), &ev, -1);
+			HAL_EV_HIDHOST_PROTO_MODE, sizeof(ev), &ev, -1);
 }
 
 static void bt_hid_notify_get_report(struct hid_device *dev, uint8_t *buf,
 									int len)
 {
-	struct hal_ev_hid_get_report *ev;
+	struct hal_ev_hidhost_get_report *ev;
 	int ev_len;
 	char address[18];
 
 	ba2str(&dev->dst, address);
 	DBG("device %s", address);
 
-	ev_len = sizeof(*ev) + sizeof(struct hal_ev_hid_get_report) + 1;
+	ev_len = sizeof(*ev) + sizeof(struct hal_ev_hidhost_get_report) + 1;
 
 	if (!((buf[0] == (HID_MSG_DATA | HID_DATA_TYPE_INPUT)) ||
 			(buf[0] == (HID_MSG_DATA | HID_DATA_TYPE_OUTPUT)) ||
@@ -356,7 +356,7 @@ static void bt_hid_notify_get_report(struct hid_device *dev, uint8_t *buf,
 	 * protocol mode id doesn't exist */
 	ev_len += (dev->boot_dev) ? (len - 1) : (len - 2);
 	ev = g_malloc0(ev_len);
-	ev->status = HAL_HID_STATUS_OK;
+	ev->status = HAL_HIDHOST_STATUS_OK;
 	bdaddr2android(&dev->dst, ev->bdaddr);
 
 	/* Report porotocol mode reply contains id after hdr, in boot
@@ -371,7 +371,7 @@ static void bt_hid_notify_get_report(struct hid_device *dev, uint8_t *buf,
 
 send:
 	ipc_send(notification_sk, HAL_SERVICE_ID_HIDHOST,
-					HAL_EV_HID_GET_REPORT, ev_len, ev, -1);
+				HAL_EV_HIDHOST_GET_REPORT, ev_len, ev, -1);
 	g_free(ev);
 }
 
@@ -416,7 +416,7 @@ static gboolean ctrl_watch_cb(GIOChannel *chan, GIOCondition cond,
 		return ctrl_io_watch_cb(chan, data);
 
 	ba2str(&dev->dst, address);
-	bt_hid_notify_state(dev, HAL_HID_STATE_DISCONNECTED);
+	bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED);
 
 	/* 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
@@ -434,7 +434,7 @@ static gboolean ctrl_watch_cb(GIOChannel *chan, GIOCondition cond,
 
 static void bt_hid_set_info(struct hid_device *dev)
 {
-	struct hal_ev_hid_info ev;
+	struct hal_ev_hidhost_info ev;
 
 	DBG("");
 
@@ -450,7 +450,7 @@ static void bt_hid_set_info(struct hid_device *dev)
 	memset(ev.descr, 0, sizeof(ev.descr));
 	memcpy(ev.descr, dev->rd_data, ev.descr_len);
 
-	ipc_send(notification_sk, HAL_SERVICE_ID_HIDHOST, HAL_EV_HID_INFO,
+	ipc_send(notification_sk, HAL_SERVICE_ID_HIDHOST, HAL_EV_HIDHOST_INFO,
 							sizeof(ev), &ev, -1);
 }
 
@@ -463,7 +463,7 @@ static int uhid_create(struct hid_device *dev)
 	dev->uhid_fd = open(UHID_DEVICE_FILE, O_RDWR | O_CLOEXEC);
 	if (dev->uhid_fd < 0) {
 		error("Failed to open uHID device: %s", strerror(errno));
-		bt_hid_notify_state(dev, HAL_HID_STATE_NO_HID);
+		bt_hid_notify_state(dev, HAL_HIDHOST_STATE_NO_HID);
 		return -errno;
 	}
 
@@ -512,7 +512,7 @@ static void interrupt_connect_cb(GIOChannel *chan, GError *conn_err,
 				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
 				intr_watch_cb, dev);
 
-	bt_hid_notify_state(dev, HAL_HID_STATE_CONNECTED);
+	bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTED);
 
 	return;
 
@@ -542,7 +542,7 @@ static void control_connect_cb(GIOChannel *chan, GError *conn_err,
 	DBG("");
 
 	if (conn_err) {
-		bt_hid_notify_state(dev, HAL_HID_STATE_DISCONNECTED);
+		bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED);
 		error("%s", conn_err->message);
 		goto failed;
 	}
@@ -663,11 +663,12 @@ static void hid_sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
 	return;
 
 fail:
-	bt_hid_notify_state(dev, HAL_HID_STATE_DISCONNECTED);
+	bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED);
 	hid_device_free(dev);
 }
 
-static uint8_t bt_hid_connect(struct hal_cmd_hid_connect *cmd, uint16_t len)
+static uint8_t bt_hid_connect(struct hal_cmd_hidhost_connect *cmd,
+								uint16_t len)
 {
 	struct hid_device *dev;
 	char addr[18];
@@ -703,12 +704,12 @@ static uint8_t bt_hid_connect(struct hal_cmd_hid_connect *cmd, uint16_t len)
 	}
 
 	devices = g_slist_append(devices, dev);
-	bt_hid_notify_state(dev, HAL_HID_STATE_CONNECTING);
+	bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTING);
 
 	return HAL_STATUS_SUCCESS;
 }
 
-static uint8_t bt_hid_disconnect(struct hal_cmd_hid_disconnect *cmd,
+static uint8_t bt_hid_disconnect(struct hal_cmd_hidhost_disconnect *cmd,
 								uint16_t len)
 {
 	struct hid_device *dev;
@@ -735,26 +736,27 @@ static uint8_t bt_hid_disconnect(struct hal_cmd_hid_disconnect *cmd,
 	if (dev->ctrl_io)
 		g_io_channel_shutdown(dev->ctrl_io, TRUE, NULL);
 
-	bt_hid_notify_state(dev, HAL_HID_STATE_DISCONNECTING);
+	bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTING);
 
 	return HAL_STATUS_SUCCESS;
 }
 
-static uint8_t bt_hid_virtual_unplug(struct hal_cmd_hid_vp *cmd, uint16_t len)
+static uint8_t bt_hid_virtual_unplug(struct hal_cmd_hidhost_vp *cmd,
+								uint16_t len)
 {
 	DBG("Not Implemented");
 
 	return HAL_STATUS_FAILED;
 }
 
-static uint8_t bt_hid_info(struct hal_cmd_hid_set_info *cmd, uint16_t len)
+static uint8_t bt_hid_info(struct hal_cmd_hidhost_set_info *cmd, uint16_t len)
 {
 	DBG("Not Implemented");
 
 	return HAL_STATUS_FAILED;
 }
 
-static uint8_t bt_hid_get_protocol(struct hal_cmd_hid_get_protocol *cmd,
+static uint8_t bt_hid_get_protocol(struct hal_cmd_hidhost_get_protocol *cmd,
 								uint16_t len)
 {
 	struct hid_device *dev;
@@ -791,7 +793,7 @@ static uint8_t bt_hid_get_protocol(struct hal_cmd_hid_get_protocol *cmd,
 	return HAL_STATUS_SUCCESS;
 }
 
-static uint8_t bt_hid_set_protocol(struct hal_cmd_hid_set_protocol *cmd,
+static uint8_t bt_hid_set_protocol(struct hal_cmd_hidhost_set_protocol *cmd,
 								uint16_t len)
 {
 	struct hid_device *dev;
@@ -828,7 +830,7 @@ static uint8_t bt_hid_set_protocol(struct hal_cmd_hid_set_protocol *cmd,
 	return HAL_STATUS_SUCCESS;
 }
 
-static uint8_t bt_hid_get_report(struct hal_cmd_hid_get_report *cmd,
+static uint8_t bt_hid_get_report(struct hal_cmd_hidhost_get_report *cmd,
 								uint16_t len)
 {
 	struct hid_device *dev;
@@ -876,7 +878,7 @@ static uint8_t bt_hid_get_report(struct hal_cmd_hid_get_report *cmd,
 	return HAL_STATUS_SUCCESS;
 }
 
-static uint8_t bt_hid_set_report(struct hal_cmd_hid_set_report *cmd,
+static uint8_t bt_hid_set_report(struct hal_cmd_hidhost_set_report *cmd,
 								uint16_t len)
 {
 	struct hid_device *dev;
@@ -919,7 +921,7 @@ static uint8_t bt_hid_set_report(struct hal_cmd_hid_set_report *cmd,
 	return HAL_STATUS_SUCCESS;
 }
 
-static uint8_t bt_hid_send_data(struct hal_cmd_hid_send_data *cmd,
+static uint8_t bt_hid_send_data(struct hal_cmd_hidhost_send_data *cmd,
 								uint16_t len)
 {
 	DBG("Not Implemented");
@@ -932,31 +934,31 @@ void bt_hid_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
 	uint8_t status = HAL_STATUS_FAILED;
 
 	switch (opcode) {
-	case HAL_OP_HID_CONNECT:
+	case HAL_OP_HIDHOST_CONNECT:
 		status = bt_hid_connect(buf, len);
 		break;
-	case HAL_OP_HID_DISCONNECT:
+	case HAL_OP_HIDHOST_DISCONNECT:
 		status = bt_hid_disconnect(buf, len);
 		break;
-	case HAL_OP_HID_VP:
+	case HAL_OP_HIDHOST_VP:
 		status = bt_hid_virtual_unplug(buf, len);
 		break;
-	case HAL_OP_HID_SET_INFO:
+	case HAL_OP_HIDHOST_SET_INFO:
 		status = bt_hid_info(buf, len);
 		break;
-	case HAL_OP_HID_GET_PROTOCOL:
+	case HAL_OP_HIDHOST_GET_PROTOCOL:
 		status = bt_hid_get_protocol(buf, len);
 		break;
-	case HAL_OP_HID_SET_PROTOCOL:
+	case HAL_OP_HIDHOST_SET_PROTOCOL:
 		status = bt_hid_set_protocol(buf, len);
 		break;
-	case HAL_OP_HID_GET_REPORT:
+	case HAL_OP_HIDHOST_GET_REPORT:
 		status = bt_hid_get_report(buf, len);
 		break;
-	case HAL_OP_HID_SET_REPORT:
+	case HAL_OP_HIDHOST_SET_REPORT:
 		status = bt_hid_set_report(buf, len);
 		break;
-	case HAL_OP_HID_SEND_DATA:
+	case HAL_OP_HIDHOST_SEND_DATA:
 		status = bt_hid_send_data(buf, len);
 		break;
 	default:
@@ -1020,7 +1022,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 		dev->ctrl_watch = g_io_add_watch(dev->ctrl_io,
 					G_IO_HUP | G_IO_ERR | G_IO_NVAL,
 					ctrl_watch_cb, dev);
-		bt_hid_notify_state(dev, HAL_HID_STATE_CONNECTING);
+		bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTING);
 		break;
 
 	case L2CAP_PSM_HIDP_INTR:
@@ -1033,7 +1035,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 		dev->intr_watch = g_io_add_watch(dev->intr_io,
 				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
 				intr_watch_cb, dev);
-		bt_hid_notify_state(dev, HAL_HID_STATE_CONNECTED);
+		bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTED);
 		break;
 	}
 }
-- 
1.8.4.2


^ permalink raw reply related

* Re: [PATCH v2 1/3] android: Rename a2dp HAL related IPC API to match service name
From: Johan Hedberg @ 2013-11-07 15:59 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1383838327-5971-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

On Thu, Nov 07, 2013, Szymon Janc wrote:
> Use 'Android HAL name' string from IPC doc as base for names.
> ---
> v2:
>  - rebased
>  - minor style fixes
> 
>  android/a2dp.c    |  9 +++++----
>  android/hal-av.c  | 16 ++++++++--------
>  android/hal-msg.h | 18 ++++++++++--------
>  3 files changed, 23 insertions(+), 20 deletions(-)

All three patches have been applied. Thanks.

Johan

^ permalink raw reply

* [PATCH v3] android: Add set/get for discovery timeout
From: Lukasz Rymanowski @ 2013-11-07 15:57 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: johan.hedberg, szymon.janc, Lukasz Rymanowski

Android handles discoverable timeout in Settings app, however still
expects BT stack to maintain this value so we should do it as well.
Otherwise we will get some unexpected behaviour.
For now we keep discovery_timeout only during runtime, but we need to move
it to some local storage once we will have it.

Note: That since Android Settings up handles timer there is no reason to
use discovery timer we have in kernel.
---
 android/adapter.c | 38 +++++++++++++++++++++++++++++++++++---
 1 file changed, 35 insertions(+), 3 deletions(-)

diff --git a/android/adapter.c b/android/adapter.c
index 2e8d2df..7daaf5c 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -48,6 +48,9 @@
 
 /* Default to DisplayYesNo */
 #define DEFAULT_IO_CAPABILITY 0x01
+/* Default discoverable timeout 120sec as in Android */
+#define DEFAULT_DISCOVERABLE_TIMEOUT 120
+
 #define BASELEN_PROP_CHANGED sizeof(struct hal_ev_adapter_props_changed) \
 				+ (sizeof(struct hal_property))
 
@@ -70,6 +73,7 @@ struct bt_adapter {
 	uint32_t current_settings;
 
 	bool discovering;
+	uint32_t discoverable_timeout;
 };
 
 struct browse_req {
@@ -1101,6 +1105,17 @@ static uint8_t set_adapter_name(uint8_t *name, uint16_t len)
 	return HAL_STATUS_FAILED;
 }
 
+static uint8_t set_discoverable_timeout(uint8_t *timeout)
+{
+	/* Android handles discoverable timeout in Settings app.
+	 * There is no need to use kernel feature for that.
+	 * Just need to store this value here */
+
+	/* TODO: This should be in some storage */
+	memcpy(&adapter->discoverable_timeout, timeout, sizeof(uint32_t));
+
+	return HAL_STATUS_SUCCESS;
+}
 static void read_info_complete(uint8_t status, uint16_t length, const void *param,
 							void *user_data)
 {
@@ -1169,6 +1184,8 @@ void bt_adapter_init(uint16_t index, struct mgmt *mgmt, bt_adapter_ready cb)
 	adapter->index = index;
 	adapter->discovering = false;
 	adapter->ready = cb;
+	/* TODO: Read it from some storage */
+	adapter->discoverable_timeout = DEFAULT_DISCOVERABLE_TIMEOUT;
 
 	if (mgmt_send(mgmt, MGMT_OP_READ_INFO, index, 0, NULL,
 					read_info_complete, NULL, NULL) > 0)
@@ -1286,11 +1303,25 @@ static bool get_devices(void)
 
 static bool get_discoverable_timeout(void)
 {
-	DBG("Not implemented");
+	struct hal_ev_adapter_props_changed *ev;
+	uint8_t buf[BASELEN_PROP_CHANGED + sizeof(uint32_t)];
 
-	/* TODO: Add implementation */
+	memset(buf, 0, sizeof(buf));
+	ev = (void *) buf;
 
-	return false;
+	ev->num_props = 1;
+	ev->status = HAL_STATUS_SUCCESS;
+
+	ev->props[0].type = HAL_PROP_ADAPTER_DISC_TIMEOUT;
+	ev->props[0].len = sizeof(uint32_t);
+	memcpy(&ev->props[0].val, &adapter->discoverable_timeout,
+						sizeof(uint32_t));
+
+	ipc_send(notification_sk, HAL_SERVICE_ID_BLUETOOTH,
+				HAL_EV_ADAPTER_PROPS_CHANGED,
+					sizeof(buf), ev, -1);
+
+	return true;
 }
 
 static bool get_property(void *buf, uint16_t len)
@@ -1441,6 +1472,7 @@ static uint8_t set_property(void *buf, uint16_t len)
 	case HAL_PROP_ADAPTER_NAME:
 		return set_adapter_name(cmd->val, cmd->len);
 	case HAL_PROP_ADAPTER_DISC_TIMEOUT:
+		return set_discoverable_timeout(cmd->val);
 	default:
 		DBG("Unhandled property type 0x%x", cmd->type);
 		return HAL_STATUS_FAILED;
-- 
1.8.4


^ permalink raw reply related

* Re: [PATCH v2] android: Add set/get for discovery timeout
From: Johan Hedberg @ 2013-11-07 15:36 UTC (permalink / raw)
  To: Lukasz Rymanowski; +Cc: linux-bluetooth, szymon.janc
In-Reply-To: <1383837979-4390-1-git-send-email-lukasz.rymanowski@tieto.com>

Hi Lukasz,

On Thu, Nov 07, 2013, Lukasz Rymanowski wrote:
> @@ -1169,6 +1184,8 @@ void bt_adapter_init(uint16_t index, struct mgmt *mgmt, bt_adapter_ready cb)
>  	adapter->index = index;
>  	adapter->discovering = false;
>  	adapter->ready = cb;
> +	/* TODO: Read it from some storage */
> +	adapter->discoverable_timeout = DEFAULT_DISCOVERABLE_TIMEOUT;
>  
>  	if (mgmt_send(mgmt, MGMT_OP_READ_INFO, index, 0, NULL,
>  					read_info_complete, NULL, NULL) > 0)
> @@ -1286,11 +1303,25 @@ static bool get_devices(void)
>  
>  static bool get_discoverable_timeout(void)
>  {
> -	DBG("Not implemented");
> +	struct hal_ev_adapter_props_changed *ev;
> +	int len = sizeof(uint32_t);
> +	uint8_t buf[BASELEN_PROP_CHANGED + len];
>  
> -	/* TODO: Add implementation */
>  
> -	return false;
> +	memset(buf, 0, sizeof(buf));

Looks like you're leaving two empty lines above? Please remove one.

> +	ev = (void *) buf;
> +
> +	ev->num_props = 1;
> +	ev->status = HAL_STATUS_SUCCESS;
> +
> +	ev->props[0].type = HAL_PROP_ADAPTER_DISC_TIMEOUT;
> +	ev->props[0].len = len;

The len variable seems quite unnecessary to me since you could just use
sizeof(uint32_t) in the two places where you need it.

> +	memcpy(&ev->props[0].val, &adapter->discoverable_timeout, sizeof(uint32_t));
> +
> +	ipc_send(notification_sk, HAL_SERVICE_ID_BLUETOOTH,
> +				HAL_EV_ADAPTER_PROPS_CHANGED, sizeof(buf), ev, -1);

Please pay attention to your line lengths. You've got at least two lines
above that are over 79 characters.

Johan

^ permalink raw reply

* [PATCH v2 3/3] android/hal: Use a2dp instead of av in a2dp HAL
From: Szymon Janc @ 2013-11-07 15:32 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1383838327-5971-1-git-send-email-szymon.janc@tieto.com>

Match functions names to HAL name. Where not needed av prefix is
removed.
---
 android/hal-a2dp.c      | 20 ++++++++++----------
 android/hal-bluetooth.c |  2 +-
 android/hal-ipc.c       |  2 +-
 android/hal.h           |  4 ++--
 4 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/android/hal-a2dp.c b/android/hal-a2dp.c
index 2ebf801..f0c301e 100644
--- a/android/hal-a2dp.c
+++ b/android/hal-a2dp.c
@@ -49,7 +49,7 @@ static void handle_audio_state(void *buf)
 }
 
 /* will be called from notification thread context */
-void bt_notify_av(uint16_t opcode, void *buf, uint16_t len)
+void bt_notify_a2dp(uint16_t opcode, void *buf, uint16_t len)
 {
 	if (!interface_ready())
 		return;
@@ -67,7 +67,7 @@ void bt_notify_av(uint16_t opcode, void *buf, uint16_t len)
 	}
 }
 
-static bt_status_t av_connect(bt_bdaddr_t *bd_addr)
+static bt_status_t a2dp_connect(bt_bdaddr_t *bd_addr)
 {
 	struct hal_cmd_a2dp_connect cmd;
 
@@ -82,7 +82,7 @@ static bt_status_t av_connect(bt_bdaddr_t *bd_addr)
 					sizeof(cmd), &cmd, NULL, NULL, NULL);
 }
 
-static bt_status_t av_disconnect(bt_bdaddr_t *bd_addr)
+static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
 {
 	struct hal_cmd_a2dp_disconnect cmd;
 
@@ -97,7 +97,7 @@ static bt_status_t av_disconnect(bt_bdaddr_t *bd_addr)
 					sizeof(cmd), &cmd, NULL, NULL, NULL);
 }
 
-static bt_status_t av_init(btav_callbacks_t *callbacks)
+static bt_status_t init(btav_callbacks_t *callbacks)
 {
 	DBG("");
 
@@ -108,7 +108,7 @@ static bt_status_t av_init(btav_callbacks_t *callbacks)
 	return BT_STATUS_SUCCESS;
 }
 
-static void av_cleanup()
+static void cleanup()
 {
 	DBG("");
 
@@ -122,13 +122,13 @@ static void av_cleanup()
 
 static btav_interface_t iface = {
 	.size = sizeof(iface),
-	.init = av_init,
-	.connect = av_connect,
-	.disconnect = av_disconnect,
-	.cleanup = av_cleanup
+	.init = init,
+	.connect = a2dp_connect,
+	.disconnect = disconnect,
+	.cleanup = cleanup
 };
 
-btav_interface_t *bt_get_av_interface()
+btav_interface_t *bt_get_a2dp_interface()
 {
 	return &iface;
 }
diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 88c7b99..3e5d41f 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -654,7 +654,7 @@ static const void *get_profile_interface(const char *profile_id)
 		return bt_get_pan_interface();
 
 	if (!strcmp(profile_id, BT_PROFILE_ADVANCED_AUDIO_ID))
-		return bt_get_av_interface();
+		return bt_get_a2dp_interface();
 
 	return NULL;
 }
diff --git a/android/hal-ipc.c b/android/hal-ipc.c
index 14be69b..1d33374 100644
--- a/android/hal-ipc.c
+++ b/android/hal-ipc.c
@@ -53,7 +53,7 @@ static void notification_dispatch(struct hal_hdr *msg, int fd)
 		bt_notify_hh(msg->opcode, msg->payload, msg->len);
 		break;
 	case HAL_SERVICE_ID_A2DP:
-		bt_notify_av(msg->opcode, msg->payload, msg->len);
+		bt_notify_a2dp(msg->opcode, msg->payload, msg->len);
 		break;
 	default:
 		DBG("Unhandled notification service=%d opcode=0x%x",
diff --git a/android/hal.h b/android/hal.h
index 5d6a93e..f47ec2a 100644
--- a/android/hal.h
+++ b/android/hal.h
@@ -24,10 +24,10 @@
 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);
+btav_interface_t *bt_get_a2dp_interface(void);
 
 void bt_notify_adapter(uint16_t opcode, void *buf, uint16_t len);
 void bt_thread_associate(void);
 void bt_thread_disassociate(void);
 void bt_notify_hh(uint16_t opcode, void *buf, uint16_t len);
-void bt_notify_av(uint16_t opcode, void *buf, uint16_t len);
+void bt_notify_a2dp(uint16_t opcode, void *buf, uint16_t len);
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH v2 2/3] android/hal: Rename hal-av.c to hal-a2dp.c
From: Szymon Janc @ 2013-11-07 15:32 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1383838327-5971-1-git-send-email-szymon.janc@tieto.com>

Name of HAL implementation will match Android HAL name. This will make
code navigation easier as daemon part and HAL library implementation
will be in foo.c and hal-foo.c respectively.
---
 android/Android.mk  |   2 +-
 android/Makefile.am |   4 +-
 android/hal-a2dp.c  | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 android/hal-av.c    | 134 ----------------------------------------------------
 4 files changed, 137 insertions(+), 137 deletions(-)
 create mode 100644 android/hal-a2dp.c
 delete mode 100644 android/hal-av.c

diff --git a/android/Android.mk b/android/Android.mk
index d76dfaf..f9bf070 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -86,7 +86,7 @@ LOCAL_SRC_FILES := \
 	hal-sock.c \
 	hal-hidhost.c \
 	hal-pan.c \
-	hal-av.c \
+	hal-a2dp.c \
 	client/textconv.c \
 
 LOCAL_C_INCLUDES += \
diff --git a/android/Makefile.am b/android/Makefile.am
index 8619641..6790f24 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -33,7 +33,7 @@ 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/hal-a2dp.c \
 					android/hardware/bluetooth.h \
 					android/hardware/bt_av.h \
 					android/hardware/bt_gatt.h \
@@ -86,7 +86,7 @@ EXTRA_DIST += android/hal-bluetooth.c \
 		android/hal-sock.c \
 		android/hal-hidhost.c \
 		android/hal-pan.c \
-		android/hal-av.c \
+		android/hal-a2dp.c \
 		android/hal-log.h
 
 EXTRA_DIST += android/client/terminal.c \
diff --git a/android/hal-a2dp.c b/android/hal-a2dp.c
new file mode 100644
index 0000000..2ebf801
--- /dev/null
+++ b/android/hal-a2dp.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "hal-log.h"
+#include "hal.h"
+#include "hal-msg.h"
+#include "hal-ipc.h"
+
+static const btav_callbacks_t *cbs = NULL;
+
+static bool interface_ready(void)
+{
+	return cbs != NULL;
+}
+
+static void handle_connection_state(void *buf)
+{
+	struct hal_ev_a2dp_connection_state *ev = buf;
+
+	if (cbs->connection_state_cb)
+		cbs->connection_state_cb(ev->state,
+						(bt_bdaddr_t *) (ev->bdaddr));
+}
+
+static void handle_audio_state(void *buf)
+{
+	struct hal_ev_a2dp_audio_state *ev = buf;
+
+	if (cbs->audio_state_cb)
+		cbs->audio_state_cb(ev->state, (bt_bdaddr_t *)(ev->bdaddr));
+}
+
+/* will be called from notification thread context */
+void bt_notify_av(uint16_t opcode, void *buf, uint16_t len)
+{
+	if (!interface_ready())
+		return;
+
+	switch (opcode) {
+	case HAL_EV_A2DP_CONNECTION_STATE:
+		handle_connection_state(buf);
+		break;
+	case HAL_EV_A2DP_AUDIO_STATE:
+		handle_audio_state(buf);
+		break;
+	default:
+		DBG("Unhandled callback opcode=0x%x", opcode);
+		break;
+	}
+}
+
+static bt_status_t av_connect(bt_bdaddr_t *bd_addr)
+{
+	struct hal_cmd_a2dp_connect cmd;
+
+	DBG("");
+
+	if (!interface_ready())
+		return BT_STATUS_NOT_READY;
+
+	memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
+
+	return hal_ipc_cmd(HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_CONNECT,
+					sizeof(cmd), &cmd, NULL, NULL, NULL);
+}
+
+static bt_status_t av_disconnect(bt_bdaddr_t *bd_addr)
+{
+	struct hal_cmd_a2dp_disconnect cmd;
+
+	DBG("");
+
+	if (!interface_ready())
+		return BT_STATUS_NOT_READY;
+
+	memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
+
+	return hal_ipc_cmd(HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_DISCONNECT,
+					sizeof(cmd), &cmd, NULL, NULL, NULL);
+}
+
+static bt_status_t av_init(btav_callbacks_t *callbacks)
+{
+	DBG("");
+
+	cbs = callbacks;
+
+	/* TODO: enable service */
+
+	return BT_STATUS_SUCCESS;
+}
+
+static void av_cleanup()
+{
+	DBG("");
+
+	if (!interface_ready())
+		return;
+
+	/* TODO: disable service */
+
+	cbs = NULL;
+}
+
+static btav_interface_t iface = {
+	.size = sizeof(iface),
+	.init = av_init,
+	.connect = av_connect,
+	.disconnect = av_disconnect,
+	.cleanup = av_cleanup
+};
+
+btav_interface_t *bt_get_av_interface()
+{
+	return &iface;
+}
diff --git a/android/hal-av.c b/android/hal-av.c
deleted file mode 100644
index 2ebf801..0000000
--- a/android/hal-av.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2013 Intel Corporation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <string.h>
-
-#include "hal-log.h"
-#include "hal.h"
-#include "hal-msg.h"
-#include "hal-ipc.h"
-
-static const btav_callbacks_t *cbs = NULL;
-
-static bool interface_ready(void)
-{
-	return cbs != NULL;
-}
-
-static void handle_connection_state(void *buf)
-{
-	struct hal_ev_a2dp_connection_state *ev = buf;
-
-	if (cbs->connection_state_cb)
-		cbs->connection_state_cb(ev->state,
-						(bt_bdaddr_t *) (ev->bdaddr));
-}
-
-static void handle_audio_state(void *buf)
-{
-	struct hal_ev_a2dp_audio_state *ev = buf;
-
-	if (cbs->audio_state_cb)
-		cbs->audio_state_cb(ev->state, (bt_bdaddr_t *)(ev->bdaddr));
-}
-
-/* will be called from notification thread context */
-void bt_notify_av(uint16_t opcode, void *buf, uint16_t len)
-{
-	if (!interface_ready())
-		return;
-
-	switch (opcode) {
-	case HAL_EV_A2DP_CONNECTION_STATE:
-		handle_connection_state(buf);
-		break;
-	case HAL_EV_A2DP_AUDIO_STATE:
-		handle_audio_state(buf);
-		break;
-	default:
-		DBG("Unhandled callback opcode=0x%x", opcode);
-		break;
-	}
-}
-
-static bt_status_t av_connect(bt_bdaddr_t *bd_addr)
-{
-	struct hal_cmd_a2dp_connect cmd;
-
-	DBG("");
-
-	if (!interface_ready())
-		return BT_STATUS_NOT_READY;
-
-	memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
-
-	return hal_ipc_cmd(HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_CONNECT,
-					sizeof(cmd), &cmd, NULL, NULL, NULL);
-}
-
-static bt_status_t av_disconnect(bt_bdaddr_t *bd_addr)
-{
-	struct hal_cmd_a2dp_disconnect cmd;
-
-	DBG("");
-
-	if (!interface_ready())
-		return BT_STATUS_NOT_READY;
-
-	memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
-
-	return hal_ipc_cmd(HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_DISCONNECT,
-					sizeof(cmd), &cmd, NULL, NULL, NULL);
-}
-
-static bt_status_t av_init(btav_callbacks_t *callbacks)
-{
-	DBG("");
-
-	cbs = callbacks;
-
-	/* TODO: enable service */
-
-	return BT_STATUS_SUCCESS;
-}
-
-static void av_cleanup()
-{
-	DBG("");
-
-	if (!interface_ready())
-		return;
-
-	/* TODO: disable service */
-
-	cbs = NULL;
-}
-
-static btav_interface_t iface = {
-	.size = sizeof(iface),
-	.init = av_init,
-	.connect = av_connect,
-	.disconnect = av_disconnect,
-	.cleanup = av_cleanup
-};
-
-btav_interface_t *bt_get_av_interface()
-{
-	return &iface;
-}
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH v2 1/3] android: Rename a2dp HAL related IPC API to match service name
From: Szymon Janc @ 2013-11-07 15:32 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

Use 'Android HAL name' string from IPC doc as base for names.
---
v2:
 - rebased
 - minor style fixes

 android/a2dp.c    |  9 +++++----
 android/hal-av.c  | 16 ++++++++--------
 android/hal-msg.h | 18 ++++++++++--------
 3 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/android/a2dp.c b/android/a2dp.c
index 0d3bfc5..052f4f3 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -40,14 +40,15 @@
 
 static int notification_sk = -1;
 
-static uint8_t bt_a2dp_connect(struct hal_cmd_av_connect *cmd, uint16_t len)
+static uint8_t bt_a2dp_connect(struct hal_cmd_a2dp_connect *cmd, uint16_t len)
 {
 	DBG("Not Implemented");
 
 	return HAL_STATUS_FAILED;
 }
 
-static uint8_t bt_a2dp_disconnect(struct hal_cmd_av_connect *cmd, uint16_t len)
+static uint8_t bt_a2dp_disconnect(struct hal_cmd_a2dp_connect *cmd,
+								uint16_t len)
 {
 	DBG("Not Implemented");
 
@@ -59,10 +60,10 @@ void bt_a2dp_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
 	uint8_t status = HAL_STATUS_FAILED;
 
 	switch (opcode) {
-	case HAL_OP_AV_CONNECT:
+	case HAL_OP_A2DP_CONNECT:
 		status = bt_a2dp_connect(buf, len);
 		break;
-	case HAL_OP_AV_DISCONNECT:
+	case HAL_OP_A2DP_DISCONNECT:
 		status = bt_a2dp_disconnect(buf, len);
 		break;
 	default:
diff --git a/android/hal-av.c b/android/hal-av.c
index 9e1b3df..2ebf801 100644
--- a/android/hal-av.c
+++ b/android/hal-av.c
@@ -33,7 +33,7 @@ static bool interface_ready(void)
 
 static void handle_connection_state(void *buf)
 {
-	struct hal_ev_av_connection_state *ev = buf;
+	struct hal_ev_a2dp_connection_state *ev = buf;
 
 	if (cbs->connection_state_cb)
 		cbs->connection_state_cb(ev->state,
@@ -42,7 +42,7 @@ static void handle_connection_state(void *buf)
 
 static void handle_audio_state(void *buf)
 {
-	struct hal_ev_av_audio_state *ev = buf;
+	struct hal_ev_a2dp_audio_state *ev = buf;
 
 	if (cbs->audio_state_cb)
 		cbs->audio_state_cb(ev->state, (bt_bdaddr_t *)(ev->bdaddr));
@@ -55,10 +55,10 @@ void bt_notify_av(uint16_t opcode, void *buf, uint16_t len)
 		return;
 
 	switch (opcode) {
-	case HAL_EV_AV_CONNECTION_STATE:
+	case HAL_EV_A2DP_CONNECTION_STATE:
 		handle_connection_state(buf);
 		break;
-	case HAL_EV_AV_AUDIO_STATE:
+	case HAL_EV_A2DP_AUDIO_STATE:
 		handle_audio_state(buf);
 		break;
 	default:
@@ -69,7 +69,7 @@ void bt_notify_av(uint16_t opcode, void *buf, uint16_t len)
 
 static bt_status_t av_connect(bt_bdaddr_t *bd_addr)
 {
-	struct hal_cmd_av_connect cmd;
+	struct hal_cmd_a2dp_connect cmd;
 
 	DBG("");
 
@@ -78,13 +78,13 @@ static bt_status_t av_connect(bt_bdaddr_t *bd_addr)
 
 	memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
 
-	return hal_ipc_cmd(HAL_SERVICE_ID_A2DP, HAL_OP_AV_CONNECT,
+	return hal_ipc_cmd(HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_CONNECT,
 					sizeof(cmd), &cmd, NULL, NULL, NULL);
 }
 
 static bt_status_t av_disconnect(bt_bdaddr_t *bd_addr)
 {
-	struct hal_cmd_av_disconnect cmd;
+	struct hal_cmd_a2dp_disconnect cmd;
 
 	DBG("");
 
@@ -93,7 +93,7 @@ static bt_status_t av_disconnect(bt_bdaddr_t *bd_addr)
 
 	memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
 
-	return hal_ipc_cmd(HAL_SERVICE_ID_A2DP, HAL_OP_AV_DISCONNECT,
+	return hal_ipc_cmd(HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_DISCONNECT,
 					sizeof(cmd), &cmd, NULL, NULL, NULL);
 }
 
diff --git a/android/hal-msg.h b/android/hal-msg.h
index a5e5c76..e1feb19 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -301,13 +301,15 @@ struct hal_cmd_hid_send_data {
 	uint8_t bdaddr[6];
 } __attribute__((packed));
 
-#define HAL_OP_AV_CONNECT	0x01
-struct hal_cmd_av_connect {
+/* a2dp HAL API */
+
+#define HAL_OP_A2DP_CONNECT	0x01
+struct hal_cmd_a2dp_connect {
 	uint8_t bdaddr[6];
 } __attribute__((packed));
 
-#define HAL_OP_AV_DISCONNECT	0x02
-struct hal_cmd_av_disconnect {
+#define HAL_OP_A2DP_DISCONNECT	0x02
+struct hal_cmd_a2dp_disconnect {
 	uint8_t bdaddr[6];
 } __attribute__((packed));
 
@@ -475,14 +477,14 @@ struct hal_ev_hid_get_report {
 	uint8_t  data[0];
 } __attribute__((packed));
 
-#define HAL_EV_AV_CONNECTION_STATE	0x81
-struct hal_ev_av_connection_state {
+#define HAL_EV_A2DP_CONNECTION_STATE	0x81
+struct hal_ev_a2dp_connection_state {
 	uint8_t state;
 	uint8_t bdaddr[6];
 } __attribute__((packed));
 
-#define HAL_EV_AV_AUDIO_STATE	0x82
-struct hal_ev_av_audio_state {
+#define HAL_EV_A2DP_AUDIO_STATE	0x82
+struct hal_ev_a2dp_audio_state {
 	uint8_t state;
 	uint8_t bdaddr[6];
 } __attribute__((packed));
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH v2] android: Add set/get for discovery timeout
From: Lukasz Rymanowski @ 2013-11-07 15:26 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: johan.hedberg, szymon.janc, Lukasz Rymanowski

Android handles discoverable timeout in Settings app, however still
expects BT stack to maintain this value so we should do it as well.
Otherwise we will get some unexpected behaviour.
For now we keep discovery_timeout only during runtime, but we need to move
it to some local storage once we will have it.

Note: That since Android Settings up handles timer there is no reason to
use discovery timer we have in kernel.
---
 android/adapter.c | 38 +++++++++++++++++++++++++++++++++++---
 1 file changed, 35 insertions(+), 3 deletions(-)

diff --git a/android/adapter.c b/android/adapter.c
index 2e8d2df..d59778b 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -48,6 +48,9 @@
 
 /* Default to DisplayYesNo */
 #define DEFAULT_IO_CAPABILITY 0x01
+/* Default discoverable timeout 120sec as in Android */
+#define DEFAULT_DISCOVERABLE_TIMEOUT 120
+
 #define BASELEN_PROP_CHANGED sizeof(struct hal_ev_adapter_props_changed) \
 				+ (sizeof(struct hal_property))
 
@@ -70,6 +73,7 @@ struct bt_adapter {
 	uint32_t current_settings;
 
 	bool discovering;
+	uint32_t discoverable_timeout;
 };
 
 struct browse_req {
@@ -1101,6 +1105,17 @@ static uint8_t set_adapter_name(uint8_t *name, uint16_t len)
 	return HAL_STATUS_FAILED;
 }
 
+static uint8_t set_discoverable_timeout(uint8_t *timeout)
+{
+	/* Android handles discoverable timeout in Settings app.
+	 * There is no need to use kernel feature for that.
+	 * Just need to store this value here */
+
+	/* TODO: This should be in some storage */
+	memcpy(&adapter->discoverable_timeout, timeout, sizeof(uint32_t));
+
+	return HAL_STATUS_SUCCESS;
+}
 static void read_info_complete(uint8_t status, uint16_t length, const void *param,
 							void *user_data)
 {
@@ -1169,6 +1184,8 @@ void bt_adapter_init(uint16_t index, struct mgmt *mgmt, bt_adapter_ready cb)
 	adapter->index = index;
 	adapter->discovering = false;
 	adapter->ready = cb;
+	/* TODO: Read it from some storage */
+	adapter->discoverable_timeout = DEFAULT_DISCOVERABLE_TIMEOUT;
 
 	if (mgmt_send(mgmt, MGMT_OP_READ_INFO, index, 0, NULL,
 					read_info_complete, NULL, NULL) > 0)
@@ -1286,11 +1303,25 @@ static bool get_devices(void)
 
 static bool get_discoverable_timeout(void)
 {
-	DBG("Not implemented");
+	struct hal_ev_adapter_props_changed *ev;
+	int len = sizeof(uint32_t);
+	uint8_t buf[BASELEN_PROP_CHANGED + len];
 
-	/* TODO: Add implementation */
 
-	return false;
+	memset(buf, 0, sizeof(buf));
+	ev = (void *) buf;
+
+	ev->num_props = 1;
+	ev->status = HAL_STATUS_SUCCESS;
+
+	ev->props[0].type = HAL_PROP_ADAPTER_DISC_TIMEOUT;
+	ev->props[0].len = len;
+	memcpy(&ev->props[0].val, &adapter->discoverable_timeout, sizeof(uint32_t));
+
+	ipc_send(notification_sk, HAL_SERVICE_ID_BLUETOOTH,
+				HAL_EV_ADAPTER_PROPS_CHANGED, sizeof(buf), ev, -1);
+
+	return true;
 }
 
 static bool get_property(void *buf, uint16_t len)
@@ -1441,6 +1472,7 @@ static uint8_t set_property(void *buf, uint16_t len)
 	case HAL_PROP_ADAPTER_NAME:
 		return set_adapter_name(cmd->val, cmd->len);
 	case HAL_PROP_ADAPTER_DISC_TIMEOUT:
+		return set_discoverable_timeout(cmd->val);
 	default:
 		DBG("Unhandled property type 0x%x", cmd->type);
 		return HAL_STATUS_FAILED;
-- 
1.8.4


^ permalink raw reply related

* [PATCH] android/ipc: Fix crash when sending file descriptor
From: Andrei Emeltchenko @ 2013-11-07 15:25 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <20131107151146.GE23283@x220.p-661hnu-f1>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Since CMSG_FIRSTHDR is defined as shown below:

  ((size_t) (mhdr)->msg_controllen >= sizeof (struct cmsghdr) \
   ? (struct cmsghdr *) (mhdr)->msg_control : (struct cmsghdr *) 0)

it return NULL if msg_controllen is not defined. Accessing
that pointer result in daemon crash.
---
 android/ipc.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/android/ipc.c b/android/ipc.c
index 9a8657d..729f157 100644
--- a/android/ipc.c
+++ b/android/ipc.c
@@ -62,6 +62,9 @@ void ipc_send(int sk, uint8_t service_id, uint8_t opcode, uint16_t len,
 	msg.msg_iovlen = 2;
 
 	if (fd >= 0) {
+		msg.msg_control = cmsgbuf;
+		msg.msg_controllen = sizeof(cmsgbuf);
+
 		cmsg = CMSG_FIRSTHDR(&msg);
 		cmsg->cmsg_level = SOL_SOCKET;
 		cmsg->cmsg_type = SCM_RIGHTS;
@@ -69,9 +72,6 @@ void ipc_send(int sk, uint8_t service_id, uint8_t opcode, uint16_t len,
 
 		/* Initialize the payload */
 		memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
-
-		msg.msg_control = cmsgbuf;
-		msg.msg_controllen = sizeof(cmsgbuf);
 	}
 
 	if (sendmsg(sk, &msg, 0) < 0) {
-- 
1.7.10.4


^ permalink raw reply related

* Re: [PATCH] android/ipc: Fix receiving file descriptors
From: Johan Hedberg @ 2013-11-07 15:15 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1383835898-30110-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Thu, Nov 07, 2013, Andrei Emeltchenko wrote:
> It does make sense iterate over !NULL controll headers. This fixes
> the bug that file descriptors cannot be send over IPC.
> ---
>  android/hal-ipc.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH] android/ipc: Fix crash when sending file descriptor
From: Johan Hedberg @ 2013-11-07 15:11 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1383831409-16900-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Thu, Nov 07, 2013, Andrei Emeltchenko wrote:
> Since CMSG_FIRSTHDR is defined as shown below:
> 
>   ((size_t) (mhdr)->msg_controllen >= sizeof (struct cmsghdr) \
>    ? (struct cmsghdr *) (mhdr)->msg_control : (struct cmsghdr *) 0)
> 
> it return NULL if msg_controllen is not defined. Accessing
> that pointer result in daemon crash.
> ---
>  android/ipc.c |    6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)

This one needs to be rebased. It doesn't apply.

Johan

^ permalink raw reply

* Re: [PATCH 1/3] android: Rename a2dp HAL related IPC API to match service name
From: Johan Hedberg @ 2013-11-07 15:11 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1383820057-15728-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

On Thu, Nov 07, 2013, Szymon Janc wrote:
> Use 'Android HAL name' string from IPC doc as base for names.
> ---
>  android/a2dp.c    | 10 ++++++----
>  android/hal-av.c  | 16 ++++++++--------
>  android/hal-msg.h | 18 ++++++++++--------
>  3 files changed, 24 insertions(+), 20 deletions(-)

Seems like this one (maybe others in this set too) needs rebasing as it
doesn't apply right now.

Johan

^ permalink raw reply

* Re: [PATCH 2/2] android: Add set/get for discovery timeout
From: Johan Hedberg @ 2013-11-07 15:10 UTC (permalink / raw)
  To: Lukasz Rymanowski; +Cc: linux-bluetooth, szymon.janc
In-Reply-To: <1383815991-18523-2-git-send-email-lukasz.rymanowski@tieto.com>

Hi Lukasz,

On Thu, Nov 07, 2013, Lukasz Rymanowski wrote:
> Android handles discoverable timeout in Settings app, however still
> expects BT stack to maintain this value so we should do it as well.
> Otherwise we will get some unexpected behaviour.
> For now we keep discovery_timeout only during runtime, but we need to move
> it to some local storage once we will have it.
> 
> Note: That since Android Settings up handles timer there is no reason to
> use discovery timer we have in kernel.
> ---
>  android/adapter.c | 38 +++++++++++++++++++++++++++++++++++---
>  1 file changed, 35 insertions(+), 3 deletions(-)

You'll need to rebase this one due to the patches from Szymon that were
recently applied (right now it applies but doesn't compile).

Johan

^ permalink raw reply

* Re: [PATCH 1/2 v2] android: Use BASELEN define for property changed
From: Johan Hedberg @ 2013-11-07 15:09 UTC (permalink / raw)
  To: Lukasz Rymanowski; +Cc: linux-bluetooth, szymon.janc
In-Reply-To: <1383815991-18523-1-git-send-email-lukasz.rymanowski@tieto.com>

Hi Lukasz,

On Thu, Nov 07, 2013, Lukasz Rymanowski wrote:
> ---
>  android/adapter.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)

This patch has been applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH 1/4] android: Make IPC helpers accept file descriptor
From: Johan Hedberg @ 2013-11-07 15:06 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1383815437-521-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

On Thu, Nov 07, 2013, Szymon Janc wrote:
> There is no need to pass GIOChannel as writes are done immediately.
> ---
>  android/a2dp.c    |  3 ++-
>  android/adapter.c | 71 ++++++++++++++++++++++++++++++++-----------------------
>  android/hid.c     | 15 ++++++++----
>  android/ipc.c     | 10 ++++----
>  android/ipc.h     |  4 ++--
>  android/main.c    | 20 +++++++++-------
>  android/pan.c     |  3 ++-
>  android/socket.c  |  7 +++---
>  8 files changed, 77 insertions(+), 56 deletions(-)

All four patches have been applied. Thanks.

Johan

^ permalink raw reply

* [PATCH] android/ipc: Fix receiving file descriptors
From: Andrei Emeltchenko @ 2013-11-07 14:51 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

It does make sense iterate over !NULL controll headers. This fixes
the bug that file descriptors cannot be send over IPC.
---
 android/hal-ipc.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/android/hal-ipc.c b/android/hal-ipc.c
index 14be69b..e4b0681 100644
--- a/android/hal-ipc.c
+++ b/android/hal-ipc.c
@@ -373,7 +373,7 @@ int hal_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len, void *param,
 
 		*fd = -1;
 
-		for (cmsg = CMSG_FIRSTHDR(&msg); !cmsg;
+		for (cmsg = CMSG_FIRSTHDR(&msg); cmsg;
 					cmsg = CMSG_NXTHDR(&msg, cmsg)) {
 			if (cmsg->cmsg_level == SOL_SOCKET
 					&& cmsg->cmsg_type == SCM_RIGHTS) {
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH] android/ipc: Fix crash when sending file descriptor
From: Andrei Emeltchenko @ 2013-11-07 13:36 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Since CMSG_FIRSTHDR is defined as shown below:

  ((size_t) (mhdr)->msg_controllen >= sizeof (struct cmsghdr) \
   ? (struct cmsghdr *) (mhdr)->msg_control : (struct cmsghdr *) 0)

it return NULL if msg_controllen is not defined. Accessing
that pointer result in daemon crash.
---
 android/ipc.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/android/ipc.c b/android/ipc.c
index e672bf8..943c196 100644
--- a/android/ipc.c
+++ b/android/ipc.c
@@ -64,6 +64,9 @@ void ipc_send(GIOChannel *io, uint8_t service_id, uint8_t opcode, uint16_t len,
 	msg.msg_iovlen = 2;
 
 	if (fd >= 0) {
+		msg.msg_control = cmsgbuf;
+		msg.msg_controllen = sizeof(cmsgbuf);
+
 		cmsg = CMSG_FIRSTHDR(&msg);
 		cmsg->cmsg_level = SOL_SOCKET;
 		cmsg->cmsg_type = SCM_RIGHTS;
@@ -71,9 +74,6 @@ void ipc_send(GIOChannel *io, uint8_t service_id, uint8_t opcode, uint16_t len,
 
 		/* Initialize the payload */
 		memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
-
-		msg.msg_control = cmsgbuf;
-		msg.msg_controllen = sizeof(cmsgbuf);
 	}
 
 	if (sendmsg(g_io_channel_unix_get_fd(io), &msg, 0) < 0) {
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 3/3] android/hal: Use a2dp instead of av in a2dp HAL
From: Szymon Janc @ 2013-11-07 10:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1383820057-15728-1-git-send-email-szymon.janc@tieto.com>

Match functions names to HAL name. Where not needed av prefix is
removed.
---
 android/hal-a2dp.c      | 20 ++++++++++----------
 android/hal-bluetooth.c |  2 +-
 android/hal-ipc.c       |  2 +-
 android/hal.h           |  4 ++--
 4 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/android/hal-a2dp.c b/android/hal-a2dp.c
index 2ebf801..f0c301e 100644
--- a/android/hal-a2dp.c
+++ b/android/hal-a2dp.c
@@ -49,7 +49,7 @@ static void handle_audio_state(void *buf)
 }
 
 /* will be called from notification thread context */
-void bt_notify_av(uint16_t opcode, void *buf, uint16_t len)
+void bt_notify_a2dp(uint16_t opcode, void *buf, uint16_t len)
 {
 	if (!interface_ready())
 		return;
@@ -67,7 +67,7 @@ void bt_notify_av(uint16_t opcode, void *buf, uint16_t len)
 	}
 }
 
-static bt_status_t av_connect(bt_bdaddr_t *bd_addr)
+static bt_status_t a2dp_connect(bt_bdaddr_t *bd_addr)
 {
 	struct hal_cmd_a2dp_connect cmd;
 
@@ -82,7 +82,7 @@ static bt_status_t av_connect(bt_bdaddr_t *bd_addr)
 					sizeof(cmd), &cmd, NULL, NULL, NULL);
 }
 
-static bt_status_t av_disconnect(bt_bdaddr_t *bd_addr)
+static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
 {
 	struct hal_cmd_a2dp_disconnect cmd;
 
@@ -97,7 +97,7 @@ static bt_status_t av_disconnect(bt_bdaddr_t *bd_addr)
 					sizeof(cmd), &cmd, NULL, NULL, NULL);
 }
 
-static bt_status_t av_init(btav_callbacks_t *callbacks)
+static bt_status_t init(btav_callbacks_t *callbacks)
 {
 	DBG("");
 
@@ -108,7 +108,7 @@ static bt_status_t av_init(btav_callbacks_t *callbacks)
 	return BT_STATUS_SUCCESS;
 }
 
-static void av_cleanup()
+static void cleanup()
 {
 	DBG("");
 
@@ -122,13 +122,13 @@ static void av_cleanup()
 
 static btav_interface_t iface = {
 	.size = sizeof(iface),
-	.init = av_init,
-	.connect = av_connect,
-	.disconnect = av_disconnect,
-	.cleanup = av_cleanup
+	.init = init,
+	.connect = a2dp_connect,
+	.disconnect = disconnect,
+	.cleanup = cleanup
 };
 
-btav_interface_t *bt_get_av_interface()
+btav_interface_t *bt_get_a2dp_interface()
 {
 	return &iface;
 }
diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 88c7b99..3e5d41f 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -654,7 +654,7 @@ static const void *get_profile_interface(const char *profile_id)
 		return bt_get_pan_interface();
 
 	if (!strcmp(profile_id, BT_PROFILE_ADVANCED_AUDIO_ID))
-		return bt_get_av_interface();
+		return bt_get_a2dp_interface();
 
 	return NULL;
 }
diff --git a/android/hal-ipc.c b/android/hal-ipc.c
index 14be69b..1d33374 100644
--- a/android/hal-ipc.c
+++ b/android/hal-ipc.c
@@ -53,7 +53,7 @@ static void notification_dispatch(struct hal_hdr *msg, int fd)
 		bt_notify_hh(msg->opcode, msg->payload, msg->len);
 		break;
 	case HAL_SERVICE_ID_A2DP:
-		bt_notify_av(msg->opcode, msg->payload, msg->len);
+		bt_notify_a2dp(msg->opcode, msg->payload, msg->len);
 		break;
 	default:
 		DBG("Unhandled notification service=%d opcode=0x%x",
diff --git a/android/hal.h b/android/hal.h
index 5d6a93e..f47ec2a 100644
--- a/android/hal.h
+++ b/android/hal.h
@@ -24,10 +24,10 @@
 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);
+btav_interface_t *bt_get_a2dp_interface(void);
 
 void bt_notify_adapter(uint16_t opcode, void *buf, uint16_t len);
 void bt_thread_associate(void);
 void bt_thread_disassociate(void);
 void bt_notify_hh(uint16_t opcode, void *buf, uint16_t len);
-void bt_notify_av(uint16_t opcode, void *buf, uint16_t len);
+void bt_notify_a2dp(uint16_t opcode, void *buf, uint16_t len);
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH 2/3] android/hal: Rename hal-av.c to hal-a2dp.c
From: Szymon Janc @ 2013-11-07 10:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1383820057-15728-1-git-send-email-szymon.janc@tieto.com>

Name of HAL implementation will match Android HAL name. This will make
code navigation easier as daemon part and HAL library implementation
will be in foo.c and hal-foo.c respectively.
---
 android/Android.mk  |   2 +-
 android/Makefile.am |   4 +-
 android/hal-a2dp.c  | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 android/hal-av.c    | 134 ----------------------------------------------------
 4 files changed, 137 insertions(+), 137 deletions(-)
 create mode 100644 android/hal-a2dp.c
 delete mode 100644 android/hal-av.c

diff --git a/android/Android.mk b/android/Android.mk
index d76dfaf..f9bf070 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -86,7 +86,7 @@ LOCAL_SRC_FILES := \
 	hal-sock.c \
 	hal-hidhost.c \
 	hal-pan.c \
-	hal-av.c \
+	hal-a2dp.c \
 	client/textconv.c \
 
 LOCAL_C_INCLUDES += \
diff --git a/android/Makefile.am b/android/Makefile.am
index 8619641..6790f24 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -33,7 +33,7 @@ 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/hal-a2dp.c \
 					android/hardware/bluetooth.h \
 					android/hardware/bt_av.h \
 					android/hardware/bt_gatt.h \
@@ -86,7 +86,7 @@ EXTRA_DIST += android/hal-bluetooth.c \
 		android/hal-sock.c \
 		android/hal-hidhost.c \
 		android/hal-pan.c \
-		android/hal-av.c \
+		android/hal-a2dp.c \
 		android/hal-log.h
 
 EXTRA_DIST += android/client/terminal.c \
diff --git a/android/hal-a2dp.c b/android/hal-a2dp.c
new file mode 100644
index 0000000..2ebf801
--- /dev/null
+++ b/android/hal-a2dp.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "hal-log.h"
+#include "hal.h"
+#include "hal-msg.h"
+#include "hal-ipc.h"
+
+static const btav_callbacks_t *cbs = NULL;
+
+static bool interface_ready(void)
+{
+	return cbs != NULL;
+}
+
+static void handle_connection_state(void *buf)
+{
+	struct hal_ev_a2dp_connection_state *ev = buf;
+
+	if (cbs->connection_state_cb)
+		cbs->connection_state_cb(ev->state,
+						(bt_bdaddr_t *) (ev->bdaddr));
+}
+
+static void handle_audio_state(void *buf)
+{
+	struct hal_ev_a2dp_audio_state *ev = buf;
+
+	if (cbs->audio_state_cb)
+		cbs->audio_state_cb(ev->state, (bt_bdaddr_t *)(ev->bdaddr));
+}
+
+/* will be called from notification thread context */
+void bt_notify_av(uint16_t opcode, void *buf, uint16_t len)
+{
+	if (!interface_ready())
+		return;
+
+	switch (opcode) {
+	case HAL_EV_A2DP_CONNECTION_STATE:
+		handle_connection_state(buf);
+		break;
+	case HAL_EV_A2DP_AUDIO_STATE:
+		handle_audio_state(buf);
+		break;
+	default:
+		DBG("Unhandled callback opcode=0x%x", opcode);
+		break;
+	}
+}
+
+static bt_status_t av_connect(bt_bdaddr_t *bd_addr)
+{
+	struct hal_cmd_a2dp_connect cmd;
+
+	DBG("");
+
+	if (!interface_ready())
+		return BT_STATUS_NOT_READY;
+
+	memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
+
+	return hal_ipc_cmd(HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_CONNECT,
+					sizeof(cmd), &cmd, NULL, NULL, NULL);
+}
+
+static bt_status_t av_disconnect(bt_bdaddr_t *bd_addr)
+{
+	struct hal_cmd_a2dp_disconnect cmd;
+
+	DBG("");
+
+	if (!interface_ready())
+		return BT_STATUS_NOT_READY;
+
+	memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
+
+	return hal_ipc_cmd(HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_DISCONNECT,
+					sizeof(cmd), &cmd, NULL, NULL, NULL);
+}
+
+static bt_status_t av_init(btav_callbacks_t *callbacks)
+{
+	DBG("");
+
+	cbs = callbacks;
+
+	/* TODO: enable service */
+
+	return BT_STATUS_SUCCESS;
+}
+
+static void av_cleanup()
+{
+	DBG("");
+
+	if (!interface_ready())
+		return;
+
+	/* TODO: disable service */
+
+	cbs = NULL;
+}
+
+static btav_interface_t iface = {
+	.size = sizeof(iface),
+	.init = av_init,
+	.connect = av_connect,
+	.disconnect = av_disconnect,
+	.cleanup = av_cleanup
+};
+
+btav_interface_t *bt_get_av_interface()
+{
+	return &iface;
+}
diff --git a/android/hal-av.c b/android/hal-av.c
deleted file mode 100644
index 2ebf801..0000000
--- a/android/hal-av.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2013 Intel Corporation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <string.h>
-
-#include "hal-log.h"
-#include "hal.h"
-#include "hal-msg.h"
-#include "hal-ipc.h"
-
-static const btav_callbacks_t *cbs = NULL;
-
-static bool interface_ready(void)
-{
-	return cbs != NULL;
-}
-
-static void handle_connection_state(void *buf)
-{
-	struct hal_ev_a2dp_connection_state *ev = buf;
-
-	if (cbs->connection_state_cb)
-		cbs->connection_state_cb(ev->state,
-						(bt_bdaddr_t *) (ev->bdaddr));
-}
-
-static void handle_audio_state(void *buf)
-{
-	struct hal_ev_a2dp_audio_state *ev = buf;
-
-	if (cbs->audio_state_cb)
-		cbs->audio_state_cb(ev->state, (bt_bdaddr_t *)(ev->bdaddr));
-}
-
-/* will be called from notification thread context */
-void bt_notify_av(uint16_t opcode, void *buf, uint16_t len)
-{
-	if (!interface_ready())
-		return;
-
-	switch (opcode) {
-	case HAL_EV_A2DP_CONNECTION_STATE:
-		handle_connection_state(buf);
-		break;
-	case HAL_EV_A2DP_AUDIO_STATE:
-		handle_audio_state(buf);
-		break;
-	default:
-		DBG("Unhandled callback opcode=0x%x", opcode);
-		break;
-	}
-}
-
-static bt_status_t av_connect(bt_bdaddr_t *bd_addr)
-{
-	struct hal_cmd_a2dp_connect cmd;
-
-	DBG("");
-
-	if (!interface_ready())
-		return BT_STATUS_NOT_READY;
-
-	memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
-
-	return hal_ipc_cmd(HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_CONNECT,
-					sizeof(cmd), &cmd, NULL, NULL, NULL);
-}
-
-static bt_status_t av_disconnect(bt_bdaddr_t *bd_addr)
-{
-	struct hal_cmd_a2dp_disconnect cmd;
-
-	DBG("");
-
-	if (!interface_ready())
-		return BT_STATUS_NOT_READY;
-
-	memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
-
-	return hal_ipc_cmd(HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_DISCONNECT,
-					sizeof(cmd), &cmd, NULL, NULL, NULL);
-}
-
-static bt_status_t av_init(btav_callbacks_t *callbacks)
-{
-	DBG("");
-
-	cbs = callbacks;
-
-	/* TODO: enable service */
-
-	return BT_STATUS_SUCCESS;
-}
-
-static void av_cleanup()
-{
-	DBG("");
-
-	if (!interface_ready())
-		return;
-
-	/* TODO: disable service */
-
-	cbs = NULL;
-}
-
-static btav_interface_t iface = {
-	.size = sizeof(iface),
-	.init = av_init,
-	.connect = av_connect,
-	.disconnect = av_disconnect,
-	.cleanup = av_cleanup
-};
-
-btav_interface_t *bt_get_av_interface()
-{
-	return &iface;
-}
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH 1/3] android: Rename a2dp HAL related IPC API to match service name
From: Szymon Janc @ 2013-11-07 10:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

Use 'Android HAL name' string from IPC doc as base for names.
---
 android/a2dp.c    | 10 ++++++----
 android/hal-av.c  | 16 ++++++++--------
 android/hal-msg.h | 18 ++++++++++--------
 3 files changed, 24 insertions(+), 20 deletions(-)

diff --git a/android/a2dp.c b/android/a2dp.c
index 28ab4b1..88f49ea 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -40,14 +40,16 @@
 
 static GIOChannel *notification_io = NULL;
 
-static uint8_t bt_a2dp_connect(struct hal_cmd_av_connect *cmd, uint16_t len)
+static uint8_t bt_a2dp_connect(struct hal_cmd_a2dp_connect *cmd,
+								uint16_t len)
 {
 	DBG("Not Implemented");
 
 	return HAL_STATUS_FAILED;
 }
 
-static uint8_t bt_a2dp_disconnect(struct hal_cmd_av_connect *cmd, uint16_t len)
+static uint8_t bt_a2dp_disconnect(struct hal_cmd_a2dp_connect *cmd,
+								uint16_t len)
 {
 	DBG("Not Implemented");
 
@@ -60,10 +62,10 @@ void bt_a2dp_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf,
 	uint8_t status = HAL_STATUS_FAILED;
 
 	switch (opcode) {
-	case HAL_OP_AV_CONNECT:
+	case HAL_OP_A2DP_CONNECT:
 		status = bt_a2dp_connect(buf, len);
 		break;
-	case HAL_OP_AV_DISCONNECT:
+	case HAL_OP_A2DP_DISCONNECT:
 		status = bt_a2dp_disconnect(buf, len);
 		break;
 	default:
diff --git a/android/hal-av.c b/android/hal-av.c
index 9e1b3df..2ebf801 100644
--- a/android/hal-av.c
+++ b/android/hal-av.c
@@ -33,7 +33,7 @@ static bool interface_ready(void)
 
 static void handle_connection_state(void *buf)
 {
-	struct hal_ev_av_connection_state *ev = buf;
+	struct hal_ev_a2dp_connection_state *ev = buf;
 
 	if (cbs->connection_state_cb)
 		cbs->connection_state_cb(ev->state,
@@ -42,7 +42,7 @@ static void handle_connection_state(void *buf)
 
 static void handle_audio_state(void *buf)
 {
-	struct hal_ev_av_audio_state *ev = buf;
+	struct hal_ev_a2dp_audio_state *ev = buf;
 
 	if (cbs->audio_state_cb)
 		cbs->audio_state_cb(ev->state, (bt_bdaddr_t *)(ev->bdaddr));
@@ -55,10 +55,10 @@ void bt_notify_av(uint16_t opcode, void *buf, uint16_t len)
 		return;
 
 	switch (opcode) {
-	case HAL_EV_AV_CONNECTION_STATE:
+	case HAL_EV_A2DP_CONNECTION_STATE:
 		handle_connection_state(buf);
 		break;
-	case HAL_EV_AV_AUDIO_STATE:
+	case HAL_EV_A2DP_AUDIO_STATE:
 		handle_audio_state(buf);
 		break;
 	default:
@@ -69,7 +69,7 @@ void bt_notify_av(uint16_t opcode, void *buf, uint16_t len)
 
 static bt_status_t av_connect(bt_bdaddr_t *bd_addr)
 {
-	struct hal_cmd_av_connect cmd;
+	struct hal_cmd_a2dp_connect cmd;
 
 	DBG("");
 
@@ -78,13 +78,13 @@ static bt_status_t av_connect(bt_bdaddr_t *bd_addr)
 
 	memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
 
-	return hal_ipc_cmd(HAL_SERVICE_ID_A2DP, HAL_OP_AV_CONNECT,
+	return hal_ipc_cmd(HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_CONNECT,
 					sizeof(cmd), &cmd, NULL, NULL, NULL);
 }
 
 static bt_status_t av_disconnect(bt_bdaddr_t *bd_addr)
 {
-	struct hal_cmd_av_disconnect cmd;
+	struct hal_cmd_a2dp_disconnect cmd;
 
 	DBG("");
 
@@ -93,7 +93,7 @@ static bt_status_t av_disconnect(bt_bdaddr_t *bd_addr)
 
 	memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
 
-	return hal_ipc_cmd(HAL_SERVICE_ID_A2DP, HAL_OP_AV_DISCONNECT,
+	return hal_ipc_cmd(HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_DISCONNECT,
 					sizeof(cmd), &cmd, NULL, NULL, NULL);
 }
 
diff --git a/android/hal-msg.h b/android/hal-msg.h
index a5e5c76..c52e495 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -301,13 +301,15 @@ struct hal_cmd_hid_send_data {
 	uint8_t bdaddr[6];
 } __attribute__((packed));
 
-#define HAL_OP_AV_CONNECT	0x01
-struct hal_cmd_av_connect {
+/* a2dp HAL API*/
+
+#define HAL_OP_A2DP_CONNECT	0x01
+struct hal_cmd_a2dp_connect {
 	uint8_t bdaddr[6];
 } __attribute__((packed));
 
-#define HAL_OP_AV_DISCONNECT	0x02
-struct hal_cmd_av_disconnect {
+#define HAL_OP_A2DP_DISCONNECT	0x02
+struct hal_cmd_a2dp_disconnect {
 	uint8_t bdaddr[6];
 } __attribute__((packed));
 
@@ -475,14 +477,14 @@ struct hal_ev_hid_get_report {
 	uint8_t  data[0];
 } __attribute__((packed));
 
-#define HAL_EV_AV_CONNECTION_STATE	0x81
-struct hal_ev_av_connection_state {
+#define HAL_EV_A2DP_CONNECTION_STATE	0x81
+struct hal_ev_a2dp_connection_state {
 	uint8_t state;
 	uint8_t bdaddr[6];
 } __attribute__((packed));
 
-#define HAL_EV_AV_AUDIO_STATE	0x82
-struct hal_ev_av_audio_state {
+#define HAL_EV_A2DP_AUDIO_STATE	0x82
+struct hal_ev_a2dp_audio_state {
 	uint8_t state;
 	uint8_t bdaddr[6];
 } __attribute__((packed));
-- 
1.8.4.2


^ permalink raw reply related

* Re: Intel 7260 bluetooth malfunction when it is connected to EHCI bus
From: Stevie Trujillo @ 2013-11-07 10:07 UTC (permalink / raw)
  To: Hui Wang; +Cc: marcel, tedd.an, linux-bluetooth
In-Reply-To: <527B0CF1.7010703@canonical.com>

On Thu, 07 Nov 2013 11:45:53 +0800
Hui Wang <hui.wang@canonical.com> wrote:

> Do you know any tools can decode the log generated by usbmon?

Hmm, I never actually used the usbmon program. I did "modprobe usbmon",
then Wireshark shows usbmon{1..4} (one for each bus) as an interface
like eth0 for ethernet. http://wiki.wireshark.org/CaptureSetup/USB

If it's difficult to compare two captures in Wireshark (I don't know any
other method than visual inspection), tshark (Wireshark's "command-line
counter-part") is able to decode to stdout. Maybe one can run the diff
program on that. The output seems a bit terse however.

Please be aware: in my Wireshark (1.10.2) one of the of the SCO setup
packets are decoded slightly wrong. It looks like Wireshark is missing
a BDADDR in the beginning, so all the other fields get shifted.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox