/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2009-2010  Marcel Holtmann <marcel@holtmann.org>
 *  Copyright (C) 2009-2010  Nokia Corporation
 *
 *
 *  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
 *
 */
#include <stdarg.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <poll.h>
#include <sys/types.h>
#include <sys/socket.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/l2cap.h>
#include <bluetooth/rfcomm.h>
#include <bluetooth/sco.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>

#include <glib.h>

#include "btio.h"

#define ERROR_FAILED(gerr, str, err) \
		g_set_error(gerr, BT_IO_ERROR, BT_IO_ERROR_FAILED, \
				str ": %s (%d)", strerror(err), err)

#define DEFAULT_DEFER_TIMEOUT 30

struct set_opts {
	bdaddr_t src;
	bdaddr_t dst;
	int defer;
	int sec_level;
	uint8_t channel;
	uint16_t psm;
	uint16_t mtu;
	uint16_t imtu;
	uint16_t omtu;
	int master;
	uint8_t mode;
};

struct connect {
	BtIOConnect connect;
	gpointer user_data;
	GDestroyNotify destroy;
};

struct accept {
	BtIOConnect connect;
	gpointer user_data;
	GDestroyNotify destroy;
};

struct server {
	BtIOConnect connect;
	BtIOConfirm confirm;
	gpointer user_data;
	GDestroyNotify destroy;
};

static void server_remove(struct server *server)
{
	if (server->destroy)
		server->destroy(server->user_data);
	g_free(server);
}

static void connect_remove(struct connect *conn)
{
	if (conn->destroy)
		conn->destroy(conn->user_data);
	g_free(conn);
}

static void accept_remove(struct accept *accept)
{
	if (accept->destroy)
		accept->destroy(accept->user_data);
	g_free(accept);
}

static gboolean check_nval(GIOChannel *io)
{
	struct pollfd fds;

	memset(&fds, 0, sizeof(fds));
	fds.fd = g_io_channel_unix_get_fd(io);
	fds.events = POLLNVAL;

	if (poll(&fds, 1, 0) > 0 && (fds.revents & POLLNVAL))
		return TRUE;

	return FALSE;
}

static gboolean accept_cb(GIOChannel *io, GIOCondition cond,
							gpointer user_data)
{
	struct accept *accept = user_data;
	GError *err = NULL;

	/* If the user aborted this accept attempt */
	if ((cond & G_IO_NVAL) || check_nval(io))
		return FALSE;

	if (cond & (G_IO_HUP | G_IO_ERR))
		g_set_error(&err, BT_IO_ERROR, BT_IO_ERROR_DISCONNECTED,
				"HUP or ERR on socket");

	accept->connect(io, err, accept->user_data);

	g_clear_error(&err);

	return FALSE;
}

static gboolean connect_cb(GIOChannel *io, GIOCondition cond,
							gpointer user_data)
{
	struct connect *conn = user_data;
	GError *gerr = NULL;

	/* If the user aborted this connect attempt */
	if ((cond & G_IO_NVAL) || check_nval(io))
		return FALSE;

	if (cond & G_IO_OUT) {
		int err = 0, sock = g_io_channel_unix_get_fd(io);
		socklen_t len = sizeof(err);

		if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, &len) < 0)
			err = errno;

		if (err)
			g_set_error(&gerr, BT_IO_ERROR,
					BT_IO_ERROR_CONNECT_FAILED, "%s (%d)",
					strerror(err), err);
	} else if (cond & (G_IO_HUP | G_IO_ERR))
		g_set_error(&gerr, BT_IO_ERROR, BT_IO_ERROR_CONNECT_FAILED,
				"HUP or ERR on socket");

	conn->connect(io, gerr, conn->user_data);

	if (gerr)
		g_error_free(gerr);

	return FALSE;
}

static gboolean server_cb(GIOChannel *io, GIOCondition cond,
							gpointer user_data)
{
	struct server *server = user_data;
	int srv_sock, cli_sock;
	GIOChannel *cli_io;

	/* If the user closed the server */
	if ((cond & G_IO_NVAL) || check_nval(io))
		return FALSE;

	srv_sock = g_io_channel_unix_get_fd(io);

	cli_sock = accept(srv_sock, NULL, NULL);
	if (cli_sock < 0)
		return TRUE;

	cli_io = g_io_channel_unix_new(cli_sock);

	g_io_channel_set_close_on_unref(cli_io, TRUE);
	g_io_channel_set_flags(cli_io, G_IO_FLAG_NONBLOCK, NULL);

	if (server->confirm)
		server->confirm(cli_io, server->user_data);
	else
		server->connect(cli_io, NULL, server->user_data);

	g_io_channel_unref(cli_io);

	return TRUE;
}

