/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2013-2014  Intel Corporation. All rights reserved.
 *
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; 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 <ctype.h>

#include <glib.h>

#include "btio/btio.h"
#include "lib/bluetooth.h"
#include "lib/sdp.h"
#include "lib/sdp_lib.h"
#include "src/shared/mgmt.h"
#include "src/shared/util.h"
#include "src/shared/uhid.h"
#include "src/sdp-client.h"
#include "src/uuid-helper.h"
#include "src/log.h"

#include "hal-msg.h"
#include "ipc-common.h"
#include "ipc.h"
#include "bluetooth.h"
#include "gatt.h"
#include "hog.h"
#include "hidhost.h"
#include "utils.h"

#define L2CAP_PSM_HIDP_CTRL	0x11
#define L2CAP_PSM_HIDP_INTR	0x13

/* HID message types */
#define HID_MSG_HANDSHAKE	0x00
#define HID_MSG_CONTROL		0x10
#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

#define HID_MSG_TYPE_MASK	0xf0

/* 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

/* HID Virtual Cable Unplug */
#define HID_VIRTUAL_CABLE_UNPLUG	0x05

#define HOG_UUID		"00001812-0000-1000-8000-00805f9b34fb"

static bdaddr_t adapter_addr;

static GIOChannel *ctrl_io = NULL;
static GIOChannel *intr_io = NULL;
static GSList *devices = NULL;
static unsigned int hog_app = 0;

static struct ipc *hal_ipc = 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;
	struct bt_uhid	*uhid;
	uint8_t		last_hid_msg;
	struct bt_hog	*hog;
	int		sec_level;
};

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 hid_device_free(void *data)
{
	struct hid_device *dev = data;

	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)
		bt_uhid_unref(dev->uhid);

	if (dev->hog)
		bt_hog_unref(dev->hog);

	g_free(dev->rd_data);
	g_free(dev);
}

static void hid_device_remove(struct hid_device *dev)
{
	devices = g_slist_remove(devices, dev);
	hid_device_free(dev);
}

static struct hid_device *hid_device_new(const bdaddr_t *addr)
{
	struct hid_device *dev;

	dev = g_new0(struct hid_device, 1);
	bacpy(&dev->dst, addr);
	dev->state = HAL_HIDHOST_STATE_DISCONNECTED;
	dev->sec_level = BT_IO_SEC_LOW;

	devices = g_slist_append(devices, dev);

	return dev;
}

static bool hex2buf(const uint8_t *hex, uint8_t *buf, int buf_size)
{
	int i, j;
	char c;
	uint8_t b;

	for (i = 0, j = 0; i < buf_size; i++, j++) {
		c = toupper(hex[j]);

		if (c >= '0' && c <= '9')
			b = c - '0';
		else if (c >= 'A' && c <= 'F')
			b = 10 + c - 'A';
		else
			return false;

		j++;

		c = toupper(hex[j]);

		if (c >= '0' && c <= '9')
			b = b * 16 + c - '0';
		else if (c >= 'A' && c <= 'F')
			b = b * 16 + 10 + c - 'A';
		else
			return false;

		buf[i] = b;
	}

	return true;
}

static void handle_uhid_output(struct uhid_event *event, void *user_data)
{
	struct uhid_output_req *output = &event->u.output;
	struct hid_device *dev = user_data;
	int fd, req_size;
	uint8_t *req;

	if (!dev->ctrl_io)
		return;

	req_size = 1 + output->size;
	req = malloc0(req_size);
	if (!req)
		return;

	req[0] = HID_MSG_SET_REPORT | output->rtype;
	memcpy(req + 1, output->data, req_size - 1);

	fd = g_io_channel_unix_get_fd(dev->ctrl_io);

	if (write(fd, req, req_size) < 0)
		error("hidhost: error writing set_report: %s (%d)",
							strerror(errno), errno);

	free(req);
}

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, err;

	/* Wait uHID if not ready */
	if (!dev->uhid)
		return TRUE;

	fd = g_io_channel_unix_get_fd(chan);
	bread = read(fd, buf, sizeof(buf));
	if (bread < 0) {
		error("hidhost: read from interrupt failed: %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);

	err = bt_uhid_send(dev->uhid, &ev);
	if (err < 0)
		DBG("bt_uhid_send: %s (%d)", strerror(-err), -err);

	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_notif(hal_ipc, HAL_SERVICE_ID_HIDHOST,
				HAL_EV_HIDHOST_CONN_STATE, sizeof(ev), &ev);
}

static gboolean intr_watch_cb(GIOChannel *chan, GIOCondition cond,
								gpointer data)
{
	struct hid_device *dev = data;

	if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL))
		goto error;

	if (cond & G_IO_IN)
		return intr_io_watch_cb(chan, data);

