/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2004-2007  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/hidp.h>
#include <bluetooth/l2cap.h>
#include <bluetooth/rfcomm.h>

#include <glib.h>

#include <dbus/dbus.h>

#include "dbus.h"
#include "dbus-helper.h"
#include "logging.h"
#include "textfile.h"
#include "uinput.h"

#include "device.h"
#include "error.h"
#include "manager.h"
#include "storage.h"

#define INPUT_DEVICE_INTERFACE	"org.bluez.input.Device"

#define BUF_SIZE	16

#define UPDOWN_ENABLED		1

struct fake_input {
	GIOChannel	*io;
	int		rfcomm; /* RFCOMM socket */
	int		uinput;	/* uinput socket */
	uint8_t		ch;	/* RFCOMM channel number */
};

struct device {
	bdaddr_t		src;
	bdaddr_t		dst;
	char			*name;
	uint8_t			major;
	uint8_t			minor;
	uint16_t		product;
	uint16_t		vendor;
	struct fake_input	*fake;
	DBusMessage		*pending_connect;
	DBusConnection		*conn;
	char			*path;
	int			ctrl_sk;
	int			intr_sk;
	guint			watch;
};

GSList *devices = NULL;

static struct device *device_new(bdaddr_t *src, bdaddr_t *dst, uint8_t subclass)
{
	struct device *idev;
	uint32_t cls;
	uint8_t major, minor;

	if (!subclass) {
		if (read_device_class(src, dst, &cls) < 0)
			return NULL;

		major 	= (cls >> 8) & 0x1f;
		minor	= (cls >> 2) & 0x3f;
	} else {
		major	= 0x05; /* Peripheral */
		minor	= (subclass >> 2) & 0x3f;
	}

	idev = g_new0(struct device, 1);

	bacpy(&idev->src, src);
	bacpy(&idev->dst, dst);

	read_device_name(src, dst, &idev->name);

	idev->major	= major;
	idev->minor	= minor;
	idev->ctrl_sk	= -1;
	idev->intr_sk	= -1;

	return idev;
}

