/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2004-2009  Marcel Holtmann <marcel@holtmann.org>
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/socket.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <bluetooth/hidp.h>
#include <bluetooth/l2cap.h>
#include <bluetooth/rfcomm.h>
#include <bluetooth/sdp.h>
#include <bluetooth/sdp_lib.h>

#include <glib.h>
#include <dbus/dbus.h>
#include <gdbus.h>

#include "logging.h"
#include "textfile.h"
#include "uinput.h"

#include "../src/storage.h"
#include "../src/manager.h"
#include "../src/dbus-common.h"
#include "adapter.h"

#include "device.h"
#include "error.h"
#include "fakehid.h"
#include "glib-helper.h"
#include "btio.h"

#define INPUT_DEVICE_INTERFACE "org.bluez.Input"

#define BUF_SIZE		16

#define UPDOWN_ENABLED		1

#define FI_FLAG_CONNECTED	1

struct input_conn {
	struct fake_input	*fake;
	DBusMessage		*pending_connect;
	char			*uuid;
	char			*alias;
	GIOChannel		*ctrl_io;
	GIOChannel		*intr_io;
	guint			ctrl_watch;
	guint			intr_watch;
	int			timeout;
	struct input_device	*idev;
};

struct input_device {
	DBusConnection		*conn;
	char			*path;
	bdaddr_t		src;
	bdaddr_t		dst;
	uint32_t		handle;
	char			*name;
	GSList			*connections;
};

GSList *devices = NULL;

static struct input_device *find_device_by_path(GSList *list, const char *path)
{
	GSList *l;

	for (l = list; l; l = l->next) {
		struct input_device *idev = l->data;

		if (!strcmp(idev->path, path))
			return idev;
	}

	return NULL;
}

static struct input_conn *find_connection(GSList *list, const char *pattern)
{
	GSList *l;

	for (l = list; l; l = l->next) {
		struct input_conn *iconn = l->data;

		if (!strcasecmp(iconn->uuid, pattern))
			return iconn;

		if (!strcasecmp(iconn->alias, pattern))
			return iconn;
	}

	return NULL;
}

static void input_conn_free(struct input_conn *iconn)
{
	if (iconn->pending_connect)
		dbus_message_unref(iconn->pending_connect);

	if (iconn->ctrl_watch)
		g_source_remove(iconn->ctrl_watch);

	if (iconn->intr_watch)
		g_source_remove(iconn->intr_watch);

	if (iconn->intr_io)
		g_io_channel_unref(iconn->intr_io);

	if (iconn->ctrl_io)
		g_io_channel_unref(iconn->ctrl_io);

	g_free(iconn->uuid);
	g_free(iconn->alias);
	g_free(iconn->fake);
	g_free(iconn);
}

static void input_device_free(struct input_device *idev)
{
	dbus_connection_unref(idev->conn);
	g_free(idev->name);
	g_free(idev->path);
	g_free(idev);
}

static int uinput_create(char *name)
{
	struct uinput_dev dev;
	int fd, err;

	fd = open("/dev/uinput", O_RDWR);
	if (fd < 0) {
		fd = open("/dev/input/uinput", O_RDWR);
		if (fd < 0) {
			fd = open("/dev/misc/uinput", O_RDWR);
			if (fd < 0) {
				err = errno;
				error("Can't open input device: %s (%d)",
							strerror(err), err);
				return -err;
			}
		}
	}

	memset(&dev, 0, sizeof(dev));
	if (name)
		strncpy(dev.name, name, UINPUT_MAX_NAME_SIZE - 1);

	dev.id.bustype = BUS_BLUETOOTH;
	dev.id.vendor  = 0x0000;
	dev.id.product = 0x0000;
	dev.id.version = 0x0000;

	if (write(fd, &dev, sizeof(dev)) < 0) {
		err = errno;
		error("Can't write device information: %s (%d)",
						strerror(err), err);
		close(fd);
		errno = err;
		return -err;
	}

	ioctl(fd, UI_SET_EVBIT, EV_KEY);
	ioctl(fd, UI_SET_EVBIT, EV_REL);
	ioctl(fd, UI_SET_EVBIT, EV_REP);

	ioctl(fd, UI_SET_KEYBIT, KEY_UP);
	ioctl(fd, UI_SET_KEYBIT, KEY_PAGEUP);
	ioctl(fd, UI_SET_KEYBIT, KEY_DOWN);
	ioctl(fd, UI_SET_KEYBIT, KEY_PAGEDOWN);

	if (ioctl(fd, UI_DEV_CREATE, NULL) < 0) {
		err = errno;
		error("Can't create uinput device: %s (%d)",
						strerror(err), err);
		close(fd);
		errno = err;
		return -err;
	}

	return fd;
}