error:
	bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED);

	/*
	 * 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);

	/* Close control channel */
	if (dev->ctrl_io && !(cond & G_IO_NVAL))
		g_io_channel_shutdown(dev->ctrl_io, TRUE, NULL);

	hid_device_remove(dev);

	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_notif(hal_ipc, HAL_SERVICE_ID_HIDHOST,
				HAL_EV_HIDHOST_PROTO_MODE, sizeof(ev), &ev);
}

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);

	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_notif(hal_ipc, HAL_SERVICE_ID_HIDHOST,
				HAL_EV_HIDHOST_GET_REPORT, ev_len, ev);
	g_free(ev);
}

static void bt_hid_notify_handshake(struct hid_device *dev, uint8_t *buf,
									int len)
{
	struct hal_ev_hidhost_handshake ev;

	bdaddr2android(&dev->dst, ev.bdaddr);

	/* crop result code to handshake status range from HAL */
	ev.status = buf[0];
	if (ev.status > HAL_HIDHOST_HS_ERROR)
		ev.status = HAL_HIDHOST_HS_ERROR;

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HIDHOST,
				HAL_EV_HIDHOST_HANDSHAKE, sizeof(ev), &ev);
}

static void bt_hid_notify_virtual_unplug(struct hid_device *dev,
							uint8_t *buf, int len)
{
	struct hal_ev_hidhost_virtual_unplug ev;
	char address[18];

	ba2str(&dev->dst, address);
	DBG("device %s", address);
	bdaddr2android(&dev->dst, ev.bdaddr);

	ev.status = HAL_HIDHOST_GENERAL_ERROR;

	/* Wait either channels to HUP */
	if (dev->intr_io && dev->ctrl_io) {
		g_io_channel_shutdown(dev->intr_io, TRUE, NULL);
		g_io_channel_shutdown(dev->ctrl_io, TRUE, NULL);
		bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTING);
		ev.status = HAL_HIDHOST_STATUS_OK;
	}

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HIDHOST,
				HAL_EV_HIDHOST_VIRTUAL_UNPLUG, sizeof(ev), &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("hidhost: read from control failed: %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;
	}

	switch (buf[0] & HID_MSG_TYPE_MASK) {
	case HID_MSG_HANDSHAKE:
		bt_hid_notify_handshake(dev, buf, bread);
		break;
	case HID_MSG_CONTROL:
		if ((buf[0] & ~HID_MSG_TYPE_MASK) == HID_VIRTUAL_CABLE_UNPLUG)
			bt_hid_notify_virtual_unplug(dev, buf, bread);
		break;
	default:
		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;

	if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL))
		goto error;

	if (cond & G_IO_IN)
		return ctrl_io_watch_cb(chan, data);

error:
	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_remove(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_notif(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_EV_HIDHOST_INFO,
							sizeof(ev), &ev);
}

