/*
 *
 *  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 <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/socket.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/rfcomm.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_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 6
#define OPEN_WAIT (1000 * 300)

static int rfcomm_ctl = -1;

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

	/* 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;
};

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->io) {
		g_io_channel_close(node->io);
		g_io_remove_watch(node->io_id);
	}
	if (node->owner)
		free(node->owner);
	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(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 void pending_connect_free(struct pending_connect *c)
{
	if (c->svc)
		free(c->svc);
	if (c->io)
		g_io_channel_close(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);

	if (node->io) {
		g_io_channel_close(node->io);
		g_io_remove_watch(node->io_id);
		node->io = NULL;
	}

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

	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 gboolean rfcomm_disconnect_cb(GIOChannel *io, GIOCondition cond,
					struct rfcomm_node *node)
{
	debug("RFCOMM node %s was disconnected", node->name);
	connected_nodes = slist_remove(connected_nodes, node);
	rfcomm_node_free(node);
	return FALSE;
}

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

	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;
	}

	/* 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));

	/* FIXME: instead of looping here we should create a timer and
	 * return to the mainloop */
	for (i = 0; i < MAX_OPEN_TRIES; i++) {
		fd = open(node->name, O_RDONLY | O_NOCTTY);
		if (fd >= 0)
			break;
		usleep(OPEN_WAIT);
	}

	if (fd < 0) {
		err = errno;
		error("Could not open %s: %s (%d)", node->name,
				strerror(err), err);
		rfcomm_release(node, NULL);
		rfcomm_node_free(node);

		error_connection_attempt_failed(c->conn, c->msg, err);
		goto failed;
	}

	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;
	}

        node->io = g_io_channel_unix_new(fd);
	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);

	goto done;

failed:
	if (fd >= 0)
		close(fd);
	if (node) {
		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);

	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);

	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 struct rfcomm_node *rfcomm_bind(bdaddr_t *src, const char *bda, uint8_t ch, 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->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);

	return node;
}

static DBusHandlerResult rfcomm_connect_req(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	error("RFCOMM.Connect not implemented");
	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

static DBusHandlerResult rfcomm_cancel_connect_req(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	error("RFCOMM.CancelConnect not implemented");
	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

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(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(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)
{
	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(connected_nodes, name);
	if (!node)
		return error_not_connected(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);
	}

	connected_nodes = slist_remove(connected_nodes, node);
	rfcomm_node_free(node);

	return send_reply_and_unref(conn, reply);
}

static DBusHandlerResult rfcomm_bind_req(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	error("RFCOMM.Bind not implemented");
	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

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, &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);

	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);
	}

	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)
{
	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;
	}

	/* 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);
}