static void device_free(struct device *idev)
{
	if (!idev)
		return;
	if (idev->name)
		g_free(idev->name);
	if (idev->fake)
		g_free(idev->fake);
	if (idev->path)
		g_free(idev->path);
	if (idev->pending_connect)
		dbus_message_unref(idev->pending_connect);
	dbus_connection_unref(idev->conn);
	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);

	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 const char *create_input_path(uint8_t major, uint8_t minor)
{
	static char path[48];
	char subpath[32];
	static int next_id = 0;

	switch (major) {
	case 0x02: /* Phone */	
		strcpy(subpath, "phone");	
		break;
	case 0x04: /* Audio */
		switch (minor) {
		/* FIXME: Testing required */
		case 0x01: /* Wearable Headset Device */
			strcpy(subpath, "wearable");
			break;
		case 0x02: /* Hands-free */
			strcpy(subpath, "handsfree");
			break;
		case 0x06: /* Headphone */
			strcpy(subpath, "headphone");
			break;
		default:
			return NULL;
		}
		break;
	case 0x05: /* Peripheral */
		switch (minor & 0x30) {
		case 0x10:
			strcpy(subpath, "keyboard");
			break;
		case 0x20:
			strcpy(subpath, "pointing");
			break;
		case 0x30:
			strcpy(subpath, "combo");
			break;
		default:
			subpath[0] = '\0';
			break;
		}

		if ((minor & 0x0f) && (strlen(subpath) > 0))
			strcat(subpath, "/");

		switch (minor & 0x0f) {
		case 0x00:
			break;
		case 0x01:
			strcat(subpath, "joystick");
			break;
		case 0x02:
			strcat(subpath, "gamepad");
			break;
		case 0x03:
			strcat(subpath, "remotecontrol");
			break;
		case 0x04:
			strcat(subpath, "sensing");
			break;
		case 0x05:
			strcat(subpath, "digitizertablet");
			break;
		case 0x06:
			strcat(subpath, "cardreader");
			break;
		default:
			strcat(subpath, "reserved");
			break;
		}
		break;
	default:
			return NULL;
	}

	snprintf(path, 48, "%s/%s%d", INPUT_PATH, subpath, next_id++);
	return path;
}

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 gboolean rfcomm_connect_cb(GIOChannel *chan,
			GIOCondition cond, struct device *idev)
{
	struct fake_input *fake;
	DBusMessage *reply;
	const char *path;
	socklen_t len;
	int ret, err;

	fake = idev->fake;
	fake->rfcomm = g_io_channel_unix_get_fd(chan);

	if (cond & G_IO_NVAL)
		return FALSE;

	if (cond & (G_IO_ERR | G_IO_HUP)) {
		err = EIO;
		goto failed;
	}

	len = sizeof(ret);
	if (getsockopt(fake->rfcomm, SOL_SOCKET, SO_ERROR, &ret, &len) < 0) {
		err = errno;
		error("getsockopt(SO_ERROR): %s (%d)", strerror(err), err);
		goto failed;
	}

	if (ret != 0) {
		err = ret;
		error("connect(): %s (%d)", strerror(err), err);
		goto failed;
	}

	/* 
	 * FIXME: Some headsets required a sco connection
	 * first to report volume gain key events
	 */
	fake->uinput = uinput_create(idev->name);
	if (fake->uinput < 0) {
		err = 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(idev->pending_connect);
	send_message_and_unref(idev->conn, reply);

	/* Sending the Connected signal */
	path = dbus_message_get_path(idev->pending_connect);
	dbus_connection_emit_signal(idev->conn, path,
			INPUT_DEVICE_INTERFACE, "Connected",
			DBUS_TYPE_INVALID); 

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

	return FALSE;

failed:
	err_connection_failed(idev->conn,
			idev->pending_connect, strerror(err));
	dbus_message_unref(idev->pending_connect);
	idev->pending_connect = NULL;

	g_io_channel_close(chan);

	return FALSE;
}

static int rfcomm_connect(struct device *idev)
{
	struct sockaddr_rc addr;
	GIOChannel *io;
	int sk, err;

	sk = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
	if (sk < 0) {
		err = errno;
		error("socket: %s (%d)", strerror(err), err);
		return -err;
	}

	memset(&addr, 0, sizeof(addr));
	addr.rc_family = AF_BLUETOOTH;
	bacpy(&addr.rc_bdaddr, &idev->src);
	addr.rc_channel =  0;

	if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		err = errno;
		error("bind: %s (%d)", strerror(err), err);
		goto failed;
	}

	if (set_nonblocking(sk) < 0) {
		err = errno;
		error("Set non blocking: %s (%d)", strerror(err), err);
		goto failed;
	}

	memset(&addr, 0, sizeof(addr));
	addr.rc_family = AF_BLUETOOTH;
	bacpy(&addr.rc_bdaddr, &idev->dst);
	addr.rc_channel = idev->fake->ch;

	io = g_io_channel_unix_new(sk);
	g_io_channel_set_close_on_unref(io, FALSE);

	if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		char peer[18]; /* FIXME: debug purpose */
		if (!(errno == EAGAIN || errno == EINPROGRESS)) {
			err = errno;
			error("connect() failed: %s (%d)",
					strerror(err), err);
			g_io_channel_unref(io);
			goto failed;
		}

		ba2str(&idev->dst, peer);
		debug("RFCOMM connection in progress: %s channel:%d", peer, idev->fake->ch);
		g_io_add_watch(io, G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
				(GIOFunc) rfcomm_connect_cb, idev);
	} else {
		debug("Connect succeeded with first try");
		rfcomm_connect_cb(io, G_IO_OUT, idev);
	}

	g_io_channel_unref(io);

	return 0;

failed:
	close(sk);
	errno = err;

	return -err;
}

static gboolean connection_event(GIOChannel *chan, GIOCondition cond, gpointer data)
{
	struct device *idev = data;
	gboolean ret = TRUE;

	if (cond & G_IO_NVAL)
		ret = FALSE;

	if (cond & (G_IO_HUP | G_IO_ERR)) {
		g_io_channel_close(chan);
		ret = FALSE;
	}

	if (ret == FALSE) {
		dbus_connection_emit_signal(idev->conn,
				idev->path,
				INPUT_DEVICE_INTERFACE,
				"Disconnected",
				DBUS_TYPE_INVALID);
		idev->watch = 0;
	}

	return ret;
}

static guint create_watch(int sk, struct device *idev)
{
	guint id;
	GIOChannel *io;

	io = g_io_channel_unix_new(sk);
	id = g_io_add_watch(io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
			connection_event, idev);
	g_io_channel_unref(io);

	return id;
}

