/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2004-2006  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 <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <arpa/inet.h>

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

#include <dbus/dbus.h>

#include "hcid.h"
#include "list.h"
#include "glib-ectomy.h"
#include "dbus.h"

/* Waiting for udev to create the device node */
#define MAX_OPEN_TRIES	5
#define OPEN_WAIT	300  /* ms */

static int rfcomm_ctl = -1;

struct rfcomm_node {
	int16_t		id;		/* Device id */
	char		name[16];       /* Node filename */

	DBusConnection	*conn;		/* for name listener handling */

	/* The following members are only valid for connected nodes */
	GIOChannel	*io;		/* IO Channel for the connection */
	guint		io_id;		/* ID for IO channel */
	char		*owner;		/* D-Bus name that created the node */
};

struct pending_connect {
	DBusConnection		*conn;
	DBusMessage		*msg;
	GIOChannel		*io;
	char 			*svc;
	int			canceled;
	struct sockaddr_rc	laddr;
	struct sockaddr_rc	raddr;

	/* Used only when we wait for udev to create the device node */
	struct rfcomm_node	*node;
	int			ntries;
};

static struct slist *pending_connects = NULL;
static struct slist *connected_nodes = NULL;
static struct slist *bound_nodes = NULL;

static char *rfcomm_node_name_from_id(int16_t id, char *dev, size_t len)
{
	snprintf(dev, len, "/dev/rfcomm%d", id);
	return dev;
}

static void rfcomm_node_free(struct rfcomm_node *node)
{
	if (node->owner)
		free(node->owner);
	if (node->io) {
		g_io_remove_watch(node->io_id);
		g_io_channel_unref(node->io);
	}
	if (node->conn)
		dbus_connection_unref(node->conn);
	free(node);
}

static struct rfcomm_node *find_node_by_name(struct slist *nodes, const char *name)
{
	struct slist *l;

	for (l = nodes; l != NULL; l = l->next) {
		struct rfcomm_node *node = l->data;
		if (!strcmp(node->name, name))
			return node;
	}

	return NULL;
}

static struct pending_connect *find_pending_connect_by_channel(const char *bda,
								uint8_t ch)
{
	struct slist *l;
	bdaddr_t dba;

	str2ba(bda, &dba);

	for (l = pending_connects; l != NULL; l = l->next) {
		struct pending_connect *pending = l->data;
		if (!bacmp(&dba, &pending->raddr.rc_bdaddr) &&
			pending->raddr.rc_channel == ch)
			return pending;
	}

	return NULL;
}

static struct pending_connect *find_pending_connect_by_service(const char *bda,
								const char *svc)
{
	struct slist *l;
	bdaddr_t dba;

	str2ba(bda, &dba);

	for (l = pending_connects; l != NULL; l = l->next) {
		struct pending_connect *pending = l->data;
		if (!bacmp(&dba, &pending->raddr.rc_bdaddr) &&
			!strcmp(pending->svc, svc))
			return pending;
	}

	return NULL;
}

static void pending_connect_free(struct pending_connect *c)
{
	if (c->svc)
		free(c->svc);
	if (c->io)
		g_io_channel_unref(c->io);
	if (c->msg)
		dbus_message_unref(c->msg);
	if (c->conn)
		dbus_connection_unref(c->conn);
	free(c);
}

static int set_nonblocking(int fd, int *err)
{
	long arg;

	arg = fcntl(fd, F_GETFL);
	if (arg < 0) {
		if (err)
			*err = errno;
		error("fcntl(F_GETFL): %s (%d)", strerror(errno), errno);
		return -1;
	}

	/* Return if already nonblocking */
	if (arg & O_NONBLOCK)
		return 0;

	arg |= O_NONBLOCK;
	if (fcntl(fd, F_SETFL, arg) < 0) {
		if (err)
			*err = errno;
		error("fcntl(F_SETFL, O_NONBLOCK): %s (%d)",
				strerror(errno), errno);
		return -1;
	}

	return 0;
}