static void server_add(GIOChannel *io, BtIOConnect connect,
				BtIOConfirm confirm, gpointer user_data,
				GDestroyNotify destroy)
{
	struct server *server;
	GIOCondition cond;

	server = g_new0(struct server, 1);
	server->connect = connect;
	server->confirm = confirm;
	server->user_data = user_data;
	server->destroy = destroy;

	cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
	g_io_add_watch_full(io, G_PRIORITY_DEFAULT, cond, server_cb, server,
					(GDestroyNotify) server_remove);
}

static void connect_add(GIOChannel *io, BtIOConnect connect,
				gpointer user_data, GDestroyNotify destroy)
{
	struct connect *conn;
	GIOCondition cond;

	conn = g_new0(struct connect, 1);
	conn->connect = connect;
	conn->user_data = user_data;
	conn->destroy = destroy;

	cond = G_IO_OUT | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
	g_io_add_watch_full(io, G_PRIORITY_DEFAULT, cond, connect_cb, conn,
					(GDestroyNotify) connect_remove);
}

static void accept_add(GIOChannel *io, BtIOConnect connect, gpointer user_data,
							GDestroyNotify destroy)
{
	struct accept *accept;
	GIOCondition cond;

	accept = g_new0(struct accept, 1);
	accept->connect = connect;
	accept->user_data = user_data;
	accept->destroy = destroy;

	cond = G_IO_OUT | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
	g_io_add_watch_full(io, G_PRIORITY_DEFAULT, cond, accept_cb, accept,
					(GDestroyNotify) accept_remove);
}

static int l2cap_bind(int sock, const bdaddr_t *src, uint16_t psm, GError **err)
{
	struct sockaddr_l2 addr;

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

	if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		ERROR_FAILED(err, "l2cap_bind", errno);
		return -1;
	}

	return 0;
}

static int l2cap_connect(int sock, const bdaddr_t *dst, uint16_t psm)
{
	int err;
	struct sockaddr_l2 addr;

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

	err = connect(sock, (struct sockaddr *) &addr, sizeof(addr));
	if (err < 0 && !(errno == EAGAIN || errno == EINPROGRESS))
		return err;

	return 0;
}

static int l2cap_set_master(int sock, int master)
{
	int flags;
	socklen_t len;

	len = sizeof(flags);
	if (getsockopt(sock, SOL_L2CAP, L2CAP_LM, &flags, &len) < 0)
		return -errno;

	if (master) {
		if (flags & L2CAP_LM_MASTER)
			return 0;
		flags |= L2CAP_LM_MASTER;
	} else {
		if (!(flags & L2CAP_LM_MASTER))
			return 0;
		flags &= ~L2CAP_LM_MASTER;
	}

	if (setsockopt(sock, SOL_L2CAP, L2CAP_LM, &flags, sizeof(flags)) < 0)
		return -errno;

	return 0;
}

static int rfcomm_set_master(int sock, int master)
{
	int flags;
	socklen_t len;

	len = sizeof(flags);
	if (getsockopt(sock, SOL_RFCOMM, RFCOMM_LM, &flags, &len) < 0)
		return -errno;

	if (master) {
		if (flags & RFCOMM_LM_MASTER)
			return 0;
		flags |= RFCOMM_LM_MASTER;
	} else {
		if (!(flags & RFCOMM_LM_MASTER))
			return 0;
		flags &= ~RFCOMM_LM_MASTER;
	}

	if (setsockopt(sock, SOL_RFCOMM, RFCOMM_LM, &flags, sizeof(flags)) < 0)
		return -errno;

	return 0;
}

static int l2cap_set_lm(int sock, int level)
{
	int lm_map[] = {
		0,
		L2CAP_LM_AUTH,
		L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT,
		L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT | L2CAP_LM_SECURE,
	}, opt = lm_map[level];

	if (setsockopt(sock, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0)
		return -errno;

	return 0;
}

static int rfcomm_set_lm(int sock, int level)
{
	int lm_map[] = {
		0,
		RFCOMM_LM_AUTH,
		RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT,
		RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE,
	}, opt = lm_map[level];

	if (setsockopt(sock, SOL_RFCOMM, RFCOMM_LM, &opt, sizeof(opt)) < 0)
		return -errno;

	return 0;
}

static gboolean set_sec_level(int sock, BtIOType type, int level, GError **err)
{
	struct bt_security sec;
	int ret;

	if (level < BT_SECURITY_LOW || level > BT_SECURITY_HIGH) {
		g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
				"Valid security level range is %d-%d",
				BT_SECURITY_LOW, BT_SECURITY_HIGH);
		return FALSE;
	}

	memset(&sec, 0, sizeof(sec));
	sec.level = level;

	if (setsockopt(sock, SOL_BLUETOOTH, BT_SECURITY, &sec,
							sizeof(sec)) == 0)
		return TRUE;

	if (errno != ENOPROTOOPT) {
		ERROR_FAILED(err, "setsockopt(BT_SECURITY)", errno);
		return FALSE;
	}

	if (type == BT_IO_L2CAP)
		ret = l2cap_set_lm(sock, level);
	else
		ret = rfcomm_set_lm(sock, level);

	if (ret < 0) {
		ERROR_FAILED(err, "setsockopt(LM)", -ret);
		return FALSE;
	}

	return TRUE;
}

