/*
 *
 *  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 cid;
	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,
						uint16_t cid, GError **err)
{
	struct sockaddr_l2 addr;

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

	if (cid)
		addr.l2_cid = htobs(cid);
	else
		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, uint16_t cid)
{
	int err;
	struct sockaddr_l2 addr;

	memset(&addr, 0, sizeof(addr));
	addr.l2_family = AF_BLUETOOTH;
	bacpy(&addr.l2_bdaddr, dst);
	if (cid)
		addr.l2_cid = htobs(cid);
	else
		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_CID:
			opts->cid = 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_CID:
			*(va_arg(args, uint16_t *)) = src.l2_cid ?
						src.l2_cid : dst.l2_cid;
			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;
		case BT_IO_OPT_MODE:
			*(va_arg(args, uint8_t *)) = l2o.mode;
			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,
							opts->cid, 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,
							opts->cid, 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, opts.cid);
		break;
	case BT_IO_L2CAP:
		err = l2cap_connect(sock, &opts.dst, opts.psm, opts.cid);
		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");
}