static int hidp_connadd(bdaddr_t *src, bdaddr_t *dst, int ctrl_sk, int intr_sk, const char *name)
{
	struct hidp_connadd_req req;
	char addr[18];
	int ctl, err, timeout = 30;

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

	ba2str(dst, addr);

	memset(&req, 0, sizeof(req));
	req.ctrl_sock = ctrl_sk;
	req.intr_sock = intr_sk;
	req.flags     = 0;
	req.idle_to   = timeout * 60;

	err = get_stored_device_info(src, dst, &req);
	if (err < 0) {
		error("Rejected connection from unknown device %s", addr);
		goto cleanup;
	}

	if (req.subclass & 0x40) {
		err = encrypt_link(src, dst);
		if (err < 0 && err != -ENOKEY)
			goto cleanup;
	}

	if (name)
		strncpy(req.name, name, 128);

	info("New input device %s (%s)", addr, req.name);

	if (req.vendor == 0x054c && req.product == 0x0268) {
		unsigned char buf[] = { 0x53, 0xf4,  0x42, 0x03, 0x00, 0x00 };
		err = write(ctrl_sk, buf, sizeof(buf));
	}

	err = ioctl(ctl, HIDPCONNADD, &req);
cleanup:
	close(ctl);

	if (req.rd_data)
		free(req.rd_data);

	return err;
}

static gboolean interrupt_connect_cb(GIOChannel *chan,
			GIOCondition cond, struct device *idev)
{
	int isk, ret, err;
	socklen_t len;

	isk = g_io_channel_unix_get_fd(chan);

	if (cond & G_IO_NVAL) {
		err = EHOSTDOWN;
		isk = -1;
		goto failed;
	}

	if (cond & (G_IO_HUP | G_IO_ERR)) {
		err = EHOSTDOWN;
		error("Hangup or error on HIDP interrupt socket");
		goto failed;

	}

	len = sizeof(ret);
	if (getsockopt(isk, SOL_SOCKET, SO_ERROR, &ret, &len) < 0) {
		err = errno;
		error("getsockopt(SO_ERROR): %s (%d)", strerror(err), err);
		goto failed;
	}

	if (ret != 0) {
		err = ret;
		error("connect(): %s (%d)", strerror(ret), ret);
		goto failed;
	}

	idev->intr_sk = isk;
	err = hidp_connadd(&idev->src, &idev->dst, idev->ctrl_sk, idev->intr_sk, idev->name);
	if (err < 0)
		goto failed;

	idev->watch = create_watch(idev->ctrl_sk, idev);
	dbus_connection_emit_signal(idev->conn,
			idev->path,
			INPUT_DEVICE_INTERFACE,
			"Connected",
			DBUS_TYPE_INVALID);

	/* Replying to the requestor */
	send_message_and_unref(idev->conn,
		dbus_message_new_method_return(idev->pending_connect));

	goto cleanup;
failed:
	err_connection_failed(idev->conn,
		idev->pending_connect, strerror(err));
	if (isk > 0)
		close(isk);
	close(idev->ctrl_sk);
	idev->intr_sk = -1;
	idev->ctrl_sk = -1;

cleanup:
	dbus_message_unref(idev->pending_connect);
	idev->pending_connect = NULL;

	return FALSE;
}

static gboolean control_connect_cb(GIOChannel *chan,
			GIOCondition cond, struct device *idev)
{
	int ret, csk, err;
	socklen_t len;

	csk = g_io_channel_unix_get_fd(chan);

	if (cond & G_IO_NVAL) {
		err = EHOSTDOWN;
		csk = -1;
		goto failed;
	}

	if (cond & (G_IO_HUP | G_IO_ERR)) {
		err = EHOSTDOWN;
		error("Hangup or error on HIDP control socket");
		goto failed;
	}

	/* Set HID control channel */
	idev->ctrl_sk = csk;

	len = sizeof(ret);
	if (getsockopt(csk, SOL_SOCKET, SO_ERROR, &ret, &len) < 0) {
		err = errno;
		error("getsockopt(SO_ERROR): %s (%d)", strerror(err), err);
		goto failed;
	}

	if (ret != 0) {
		err = ret;
		error("connect(): %s (%d)", strerror(ret), ret);
		goto failed;
	}

	/* Connect to the HID interrupt channel */
	if (l2cap_connect(&idev->src, &idev->dst, L2CAP_PSM_HIDP_INTR,
				(GIOFunc) interrupt_connect_cb, idev) < 0) {

		err = errno;
		error("L2CAP connect failed:%s (%d)", strerror(errno), errno);
		goto failed;
	}

	return FALSE;

failed:
	if (csk > 0)
		close(csk);

	idev->ctrl_sk = -1;
	err_connection_failed(idev->conn,
			idev->pending_connect, strerror(err));
	dbus_message_unref(idev->pending_connect);
	idev->pending_connect = NULL;

	return FALSE;
}