static int rfcomm_release(struct rfcomm_node *node, int *err)
{
	struct rfcomm_dev_req req;

	debug("rfcomm_release(%s)", node->name);

	memset(&req, 0, sizeof(req));
	req.dev_id = node->id;

#if 0
	/*
	 * We are hitting a kernel bug inside RFCOMM code when
	 * RFCOMM_HANGUP_NOW bit is set on request's flags passed to
	 * ioctl(RFCOMMRELEASEDEV)!
	 */
	req.flags = (1 << RFCOMM_HANGUP_NOW);
#endif

	if (ioctl(rfcomm_ctl, RFCOMMRELEASEDEV, &req) < 0) {
		if (err)
			*err = errno;
		error("Can't release device %d: %s (%d)", node->id,
				strerror(errno), errno);
		return -1;
	}

	return 0;
}

static void rfcomm_connect_req_exit(const char *name, void *data)
{
	struct rfcomm_node *node = data;
	debug("Connect requestor %s exited. Releasing %s node",
		name, node->name);
	rfcomm_release(node, NULL);
	connected_nodes = slist_remove(connected_nodes, node);
	rfcomm_node_free(node);
}

static gboolean rfcomm_disconnect_cb(GIOChannel *io, GIOCondition cond,
					struct rfcomm_node *node)
{
	debug("RFCOMM node %s was disconnected", node->name);
	name_listener_remove(node->conn, node->owner,
				rfcomm_connect_req_exit, node);
	connected_nodes = slist_remove(connected_nodes, node);
	rfcomm_node_free(node);
	return FALSE;
}

static void rfcomm_connect_cb_devnode_opened(int fd, struct pending_connect *c,
						struct rfcomm_node *node)
{
	DBusMessage *reply = NULL;
	char *ptr;

	reply = dbus_message_new_method_return(c->msg);
	if (!reply) {
		error_failed(c->conn, c->msg, ENOMEM);
		goto failed;
	}

	ptr = node->name;
	if (!dbus_message_append_args(reply,
					DBUS_TYPE_STRING, &ptr,
					DBUS_TYPE_INVALID)) {
		error_failed(c->conn, c->msg, ENOMEM);
		goto failed;
	}

	node->owner = strdup(dbus_message_get_sender(c->msg));
	if (!node->owner) {
		error_failed(c->conn, c->msg, ENOMEM);
		goto failed;
	}

	/* Check if the caller is still present */
	if (!dbus_bus_name_has_owner(c->conn, node->owner, NULL)) {
		error("RFCOMM.Connect requestor %s exited", node->owner);
		goto failed;
	}

	node->io = g_io_channel_unix_new(fd);
	g_io_channel_set_close_on_unref(node->io, TRUE);
	node->io_id = g_io_add_watch(node->io, G_IO_ERR | G_IO_HUP,
					(GIOFunc) rfcomm_disconnect_cb, node);

	send_reply_and_unref(c->conn, reply);

	connected_nodes = slist_append(connected_nodes, node);

	node->conn = dbus_connection_ref(c->conn);
	name_listener_add(node->conn, node->owner,
			  rfcomm_connect_req_exit, node);

	goto done;

failed:
	close(fd);
	rfcomm_release(node, NULL);
	rfcomm_node_free(node);
	if (reply)
		dbus_message_unref(reply);
done:
	pending_connects = slist_remove(pending_connects, c);
	pending_connect_free(c);
}

static gboolean rfcomm_connect_cb_continue(void *data)
{
	struct pending_connect *c = data;
	struct rfcomm_node *node = c->node;
	int fd;

	if (c->canceled) {
		error_connect_canceled(c->conn, c->msg);
		goto failed;
	}

	fd = open(node->name, O_RDONLY | O_NOCTTY);
	if (fd < 0) {
		if (++c->ntries >= MAX_OPEN_TRIES) {
			int err = errno;
			error("Could not open %s: %s (%d)",
					node->name, strerror(err), err);
			error_connection_attempt_failed(c->conn, c->msg, err);
			goto failed;
		}
		return TRUE;
	}

	rfcomm_connect_cb_devnode_opened(fd, c, node);

	return FALSE;

failed:
	rfcomm_release(node, NULL);
	rfcomm_node_free(node);

	pending_connects = slist_remove(pending_connects, c);
	pending_connect_free(c);

	return FALSE;
}

static gboolean rfcomm_connect_cb(GIOChannel *chan, GIOCondition cond,
					struct pending_connect *c)
{
	struct rfcomm_node *node = NULL;
	struct rfcomm_dev_req req;
	int sk, ret, err, fd = -1;
	socklen_t len;