static int uhid_create(struct hid_device *dev)
{
	struct uhid_event ev;
	int err;

	dev->uhid = bt_uhid_new_default();
	if (!dev->uhid) {
		err = -errno;
		error("hidhost: Failed to create bt_uhid instance");
		return err;
	}

	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;

	err = bt_uhid_send(dev->uhid, &ev);
	if (err < 0) {
		error("hidhost: Failed to create uHID device: %s",
							strerror(-err));
		bt_uhid_unref(dev->uhid);
		dev->uhid = NULL;
		return err;
	}

	bt_uhid_register(dev->uhid, UHID_OUTPUT, handle_uhid_output, dev);
	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;
	uint8_t state;

	DBG("");

	if (conn_err) {
		error("hidhost: Failed to connect interrupt channel (%s)",
							conn_err->message);
		state = HAL_HIDHOST_STATE_FAILED;
		goto failed;
	}

	if (uhid_create(dev) < 0) {
		state = HAL_HIDHOST_STATE_NO_HID;
		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:
	bt_hid_notify_state(dev, state);
	hid_device_remove(dev);
}

static void control_connect_cb(GIOChannel *chan, GError *conn_err,
							gpointer user_data)
{
	struct hid_device *dev = user_data;
	GError *err = NULL;

	DBG("");

	if (conn_err) {
		bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED);
		error("hidhost: Failed to connect control channel (%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, &adapter_addr,
					BT_IO_OPT_DEST_BDADDR, &dev->dst,
					BT_IO_OPT_PSM, L2CAP_PSM_HIDP_INTR,
					BT_IO_OPT_SEC_LEVEL, dev->sec_level,
					BT_IO_OPT_INVALID);
	if (!dev->intr_io) {
		error("hidhost: Failed to connect interrupt channel (%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_remove(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;

	DBG("");

	if (err < 0) {
		error("hidhost: Unable to get SDP record: %s", strerror(-err));
		goto fail;
	}

	if (!recs || !recs->data) {
		error("hidhost: 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_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;

			/* Encryption is mandatory for keyboards */
			if (dev->subclass & 0x40)
				dev->sec_level = BT_IO_SEC_MEDIUM;
		}

		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) {
		/* Raise the security level for this device if needed. */
		if ((dev->sec_level > BT_IO_SEC_LOW) &&
			!bt_io_set(dev->ctrl_io, &gerr,
					BT_IO_OPT_SEC_LEVEL, dev->sec_level,
					BT_IO_OPT_INVALID)) {
			error("hidhost: Cannot raise security level: %s",
								gerr->message);
			g_error_free(gerr);

			goto fail;
		}

		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, &adapter_addr,
					BT_IO_OPT_DEST_BDADDR, &dev->dst,
					BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL,
					BT_IO_OPT_SEC_LEVEL, dev->sec_level,
					BT_IO_OPT_INVALID);
	if (gerr) {
		error("hidhost: Failed to connect control channel (%s)",
								gerr->message);
		g_error_free(gerr);
		goto fail;
	}

	return;

fail:
	bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED);
	hid_device_remove(dev);
}

static void hid_sdp_did_search_cb(sdp_list_t *recs, int err, gpointer data)
{
	struct hid_device *dev = data;
	sdp_list_t *list;
	uuid_t uuid;

	DBG("");

	if (err < 0) {
		error("hidhost: Unable to get Device ID SDP record: %s",
								strerror(-err));
		goto fail;
	}

	if (!recs || !recs->data) {
		error("hidhost: No Device ID SDP records found");
		goto fail;
	}

	for (list = recs; list; 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;
	}

	sdp_uuid16_create(&uuid, HID_SVCLASS_ID);
	if (bt_search_service(&adapter_addr, &dev->dst, &uuid,
				hid_sdp_search_cb, dev, NULL, 0) < 0) {
		error("hidhost: Failed to search SDP details");
		goto fail;
	}

	return;

fail:
	bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED);
	hid_device_remove(dev);
}

static void hog_conn_cb(const bdaddr_t *addr, int err, void *attrib)
{
	GSList *l;
	struct hid_device *dev;

	l = g_slist_find_custom(devices, addr, device_cmp);
	dev = l ? l->data : NULL;

	if (err < 0) {
		if (!dev)
			return;
		if (dev->hog) {
			bt_hid_notify_state(dev,
						HAL_HIDHOST_STATE_DISCONNECTED);
			bt_hog_detach(dev->hog);
			return;
		}
		goto fail;
	}

	if (!dev)
		dev = hid_device_new(addr);

	if (!dev->hog) {
		/* TODO: Get device details and primary */
		dev->hog = bt_hog_new_default("bluez-input-device", dev->vendor,
					dev->product, dev->version, NULL);
		if (!dev->hog) {
			error("HoG: unable to create session");
			goto fail;
		}
	}

	if (!bt_hog_attach(dev->hog, attrib)) {
		error("HoG: unable to attach");
		goto fail;
	}

	if (!bt_gatt_set_security(addr, BT_IO_SEC_MEDIUM)) {
		error("Failed to set security level");
		goto fail;
	}

	DBG("");

	bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTED);

	if (!bt_gatt_add_autoconnect(hog_app, &dev->dst))
		error("hidhost: Could not add to autoconnect list");

	return;

fail:
	bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED);
	hid_device_remove(dev);
}