static int disconnect(struct device *idev, uint32_t flags)
{
	struct fake_input *fake = idev->fake;
	struct hidp_conndel_req req;
	struct hidp_conninfo ci;
	int ctl, err;

	/* Fake input disconnect */
	if (fake) {
		if (!fake->io)
			return -ENOTCONN;

		g_io_channel_close(fake->io);
		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;
	}

	/* Standard HID disconnect */
	if (idev->ctrl_sk >= 0) {
		close(idev->ctrl_sk);
		idev->ctrl_sk = -1;
	}
	if (idev->intr_sk >= 0) {
		close(idev->intr_sk);
		idev->intr_sk = -1;
	}

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

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

	memset(&req, 0, sizeof(struct hidp_conndel_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 is_connected(struct device *idev)
{
	struct fake_input *fake = idev->fake;
	struct hidp_conninfo ci;
	int ctl;

	/* Fake input */
	if (fake) {
		if (fake->io)
			return 1;
		else
			return 0;
	}

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

	memset(&ci, 0, sizeof(struct hidp_conninfo));
	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;
}

/*
 * Input Device methods
 */
static DBusHandlerResult device_connect(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct device *idev = data;

	if (idev->pending_connect)
		return err_connection_failed(conn, msg, "Connection in progress");

	if (is_connected(idev))
		return err_already_connected(conn, msg);

	idev->pending_connect = dbus_message_ref(msg);

	/* Fake input device */
	if (idev->fake) {
		if (rfcomm_connect(idev) < 0) {
			const char *str = strerror(errno);
			error("RFCOMM connect failed: %s(%d)", str, errno);
			dbus_message_unref(idev->pending_connect);
			idev->pending_connect = NULL;
			return err_connection_failed(conn, msg, str);
		}
		return DBUS_HANDLER_RESULT_HANDLED;
	}

	/* HID devices */
	if (l2cap_connect(&idev->src, &idev->dst, L2CAP_PSM_HIDP_CTRL,
				(GIOFunc) control_connect_cb, idev) < 0) {
		int err = errno;

		error("L2CAP connect failed: %s(%d)", strerror(err), err);
		dbus_message_unref(idev->pending_connect);
		idev->pending_connect = NULL;
		return err_connection_failed(conn, msg, strerror(err));
	}

	return DBUS_HANDLER_RESULT_HANDLED;
}

static DBusHandlerResult device_disconnect(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct device *idev = data;

	if (disconnect(idev, 0) < 0)
		return err_failed(conn, msg, strerror(errno));

	/* Replying to the requestor */
	return send_message_and_unref(conn,
			dbus_message_new_method_return(msg));
}

static DBusHandlerResult device_is_connected(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct device *idev = data;
	DBusMessage *reply;
	dbus_bool_t connected;

	connected = is_connected(idev);
	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	dbus_message_append_args(reply,
			DBUS_TYPE_BOOLEAN, &connected,
			DBUS_TYPE_INVALID);

	return send_message_and_unref(conn, reply);
}

static DBusHandlerResult device_get_adapter(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct device *idev = data;
	DBusMessage *reply;
	char addr[18];
	const char *paddr = addr;

	ba2str(&idev->src, addr);

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

	dbus_message_append_args(reply,
			DBUS_TYPE_STRING, &paddr,
			DBUS_TYPE_INVALID);

	return send_message_and_unref(conn, reply);
}

static DBusHandlerResult device_get_address(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct device *idev = data;
	DBusMessage *reply;
	char addr[18];
	const char *paddr = addr;

	ba2str(&idev->dst, addr);

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

	dbus_message_append_args(reply,
			DBUS_TYPE_STRING, &paddr,
			DBUS_TYPE_INVALID);

	return send_message_and_unref(conn, reply);
}

static DBusHandlerResult device_get_name(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct device *idev = data;
	DBusMessage *reply;
	const char *pname = (idev->name ? idev->name : "");
	
	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	dbus_message_append_args(reply,
			DBUS_TYPE_STRING, &pname,
			DBUS_TYPE_INVALID);

	return send_message_and_unref(conn, reply);
}

static DBusHandlerResult device_get_product_id(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct device *idev = data;
	DBusMessage *reply;

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

	dbus_message_append_args(reply,
			DBUS_TYPE_UINT16, &idev->product,
			DBUS_TYPE_INVALID);

	return send_message_and_unref(conn, reply);
}

static DBusHandlerResult device_get_vendor_id(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct device *idev = data;
	DBusMessage *reply;

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

	dbus_message_append_args(reply,
			DBUS_TYPE_UINT16, &idev->vendor,
			DBUS_TYPE_INVALID);

	return send_message_and_unref(conn, reply);
}

static void device_unregister(DBusConnection *conn, void *data)
{
	struct device *idev = data;

	/* Disconnect if applied */
	disconnect(idev, (1 << HIDP_VIRTUAL_CABLE_UNPLUG));
	device_free(idev);
}

static DBusMethodVTable device_methods[] = {
	{ "Connect",		device_connect,		"",	"" 	},
	{ "Disconnect",		device_disconnect,	"",	"" 	},
	{ "IsConnected",	device_is_connected,	"",	"b"	},
	{ "GetAdapter",		device_get_adapter,	"",	"s"	},
	{ "GetAddress",		device_get_address,	"",	"s"	},
	{ "GetName",		device_get_name,	"",	"s"	},
	{ "GetProductId",	device_get_product_id,	"",	"q"	},
	{ "GetVendorId",	device_get_vendor_id,	"",	"q"	},
	{ NULL, NULL, NULL, NULL }
};

static DBusSignalVTable device_signals[] = {
	{ "Connected",		""	},
	{ "Disconnected",	""	},
	{ NULL, NULL }
};

/*
 * Input registration functions
 */
static int register_path(DBusConnection *conn, const char *path, struct device *idev)
{
	if (!dbus_connection_create_object_path(conn, path,
						idev, device_unregister)) {
		error("Input device path registration failed");
		return -EINVAL;
	}

	if (!dbus_connection_register_interface(conn, path,
						INPUT_DEVICE_INTERFACE,
						device_methods,
						device_signals, NULL)) {
		error("Failed to register %s interface to %s",
				INPUT_DEVICE_INTERFACE, path);
		dbus_connection_destroy_object_path(conn, path);
		return -1;
	}

	dbus_connection_emit_signal(conn, INPUT_PATH,
			INPUT_MANAGER_INTERFACE, "DeviceCreated",
			DBUS_TYPE_STRING, &path,
			DBUS_TYPE_INVALID);

	devices = g_slist_append(devices, idev);

	info("Created input device: %s", path);

	return 0;
}

int input_device_register(DBusConnection *conn, bdaddr_t *src, bdaddr_t *dst,
				struct hidp_connadd_req *hid, const char **ppath)
{
	struct device *idev;
	const char *path;
	int err;

	idev = device_new(src, dst, hid->subclass);
	if (!idev)
		return -EINVAL;

	path = create_input_path(idev->major, idev->minor);
	if (!path) {
		device_free(idev);
		return -EINVAL;
	}

	idev->path	= g_strdup(path);
	idev->product	= hid->product;
	idev->vendor	= hid->vendor;
	idev->conn	= dbus_connection_ref(conn);

	err = register_path(conn, path, idev);

	if (!err && ppath)
		*ppath = path;

	return err;
}

int fake_input_register(DBusConnection *conn, bdaddr_t *src,
			bdaddr_t *dst, uint8_t ch, const char **ppath)
{
	struct device *idev;
	const char *path;
	int err;

	idev = device_new(src, dst, 0);
	if (!idev)
		return -EINVAL;

	path = create_input_path(idev->major, idev->minor);
	if (!path) {
		device_free(idev);
		return -EINVAL;
	}

	idev->path = g_strdup(path);
	idev->conn = dbus_connection_ref(conn);

	/* FIXME: Missing set product and vendor */

	idev->fake = g_new0(struct fake_input, 1);
	idev->fake->ch = ch;

	err = register_path(conn, path, idev);

	if (!err && ppath)
		*ppath = path;

	return err;
}

int input_device_unregister(DBusConnection *conn, const char *path)
{
	struct device *idev;

	if (!dbus_connection_get_object_user_data(conn,
				path, (void *) &idev) || !idev)
		return -EINVAL;

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

	del_stored_device_info(&idev->src, &idev->dst);

	devices = g_slist_remove(devices, idev);

	/*
	 * Workaround: if connected, the watch will not be able
	 * to access the D-Bus data assigned to this path
	 * because the object path data was destroyed.
	 */
	if (idev->watch) {
		g_source_remove(idev->watch);
		idev->watch  = 0;
		dbus_connection_emit_signal(conn,
				path,
				INPUT_DEVICE_INTERFACE,
				"Disconnected",
				DBUS_TYPE_INVALID);
	}

	dbus_connection_destroy_object_path(conn, path);

	dbus_connection_emit_signal(conn, INPUT_PATH,
			INPUT_MANAGER_INTERFACE, "DeviceRemoved" ,
			DBUS_TYPE_STRING, &path,
			DBUS_TYPE_INVALID); 

	return 0;
}

int l2cap_connect(bdaddr_t *src, bdaddr_t *dst, unsigned short psm,
						GIOFunc cb, void *data)
{
	GIOChannel *io;
	struct sockaddr_l2 addr;
	struct l2cap_options opts;
	int sk, err;

	sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
	if (sk < 0)
		return -1;

	memset(&addr, 0, sizeof(addr));
	addr.l2_family  = AF_BLUETOOTH;
	bacpy(&addr.l2_bdaddr, src);

	if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0)
		goto failed;

	if (set_nonblocking(sk) < 0)
		goto failed;

	memset(&opts, 0, sizeof(opts));
#if 0
	opts.imtu = HIDP_DEFAULT_MTU;
	opts.omtu = HIDP_DEFAULT_MTU;
	opts.flush_to = 0xffff;

	if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0)
		goto failed;
#endif

	memset(&addr, 0, sizeof(addr));
	addr.l2_family  = AF_BLUETOOTH;
	bacpy(&addr.l2_bdaddr, dst);
	addr.l2_psm = htobs(psm);

	io = g_io_channel_unix_new(sk);
	g_io_channel_set_close_on_unref(io, FALSE);

	if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		if (!(errno == EAGAIN || errno == EINPROGRESS)) {
			g_io_channel_unref(io);
			goto failed;
		}

		g_io_add_watch(io, G_IO_OUT | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
				(GIOFunc) cb, data);
	} else
		cb(io, G_IO_OUT, data);

	g_io_channel_unref(io);

	return 0;

failed:
	err = errno;
	close(sk);
	errno = err;

	return -1;
}