static int l2cap_get_lm(int sock, int *sec_level)
{
	int opt;
	socklen_t len;

	len = sizeof(opt);
	if (getsockopt(sock, SOL_L2CAP, L2CAP_LM, &opt, &len) < 0)
		return -errno;

	*sec_level = 0;

	if (opt & L2CAP_LM_AUTH)
		*sec_level = BT_SECURITY_LOW;
	if (opt & L2CAP_LM_ENCRYPT)
		*sec_level = BT_SECURITY_MEDIUM;
	if (opt & L2CAP_LM_SECURE)
		*sec_level = BT_SECURITY_HIGH;

	return 0;
}

static int rfcomm_get_lm(int sock, int *sec_level)
{
	int opt;
	socklen_t len;

	len = sizeof(opt);
	if (getsockopt(sock, SOL_RFCOMM, RFCOMM_LM, &opt, &len) < 0)
		return -errno;

	*sec_level = 0;

	if (opt & RFCOMM_LM_AUTH)
		*sec_level = BT_SECURITY_LOW;
	if (opt & RFCOMM_LM_ENCRYPT)
		*sec_level = BT_SECURITY_MEDIUM;
	if (opt & RFCOMM_LM_SECURE)
		*sec_level = BT_SECURITY_HIGH;

	return 0;
}

static gboolean get_sec_level(int sock, BtIOType type, int *level,
								GError **err)
{
	struct bt_security sec;
	socklen_t len;
	int ret;

	memset(&sec, 0, sizeof(sec));
	len = sizeof(sec);
	if (getsockopt(sock, SOL_BLUETOOTH, BT_SECURITY, &sec, &len) == 0) {
		*level = sec.level;
		return TRUE;
	}

	if (errno != ENOPROTOOPT) {
		ERROR_FAILED(err, "getsockopt(BT_SECURITY)", errno);
		return FALSE;
	}

	if (type == BT_IO_L2CAP)
		ret = l2cap_get_lm(sock, level);
	else
		ret = rfcomm_get_lm(sock, level);

	if (ret < 0) {
		ERROR_FAILED(err, "getsockopt(LM)", -ret);
		return FALSE;
	}

	return TRUE;
}

static gboolean l2cap_set(int sock, int sec_level, uint16_t imtu, uint16_t omtu,
					uint8_t mode, int master, GError **err)
{
	if (imtu || omtu || mode) {
		struct l2cap_options l2o;
		socklen_t len;

		memset(&l2o, 0, sizeof(l2o));
		len = sizeof(l2o);
		if (getsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, &l2o,
								&len) < 0) {
			ERROR_FAILED(err, "getsockopt(L2CAP_OPTIONS)", errno);
			return FALSE;
		}

		if (imtu)
			l2o.imtu = imtu;
		if (omtu)
			l2o.omtu = omtu;
		if (mode)
			l2o.mode = mode;

		if (setsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, &l2o,
							sizeof(l2o)) < 0) {
			ERROR_FAILED(err, "setsockopt(L2CAP_OPTIONS)", errno);
			return FALSE;
		}
	}

	if (master >= 0 && l2cap_set_master(sock, master) < 0) {
		ERROR_FAILED(err, "l2cap_set_master", errno);
		return FALSE;
	}

	if (sec_level && !set_sec_level(sock, BT_IO_L2CAP, sec_level, err))
		return FALSE;

	return TRUE;
}

static int rfcomm_bind(int sock,
		const bdaddr_t *src, uint8_t channel, GError **err)
{
	struct sockaddr_rc addr;

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

	if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		ERROR_FAILED(err, "rfcomm_bind", errno);
		return -1;
	}

	return 0;
}

static int rfcomm_connect(int sock, const bdaddr_t *dst, uint8_t channel)
{
	int err;
	struct sockaddr_rc addr;

	memset(&addr, 0, sizeof(addr));
	addr.rc_family = AF_BLUETOOTH;
	bacpy(&addr.rc_bdaddr, dst);
	addr.rc_channel = channel;

	err = connect(sock, (struct sockaddr *) &addr, sizeof(addr));
	if (err < 0 && !(errno == EAGAIN || errno == EINPROGRESS))
		return err;

	return 0;
}

