/*
 *
 *  OBEX Server
 *
 *  Copyright (C) 2007-2010  Nokia Corporation
 *  Copyright (C) 2007-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 <string.h>
#include <unistd.h>
#include <inttypes.h>
#include <fcntl.h>
#include <sys/socket.h>

#include <glib.h>

#include "lib/bluetooth.h"
#include "lib/uuid.h"

#include "gdbus/gdbus.h"

#include "btio/btio.h"
#include "obexd/src/obexd.h"
#include "obexd/src/plugin.h"
#include "obexd/src/server.h"
#include "obexd/src/obex.h"
#include "obexd/src/transport.h"
#include "obexd/src/service.h"
#include "obexd/src/log.h"

#define BT_RX_MTU 32767
#define BT_TX_MTU 32767

struct bluetooth_profile {
	struct obex_server *server;
	struct obex_service_driver *driver;
	char *uuid;
	char *path;
};

static GSList *profiles = NULL;

static DBusConnection *connection = NULL;

static DBusMessage *profile_release(DBusConnection *conn, DBusMessage *msg,
								void *data)
{
	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}

static void connect_event(GIOChannel *io, GError *err, void *user_data)
{
	int sk = g_io_channel_unix_get_fd(io);
	struct bluetooth_profile *profile = user_data;
	struct obex_server *server = profile->server;
	int type;
	uint16_t omtu = BT_TX_MTU;
	uint16_t imtu = BT_RX_MTU;
	gboolean stream = TRUE;
	socklen_t len = sizeof(int);

	if (err)
		goto drop;

	if (getsockopt(sk, SOL_SOCKET, SO_TYPE, &type, &len) < 0)
		goto done;

	if (type != SOCK_SEQPACKET)
		goto done;

	stream = FALSE;

	/* Read MTU if io is an L2CAP socket */
	bt_io_get(io, NULL, BT_IO_OPT_OMTU, &omtu, BT_IO_OPT_IMTU, &imtu,
							BT_IO_OPT_INVALID);

done:
	if (obex_server_new_connection(server, io, omtu, imtu, stream) < 0)
		g_io_channel_shutdown(io, TRUE, NULL);

	return;

drop:
	error("%s", err->message);
	g_io_channel_shutdown(io, TRUE, NULL);
	return;
}

static DBusMessage *invalid_args(DBusMessage *msg)
{
	return g_dbus_create_error(msg, "org.bluez.Error.InvalidArguments",
					"Invalid arguments in method call");
}

static DBusMessage *profile_new_connection(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	DBusMessageIter args;
	const char *device;
	int fd;
	GIOChannel *io;

	dbus_message_iter_init(msg, &args);

	if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH)
		return invalid_args(msg);

	dbus_message_iter_get_basic(&args, &device);

	dbus_message_iter_next(&args);

	if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_UNIX_FD)
		return invalid_args(msg);

	dbus_message_iter_get_basic(&args, &fd);

	if (fd < 0) {
		error("bluetooth: NewConnection invalid fd");
		return invalid_args(msg);
	}

	/* Read fd flags to make sure it can be used */
	if (fcntl(fd, F_GETFD) < 0) {
		error("bluetooth: fcntl(%d, F_GETFD): %s (%d)", fd,
						strerror(errno), errno);
		close(fd);
		return invalid_args(msg);
	}

	io = g_io_channel_unix_new(fd);
	if (io == NULL) {
		close(fd);
		return invalid_args(msg);
	}

	DBG("device %s", device);

	connect_event(io, NULL, data);
	g_io_channel_unref(io);

	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}

static DBusMessage *profile_request_disconnection(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}

static DBusMessage *profile_cancel(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}

static const GDBusMethodTable profile_methods[] = {
	{ GDBUS_METHOD("Release",
			NULL, NULL,
			profile_release) },
	{ GDBUS_METHOD("NewConnection",
			GDBUS_ARGS({ "device", "o" }, { "fd", "h" },
			{ "options", "a{sv}" }), NULL,
			profile_new_connection) },
	{ GDBUS_METHOD("RequestDisconnection",
			GDBUS_ARGS({ "device", "o" }), NULL,
			profile_request_disconnection) },
	{ GDBUS_METHOD("Cancel",
			NULL, NULL,
			profile_cancel) },
	{ }
};

static void unregister_profile(struct bluetooth_profile *profile)
{
	g_dbus_unregister_interface(connection, profile->path,
						"org.bluez.Profile1");
	g_free(profile->path);
	profile->path = NULL;
}

static void register_profile_reply(DBusPendingCall *call, void *user_data)
{
	struct bluetooth_profile *profile = user_data;
	DBusMessage *reply = dbus_pending_call_steal_reply(call);
	DBusError derr;

	dbus_error_init(&derr);
	if (!dbus_set_error_from_message(&derr, reply)) {
		DBG("Profile %s registered", profile->path);
		goto done;
	}

	unregister_profile(profile);

	error("bluetooth: RequestProfile error: %s, %s", derr.name,
								derr.message);
	dbus_error_free(&derr);
done:
	dbus_message_unref(reply);
}

static void profile_free(void *data)
{
	struct bluetooth_profile *profile = data;

	if (profile->path != NULL)
		unregister_profile(profile);

	g_free(profile->uuid);
	g_free(profile);
}