	if (c->canceled) {
		error_connect_canceled(c->conn, c->msg);
		goto failed;
	}

	sk = g_io_channel_unix_get_fd(chan);

	len = sizeof(ret);
	if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &ret, &len) < 0) {
		err = errno;
		error("getsockopt(SO_ERROR): %s (%d)", strerror(err), err);
		error_failed(c->conn, c->msg, err);
		goto failed;
	}
	if (ret != 0) {
		error("connect(): %s (%d)", strerror(ret), ret);
		error_connection_attempt_failed(c->conn, c->msg, ret);
		goto failed;
	}

	debug("rfcomm_connect_cb: connected");

	len = sizeof(c->laddr);
	if (getsockname(sk, (struct sockaddr *) &c->laddr, &len) < 0) {
		err = errno;
		error_failed(c->conn, c->msg, err);
		error("getsockname: %s (%d)", strerror(err), err);
		goto failed;
	}

	node = malloc(sizeof(struct rfcomm_node));
	if (!node) {
		error_failed(c->conn, c->msg, ENOMEM);
		goto failed;
	}
	memset(node, 0, sizeof(*node));

	/* Create the rfcomm device node */
	memset(&req, 0, sizeof(req));

	req.dev_id = -1;
	req.flags = (1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP);

	bacpy(&req.src, &c->laddr.rc_bdaddr);
	bacpy(&req.dst, &c->raddr.rc_bdaddr);
	req.channel = c->raddr.rc_channel;

	node->id = ioctl(sk, RFCOMMCREATEDEV, &req);
	if (node->id < 0) {
		err = errno;
		error("ioctl(RFCOMMCREATEDEV): %s (%d)", strerror(errno), err);
		error_failed(c->conn, c->msg, err);
		goto failed;
	}

	rfcomm_node_name_from_id(node->id, node->name, sizeof(node->name));

	fd = open(node->name, O_RDONLY | O_NOCTTY);
	if (fd < 0) {
		c->node = node;
		c->ntries = 0;
		g_timeout_add(OPEN_WAIT, rfcomm_connect_cb_continue, c);
		return FALSE;
	}

	rfcomm_connect_cb_devnode_opened(fd, c, node);

	return FALSE;

failed:
	if (node)
		rfcomm_node_free(node);

	pending_connects = slist_remove(pending_connects, c);
	pending_connect_free(c);

	return FALSE;
}

static int rfcomm_connect(DBusConnection *conn, DBusMessage *msg, bdaddr_t *src,
			const char *bda, const char *svc, uint8_t ch, int *err)
{
	int sk = -1;
	struct pending_connect *c = NULL;

	c = malloc(sizeof(struct pending_connect));
	if (!c) {
		if (err)
			*err = ENOMEM;
		goto failed;
	}
	memset(c, 0, sizeof(struct pending_connect));

	if (svc) {
		c->svc = strdup(svc);
		if (!c->svc) {
			if (err)
				*err = ENOMEM;
			goto failed;
		}
	}

	c->laddr.rc_family = AF_BLUETOOTH;
	bacpy(&c->laddr.rc_bdaddr, src);
	c->laddr.rc_channel = 0;

	c->raddr.rc_family = AF_BLUETOOTH;
	str2ba(bda, &c->raddr.rc_bdaddr);
	c->raddr.rc_channel = ch;

	sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
	if (sk < 0) {
		if (err)
			*err = errno;
		goto failed;
	}

	if (bind(sk, (struct sockaddr *) &c->laddr, sizeof(c->laddr)) < 0) {
		if (err)
			*err = errno;
		goto failed;
	}

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

	/* So we can reply to the message later */
	c->msg = dbus_message_ref(msg);
	c->conn = dbus_connection_ref(conn);

	c->io = g_io_channel_unix_new(sk);
	g_io_channel_set_close_on_unref(c->io, TRUE);

	if (connect(sk, (struct sockaddr *) &c->raddr, sizeof(c->raddr)) < 0) {
		/* BlueZ returns EAGAIN eventhough it should return EINPROGRESS */
		if (!(errno == EAGAIN || errno == EINPROGRESS)) {
			if (err)
				*err = errno;
			error("connect() failed: %s (%d)", strerror(errno), errno);
			goto failed;
		}

		debug("Connect in progress");
		g_io_add_watch(c->io, G_IO_OUT, (GIOFunc) rfcomm_connect_cb, c);
		pending_connects = slist_append(pending_connects, c);
	} else {
		debug("Connect succeeded with first try");
		(void) rfcomm_connect_cb(c->io, G_IO_OUT, c);
	}

	return 0;

failed:
	if (c)
		pending_connect_free(c);
	if (sk >= 0)
		close(sk);
	return -1;
}