static int decode_key(const char *str)
{
	static int mode = UPDOWN_ENABLED, gain = 0;

	uint16_t key;
	int new_gain;

	/* Switch from key up/down to page up/down */
	if (strncmp("AT+CKPD=200", str, 11) == 0) {
		mode = ~mode;
		return KEY_RESERVED;
	}

	if (strncmp("AT+VG", str, 5))
		return KEY_RESERVED;

	/* Gain key pressed */
	if (strlen(str) != 10)
		return KEY_RESERVED;

	new_gain = strtol(&str[7], NULL, 10);
	if (new_gain <= gain)
		key = (mode == UPDOWN_ENABLED ? KEY_UP : KEY_PAGEUP);
	else
		key = (mode == UPDOWN_ENABLED ? KEY_DOWN : KEY_PAGEDOWN);

	gain = new_gain;

	return key;
}

static void send_event(int fd, uint16_t type, uint16_t code, int32_t value)
{
	struct uinput_event event;
	int err;

	memset(&event, 0, sizeof(event));
	event.type	= type;
	event.code	= code;
	event.value	= value;

	err = write(fd, &event, sizeof(event));
}

static void send_key(int fd, uint16_t key)
{
	/* Key press */
	send_event(fd, EV_KEY, key, 1);
	send_event(fd, EV_SYN, SYN_REPORT, 0);
	/* Key release */
	send_event(fd, EV_KEY, key, 0);
	send_event(fd, EV_SYN, SYN_REPORT, 0);
}

static gboolean rfcomm_io_cb(GIOChannel *chan, GIOCondition cond, gpointer data)
{
	struct fake_input *fake = data;
	const char *ok = "\r\nOK\r\n";
	char buf[BUF_SIZE];
	gsize bread = 0, bwritten;
	uint16_t key;

	if (cond & G_IO_NVAL)
		return FALSE;

	if (cond & (G_IO_HUP | G_IO_ERR)) {
		error("Hangup or error on rfcomm server socket");
		goto failed;
	}

	memset(buf, 0, BUF_SIZE);
	if (g_io_channel_read(chan, buf, sizeof(buf) - 1,
				&bread) != G_IO_ERROR_NONE) {
		error("IO Channel read error");
		goto failed;
	}

	debug("Received: %s", buf);

	if (g_io_channel_write(chan, ok, 6, &bwritten) != G_IO_ERROR_NONE) {
		error("IO Channel write error");
		goto failed;
	}

	key = decode_key(buf);
	if (key != KEY_RESERVED)
		send_key(fake->uinput, key);

	return TRUE;

failed:
	ioctl(fake->uinput, UI_DEV_DESTROY);
	close(fake->uinput);
	fake->uinput = -1;
	g_io_channel_unref(fake->io);

	return FALSE;
}

static inline DBusMessage *not_supported(DBusMessage *msg)
{
	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
							"Not supported");
}

static inline DBusMessage *in_progress(DBusMessage *msg)
{
	return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress",
				"Device connection already in progress");
}

static inline DBusMessage *already_connected(DBusMessage *msg)
{
	return g_dbus_create_error(msg, ERROR_INTERFACE ".AlreadyConnected",
					"Already connected to a device");
}

static inline DBusMessage *connection_attempt_failed(DBusMessage *msg,
							const char *err)
{
	return g_dbus_create_error(msg,
				ERROR_INTERFACE ".ConnectionAttemptFailed",
				err ? err : "Connection attempt failed");
}