static int register_profile(struct bluetooth_profile *profile)
{
	DBusMessage *msg;
	DBusMessageIter iter, opt;
	DBusPendingCall *call;
	dbus_bool_t auto_connect = FALSE;
	char *xml;
	int ret = 0;

	profile->path = g_strconcat("/org/bluez/obex/", profile->uuid, NULL);
	g_strdelimit(profile->path, "-", '_');

	if (!g_dbus_register_interface(connection, profile->path,
					"org.bluez.Profile1", profile_methods,
					NULL, NULL,
					profile, NULL)) {
		error("D-Bus failed to register %s", profile->path);
		g_free(profile->path);
		profile->path = NULL;
		return -1;
	}

	msg = dbus_message_new_method_call("org.bluez", "/org/bluez",
						"org.bluez.ProfileManager1",
						"RegisterProfile");

	dbus_message_iter_init_append(msg, &iter);

	dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
							&profile->path);
	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
							&profile->uuid);
	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
					DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
					DBUS_TYPE_STRING_AS_STRING
					DBUS_TYPE_VARIANT_AS_STRING
					DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
					&opt);
	g_dbus_dict_append_entry(&opt, "AutoConnect", DBUS_TYPE_BOOLEAN,
								&auto_connect);
	if (profile->driver->record) {
		if (profile->driver->port != 0)
			xml = g_markup_printf_escaped(profile->driver->record,
						profile->driver->channel,
						profile->driver->name,
						profile->driver->port);
		else
			xml = g_markup_printf_escaped(profile->driver->record,
						profile->driver->channel,
						profile->driver->name);
		g_dbus_dict_append_entry(&opt, "ServiceRecord",
						DBUS_TYPE_STRING, &xml);
		g_free(xml);
	}
	dbus_message_iter_close_container(&iter, &opt);

	if (!g_dbus_send_message_with_reply(connection, msg, &call, -1)) {
		ret = -1;
		unregister_profile(profile);
		goto failed;
	}

	dbus_pending_call_set_notify(call, register_profile_reply, profile,
									NULL);
	dbus_pending_call_unref(call);

failed:
	dbus_message_unref(msg);
	return ret;
}

static const char *service2uuid(uint16_t service)
{
	switch (service) {
	case OBEX_OPP:
		return OBEX_OPP_UUID;
	case OBEX_FTP:
		return OBEX_FTP_UUID;
	case OBEX_PBAP:
		return OBEX_PSE_UUID;
	case OBEX_IRMC:
		return OBEX_SYNC_UUID;
	case OBEX_PCSUITE:
		return "00005005-0000-1000-8000-0002ee000001";
	case OBEX_SYNCEVOLUTION:
		return "00000002-0000-1000-8000-0002ee000002";
	case OBEX_MAS:
		return OBEX_MAS_UUID;
	case OBEX_MNS:
		return OBEX_MNS_UUID;
	}

	return NULL;
}

static void name_acquired(DBusConnection *conn, void *user_data)
{
	GSList *l;

	DBG("org.bluez appeared");

	for (l = profiles; l; l = l->next) {
		struct bluetooth_profile *profile = l->data;

		if (profile->path != NULL)
			continue;

		if (register_profile(profile) < 0) {
			error("bluetooth: Failed to register profile %s",
							profile->path);
			g_free(profile->path);
			profile->path = NULL;
		}
	}
}

static void name_released(DBusConnection *conn, void *user_data)
{
	GSList *l;

	DBG("org.bluez disappered");

	for (l = profiles; l; l = l->next) {
		struct bluetooth_profile *profile = l->data;

		if (profile->path == NULL)
			continue;

		unregister_profile(profile);
	}
}

static void *bluetooth_start(struct obex_server *server, int *err)
{
	const GSList *l;

	for (l = server->drivers; l; l = l->next) {
		struct obex_service_driver *driver = l->data;
		struct bluetooth_profile *profile;
		const char *uuid;

		uuid = service2uuid(driver->service);
		if (uuid == NULL)
			continue;

		profile = g_new0(struct bluetooth_profile, 1);
		profile->driver = driver;
		profile->server = server;
		profile->uuid = g_strdup(uuid);

		profiles = g_slist_prepend(profiles, profile);
	}

	return profiles;
}

static void bluetooth_stop(void *data)
{
	g_slist_free_full(profiles, profile_free);
	profiles = NULL;
}

static int bluetooth_getpeername(GIOChannel *io, char **name)
{
	GError *gerr = NULL;
	char address[18];

	bt_io_get(io, &gerr, BT_IO_OPT_DEST, address, BT_IO_OPT_INVALID);

	if (gerr) {
		error("%s", gerr->message);
		g_error_free(gerr);
		return -EINVAL;
	}

	*name = g_strdup(address);

	return 0;
}

static int bluetooth_getsockname(GIOChannel *io, char **name)
{
	GError *gerr = NULL;
	char address[18];

	bt_io_get(io, &gerr, BT_IO_OPT_SOURCE, address, BT_IO_OPT_INVALID);

	if (gerr) {
		error("%s", gerr->message);
		g_error_free(gerr);
		return -EINVAL;
	}

	*name = g_strdup(address);

	return 0;
}

static struct obex_transport_driver driver = {
	.name = "bluetooth",
	.start = bluetooth_start,
	.getpeername = bluetooth_getpeername,
	.getsockname = bluetooth_getsockname,
	.stop = bluetooth_stop
};

static unsigned int listener_id = 0;

static int bluetooth_init(void)
{
	connection = g_dbus_setup_private(DBUS_BUS_SYSTEM, NULL, NULL);
	if (connection == NULL)
		return -EPERM;

	listener_id = g_dbus_add_service_watch(connection, "org.bluez",
				name_acquired, name_released, NULL, NULL);

	return obex_transport_driver_register(&driver);
}

static void bluetooth_exit(void)
{
	g_dbus_remove_watch(connection, listener_id);

	g_slist_free_full(profiles, profile_free);

	if (connection)
		dbus_connection_unref(connection);

	obex_transport_driver_unregister(&driver);
}

OBEX_PLUGIN_DEFINE(bluetooth, bluetooth_init, bluetooth_exit)