static gboolean rfcomm_set(int sock, int sec_level, int master, GError **err)
{
	if (sec_level && !set_sec_level(sock, BT_IO_RFCOMM, sec_level, err))
		return FALSE;

	if (master >= 0 && rfcomm_set_master(sock, master) < 0) {
		ERROR_FAILED(err, "rfcomm_set_master", errno);
		return FALSE;
	}

	return TRUE;
}

static int sco_bind(int sock, const bdaddr_t *src, GError **err)
{
	struct sockaddr_sco addr;

	memset(&addr, 0, sizeof(addr));
	addr.sco_family = AF_BLUETOOTH;
	bacpy(&addr.sco_bdaddr, src);

	if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		ERROR_FAILED(err, "sco_bind", errno);
		return -1;
	}

	return 0;
}

static int sco_connect(int sock, const bdaddr_t *dst)
{
	struct sockaddr_sco addr;
	int err;

	memset(&addr, 0, sizeof(addr));
	addr.sco_family = AF_BLUETOOTH;
	bacpy(&addr.sco_bdaddr, dst);

	err = connect(sock, (struct sockaddr *) &addr, sizeof(addr));
	if (err < 0 && !(errno == EAGAIN || errno == EINPROGRESS))
		return err;

	return 0;
}

static gboolean sco_set(int sock, uint16_t mtu, GError **err)
{
	struct sco_options sco_opt;
	socklen_t len;

	if (!mtu)
		return TRUE;

	len = sizeof(sco_opt);
	memset(&sco_opt, 0, len);
	if (getsockopt(sock, SOL_SCO, SCO_OPTIONS, &sco_opt, &len) < 0) {
		ERROR_FAILED(err, "getsockopt(SCO_OPTIONS)", errno);
		return FALSE;
	}

	sco_opt.mtu = mtu;
	if (setsockopt(sock, SOL_SCO, SCO_OPTIONS, &sco_opt,
						sizeof(sco_opt)) < 0) {
		ERROR_FAILED(err, "setsockopt(SCO_OPTIONS)", errno);
		return FALSE;
	}

	return TRUE;
}

static gboolean parse_set_opts(struct set_opts *opts, GError **err,
						BtIOOption opt1, va_list args)
{
	BtIOOption opt = opt1;
	const char *str;

	memset(opts, 0, sizeof(*opts));

	/* Set defaults */
	opts->defer = DEFAULT_DEFER_TIMEOUT;
	opts->master = -1;
	opts->sec_level = BT_IO_SEC_MEDIUM;
	opts->mode = L2CAP_MODE_BASIC;

	while (opt != BT_IO_OPT_INVALID) {
		switch (opt) {
		case BT_IO_OPT_SOURCE:
			str = va_arg(args, const char *);
			if (strncasecmp(str, "hci", 3) == 0)
				hci_devba(atoi(str + 3), &opts->src);
			else
				str2ba(str, &opts->src);
			break;
		case BT_IO_OPT_SOURCE_BDADDR:
			bacpy(&opts->src, va_arg(args, const bdaddr_t *));
			break;
		case BT_IO_OPT_DEST:
			str2ba(va_arg(args, const char *), &opts->dst);
			break;
		case BT_IO_OPT_DEST_BDADDR:
			bacpy(&opts->dst, va_arg(args, const bdaddr_t *));
			break;
		case BT_IO_OPT_DEFER_TIMEOUT:
			opts->defer = va_arg(args, int);
			break;
		case BT_IO_OPT_SEC_LEVEL:
			opts->sec_level = va_arg(args, int);
			break;
		case BT_IO_OPT_CHANNEL:
			opts->channel = va_arg(args, int);
			break;
		case BT_IO_OPT_PSM:
			opts->psm = va_arg(args, int);
			break;
		case BT_IO_OPT_MTU:
			opts->mtu = va_arg(args, int);
			opts->imtu = opts->mtu;
			opts->omtu = opts->mtu;
			break;
		case BT_IO_OPT_OMTU:
			opts->omtu = va_arg(args, int);
			if (!opts->mtu)
				opts->mtu = opts->omtu;
			break;
		case BT_IO_OPT_IMTU:
			opts->imtu = va_arg(args, int);
			if (!opts->mtu)
				opts->mtu = opts->imtu;
			break;
		case BT_IO_OPT_MASTER:
			opts->master = va_arg(args, gboolean);
			break;
		case BT_IO_OPT_MODE:
			opts->mode = va_arg(args, int);
			break;
		default:
			g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
					"Unknown option %d", opt);
			return FALSE;
		}

		opt = va_arg(args, int);
	}

	return TRUE;
}