static void rfcomm_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
{
	struct input_conn *iconn = user_data;
	struct input_device *idev = iconn->idev;
	struct fake_input *fake = iconn->fake;
	DBusMessage *reply;

	if (err) {
		reply = connection_attempt_failed(iconn->pending_connect,
								err->message);
		goto failed;
	}

	fake->rfcomm = g_io_channel_unix_get_fd(chan);

	/*
	 * FIXME: Some headsets required a sco connection
	 * first to report volume gain key events
	 */
	fake->uinput = uinput_create(idev->name);
	if (fake->uinput < 0) {
		g_io_channel_shutdown(chan, TRUE, NULL);
		reply = connection_attempt_failed(iconn->pending_connect,
							strerror(errno));
		goto failed;
	}

	fake->io = g_io_channel_unix_new(fake->rfcomm);
	g_io_channel_set_close_on_unref(fake->io, TRUE);
	g_io_add_watch(fake->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
						(GIOFunc) rfcomm_io_cb, fake);

	/* Replying to the requestor */
	reply = dbus_message_new_method_return(iconn->pending_connect);
	g_dbus_send_message(idev->conn, reply);

	dbus_message_unref(iconn->pending_connect);
	iconn->pending_connect = NULL;

	return;

failed:
	g_dbus_send_message(idev->conn, reply);
	dbus_message_unref(iconn->pending_connect);
	iconn->pending_connect = NULL;
}

static gboolean rfcomm_connect(struct input_conn *iconn, GError **err)
{
	struct input_device *idev = iconn->idev;
	GIOChannel *io;

	io = bt_io_connect(BT_IO_RFCOMM, rfcomm_connect_cb, iconn,
				NULL, err,
				BT_IO_OPT_SOURCE_BDADDR, &idev->src,
				BT_IO_OPT_DEST_BDADDR, &idev->dst,
				BT_IO_OPT_INVALID);
	if (!io)
		return FALSE;

	g_io_channel_unref(io);

	return TRUE;
}

static gboolean intr_watch_cb(GIOChannel *chan, GIOCondition cond, gpointer data)
{
	struct input_conn *iconn = data;
	struct input_device *idev = iconn->idev;
	gboolean connected = FALSE;

	/* 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)) && iconn->ctrl_watch)
		g_io_channel_shutdown(chan, TRUE, NULL);

	emit_property_changed(idev->conn, idev->path, INPUT_DEVICE_INTERFACE,
				"Connected", DBUS_TYPE_BOOLEAN, &connected);

	iconn->intr_watch = 0;

	g_io_channel_unref(iconn->intr_io);
	iconn->intr_io = NULL;

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

	return FALSE;
}

static gboolean ctrl_watch_cb(GIOChannel *chan, GIOCondition cond, gpointer data)
{
	struct input_conn *iconn = data;

	/* 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)) && iconn->intr_watch)
		g_io_channel_shutdown(chan, TRUE, NULL);

	iconn->ctrl_watch = 0;

	g_io_channel_unref(iconn->ctrl_io);
	iconn->ctrl_io = NULL;

	/* Close interrupt channel */
	if (iconn->intr_io && !(cond & G_IO_NVAL))
		g_io_channel_shutdown(iconn->intr_io, TRUE, NULL);

	return FALSE;
}

static gboolean fake_hid_connect(struct input_conn *iconn, GError **err)
{
	struct fake_hid *fhid = iconn->fake->priv;

	return fhid->connect(iconn->fake, err);
}

static int fake_hid_disconnect(struct input_conn *iconn)
{
	struct fake_hid *fhid = iconn->fake->priv;

	return fhid->disconnect(iconn->fake);
}

static void epox_endian_quirk(unsigned char *data, int size)
{
	/* USAGE_PAGE (Keyboard)	05 07
	 * USAGE_MINIMUM (0)		19 00
	 * USAGE_MAXIMUM (65280)	2A 00 FF   <= must be FF 00
	 * LOGICAL_MINIMUM (0)		15 00
	 * LOGICAL_MAXIMUM (65280)	26 00 FF   <= must be FF 00
	 */
	unsigned char pattern[] = { 0x05, 0x07, 0x19, 0x00, 0x2a, 0x00, 0xff,
						0x15, 0x00, 0x26, 0x00, 0xff };
	unsigned int i;

	if (!data)
		return;

	for (i = 0; i < size - sizeof(pattern); i++) {
		if (!memcmp(data + i, pattern, sizeof(pattern))) {
			data[i + 5] = 0xff;
			data[i + 6] = 0x00;
			data[i + 10] = 0xff;
			data[i + 11] = 0x00;
		}
	}
}

