/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2004-2010  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 "log.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 */
	GIOChannel	*io;		/* BtIO channel */
	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;
	int channel;
	char *endptr = NULL;

	channel = strtol(pattern, &endptr, 10);

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

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

		if (endptr && *endptr == '\0' && port->channel == channel)
			return port;

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

		if (!port->uuid)
			continue;

		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;

	if (port->id < 0) {
		if (port->io) {
			g_io_channel_shutdown(port->io, TRUE, NULL);
			g_io_channel_unref(port->io);
			port->io = NULL;
		} else
			bt_cancel_discovery(&port->device->src,
						&port->device->dst);

		return 0;
	}

	DBG("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)
{
	struct serial_device *device = port->device;

	if (device && port->listener_id > 0)
		g_dbus_remove_watch(device->conn, port->listener_id);

	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;

	port_release(port);

	port->listener_id = 0;
}

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

	DBG("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;

	g_io_channel_unref(port->io);
	port->io = NULL;

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

	DBG("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 void get_record_cb(sdp_list_t *recs, int err, gpointer user_data)
{
	struct serial_port *port = user_data;
	struct serial_device *device = port->device;
	sdp_record_t *record = NULL;
	sdp_list_t *protos;
	DBusMessage *reply;
	GError *gerr = NULL;

	if (!port->listener_id) {
		reply = NULL;
		goto failed;
	}

	if (err < 0) {
		error("Unable to get service record: %s (%d)", strerror(-err),
			-err);
		reply = failed(port->msg, strerror(-err));
		goto failed;
	}

	if (!recs || !recs->data) {
		error("No record found");
		reply = failed(port->msg, "No record found");
		goto failed;
	}

	record = recs->data;

	if (sdp_get_access_protos(record, &protos) < 0) {
		error("Unable to get access protos from port record");
		reply = failed(port->msg, "Invalid channel");
		goto failed;
	}

	port->channel = sdp_get_proto_port(protos, RFCOMM_UUID);

	sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL);
	sdp_list_free(protos, NULL);

	port->io = bt_io_connect(BT_IO_RFCOMM, rfcomm_connect_cb, port,
				NULL, &gerr,
				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 (!port->io) {
		error("%s", gerr->message);
		reply = failed(port->msg, gerr->message);
		g_error_free(gerr);
		goto failed;
	}

	return;

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

static int connect_port(struct serial_port *port)
{
	struct serial_device *device = port->device;
	uuid_t uuid;
	int err;

	if (!port->uuid)
		goto connect;

	err = bt_string2uuid(&uuid, port->uuid);
	if (err < 0)
		return err;

	sdp_uuid128_to_uuid(&uuid);

	return bt_search_service(&device->src, &device->dst, &uuid,
				get_record_cb, port, NULL);

connect:
	port->io = bt_io_connect(BT_IO_RFCOMM, rfcomm_connect_cb, port,
				NULL, NULL,
				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 (port->io)
		return 0;

	return -errno;
}

static struct serial_port *create_port(struct serial_device *device,
					const char *uuid, uint8_t channel)
{
	struct serial_port *port;

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

static DBusMessage *port_connect(DBusConnection *conn,
					DBusMessage *msg, void *user_data)
{
	struct serial_device *device = user_data;
	struct serial_port *port;
	const char *pattern;
	int err;

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

	port = find_port(device->ports, pattern);
	if (!port) {
		char *endptr = NULL;
		int channel;

		channel = strtol(pattern, &endptr, 10);
		if ((endptr && *endptr != '\0') || channel < 1 || channel > 30)
			return does_not_exist(msg, "Does not match");

		port = create_port(device, NULL, channel);
	}

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

	err = connect_port(port);
	if (err < 0) {
		DBusMessage *reply;

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

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

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

	DBG("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;
}