static gboolean get_peers(int sock, struct sockaddr *src, struct sockaddr *dst,
				socklen_t len, GError **err)
{
	socklen_t olen;

	memset(src, 0, len);
	olen = len;
	if (getsockname(sock, src, &olen) < 0) {
		ERROR_FAILED(err, "getsockname", errno);
		return FALSE;
	}

	memset(dst, 0, len);
	olen = len;
	if (getpeername(sock, dst, &olen) < 0) {
		ERROR_FAILED(err, "getpeername", errno);
		return FALSE;
	}

	return TRUE;
}

static int l2cap_get_info(int sock, uint16_t *handle, uint8_t *dev_class)
{
	struct l2cap_conninfo info;
	socklen_t len;

	len = sizeof(info);
	if (getsockopt(sock, SOL_L2CAP, L2CAP_CONNINFO, &info, &len) < 0)
		return -errno;

	if (handle)
		*handle = info.hci_handle;

	if (dev_class)
		memcpy(dev_class, info.dev_class, 3);

	return 0;
}

static gboolean l2cap_get(int sock, GError **err, BtIOOption opt1,
								va_list args)
{
	BtIOOption opt = opt1;
	struct sockaddr_l2 src, dst;
	struct l2cap_options l2o;
	int flags;
	uint8_t dev_class[3];
	uint16_t handle;
	socklen_t len;

	len = sizeof(l2o);
	memset(&l2o, 0, len);
	if (getsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &len) < 0) {
		ERROR_FAILED(err, "getsockopt(L2CAP_OPTIONS)", errno);
		return FALSE;
	}

	if (!get_peers(sock, (struct sockaddr *) &src,
				(struct sockaddr *) &dst, sizeof(src), err))
		return FALSE;

	while (opt != BT_IO_OPT_INVALID) {
		switch (opt) {
		case BT_IO_OPT_SOURCE:
			ba2str(&src.l2_bdaddr, va_arg(args, char *));
			break;
		case BT_IO_OPT_SOURCE_BDADDR:
			bacpy(va_arg(args, bdaddr_t *), &src.l2_bdaddr);
			break;
		case BT_IO_OPT_DEST:
			ba2str(&dst.l2_bdaddr, va_arg(args, char *));
			break;
		case BT_IO_OPT_DEST_BDADDR:
			bacpy(va_arg(args, bdaddr_t *), &dst.l2_bdaddr);
			break;
		case BT_IO_OPT_DEFER_TIMEOUT:
			len = sizeof(int);
			if (getsockopt(sock, SOL_BLUETOOTH, BT_DEFER_SETUP,
					va_arg(args, int *), &len) < 0) {
				ERROR_FAILED(err, "getsockopt(DEFER_SETUP)",
									errno);
				return FALSE;
			}
			break;
		case BT_IO_OPT_SEC_LEVEL:
			if (!get_sec_level(sock, BT_IO_L2CAP,
						va_arg(args, int *), err))
				return FALSE;
			break;
		case BT_IO_OPT_PSM:
			*(va_arg(args, uint16_t *)) = src.l2_psm ?
						src.l2_psm : dst.l2_psm;
			break;
		case BT_IO_OPT_OMTU:
			*(va_arg(args, uint16_t *)) = l2o.omtu;
			break;
		case BT_IO_OPT_IMTU:
			*(va_arg(args, uint16_t *)) = l2o.imtu;
			break;
		case BT_IO_OPT_MASTER:
			len = sizeof(flags);
			if (getsockopt(sock, SOL_L2CAP, L2CAP_LM, &flags,
								&len) < 0) {
				ERROR_FAILED(err, "getsockopt(L2CAP_LM)",
									errno);
				return FALSE;
			}
			*(va_arg(args, gboolean *)) =
				(flags & L2CAP_LM_MASTER) ? TRUE : FALSE;
			break;
		case BT_IO_OPT_HANDLE:
			if (l2cap_get_info(sock, &handle, dev_class) < 0) {
				ERROR_FAILED(err, "L2CAP_CONNINFO", errno);
				return FALSE;
			}
			*(va_arg(args, uint16_t *)) = handle;
			break;
		case BT_IO_OPT_CLASS:
			if (l2cap_get_info(sock, &handle, dev_class) < 0) {
				ERROR_FAILED(err, "L2CAP_CONNINFO", errno);
				return FALSE;
			}
			memcpy(va_arg(args, uint8_t *), dev_class, 3);
			break;
		default:
			g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
					"Unknown option %d", opt);
			return FALSE;
		}

		opt = va_arg(args, int);
	}

	return TRUE;
}