static void extract_hid_record(sdp_record_t *rec, struct hidp_connadd_req *req)
{
	sdp_data_t *pdlist, *pdlist2;
	uint8_t attr_val;

	pdlist = sdp_data_get(rec, 0x0101);
	pdlist2 = sdp_data_get(rec, 0x0102);
	if (pdlist) {
		if (pdlist2) {
			if (strncmp(pdlist->val.str, pdlist2->val.str, 5)) {
				strncpy(req->name, pdlist2->val.str, 127);
				strcat(req->name, " ");
			}
			strncat(req->name, pdlist->val.str, 127 - strlen(req->name));
		} else
			strncpy(req->name, pdlist->val.str, 127);
	} else {
		pdlist2 = sdp_data_get(rec, 0x0100);
		if (pdlist2)
			strncpy(req->name, pdlist2->val.str, 127);
	}

	pdlist = sdp_data_get(rec, SDP_ATTR_HID_PARSER_VERSION);
	req->parser = pdlist ? pdlist->val.uint16 : 0x0100;

	pdlist = sdp_data_get(rec, SDP_ATTR_HID_DEVICE_SUBCLASS);
	req->subclass = pdlist ? pdlist->val.uint8 : 0;

	pdlist = sdp_data_get(rec, SDP_ATTR_HID_COUNTRY_CODE);
	req->country = pdlist ? pdlist->val.uint8 : 0;

	pdlist = sdp_data_get(rec, SDP_ATTR_HID_VIRTUAL_CABLE);
	attr_val = pdlist ? pdlist->val.uint8 : 0;
	if (attr_val)
		req->flags |= (1 << HIDP_VIRTUAL_CABLE_UNPLUG);

	pdlist = sdp_data_get(rec, SDP_ATTR_HID_BOOT_DEVICE);
	attr_val = pdlist ? pdlist->val.uint8 : 0;
	if (attr_val)
		req->flags |= (1 << HIDP_BOOT_PROTOCOL_MODE);

	pdlist = sdp_data_get(rec, SDP_ATTR_HID_DESCRIPTOR_LIST);
	if (pdlist) {
		pdlist = pdlist->val.dataseq;
		pdlist = pdlist->val.dataseq;
		pdlist = pdlist->next;

		req->rd_data = g_try_malloc0(pdlist->unitSize);
		if (req->rd_data) {
			memcpy(req->rd_data, (unsigned char *) pdlist->val.str,
								pdlist->unitSize);
			req->rd_size = pdlist->unitSize;
			epox_endian_quirk(req->rd_data, req->rd_size);
		}
	}
}

static int ioctl_connadd(struct hidp_connadd_req *req)
{
	int ctl, err = 0;

	ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HIDP);
	if (ctl < 0)
		return -errno;

	if (ioctl(ctl, HIDPCONNADD, req) < 0)
		err = errno;

	close(ctl);

	return -err;
}

static void encrypt_completed(uint8_t status, gpointer user_data)
{
	struct hidp_connadd_req *req = user_data;
	int err;

	if (status) {
		error("Encryption failed: %s(0x%x)",
				strerror(bt_error(status)), status);
		goto failed;
	}

	err = ioctl_connadd(req);
	if (err == 0)
		goto cleanup;

	error("ioctl_connadd(): %s(%d)", strerror(-err), -err);
failed:
	close(req->intr_sock);
	close(req->ctrl_sock);

cleanup:
	if (req->rd_data)
		free(req->rd_data);

	g_free(req);
}

static int hidp_add_connection(const struct input_device *idev,
				const struct input_conn *iconn)
{
	struct hidp_connadd_req *req;
	struct fake_hid *fake_hid;
	struct fake_input *fake;
	sdp_record_t *rec;
	char src_addr[18], dst_addr[18];
	int err;

	req = g_new0(struct hidp_connadd_req, 1);
	req->ctrl_sock = g_io_channel_unix_get_fd(iconn->ctrl_io);
	req->intr_sock = g_io_channel_unix_get_fd(iconn->intr_io);
	req->flags     = 0;
	req->idle_to   = iconn->timeout;

	ba2str(&idev->src, src_addr);
	ba2str(&idev->dst, dst_addr);

	rec = fetch_record(src_addr, dst_addr, idev->handle);
	if (!rec) {
		error("Rejected connection from unknown device %s", dst_addr);
		err = -EPERM;
		goto cleanup;
	}

	extract_hid_record(rec, req);
	sdp_record_free(rec);

	read_device_id(src_addr, dst_addr, NULL,
				&req->vendor, &req->product, &req->version);

	fake_hid = get_fake_hid(req->vendor, req->product);
	if (fake_hid) {
		fake = g_new0(struct fake_input, 1);
		fake->connect = fake_hid_connect;
		fake->disconnect = fake_hid_disconnect;
		fake->priv = fake_hid;
		err = fake_hid_connadd(fake, iconn->intr_io, fake_hid);
		goto cleanup;
	}

	if (idev->name)
		strncpy(req->name, idev->name, sizeof(req->name) - 1);

	/* Encryption is mandatory for keyboards */
	if (req->subclass & 0x40) {
		err = bt_acl_encrypt(&idev->src, &idev->dst, encrypt_completed, req);
		if (err == 0) {
			/* Waiting async encryption */
			return 0;
		} else if (err != -EALREADY) {
			error("bt_acl_encrypt(): %s(%d)", strerror(-err), -err);
			goto cleanup;
		}

		/* Link already encrypted - reset error */
		err = 0;
	}

	if (req->vendor == 0x054c && req->product == 0x0268) {
		unsigned char buf[] = { 0x53, 0xf4,  0x42, 0x03, 0x00, 0x00 };
		int sk = g_io_channel_unix_get_fd(iconn->ctrl_io);
		err = write(sk, buf, sizeof(buf));
	}

	err = ioctl_connadd(req);

cleanup:
	if (req->rd_data)
		free(req->rd_data);
	g_free(req);

	return err;
}