static bool hog_connect(struct hid_device *dev)
{
	DBG("");

	if (hog_app)
		return bt_gatt_connect_app(hog_app, &dev->dst);

	hog_app = bt_gatt_register_app(HOG_UUID, GATT_CLIENT, hog_conn_cb);
	if (!hog_app) {
		error("hidhost: bt_gatt_register_app failed");
		return false;
	}

	return bt_gatt_connect_app(hog_app, &dev->dst);
}

static void bt_hid_connect(const void *buf, uint16_t len)
{
	const struct hal_cmd_hidhost_connect *cmd = buf;
	struct hid_device *dev;
	uint8_t status;
	char addr[18];
	bdaddr_t dst;
	GSList *l;
	uuid_t uuid;

	DBG("");

	android2bdaddr(&cmd->bdaddr, &dst);

	l = g_slist_find_custom(devices, &dst, device_cmp);
	if (l)
		dev = l->data;
	else
		dev = hid_device_new(&dst);

	if (dev->state != HAL_HIDHOST_STATE_DISCONNECTED)
		goto done;

	ba2str(&dev->dst, addr);
	DBG("connecting to %s", addr);

	if (bt_device_last_seen_bearer(&dev->dst) != BDADDR_BREDR) {
		if (!hog_connect(dev)) {
			status = HAL_STATUS_FAILED;
			hid_device_remove(dev);
			goto failed;
		}
		goto done;
	}

	sdp_uuid16_create(&uuid, PNP_INFO_SVCLASS_ID);
	if (bt_search_service(&adapter_addr, &dev->dst, &uuid,
				hid_sdp_did_search_cb, dev, NULL, 0) < 0) {
		error("hidhost: Failed to search DeviceID SDP details");
		hid_device_remove(dev);
		status = HAL_STATUS_FAILED;
		goto failed;
	}

done:
	if (dev->state == HAL_HIDHOST_STATE_DISCONNECTED)
		bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTING);

	status = HAL_STATUS_SUCCESS;

failed:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_CONNECT,
									status);
}

static bool hog_disconnect(struct hid_device *dev)
{
	DBG("");

	if (dev->state == HAL_HIDHOST_STATE_DISCONNECTED)
		return false;

	bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTING);

	if (!bt_gatt_disconnect_app(hog_app, &dev->dst)) {
		bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED);
		hid_device_remove(dev);
	}

	return true;
}

static void bt_hid_disconnect(const void *buf, uint16_t len)
{
	const struct hal_cmd_hidhost_disconnect *cmd = buf;
	struct hid_device *dev;
	uint8_t status;
	GSList *l;
	bdaddr_t dst;

	DBG("");

	android2bdaddr(&cmd->bdaddr, &dst);

	l = g_slist_find_custom(devices, &dst, device_cmp);
	if (!l) {
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	dev = l->data;
	if (bt_is_device_le(&dst)) {
		if (!hog_disconnect(dev)) {
			status = HAL_STATUS_FAILED;
			goto failed;
		}
		goto done;
	}

	/* 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);


done:
	status = HAL_STATUS_SUCCESS;

failed:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_DISCONNECT,
									status);
}

static bool bt_hid_write_virtual_unplug(GIOChannel *chan)
{
	uint8_t hdr = HID_MSG_CONTROL | HID_VIRTUAL_CABLE_UNPLUG;
	int fd = g_io_channel_unix_get_fd(chan);

	if (write(fd, &hdr, sizeof(hdr)) == sizeof(hdr))
		return true;

	error("hidhost: Error writing virtual unplug command: %s (%d)",
							strerror(errno), errno);
	return false;
}

static void bt_hid_virtual_unplug(const void *buf, uint16_t len)
{
	const struct hal_cmd_hidhost_virtual_unplug *cmd = buf;
	struct hid_device *dev;
	GSList *l;
	uint8_t status;
	bdaddr_t dst;

	DBG("");

	android2bdaddr(&cmd->bdaddr, &dst);

	l = g_slist_find_custom(devices, &dst, device_cmp);
	if (!l) {
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	dev = l->data;

	if (!(dev->ctrl_io)) {
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	if (!bt_hid_write_virtual_unplug(dev->ctrl_io)) {
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	/* 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);

	status = HAL_STATUS_SUCCESS;

failed:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST,
					HAL_OP_HIDHOST_VIRTUAL_UNPLUG, status);
}

static void bt_hid_info(const void *buf, uint16_t len)
{
	const struct hal_cmd_hidhost_set_info *cmd = buf;

	if (len != sizeof(*cmd) + cmd->descr_len) {
		error("Invalid hid set info size (%u bytes), terminating", len);
		raise(SIGTERM);
		return;
	}

	/*
	 * Data from hal_cmd_hidhost_set_info is usefull only when we create
	 * UHID device. Once device is created all the transactions will be
	 * done through the fd. There is no way to use this information
	 * once device is created with HID internals.
	 */
	DBG("Not supported");

	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SET_INFO,
							HAL_STATUS_UNSUPPORTED);
}