static int rfcomm_get_info(int sock, uint16_t *handle, uint8_t *dev_class)
{
	struct rfcomm_conninfo info;
	socklen_t len;

	len = sizeof(info);
	if (getsockopt(sock, SOL_RFCOMM, RFCOMM_CONNINFO, &info, &len) < 0)
		return -errno;

	if (handle)
		*handle = info.hci_handle;

	if (dev_class)
		memcpy(dev_class, info.dev_class, 3);

	return 0;
}

static gboolean rfcomm_get(int sock, GError **err, BtIOOption opt1,
								va_list args)
{
	BtIOOption opt = opt1;
	struct sockaddr_rc src, dst;
	int flags;
	socklen_t len;
	uint8_t dev_class[3];
	uint16_t handle;

	if (!get_peers(sock, (struct sockaddr *) &src,
				(struct sockaddr *) &dst, sizeof(src), err))
		return FALSE;

	while (opt != BT_IO_OPT_INVALID) {
		switch (opt) {
		case BT_IO_OPT_SOURCE:
			ba2str(&src.rc_bdaddr, va_arg(args, char *));
			break;
		case BT_IO_OPT_SOURCE_BDADDR:
			bacpy(va_arg(args, bdaddr_t *), &src.rc_bdaddr);
			break;
		case BT_IO_OPT_DEST:
			ba2str(&dst.rc_bdaddr, va_arg(args, char *));
			break;
		case BT_IO_OPT_DEST_BDADDR:
			bacpy(va_arg(args, bdaddr_t *), &dst.rc_bdaddr);
			break;
		case BT_IO_OPT_DEFER_TIMEOUT:
			len = sizeof(int);
			if (getsockopt(sock, SOL_BLUETOOTH, BT_DEFER_SETUP,
					va_arg(args, int *), &len) < 0) {
				ERROR_FAILED(err, "getsockopt(DEFER_SETUP)",
									errno);
				return FALSE;
			}
			break;
		case BT_IO_OPT_SEC_LEVEL:
			if (!get_sec_level(sock, BT_IO_RFCOMM,
						va_arg(args, int *), err))
				return FALSE;
			break;
		case BT_IO_OPT_CHANNEL:
			*(va_arg(args, uint8_t *)) = src.rc_channel ?
					src.rc_channel : dst.rc_channel;
			break;
		case BT_IO_OPT_SOURCE_CHANNEL:
			*(va_arg(args, uint8_t *)) = src.rc_channel;
			break;
		case BT_IO_OPT_DEST_CHANNEL:
			*(va_arg(args, uint8_t *)) = dst.rc_channel;
			break;
		case BT_IO_OPT_MASTER:
			len = sizeof(flags);
			if (getsockopt(sock, SOL_RFCOMM, RFCOMM_LM, &flags,
								&len) < 0) {
				ERROR_FAILED(err, "getsockopt(RFCOMM_LM)",
									errno);
				return FALSE;
			}
			*(va_arg(args, gboolean *)) =
				(flags & RFCOMM_LM_MASTER) ? TRUE : FALSE;
			break;
		case BT_IO_OPT_HANDLE:
			if (rfcomm_get_info(sock, &handle, dev_class) < 0) {
				ERROR_FAILED(err, "RFCOMM_CONNINFO", errno);
				return FALSE;
			}
			*(va_arg(args, uint16_t *)) = handle;
			break;
		case BT_IO_OPT_CLASS:
			if (rfcomm_get_info(sock, &handle, dev_class) < 0) {
				ERROR_FAILED(err, "RFCOMM_CONNINFO", errno);
				return FALSE;
			}
			memcpy(va_arg(args, uint8_t *), dev_class, 3);
			break;
		default:
			g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
					"Unknown option %d", opt);
			return FALSE;
		}

		opt = va_arg(args, int);
	}

	return TRUE;
}

static int sco_get_info(int sock, uint16_t *handle, uint8_t *dev_class)
{
	struct sco_conninfo info;
	socklen_t len;

	len = sizeof(info);
	if (getsockopt(sock, SOL_SCO, SCO_CONNINFO, &info, &len) < 0)
		return -errno;

	if (handle)
		*handle = info.hci_handle;

	if (dev_class)
		memcpy(dev_class, info.dev_class, 3);

	return 0;
}