static int input_device_connected(struct input_device *idev,
						struct input_conn *iconn)
{
	dbus_bool_t connected;
	int err;

	if (iconn->intr_io == NULL || iconn->ctrl_io == NULL)
		return -ENOTCONN;

	err = hidp_add_connection(idev, iconn);
	if (err < 0)
		return err;

	iconn->intr_watch = g_io_add_watch(iconn->intr_io,
					G_IO_HUP | G_IO_ERR | G_IO_NVAL,
					intr_watch_cb, iconn);
	iconn->ctrl_watch = g_io_add_watch(iconn->ctrl_io,
					G_IO_HUP | G_IO_ERR | G_IO_NVAL,
					ctrl_watch_cb, iconn);

	connected = TRUE;
	emit_property_changed(idev->conn, idev->path, INPUT_DEVICE_INTERFACE,
				"Connected", DBUS_TYPE_BOOLEAN, &connected);

	return 0;
}

static void interrupt_connect_cb(GIOChannel *chan, GError *conn_err,
							gpointer user_data)
{
	struct input_conn *iconn = user_data;
	struct input_device *idev = iconn->idev;
	DBusMessage *reply;
	int err;
	const char *err_msg;

	if (conn_err) {
		err_msg = conn_err->message;
		g_io_channel_unref(iconn->intr_io);
		iconn->intr_io = NULL;
		goto failed;
	}

	err = input_device_connected(idev, iconn);
	if (err < 0) {
		err_msg = strerror(-err);
		goto failed;
	}

	/* Replying to the requestor */
	g_dbus_send_reply(idev->conn, iconn->pending_connect, DBUS_TYPE_INVALID);

	dbus_message_unref(iconn->pending_connect);
	iconn->pending_connect = NULL;

	return;

failed:
	error("%s", err_msg);
	reply = connection_attempt_failed(iconn->pending_connect, err_msg);
	g_dbus_send_message(idev->conn, reply);

	if (iconn->ctrl_io)
		g_io_channel_shutdown(iconn->ctrl_io, FALSE, NULL);

	if (iconn->intr_io) {
		if (!conn_err)
			g_io_channel_shutdown(iconn->intr_io, FALSE, NULL);
		g_io_channel_unref(iconn->intr_io);
		iconn->intr_io = NULL;
	}
}

static void control_connect_cb(GIOChannel *chan, GError *conn_err,
							gpointer user_data)
{
	struct input_conn *iconn = user_data;
	struct input_device *idev = iconn->idev;
	DBusMessage *reply;
	GIOChannel *io;
	GError *err = NULL;

	if (conn_err) {
		error("%s", conn_err->message);
		reply = connection_attempt_failed(iconn->pending_connect,
							conn_err->message);
		goto failed;
	}

	/* Connect to the HID interrupt channel */
	io = bt_io_connect(BT_IO_L2CAP, interrupt_connect_cb, iconn,
				NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, &idev->src,
				BT_IO_OPT_DEST_BDADDR, &idev->dst,
				BT_IO_OPT_PSM, L2CAP_PSM_HIDP_INTR,
				BT_IO_OPT_INVALID);
	if (!io) {
		error("%s", err->message);
		reply = connection_attempt_failed(iconn->pending_connect,
							err->message);
		g_error_free(err);
		g_io_channel_shutdown(chan, TRUE, NULL);
		goto failed;
	}

	iconn->intr_io = io;

	return;

failed:
	g_dbus_send_message(idev->conn, reply);
	dbus_message_unref(iconn->pending_connect);
	iconn->pending_connect = NULL;
}