static struct device *find_device(bdaddr_t *src, bdaddr_t *dst)
{
	struct device *idev;
	GSList *list;

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

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

	return NULL;
}

gboolean input_device_is_registered(bdaddr_t *src, bdaddr_t *dst)
{
	struct device *idev = find_device(src, dst);
	if (!idev)
		return FALSE;
	else
		return TRUE;
}

int input_device_set_channel(bdaddr_t *src, bdaddr_t *dst, int psm, int nsk)
{
	struct device *idev = find_device(src, dst);
	if (!idev)
		return -ENOENT;

	switch (psm) {
	case L2CAP_PSM_HIDP_CTRL:
		idev->ctrl_sk = nsk;
		break;
	case L2CAP_PSM_HIDP_INTR:
		idev->intr_sk = nsk;
		break;
	}

	return 0;
}

int input_device_close_channels(bdaddr_t *src, bdaddr_t *dst)
{
	struct device *idev = find_device(src, dst);
	if (!idev)
		return -ENOENT;

	if (idev->ctrl_sk >= 0) {
		close(idev->ctrl_sk);
		idev->ctrl_sk = -1;
	}

	if (idev->intr_sk >= 0) {
		close(idev->intr_sk);
		idev->intr_sk = -1;
	}

	return 0;
}

int input_device_connadd(bdaddr_t *src, bdaddr_t *dst)
{
	struct device *idev;
	int err;

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

	err = hidp_connadd(src, dst, idev->ctrl_sk, idev->intr_sk, idev->name);
	if (err < 0) {
		close(idev->ctrl_sk);
		close(idev->intr_sk);
		idev->ctrl_sk = -1;
		idev->intr_sk = -1;

		return err;
	}

	idev->watch = create_watch(idev->ctrl_sk, idev);
	dbus_connection_emit_signal(idev->conn,
			idev->path,
			INPUT_DEVICE_INTERFACE,
			"Connected",
			DBUS_TYPE_INVALID);
	return 0;
}