static gboolean sco_get(int sock, GError **err, BtIOOption opt1, va_list args)
{
	BtIOOption opt = opt1;
	struct sockaddr_sco src, dst;
	struct sco_options sco_opt;
	socklen_t len;
	uint8_t dev_class[3];
	uint16_t handle;

	len = sizeof(sco_opt);
	memset(&sco_opt, 0, len);
	if (getsockopt(sock, SOL_SCO, SCO_OPTIONS, &sco_opt, &len) < 0) {
		ERROR_FAILED(err, "getsockopt(SCO_OPTIONS)", errno);
		return FALSE;
	}

	if (!get_peers(sock, (struct sockaddr *) &src,
				(struct sockaddr *) &dst, sizeof(src), err))
		return FALSE;

	while (opt != BT_IO_OPT_INVALID) {
		switch (opt) {
		case BT_IO_OPT_SOURCE:
			ba2str(&src.sco_bdaddr, va_arg(args, char *));
			break;
		case BT_IO_OPT_SOURCE_BDADDR:
			bacpy(va_arg(args, bdaddr_t *), &src.sco_bdaddr);
			break;
		case BT_IO_OPT_DEST:
			ba2str(&dst.sco_bdaddr, va_arg(args, char *));
			break;
		case BT_IO_OPT_DEST_BDADDR:
			bacpy(va_arg(args, bdaddr_t *), &dst.sco_bdaddr);
			break;
		case BT_IO_OPT_MTU:
		case BT_IO_OPT_IMTU:
		case BT_IO_OPT_OMTU:
			*(va_arg(args, uint16_t *)) = sco_opt.mtu;
			break;
		case BT_IO_OPT_HANDLE:
			if (sco_get_info(sock, &handle, dev_class) < 0) {
				ERROR_FAILED(err, "RFCOMM_CONNINFO", errno);
				return FALSE;
			}
			*(va_arg(args, uint16_t *)) = handle;
			break;
		case BT_IO_OPT_CLASS:
			if (sco_get_info(sock, &handle, dev_class) < 0) {
				ERROR_FAILED(err, "RFCOMM_CONNINFO", errno);
				return FALSE;
			}
			memcpy(va_arg(args, uint8_t *), dev_class, 3);
			break;
		default:
			g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
					"Unknown option %d", opt);
			return FALSE;
		}

		opt = va_arg(args, int);
	}

	return TRUE;
}

static gboolean get_valist(GIOChannel *io, BtIOType type, GError **err,
						BtIOOption opt1, va_list args)
{
	int sock;

	sock = g_io_channel_unix_get_fd(io);

	switch (type) {
	case BT_IO_L2RAW:
	case BT_IO_L2CAP:
		return l2cap_get(sock, err, opt1, args);
	case BT_IO_RFCOMM:
		return rfcomm_get(sock, err, opt1, args);
	case BT_IO_SCO:
		return sco_get(sock, err, opt1, args);
	}

	g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
			"Unknown BtIO type %d", type);
	return FALSE;
}

gboolean bt_io_accept(GIOChannel *io, BtIOConnect connect, gpointer user_data,
					GDestroyNotify destroy, GError **err)
{
	int sock;
	char c;
	struct pollfd pfd;

	sock = g_io_channel_unix_get_fd(io);

	memset(&pfd, 0, sizeof(pfd));
	pfd.fd = sock;
	pfd.events = POLLOUT;

	if (poll(&pfd, 1, 0) < 0) {
		ERROR_FAILED(err, "poll", errno);
		return FALSE;
	}

	if (!(pfd.revents & POLLOUT)) {
		int ret;
		ret = read(sock, &c, 1);
	}

	accept_add(io, connect, user_data, destroy);

	return TRUE;
}

gboolean bt_io_set(GIOChannel *io, BtIOType type, GError **err,
							BtIOOption opt1, ...)
{
	va_list args;
	gboolean ret;
	struct set_opts opts;
	int sock;

	va_start(args, opt1);
	ret = parse_set_opts(&opts, err, opt1, args);
	va_end(args);

	if (!ret)
		return ret;

	sock = g_io_channel_unix_get_fd(io);

	switch (type) {
	case BT_IO_L2RAW:
	case BT_IO_L2CAP:
		return l2cap_set(sock, opts.sec_level, opts.imtu, opts.omtu,
						opts.mode, opts.master, err);
	case BT_IO_RFCOMM:
		return rfcomm_set(sock, opts.sec_level, opts.master, err);
	case BT_IO_SCO:
		return sco_set(sock, opts.mtu, err);
	}

	g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
			"Unknown BtIO type %d", type);
	return FALSE;
}

gboolean bt_io_get(GIOChannel *io, BtIOType type, GError **err,
							BtIOOption opt1, ...)
{
	va_list args;
	gboolean ret;

	va_start(args, opt1);
	ret = get_valist(io, type, err, opt1, args);
	va_end(args);

	return ret;
}

static GIOChannel *create_io(BtIOType type, gboolean server,
					struct set_opts *opts, GError **err)
{
	int sock;
	GIOChannel *io;