static int fake_disconnect(struct input_conn *iconn)
{
	struct fake_input *fake = iconn->fake;

	if (!fake->io)
		return -ENOTCONN;

	g_io_channel_shutdown(fake->io, TRUE, NULL);
	g_io_channel_unref(fake->io);
	fake->io = NULL;

	if (fake->uinput >= 0) {
		ioctl(fake->uinput, UI_DEV_DESTROY);
		close(fake->uinput);
		fake->uinput = -1;
	}

	return 0;
}

static int is_connected(struct input_conn *iconn)
{
	struct input_device *idev = iconn->idev;
	struct fake_input *fake = iconn->fake;
	struct hidp_conninfo ci;
	int ctl;

	/* Fake input */
	if (fake)
		return fake->flags & FI_FLAG_CONNECTED;

	/* Standard HID */
	ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HIDP);
	if (ctl < 0)
		return 0;

	memset(&ci, 0, sizeof(ci));
	bacpy(&ci.bdaddr, &idev->dst);
	if (ioctl(ctl, HIDPGETCONNINFO, &ci) < 0) {
		close(ctl);
		return 0;
	}

	close(ctl);

	if (ci.state != BT_CONNECTED)
		return 0;
	else
		return 1;
}

static int connection_disconnect(struct input_conn *iconn, uint32_t flags)
{
	struct input_device *idev = iconn->idev;
	struct fake_input *fake = iconn->fake;
	struct hidp_conndel_req req;
	struct hidp_conninfo ci;
	int ctl, err;

	/* Fake input disconnect */
	if (fake) {
		err = fake->disconnect(iconn);
		if (err == 0)
			fake->flags &= ~FI_FLAG_CONNECTED;
		return err;
	}

	/* Standard HID disconnect */
	if (iconn->intr_io)
		g_io_channel_shutdown(iconn->intr_io, TRUE, NULL);
	if (iconn->ctrl_io)
		g_io_channel_shutdown(iconn->ctrl_io, TRUE, NULL);

	ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HIDP);
	if (ctl < 0) {
		error("Can't open HIDP control socket");
		return -errno;
	}

	memset(&ci, 0, sizeof(ci));
	bacpy(&ci.bdaddr, &idev->dst);
	if ((ioctl(ctl, HIDPGETCONNINFO, &ci) < 0) ||
				(ci.state != BT_CONNECTED)) {
		errno = ENOTCONN;
		goto fail;
	}

	memset(&req, 0, sizeof(req));
	bacpy(&req.bdaddr, &idev->dst);
	req.flags = flags;
	if (ioctl(ctl, HIDPCONNDEL, &req) < 0) {
		error("Can't delete the HID device: %s(%d)",
				strerror(errno), errno);
		goto fail;
	}

	close(ctl);

	return 0;

fail:
	err = errno;
	close(ctl);
	errno = err;

	return -err;
}

static int disconnect(struct input_device *idev, uint32_t flags)
{
	struct input_conn *iconn = NULL;
	GSList *l;

	for (l = idev->connections; l; l = l->next) {
		iconn = l->data;

		if (is_connected(iconn))
			break;
	}

	if (!iconn)
		return ENOTCONN;

	return connection_disconnect(iconn, flags);
}

/*
 * Input Device methods
 */
static DBusMessage *device_connect(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct input_device *idev = data;
	struct input_conn *iconn;
	struct fake_input *fake;
	DBusMessage *reply;
	GError *err = NULL;

	iconn = find_connection(idev->connections, "HID");
	if (!iconn)
		return not_supported(msg);

	if (iconn->pending_connect)
		return in_progress(msg);

	if (is_connected(iconn))
		return already_connected(msg);

	iconn->pending_connect = dbus_message_ref(msg);
	fake = iconn->fake;

	if (fake) {
		/* Fake input device */
		if (fake->connect(iconn, &err))
			fake->flags |= FI_FLAG_CONNECTED;
	} else {
		/* HID devices */
		GIOChannel *io;

		io = bt_io_connect(BT_IO_L2CAP, control_connect_cb, iconn,
					NULL, &err,
					BT_IO_OPT_SOURCE_BDADDR, &idev->src,
					BT_IO_OPT_DEST_BDADDR, &idev->dst,
					BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL,
					BT_IO_OPT_INVALID);
		iconn->ctrl_io = io;
	}

	if (err == NULL)
		return NULL;

	error("%s", err->message);
	dbus_message_unref(iconn->pending_connect);
	iconn->pending_connect = NULL;
	reply = connection_attempt_failed(msg, err->message);
	g_error_free(err);
	return reply;
}