static void rfcomm_bind_req_exit(const char *name, void *data)
{
	struct rfcomm_node *node = data;
	debug("Bind requestor %s exited. Releasing %s node", name, node->name);
	rfcomm_release(node, NULL);
	bound_nodes = slist_remove(bound_nodes, node);
	rfcomm_node_free(node);
}

static struct rfcomm_node *rfcomm_bind(bdaddr_t *src, const char *bda,
		uint8_t ch, DBusConnection *conn, const char *owner, int *err)
{
	struct rfcomm_dev_req req;
	struct rfcomm_node *node;

	debug("rfcomm_bind(%s, %d)", bda, ch);

	memset(&req, 0, sizeof(req));
	req.dev_id = -1;
	req.flags = 0;
	bacpy(&req.src, src);

	str2ba(bda, &req.dst);
	req.channel = ch;

	node = malloc(sizeof(struct rfcomm_node));
	if (!node) {
		if (err)
			*err = ENOMEM;
		return NULL;
	}
	memset(node, 0, sizeof(struct rfcomm_node));

	node->owner = strdup(owner);
	if (!node->owner) {
		if (err)
			*err = ENOMEM;
		rfcomm_node_free(node);
		return NULL;
	}

	node->id = ioctl(rfcomm_ctl, RFCOMMCREATEDEV, &req);
	if (node->id < 0) {
		if (err)
			*err = errno;
		error("RFCOMMCREATEDEV failed: %s (%d)", strerror(errno), errno);
		rfcomm_node_free(node);
		return NULL;
	}

	rfcomm_node_name_from_id(node->id, node->name, sizeof(node->name));
	bound_nodes = slist_append(bound_nodes, node);

	node->conn = dbus_connection_ref(conn);
	name_listener_add(node->conn, node->owner, rfcomm_bind_req_exit, node);

	return node;
}

typedef struct {
	DBusConnection *conn;
	DBusMessage *msg;
	char *dst;
	char *svc;
	struct hci_dbus_data *dbus_data;
} rfcomm_continue_data_t;

static rfcomm_continue_data_t *rfcomm_continue_data_new(DBusConnection *conn,
							DBusMessage *msg,
							const char *dst,
							const char *svc,
							struct hci_dbus_data *dbus_data)
{
	rfcomm_continue_data_t *new;

	new = malloc(sizeof(*new));
	if (!new)
		return NULL;

	new->dst = strdup(dst);
	if (!new->dst) {
		free(new);
		return NULL;
	}

	new->svc = strdup(svc);
	if (!new->svc) {
		free(new->dst);
		free(new);
		return NULL;
	}

	new->conn = dbus_connection_ref(conn);
	new->msg = dbus_message_ref(msg);
	new->dbus_data = dbus_data;

	return new;
}

static void rfcomm_continue_data_free(rfcomm_continue_data_t *d)
{
	dbus_connection_unref(d->conn);
	dbus_message_unref(d->msg);
	free(d->svc);
	free(d->dst);
	free(d);
}

static void rfcomm_conn_req_continue(sdp_record_t *rec, void *data, int err)
{
	rfcomm_continue_data_t *cdata = data;
	int ch = -1, conn_err;
	sdp_list_t *protos;
	bdaddr_t bdaddr;

	if (err || !rec) {
		error_record_does_not_exist(cdata->conn, cdata->msg);
		goto failed;
	}

	if (!sdp_get_access_protos(rec, &protos)) {
		ch = sdp_get_proto_port(protos, RFCOMM_UUID);
		sdp_list_foreach(protos, (sdp_list_func_t)sdp_list_free, NULL);
		sdp_list_free(protos, NULL);
	}
	if (ch == -1) {
		error_record_does_not_exist(cdata->conn, cdata->msg);
		goto failed;
	}

	if (find_pending_connect_by_channel(cdata->dst, ch)) {
		error_connect_in_progress(cdata->conn, cdata->msg);
		goto failed;
	}

	hci_devba(cdata->dbus_data->dev_id, &bdaddr);
	if (rfcomm_connect(cdata->conn, cdata->msg, &bdaddr,
				cdata->dst, cdata->svc, ch, &conn_err) < 0)
		error_failed(cdata->conn, cdata->msg, conn_err);

failed:
	rfcomm_continue_data_free(cdata);
}