	switch (type) {
	case BT_IO_L2RAW:
		sock = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP);
		if (sock < 0) {
			ERROR_FAILED(err, "socket(RAW, L2CAP)", errno);
			return NULL;
		}
		if (l2cap_bind(sock, &opts->src,
					server ? opts->psm : 0, err) < 0)
			goto failed;
		if (!l2cap_set(sock, opts->sec_level, 0, 0, 0, -1, err))
			goto failed;
		break;
	case BT_IO_L2CAP:
		sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
		if (sock < 0) {
			ERROR_FAILED(err, "socket(SEQPACKET, L2CAP)", errno);
			return NULL;
		}
		if (l2cap_bind(sock, &opts->src,
					server ? opts->psm : 0, err) < 0)
			goto failed;
		if (!l2cap_set(sock, opts->sec_level, opts->imtu, opts->omtu,
						opts->mode, opts->master, err))
			goto failed;
		break;
	case BT_IO_RFCOMM:
		sock = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
		if (sock < 0) {
			ERROR_FAILED(err, "socket(STREAM, RFCOMM)", errno);
			return NULL;
		}
		if (rfcomm_bind(sock, &opts->src,
					server ? opts->channel : 0, err) < 0)
			goto failed;
		if (!rfcomm_set(sock, opts->sec_level, opts->master, err))
			goto failed;
		break;
	case BT_IO_SCO:
		sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);
		if (sock < 0) {
			ERROR_FAILED(err, "socket(SEQPACKET, SCO)", errno);
			return NULL;
		}
		if (sco_bind(sock, &opts->src, err) < 0)
			goto failed;
		if (!sco_set(sock, opts->mtu, err))
			goto failed;
		break;
	default:
		g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
				"Unknown BtIO type %d", type);
		return NULL;
	}

	io = g_io_channel_unix_new(sock);

	g_io_channel_set_close_on_unref(io, TRUE);
	g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL);

	return io;

failed:
	close(sock);

	return NULL;
}

GIOChannel *bt_io_connect(BtIOType type, BtIOConnect connect,
				gpointer user_data, GDestroyNotify destroy,
				GError **gerr, BtIOOption opt1, ...)
{
	GIOChannel *io;
	va_list args;
	struct set_opts opts;
	int err, sock;
	gboolean ret;

	va_start(args, opt1);
	ret = parse_set_opts(&opts, gerr, opt1, args);
	va_end(args);

	if (ret == FALSE)
		return NULL;

	io = create_io(type, FALSE, &opts, gerr);
	if (io == NULL)
		return NULL;

	sock = g_io_channel_unix_get_fd(io);

	switch (type) {
	case BT_IO_L2RAW:
		err = l2cap_connect(sock, &opts.dst, 0);
		break;
	case BT_IO_L2CAP:
		err = l2cap_connect(sock, &opts.dst, opts.psm);
		break;
	case BT_IO_RFCOMM:
		err = rfcomm_connect(sock, &opts.dst, opts.channel);
		break;
	case BT_IO_SCO:
		err = sco_connect(sock, &opts.dst);
		break;
	default:
		g_set_error(gerr, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
						"Unknown BtIO type %d", type);
		return NULL;
	}

	if (err < 0) {
		g_set_error(gerr, BT_IO_ERROR, BT_IO_ERROR_CONNECT_FAILED,
				"connect: %s (%d)", strerror(-err), -err);
		g_io_channel_unref(io);
		return NULL;
	}

	connect_add(io, connect, user_data, destroy);

	return io;
}

GIOChannel *bt_io_listen(BtIOType type, BtIOConnect connect,
				BtIOConfirm confirm, gpointer user_data,
				GDestroyNotify destroy, GError **err,
				BtIOOption opt1, ...)
{
	GIOChannel *io;
	va_list args;
	struct set_opts opts;
	int sock;
	gboolean ret;

	if (type == BT_IO_L2RAW) {
		g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
				"Server L2CAP RAW sockets not supported");
		return NULL;
	}

	va_start(args, opt1);
	ret = parse_set_opts(&opts, err, opt1, args);
	va_end(args);

	if (ret == FALSE)
		return NULL;

	io = create_io(type, TRUE, &opts, err);
	if (io == NULL)
		return NULL;

	sock = g_io_channel_unix_get_fd(io);

	if (confirm)
		setsockopt(sock, SOL_BLUETOOTH, BT_DEFER_SETUP, &opts.defer,
							sizeof(opts.defer));

	if (listen(sock, 5) < 0) {
		ERROR_FAILED(err, "listen", errno);
		g_io_channel_unref(io);
		return NULL;
	}

	server_add(io, connect, confirm, user_data, destroy);

	return io;
}

GQuark bt_io_error_quark(void)
{
	return g_quark_from_static_string("bt-io-error-quark");
}

