/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2004-2009  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 <errno.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

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

#include <glib.h>
#include <gdbus.h>

#include "../src/dbus-common.h"

#include "logging.h"
#include "glib-helper.h"
#include "btio.h"

#include "error.h"
#include "manager.h"
#include "storage.h"
#include "port.h"

#define SERIAL_PORT_INTERFACE	"org.bluez.Serial"
#define ERROR_INVALID_ARGS	"org.bluez.Error.InvalidArguments"
#define ERROR_DOES_NOT_EXIST	"org.bluez.Error.DoesNotExist"

#define MAX_OPEN_TRIES		5
#define OPEN_WAIT		300	/* ms. udev node creation retry wait */

struct serial_device {
	DBusConnection	*conn;		/* for name listener handling */
	bdaddr_t	src;		/* Source (local) address */
	bdaddr_t	dst;		/* Destination address */
	char		*path;		/* Device path */
	GSList		*ports;		/* Available ports */
};

struct serial_port {
	DBusMessage	*msg;		/* for name listener handling */
	int16_t		id;		/* RFCOMM device id */
	uint8_t		channel;	/* RFCOMM channel */
	char		*uuid;		/* service identification */
	char		*dev;		/* RFCOMM device name */
	int		fd;		/* Opened file descriptor */
	guint		listener_id;
	struct serial_device *device;
};

static GSList *devices = NULL;

static struct serial_device *find_device(GSList *devices, const char *path)
{
	GSList *l;

	for (l = devices; l != NULL; l = l->next) {
		struct serial_device *device = l->data;

		if (!strcmp(device->path, path))
			return device;
	}

	return NULL;
}

static struct serial_port *find_port(GSList *ports, const char *pattern)
{
	GSList *l;

	for (l = ports; l != NULL; l = l->next) {
		struct serial_port *port = l->data;
		char *uuid_str;
		int ret;

		if (!strcasecmp(port->uuid, pattern))
			return port;

		if (port->dev && !strcmp(port->dev, pattern))
			return port;

		uuid_str = bt_name2string(pattern);
		if (!uuid_str)
			continue;

		ret = strcasecmp(port->uuid, uuid_str);

		g_free(uuid_str);

		if (ret == 0)
			return port;
	}

	return NULL;
}

static int port_release(struct serial_port *port)
{
	struct rfcomm_dev_req req;
	int rfcomm_ctl;
	int err = 0;

	debug("Serial port %s released", port->dev);

	rfcomm_ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_RFCOMM);
	if (rfcomm_ctl < 0)
		return -errno;

	if (port->fd >= 0) {
		close(port->fd);
		port->fd = -1;
	}

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

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

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

	g_free(port->dev);
	port->dev = NULL;
	port->id = -1;
	close(rfcomm_ctl);
	return -err;
}

static void serial_port_free(struct serial_port *port)
{
	if (port->id >= 0)
		port_release(port);
	g_free(port->uuid);
	g_free(port);
}

static void serial_device_free(struct serial_device *device)
{
	g_free(device->path);
	if (device->conn)
		dbus_connection_unref(device->conn);
	g_free(device);
}

static void port_owner_exited(DBusConnection *conn, void *user_data)
{
	struct serial_port *port = user_data;

	if (port->id >= 0)
		port_release(port);

	port->listener_id = 0;
}

static void path_unregister(void *data)
{
	struct serial_device *device = data;

	info("Unregistered interface %s on path %s", SERIAL_PORT_INTERFACE,
		device->path);

	devices = g_slist_remove(devices, device);
	serial_device_free(device);
}

void port_release_all(void)
{
	g_slist_foreach(devices, (GFunc) serial_device_free, NULL);
	g_slist_free(devices);
}

static inline DBusMessage *does_not_exist(DBusMessage *msg,
					const char *description)
{
	return g_dbus_create_error(msg, ERROR_INTERFACE ".DoesNotExist",
				description);
}