static void bt_hid_get_protocol(const void *buf, uint16_t len)
{
	const struct hal_cmd_hidhost_get_protocol *cmd = buf;
	struct hid_device *dev;
	GSList *l;
	bdaddr_t dst;
	int fd;
	uint8_t hdr;
	uint8_t status;

	DBG("");

	switch (cmd->mode) {
	case HAL_HIDHOST_REPORT_PROTOCOL:
	case HAL_HIDHOST_BOOT_PROTOCOL:
		break;
	default:
		status = HAL_STATUS_INVALID;
		goto failed;
	}

	android2bdaddr(&cmd->bdaddr, &dst);

	l = g_slist_find_custom(devices, &dst, device_cmp);
	if (!l) {
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	dev = l->data;

	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("hidhost: Error writing device_get_protocol: %s (%d)",
						strerror(errno), errno);
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	dev->last_hid_msg = HID_MSG_GET_PROTOCOL;

	status = HAL_STATUS_SUCCESS;

failed:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST,
					HAL_OP_HIDHOST_GET_PROTOCOL, status);
}

static void bt_hid_set_protocol(const void *buf, uint16_t len)
{
	const struct hal_cmd_hidhost_set_protocol *cmd = buf;
	struct hid_device *dev;
	GSList *l;
	bdaddr_t dst;
	int fd;
	uint8_t hdr;
	uint8_t status;

	DBG("");

	switch (cmd->mode) {
	case HAL_HIDHOST_REPORT_PROTOCOL:
	case HAL_HIDHOST_BOOT_PROTOCOL:
		break;
	default:
		status = HAL_STATUS_INVALID;
		goto failed;
	}

	android2bdaddr(&cmd->bdaddr, &dst);

	l = g_slist_find_custom(devices, &dst, device_cmp);
	if (!l) {
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	dev = l->data;

	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("hidhost: error writing device_set_protocol: %s (%d)",
						strerror(errno), errno);
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	dev->last_hid_msg = HID_MSG_SET_PROTOCOL;

	status = HAL_STATUS_SUCCESS;

failed:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST,
					HAL_OP_HIDHOST_SET_PROTOCOL, status);
}

static void bt_hid_get_report(const void *buf, uint16_t len)
{
	const struct hal_cmd_hidhost_get_report *cmd = buf;
	struct hid_device *dev;
	GSList *l;
	bdaddr_t dst;
	int fd;
	uint8_t *req;
	uint8_t req_size;
	uint8_t status;

	DBG("");

	switch (cmd->type) {
	case HAL_HIDHOST_INPUT_REPORT:
	case HAL_HIDHOST_OUTPUT_REPORT:
	case HAL_HIDHOST_FEATURE_REPORT:
		break;
	default:
		status = HAL_STATUS_INVALID;
		goto failed;
	}

	android2bdaddr(&cmd->bdaddr, &dst);

	l = g_slist_find_custom(devices, &dst, device_cmp);
	if (!l) {
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	dev = l->data;
	req_size = (cmd->buf_size > 0) ? 4 : 2;
	req = g_try_malloc0(req_size);
	if (!req) {
		status = HAL_STATUS_NOMEM;
		goto failed;
	}

	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;
		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("hidhost: error writing hid_get_report: %s (%d)",
						strerror(errno), errno);
		g_free(req);
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	dev->last_hid_msg = HID_MSG_GET_REPORT;
	g_free(req);

	status = HAL_STATUS_SUCCESS;

failed:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_GET_REPORT,
									status);
}