static DBusHandlerResult rfcomm_connect_req(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct hci_dbus_data *dbus_data = data;
	rfcomm_continue_data_t *cdata;
	uint32_t handle;
	uuid_t uuid;
	const char *string;
	const char *dst;
	int err;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &dst,
				DBUS_TYPE_STRING, &string,
				DBUS_TYPE_INVALID))
		return error_invalid_arguments(conn, msg);

	cdata = rfcomm_continue_data_new(conn, msg, dst, string, dbus_data);
	if (!cdata)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	if (str2uuid(&uuid, string) == 0)
		err = get_record_with_uuid(conn, msg, dbus_data->dev_id, dst,
					&uuid, rfcomm_conn_req_continue, cdata);
	else if ((handle = strtol(string, NULL, 0)))
		err = get_record_with_handle(conn, msg, dbus_data->dev_id, dst,
					handle, rfcomm_conn_req_continue, cdata);
	else {
		rfcomm_continue_data_free(cdata);
		return error_invalid_arguments(conn, msg);
	}

	if (!err)
		return DBUS_HANDLER_RESULT_HANDLED;

	rfcomm_continue_data_free(cdata);

	if (err == -ENOMEM)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	return error_failed(conn, msg, err);
}

static DBusHandlerResult rfcomm_cancel_connect_req(DBusConnection *conn,
						DBusMessage *msg,
						void *data)
{
	struct pending_connect *pending;
	DBusMessage *reply;
	const char *string;
	const char *dst;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &dst,
				DBUS_TYPE_STRING, &string,
				DBUS_TYPE_INVALID))
		return error_invalid_arguments(conn, msg);

	pending = find_pending_connect_by_service(dst, string);
	if (!pending)
		return error_connect_not_in_progress(conn, msg);

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

	pending->canceled = 1;

	return send_reply_and_unref(conn, reply);
}

static DBusHandlerResult rfcomm_connect_by_ch_req(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	bdaddr_t bdaddr;
	const char *dst;
	uint8_t ch;
	int err;
	struct hci_dbus_data *dbus_data = data;

	hci_devba(dbus_data->dev_id, &bdaddr);

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &dst,
				DBUS_TYPE_BYTE, &ch,
				DBUS_TYPE_INVALID))
		return error_invalid_arguments(conn, msg);

	if (find_pending_connect_by_channel(dst, ch))
		return error_connect_in_progress(conn, msg);

	if (rfcomm_connect(conn, msg, &bdaddr, dst, NULL, ch, &err) < 0)
		return error_failed(conn, msg, err);

	return DBUS_HANDLER_RESULT_HANDLED;
}

static DBusHandlerResult rfcomm_cancel_connect_by_ch_req(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	const char *dst;
	uint8_t ch;
	DBusMessage *reply;
	struct pending_connect *pending;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &dst,
				DBUS_TYPE_BYTE, &ch,
				DBUS_TYPE_INVALID))
		return error_invalid_arguments(conn, msg);

	pending = find_pending_connect_by_channel(dst, ch);
	if (!pending)
		return error_connect_not_in_progress(conn, msg);

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

	pending->canceled = 1;

	return send_reply_and_unref(conn, reply);
}

static DBusHandlerResult rfcomm_disconnect_req(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct rfcomm_node *node;
	DBusMessage *reply;
	const char *name;
	int err;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &name,
				DBUS_TYPE_INVALID))
		return error_invalid_arguments(conn, msg);

	node = find_node_by_name(connected_nodes, name);
	if (!node)
		return error_not_connected(conn, msg);

	if (strcmp(node->owner, dbus_message_get_sender(msg)))
		return error_not_authorized(conn, msg);

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

	if (rfcomm_release(node, &err) < 0) {
		dbus_message_unref(reply);
		return error_failed(conn, msg, err);
	}

	name_listener_remove(node->conn, node->owner,
			     rfcomm_connect_req_exit, node);
	connected_nodes = slist_remove(connected_nodes, node);
	rfcomm_node_free(node);

	return send_reply_and_unref(conn, reply);
}