static inline DBusMessage *invalid_arguments(DBusMessage *msg,
					const char *description)
{
	return g_dbus_create_error(msg, ERROR_INTERFACE ".InvalidArguments",
				description);
}

static inline DBusMessage *failed(DBusMessage *msg, const char *description)
{
	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
				description);
}

static void open_notify(int fd, int err, struct serial_port *port)
{
	struct serial_device *device = port->device;
	DBusMessage *reply;

	if (err) {
		/* Max tries exceeded */
		port_release(port);
		reply = failed(port->msg, strerror(err));
	} else {
		port->fd = fd;
		reply = g_dbus_create_reply(port->msg,
				DBUS_TYPE_STRING, &port->dev,
				DBUS_TYPE_INVALID);
	}

	/* Reply to the requestor */
	g_dbus_send_message(device->conn, reply);
}

static gboolean open_continue(gpointer user_data)
{
	struct serial_port *port = user_data;
	int fd;
	static int ntries = MAX_OPEN_TRIES;

	if (!port->listener_id)
		return FALSE; /* Owner exited */

	fd = open(port->dev, O_RDONLY | O_NOCTTY);
	if (fd < 0) {
		int err = errno;
		error("Could not open %s: %s (%d)",
				port->dev, strerror(err), err);
		if (!--ntries) {
			/* Reporting error */
			open_notify(fd, err, port);
			ntries = MAX_OPEN_TRIES;
			return FALSE;
		}
		return TRUE;
	}

	/* Connection succeeded */
	open_notify(fd, 0, port);
	return FALSE;
}

static int port_open(struct serial_port *port)
{
	int fd;

	fd = open(port->dev, O_RDONLY | O_NOCTTY);
	if (fd < 0) {
		g_timeout_add(OPEN_WAIT, open_continue, port);
		return -EINPROGRESS;
	}

	return fd;
}

static void rfcomm_connect_cb(GIOChannel *chan, GError *conn_err,
							gpointer user_data)
{
	struct serial_port *port = user_data;
	struct serial_device *device = port->device;
	struct rfcomm_dev_req req;
	int sk, fd;
	DBusMessage *reply;

	/* Owner exited? */
	if (!port->listener_id)
		return;

	if (conn_err) {
		error("%s", conn_err->message);
		reply = failed(port->msg, conn_err->message);
		goto fail;
	}

	memset(&req, 0, sizeof(req));
	req.dev_id = -1;
	req.flags = (1 << RFCOMM_REUSE_DLC);
	bacpy(&req.src, &device->src);
	bacpy(&req.dst, &device->dst);
	req.channel = port->channel;

	sk = g_io_channel_unix_get_fd(chan);
	port->id = ioctl(sk, RFCOMMCREATEDEV, &req);
	if (port->id < 0) {
		int err = errno;
		error("ioctl(RFCOMMCREATEDEV): %s (%d)", strerror(err), err);
		reply = failed(port->msg, strerror(err));
		g_io_channel_shutdown(chan, TRUE, NULL);
		goto fail;
	}

	port->dev = g_strdup_printf("/dev/rfcomm%d", port->id);

	debug("Serial port %s created", port->dev);

	g_io_channel_shutdown(chan, TRUE, NULL);

	/* Addressing connect port */
	fd = port_open(port);
	if (fd < 0)
		/* Open in progress: Wait the callback */
		return;

	open_notify(fd, 0, port);
	return;

fail:
	g_dbus_send_message(device->conn, reply);
	g_dbus_remove_watch(device->conn, port->listener_id);
	port->listener_id = 0;
}