static DBusMessage *create_errno_message(DBusMessage *msg, int err)
{
	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
							strerror(err));
}

static DBusMessage *device_disconnect(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct input_device *idev = data;
	int err;

	err = disconnect(idev, 0);
	if (err < 0)
		return create_errno_message(msg, -err);

	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}

static void device_unregister(void *data)
{
	struct input_device *idev = data;

	info("Unregistered interface %s on path %s", INPUT_DEVICE_INTERFACE, idev->path);

	/* Disconnect if applied */
	disconnect(idev, (1 << HIDP_VIRTUAL_CABLE_UNPLUG));
	devices = g_slist_remove(devices, idev);
	input_device_free(idev);
}

static gint connected_cmp(gpointer a, gpointer b)
{
	struct input_conn *iconn = a;

	return !is_connected(iconn);
}

static DBusMessage *device_get_properties(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct input_device *idev = data;
	DBusMessage *reply;
	DBusMessageIter iter;
	DBusMessageIter dict;
	dbus_bool_t connected;

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return NULL;

	dbus_message_iter_init_append(reply, &iter);

	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);

	/* Connected */
	connected = !!g_slist_find_custom(idev->connections, NULL,
					(GCompareFunc) connected_cmp);
	dict_append_entry(&dict, "Connected", DBUS_TYPE_BOOLEAN, &connected);

	dbus_message_iter_close_container(&iter, &dict);

	return reply;
}

static GDBusMethodTable device_methods[] = {
	{ "Connect",		"",	"",	device_connect,
						G_DBUS_METHOD_FLAG_ASYNC },
	{ "Disconnect",		"",	"",	device_disconnect	},
	{ "GetProperties",	"",	"a{sv}",device_get_properties },
	{ }
};

static GDBusSignalTable device_signals[] = {
	{ "PropertyChanged",	"sv"	},
	{ }
};

static struct input_device *input_device_new(DBusConnection *conn,
					const char *path, const bdaddr_t *src,
					const bdaddr_t *dst, const uint32_t handle)
{
	struct input_device *idev;
	char name[249], src_addr[18], dst_addr[18];

	idev = g_new0(struct input_device, 1);
	bacpy(&idev->src, src);
	bacpy(&idev->dst, dst);
	idev->path = g_strdup(path);
	idev->conn = dbus_connection_ref(conn);
	idev->handle = handle;

	ba2str(src, src_addr);
	ba2str(dst, dst_addr);
	if (read_device_name(src_addr, dst_addr, name) == 0)
		idev->name = g_strdup(name);

	if (g_dbus_register_interface(conn, idev->path, INPUT_DEVICE_INTERFACE,
					device_methods, device_signals, NULL,
					idev, device_unregister) == FALSE) {
		error("Failed to register interface %s on path %s",
			INPUT_DEVICE_INTERFACE, path);
		input_device_free(idev);
		return NULL;
	}

	info("Registered interface %s on path %s",
			INPUT_DEVICE_INTERFACE, idev->path);

	return idev;
}

static struct input_conn *input_conn_new(struct input_device *idev,
					const char *uuid, const char *alias,
					int timeout)
{
	struct input_conn *iconn;

	iconn = g_new0(struct input_conn, 1);
	iconn->timeout = timeout;
	iconn->uuid = g_strdup(uuid);
	iconn->alias = g_strdup(alias);
	iconn->idev = idev;

	return iconn;
}

int input_device_register(DBusConnection *conn, const char *path,
			const bdaddr_t *src, const bdaddr_t *dst,
			const char *uuid, uint32_t handle, int timeout)
{
	struct input_device *idev;
	struct input_conn *iconn;

	idev = find_device_by_path(devices, path);
	if (!idev) {
		idev = input_device_new(conn, path, src, dst, handle);
		if (!idev)
			return -EINVAL;
		devices = g_slist_append(devices, idev);
	}

	iconn = input_conn_new(idev, uuid, "hid", timeout);
	if (!iconn)
		return -EINVAL;

	idev->connections = g_slist_append(idev->connections, iconn);

	return 0;
}