static void rfcomm_bind_req_continue(sdp_record_t *rec, void *data, int err)
{
	rfcomm_continue_data_t *cdata = data;
	struct rfcomm_node *node = NULL;
	DBusMessage *reply = NULL;
	int ch = -1, bind_err;
	sdp_list_t *protos;
	const char *name;
	bdaddr_t bdaddr;

	if (err || !rec) {
		error_record_does_not_exist(cdata->conn, cdata->msg);
		goto failed;
	}

	if (!sdp_get_access_protos(rec, &protos)) {
		ch = sdp_get_proto_port(protos, RFCOMM_UUID);
		sdp_list_foreach(protos, (sdp_list_func_t)sdp_list_free, NULL);
		sdp_list_free(protos, NULL);
	}
	if (ch == -1) {
		error_record_does_not_exist(cdata->conn, cdata->msg);
		goto failed;
	}

	hci_devba(cdata->dbus_data->dev_id, &bdaddr);

	node = rfcomm_bind(&bdaddr, cdata->dst, ch, cdata->conn,
			dbus_message_get_sender(cdata->msg), &bind_err);
	if (!node) {
		error_failed(cdata->conn, cdata->msg, bind_err);
		goto failed;
	}

	reply = dbus_message_new_method_return(cdata->msg);
	if (!reply) {
		error_failed(cdata->conn, cdata->msg, ENOMEM);
		goto failed;
	}

	name = node->name;
	if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &name,
					DBUS_TYPE_INVALID)) {
		error_failed(cdata->conn, cdata->msg, ENOMEM);
		goto failed;
	}

	send_reply_and_unref(cdata->conn, reply);

	rfcomm_continue_data_free(cdata);

	return;

failed:
	if (reply)
		dbus_message_unref(reply);
	if (node) {
		bound_nodes = slist_remove(bound_nodes, node);
		rfcomm_release(node, NULL);
		rfcomm_node_free(node);
	}

	rfcomm_continue_data_free(cdata);
}

static DBusHandlerResult rfcomm_bind_req(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct hci_dbus_data *dbus_data = data;
	rfcomm_continue_data_t *cdata;
	uint32_t handle;
	uuid_t uuid;
	const char *string;
	const char *dst;
	int err;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &dst,
				DBUS_TYPE_STRING, &string,
				DBUS_TYPE_INVALID))
		return error_invalid_arguments(conn, msg);

	cdata = rfcomm_continue_data_new(conn, msg, dst, string, dbus_data);
	if (!cdata)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	if (str2uuid(&uuid, string) == 0)
		err = get_record_with_uuid(conn, msg, dbus_data->dev_id, dst,
					&uuid, rfcomm_bind_req_continue, cdata);
	else if ((handle = strtol(string, NULL, 0)))
		err = get_record_with_handle(conn, msg, dbus_data->dev_id, dst,
					handle, rfcomm_bind_req_continue, cdata);
	else {
		rfcomm_continue_data_free(cdata);
		return error_invalid_arguments(conn, msg);
	}

	if (!err)
		return DBUS_HANDLER_RESULT_HANDLED;

	rfcomm_continue_data_free(cdata);

	if (err == -ENOMEM)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	return error_failed(conn, msg, err);
}

static DBusHandlerResult rfcomm_bind_by_ch_req(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	bdaddr_t bdaddr;
	DBusMessage *reply = NULL;
	uint8_t ch;
	int err;
	const char *dst, *name;
	struct hci_dbus_data *dbus_data = data;
	struct rfcomm_node *node = NULL;

	hci_devba(dbus_data->dev_id, &bdaddr);

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &dst,
				DBUS_TYPE_BYTE, &ch,
				DBUS_TYPE_INVALID))
		return error_invalid_arguments(conn, msg);

	node = rfcomm_bind(&bdaddr, dst, ch, conn,
			dbus_message_get_sender(msg), &err);
	if (!node)
		return error_failed(conn, msg, err);

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		goto need_memory;

	name = node->name;
	if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &name,
					DBUS_TYPE_INVALID))
		goto need_memory;

	return send_reply_and_unref(conn, reply);