static void bt_hid_set_report(const void *buf, uint16_t len)
{
	const struct hal_cmd_hidhost_set_report *cmd = buf;
	struct hid_device *dev;
	GSList *l;
	bdaddr_t dst;
	int fd;
	uint8_t *req = NULL;
	uint8_t req_size;
	uint8_t status;

	DBG("");

	if (len != sizeof(*cmd) + cmd->len) {
		error("Invalid hid set report size (%u bytes), terminating",
									len);
		raise(SIGTERM);
		return;
	}

	switch (cmd->type) {
	case HAL_HIDHOST_INPUT_REPORT:
	case HAL_HIDHOST_OUTPUT_REPORT:
	case HAL_HIDHOST_FEATURE_REPORT:
		break;
	default:
		status = HAL_STATUS_INVALID;
		goto failed;
	}

	android2bdaddr(&cmd->bdaddr, &dst);

	l = g_slist_find_custom(devices, &dst, device_cmp);
	if (!l) {
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	dev = l->data;

	if (!dev->ctrl_io && !dev->hog) {
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	req_size = 1 + (cmd->len / 2);
	req = g_try_malloc0(req_size);
	if (!req) {
		status = HAL_STATUS_NOMEM;
		goto failed;
	}

	req[0] = HID_MSG_SET_REPORT | cmd->type;
	/*
	 * Report data coming to HAL is in ascii format, HAL sends
	 * data in hex to daemon, so convert to binary.
	 */
	if (!hex2buf(cmd->data, req + 1, req_size - 1)) {
		status = HAL_STATUS_INVALID;
		goto failed;
	}

	if (dev->hog) {
		if (bt_hog_send_report(dev->hog, req + 1, req_size - 1,
							cmd->type) < 0) {
			status = HAL_STATUS_FAILED;
			goto failed;
		}

		goto done;
	}

	fd = g_io_channel_unix_get_fd(dev->ctrl_io);

	if (write(fd, req, req_size) < 0) {
		error("hidhost: error writing hid_set_report: %s (%d)",
						strerror(errno), errno);
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	dev->last_hid_msg = HID_MSG_SET_REPORT;

done:
	status = HAL_STATUS_SUCCESS;

failed:
	g_free(req);

	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SET_REPORT,
									status);
}

static void bt_hid_send_data(const void *buf, uint16_t len)
{
	const struct hal_cmd_hidhost_send_data *cmd = buf;
	struct hid_device *dev;
	GSList *l;
	bdaddr_t dst;
	int fd;
	uint8_t *req = NULL;
	uint8_t req_size;
	uint8_t status;

	DBG("");

	if (len != sizeof(*cmd) + cmd->len) {
		error("Invalid hid send data size (%u bytes), terminating",
									len);
		raise(SIGTERM);
		return;
	}

	android2bdaddr(&cmd->bdaddr, &dst);

	l = g_slist_find_custom(devices, &dst, device_cmp);
	if (!l) {
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	dev = l->data;

	if (!(dev->intr_io)) {
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	req_size = 1 + (cmd->len / 2);
	req = g_try_malloc0(req_size);
	if (!req) {
		status = HAL_STATUS_NOMEM;
		goto failed;
	}

	req[0] = HID_MSG_DATA | HID_DATA_TYPE_OUTPUT;
	/*
	 * Report data coming to HAL is in ascii format, HAL sends
	 * data in hex to daemon, so convert to binary.
	 */
	if (!hex2buf(cmd->data, req + 1, req_size - 1)) {
		status = HAL_STATUS_INVALID;
		goto failed;
	}

	fd = g_io_channel_unix_get_fd(dev->intr_io);

	if (write(fd, req, req_size) < 0) {
		error("hidhost: error writing data to HID device: %s (%d)",
						strerror(errno), errno);
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	status = HAL_STATUS_SUCCESS;

failed:
	g_free(req);

	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SEND_DATA,
									status);
}

static const struct ipc_handler cmd_handlers[] = {
	/* HAL_OP_HIDHOST_CONNECT */
	{ bt_hid_connect, false, sizeof(struct hal_cmd_hidhost_connect) },
	/* HAL_OP_HIDHOST_DISCONNECT */
	{ bt_hid_disconnect, false, sizeof(struct hal_cmd_hidhost_disconnect) },
	/* HAL_OP_HIDHOST_VIRTUAL_UNPLUG */
	{ bt_hid_virtual_unplug, false,
				sizeof(struct hal_cmd_hidhost_virtual_unplug) },
	/* HAL_OP_HIDHOST_SET_INFO */
	{ bt_hid_info, true, sizeof(struct hal_cmd_hidhost_set_info) },
	/* HAL_OP_HIDHOST_GET_PROTOCOL */
	{ bt_hid_get_protocol, false,
				sizeof(struct hal_cmd_hidhost_get_protocol) },
	/* HAL_OP_HIDHOST_SET_PROTOCOL */
	{ bt_hid_set_protocol, false,
				sizeof(struct hal_cmd_hidhost_get_protocol) },
	/* HAL_OP_HIDHOST_GET_REPORT */
	{ bt_hid_get_report, false, sizeof(struct hal_cmd_hidhost_get_report) },
	/* HAL_OP_HIDHOST_SET_REPORT */
	{ bt_hid_set_report, true, sizeof(struct hal_cmd_hidhost_set_report) },
	/* HAL_OP_HIDHOST_SEND_DATA */
	{ bt_hid_send_data, true, sizeof(struct hal_cmd_hidhost_send_data)  },
};

static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
{
	struct hid_device *dev;
	bdaddr_t dst;
	char address[18];
	uint16_t psm;
	GError *gerr = NULL;
	GSList *l;
	uuid_t uuid;

	if (err) {
		error("hidhost: Connect failed (%s)", err->message);
		return;
	}

	bt_io_get(chan, &gerr,
			BT_IO_OPT_DEST_BDADDR, &dst,
			BT_IO_OPT_PSM, &psm,
			BT_IO_OPT_INVALID);
	if (gerr) {
		error("hidhost: Failed to read remote address (%s)",
								gerr->message);
		g_io_channel_shutdown(chan, TRUE, NULL);
		g_error_free(gerr);
		return;
	}

	ba2str(&dst, address);
	DBG("Incoming connection from %s on PSM %d", address, psm);

	if (!bt_device_is_bonded(&dst)) {
		warn("hidhost: Rejecting connection from unknown device %s",
								address);
		if (psm == L2CAP_PSM_HIDP_CTRL)
			bt_hid_write_virtual_unplug(chan);

		g_io_channel_shutdown(chan, TRUE, NULL);
		return;
	}

	switch (psm) {
	case L2CAP_PSM_HIDP_CTRL:
		l = g_slist_find_custom(devices, &dst, device_cmp);
		if (l)
			return;

		dev = hid_device_new(&dst);
		dev->ctrl_io = g_io_channel_ref(chan);

		sdp_uuid16_create(&uuid, PNP_INFO_SVCLASS_ID);
		if (bt_search_service(&adapter_addr, &dev->dst, &uuid,
				hid_sdp_did_search_cb, dev, NULL, 0) < 0) {
			error("hidhost: Failed to search DID SDP details");
			hid_device_remove(dev);
			return;
		}

		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;
	}
}

static void hid_unpaired_cb(const bdaddr_t *addr)
{
	GSList *l;
	struct hid_device *dev;
	char address[18];

	l = g_slist_find_custom(devices, addr, device_cmp);
	if (!l)
		return;

	dev = l->data;

	ba2str(addr, address);
	DBG("Unpaired device %s", address);

	if (hog_app)
		bt_gatt_remove_autoconnect(hog_app, addr);

	hid_device_remove(dev);
}

bool bt_hid_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
{
	GError *err = NULL;

	DBG("");

	if (!bt_unpaired_register(hid_unpaired_cb)) {
		error("hidhost: Could not register unpaired callback");
		return false;
	}

	bacpy(&adapter_addr, addr);

	ctrl_io = bt_io_listen(connect_cb, NULL, NULL, NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
				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("hidhost: Failed to listen on control 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, &adapter_addr,
				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("hidhost: Failed to listen on interrupt channel: %s",
								err->message);
		g_error_free(err);

		g_io_channel_shutdown(ctrl_io, TRUE, NULL);
		g_io_channel_unref(ctrl_io);
		ctrl_io = NULL;

		return false;
	}

	hal_ipc = ipc;

	ipc_register(hal_ipc, HAL_SERVICE_ID_HIDHOST, cmd_handlers,
						G_N_ELEMENTS(cmd_handlers));

	return true;
}

void bt_hid_unregister(void)
{
	DBG("");

	if (hog_app > 0)
		bt_gatt_unregister_app(hog_app);

	g_slist_free_full(devices, hid_device_free);
	devices = NULL;

	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;
	}

	ipc_unregister(hal_ipc, HAL_SERVICE_ID_HIDHOST);
	hal_ipc = NULL;

	bt_unpaired_unregister(hid_unpaired_cb);
}
