/*
 *
 *  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)
{
	struct device *idev;
	uint32_t cls;

	idev = g_new0(struct device, 1);

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

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

	idev->major 	= (cls >> 8) & 0x1f;
	idev->minor	= (cls >> 2) & 0x3f;
	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;

	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);
	path = create_input_path(idev->major, idev->minor);
	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);
	path = create_input_path(idev->major, idev->minor);
	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;
}