need_memory:
	if (reply)
		dbus_message_unref(reply);
	if (node) {
		bound_nodes = slist_remove(bound_nodes, node);
		rfcomm_release(node, NULL);
		rfcomm_node_free(node);
	}
	return DBUS_HANDLER_RESULT_NEED_MEMORY;
}

static DBusHandlerResult rfcomm_release_req(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	DBusMessage *reply;
	const char *name;
	struct rfcomm_node *node;
	int err;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &name,
				DBUS_TYPE_INVALID))
		return error_invalid_arguments(conn, msg);

	node = find_node_by_name(bound_nodes, name);
	if (!node)
		return error_binding_does_not_exist(conn, msg);

	if (strcmp(node->owner, dbus_message_get_sender(msg)))
		return error_not_authorized(conn, msg);

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

	if (rfcomm_release(node, &err) < 0) {
		dbus_message_unref(reply);
		return error_failed(conn, msg, err);
	}

	name_listener_remove(node->conn, node->owner,
				rfcomm_bind_req_exit, node);
	bound_nodes = slist_remove(bound_nodes, node);
	rfcomm_node_free(node);

	return send_reply_and_unref(conn, reply);
}

static DBusHandlerResult rfcomm_list_bindings_req(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	bdaddr_t bdaddr;
	DBusMessage *reply;
	DBusMessageIter iter, sub;
	struct hci_dbus_data *dbus_data = data;
	struct slist *l;

	hci_devba(dbus_data->dev_id, &bdaddr);

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

	dbus_message_iter_init_append(reply, &iter);

	if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub)) {
		dbus_message_unref(reply);
		return DBUS_HANDLER_RESULT_NEED_MEMORY;
	}

	for (l = bound_nodes; l != NULL; l = l->next) {
		struct rfcomm_node *node = l->data;
		struct rfcomm_dev_info di = { id: node->id };
		char *name = node->name;

		if (ioctl(rfcomm_ctl, RFCOMMGETDEVINFO, &di) < 0) {
			error("RFCOMMGETDEVINFO(%d): %s (%d)",
					node->id, strerror(errno), errno);
			continue;
		}

		/* Ignore nodes not specific to this adapter */
		if (bacmp(&di.src, &bdaddr))
			continue;

		dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &name);
	}

	if (!dbus_message_iter_close_container(&iter, &sub)) {
		dbus_message_unref(reply);
		return DBUS_HANDLER_RESULT_NEED_MEMORY;
	}

	return send_reply_and_unref(conn, reply);
}

static struct service_data rfcomm_services[] = {
	{ "Connect",			rfcomm_connect_req,			},
	{ "CancelConnect",		rfcomm_cancel_connect_req,		},
	{ "ConnectByChannel",		rfcomm_connect_by_ch_req,		},
	{ "CancelConnectByChannel",	rfcomm_cancel_connect_by_ch_req,	},
	{ "Disconnect",			rfcomm_disconnect_req,			},
	{ "Bind",			rfcomm_bind_req,			},
	{ "BindByChannel",		rfcomm_bind_by_ch_req,			},
	{ "Release",			rfcomm_release_req,			},
	{ "ListBindings",		rfcomm_list_bindings_req,		},
	{ NULL,				NULL,					}
};

DBusHandlerResult handle_rfcomm_method(DBusConnection *conn, DBusMessage *msg,
					void *data)
{
	const struct hci_dbus_data *pdata = data;
	service_handler_func_t handler;

	if (!hcid_dbus_use_experimental())
		return error_unknown_method(conn, msg);

	if (!data) {
		error("RFCOMM method called with NULL data pointer!");
		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
	}

	if (!pdata->up)
		return error_not_ready(conn, msg);

	/* Initialize the RFCOMM control socket if has not yet been done */
	if (rfcomm_ctl < 0) {
		rfcomm_ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_RFCOMM);
		if (rfcomm_ctl < 0)
			return error_failed(conn, msg, errno);
	}

	handler = find_service_handler(rfcomm_services, msg);

	if (handler)
		return handler(conn, msg, data);

	return error_unknown_method(conn, msg);
}