static DBusMessage *port_connect(DBusConnection *conn,
					DBusMessage *msg, void *user_data)
{
	struct serial_device *device = user_data;
	struct serial_port *port;
	const char *uuid;
	GIOChannel *io;
	GError *err = NULL;

	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &uuid,
						DBUS_TYPE_INVALID) == FALSE)
		return NULL;

	port = find_port(device->ports, uuid);
	if (!port)
		return does_not_exist(msg, "Does not match");

	if (port->listener_id)
		return failed(msg, "Port already in use");

	port->listener_id = g_dbus_add_disconnect_watch(conn,
						dbus_message_get_sender(msg),
						port_owner_exited, port,
						NULL);
	port->msg = dbus_message_ref(msg);

	io = bt_io_connect(BT_IO_RFCOMM, rfcomm_connect_cb, port,
				NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, &device->src,
				BT_IO_OPT_DEST_BDADDR, &device->dst,
				BT_IO_OPT_CHANNEL, port->channel,
				BT_IO_OPT_INVALID);
	if (!io) {
		DBusMessage *reply;

		error("%s", err->message);
		g_dbus_remove_watch(conn, port->listener_id);
		port->listener_id = 0;
		reply = failed(msg, err->message);
		g_error_free(err);
		return reply;
	}

	g_io_channel_unref(io);

	return NULL;
}

static DBusMessage *port_disconnect(DBusConnection *conn,
					DBusMessage *msg, void *user_data)
{
	struct serial_device *device = user_data;
	struct serial_port *port;
	const char *dev, *owner, *caller;

	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &dev,
						DBUS_TYPE_INVALID) == FALSE)
		return NULL;

	port = find_port(device->ports, dev);
	if (!port)
		return does_not_exist(msg, "Port does not exist");

	if (!port->listener_id)
		return failed(msg, "Not connected");

	owner = dbus_message_get_sender(port->msg);
	caller = dbus_message_get_sender(msg);
	if (!g_str_equal(owner, caller))
		return failed(msg, "Operation not permited");

	if (port->id >= 0)
		port_release(port);

	g_dbus_remove_watch(conn, port->listener_id);
	port->listener_id = 0;

	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}

static GDBusMethodTable port_methods[] = {
	{ "Connect",    "s", "s", port_connect, G_DBUS_METHOD_FLAG_ASYNC },
	{ "Disconnect", "s", "",  port_disconnect },
	{ }
};

static struct serial_device *create_serial_device(DBusConnection *conn,
					const char *path, bdaddr_t *src,
					bdaddr_t *dst)
{
	struct serial_device *device;

	device = g_new0(struct serial_device, 1);
	device->conn = dbus_connection_ref(conn);
	bacpy(&device->dst, dst);
	bacpy(&device->src, src);
	device->path = g_strdup(path);

	if (!g_dbus_register_interface(conn, path,
				SERIAL_PORT_INTERFACE,
				port_methods, NULL, NULL,
				device, path_unregister)) {
		error("D-Bus failed to register %s interface",
				SERIAL_PORT_INTERFACE);
		serial_device_free(device);
		return NULL;
	}

	info("Registered interface %s on path %s",
		SERIAL_PORT_INTERFACE, path);

	return device;
}

int port_register(DBusConnection *conn, const char *path, bdaddr_t *src,
			bdaddr_t *dst, const char *uuid, uint8_t channel)
{
	struct serial_device *device;
	struct serial_port *port;

	device = find_device(devices, path);
	if (!device) {
		device = create_serial_device(conn, path, src, dst);
		if (!device)
			return -1;
		devices = g_slist_append(devices, device);
	}

	if (find_port(device->ports, uuid))
		return 0;

	port = g_new0(struct serial_port, 1);
	port->uuid = g_strdup(uuid);
	port->channel = channel;
	port->device = device;
	port->id = -1;
	port->fd = -1;

	device->ports = g_slist_append(device->ports, port);

	return 0;
}

int port_unregister(const char *path)
{
	struct serial_device *device;

	device = find_device(devices, path);
	if (!device)
		return -ENOENT;

	g_slist_foreach(device->ports, (GFunc) serial_port_free, NULL);
	g_slist_free(device->ports);

	g_dbus_unregister_interface(device->conn, path, SERIAL_PORT_INTERFACE);

	return 0;
}