int fake_input_register(DBusConnection *conn, const char *path, bdaddr_t *src,
			bdaddr_t *dst, const char *uuid, uint8_t channel)
{
	struct input_device *idev;
	struct input_conn *iconn;

	idev = find_device_by_path(devices, path);
	if (!idev) {
		idev = input_device_new(conn, path, src, dst, 0);
		if (!idev)
			return -EINVAL;
		devices = g_slist_append(devices, idev);
	}

	iconn = input_conn_new(idev, uuid, "hsp", 0);
	if (!iconn)
		return -EINVAL;

	iconn->fake = g_new0(struct fake_input, 1);
	iconn->fake->ch = channel;
	iconn->fake->connect = rfcomm_connect;
	iconn->fake->disconnect = fake_disconnect;

	idev->connections = g_slist_append(idev->connections, iconn);

	return 0;
}

static struct input_device *find_device(const bdaddr_t *src,
					const bdaddr_t *dst)
{
	GSList *list;

	for (list = devices; list != NULL; list = list->next) {
		struct input_device *idev = list->data;

		if (!bacmp(&idev->src, src) && !bacmp(&idev->dst, dst))
			return idev;
	}

	return NULL;
}

int input_device_unregister(const char *path, const char *uuid)
{
	struct input_device *idev;
	struct input_conn *iconn;

	idev = find_device_by_path(devices, path);
	if (idev == NULL)
		return -EINVAL;

	iconn = find_connection(idev->connections, uuid);
	if (iconn == NULL)
		return -EINVAL;

	if (iconn->pending_connect) {
		/* Pending connection running */
		return -EBUSY;
	}

	idev->connections = g_slist_remove(idev->connections, iconn);
	input_conn_free(iconn);
	if (idev->connections)
		return 0;

	g_dbus_unregister_interface(idev->conn, path, INPUT_DEVICE_INTERFACE);

	return 0;
}

int input_device_set_channel(const bdaddr_t *src, const bdaddr_t *dst, int psm,
								GIOChannel *io)
{
	struct input_device *idev = find_device(src, dst);
	struct input_conn *iconn;

	if (!idev)
		return -ENOENT;

	iconn = find_connection(idev->connections, "hid");
	if (!iconn)
		return -ENOENT;

	switch (psm) {
	case L2CAP_PSM_HIDP_CTRL:
		if (iconn->ctrl_io)
			return -EALREADY;
		iconn->ctrl_io = g_io_channel_ref(io);
		break;
	case L2CAP_PSM_HIDP_INTR:
		if (iconn->intr_io)
			return -EALREADY;
		iconn->intr_io = g_io_channel_ref(io);
		break;
	}

	return 0;
}

int input_device_close_channels(const bdaddr_t *src, const bdaddr_t *dst)
{
	struct input_device *idev = find_device(src, dst);
	struct input_conn *iconn;

	if (!idev)
		return -ENOENT;

	iconn = find_connection(idev->connections, "hid");
	if (!iconn)
		return -ENOENT;

	if (iconn->intr_io)
		g_io_channel_shutdown(iconn->intr_io, TRUE, NULL);

	if (iconn->ctrl_io)
		g_io_channel_shutdown(iconn->ctrl_io, TRUE, NULL);

	return 0;
}

int input_device_connadd(const bdaddr_t *src, const bdaddr_t *dst)
{
	struct input_device *idev;
	struct input_conn *iconn;
	int err;

	idev = find_device(src, dst);
	if (!idev)
		return -ENOENT;

	iconn = find_connection(idev->connections, "hid");
	if (!iconn)
		return -ENOENT;

	err = input_device_connected(idev, iconn);
	if (err < 0)
		goto error;

	return 0;

error:
	if (iconn->ctrl_io) {
		g_io_channel_shutdown(iconn->ctrl_io, FALSE, NULL);
		g_io_channel_unref(iconn->ctrl_io);
		iconn->ctrl_io = NULL;
	}
	if (iconn->intr_io) {
		g_io_channel_shutdown(iconn->intr_io, FALSE, NULL);
		g_io_channel_unref(iconn->intr_io);
		iconn->intr_io = NULL;
	}

	return err;
}
