/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2011  ST-Ericsson SA
 *
 *  Author: Szymon Janc <szymon.janc@tieto.com> for ST-Ericsson
 *
 *
 *  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 <gdbus.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/sdp.h>

#include "plugin.h"
#include "log.h"
#include "adapter.h"
#include "device.h"
#include "manager.h"
#include "dbus-common.h"
#include "event.h"
#include "error.h"
#include "oob.h"

#define REQUEST_TIMEOUT	(60 * 1000)	/* 60 seconds */
#define OOB_INTERFACE	"org.bluez.Oob"

struct oob_request {
	struct btd_adapter *adapter;
	DBusMessage *msg;
};

static GSList *oob_requests = NULL;
static DBusConnection *connection = NULL;

static gint oob_request_cmp(gconstpointer a, gconstpointer b)
{
	const struct oob_request *data = a;
	const struct btd_adapter *adapter = b;

	return data->adapter != adapter;
}

static struct oob_request *find_oob_request(struct btd_adapter *adapter)
{
	GSList *match;

	match = g_slist_find_custom(oob_requests, adapter, oob_request_cmp);

	if (match)
		return match->data;

	return NULL;
}

static void read_local_data_complete(struct btd_adapter *adapter, uint8_t *hash,
				uint8_t *randomizer)
{
	struct DBusMessage *reply;
	struct oob_request *oob_request;

	oob_request = find_oob_request(adapter);
	if (!oob_request)
		return;

	if (hash && randomizer)
		reply = g_dbus_create_reply(oob_request->msg,
			DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &hash, 16,
			DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &randomizer, 16,
			DBUS_TYPE_INVALID);
	else
		reply = btd_error_failed(oob_request->msg,
					"Failed to read local OOB data.");

	oob_requests = g_slist_remove(oob_requests, oob_request);
	dbus_message_unref(oob_request->msg);
	g_free(oob_request);

	if (!reply) {
		error("Couldn't allocate D-Bus message");
		return;
	}

	if (!g_dbus_send_message(connection, reply))
		error("D-Bus send failed");
}

static DBusMessage *read_local_data(DBusConnection *conn, DBusMessage *msg,
								void *data)
{
	struct btd_adapter *adapter = data;
	struct oob_request *oob_request;

	if (find_oob_request(adapter))
		return btd_error_in_progress(msg);

	if (btd_adapter_read_local_oob_data(adapter))
		return btd_error_failed(msg, "Request failed.");

	oob_request = g_new(struct oob_request, 1);
	oob_request->adapter = adapter;
	oob_requests = g_slist_append(oob_requests, oob_request);
	oob_request->msg = dbus_message_ref(msg);

	return NULL;
}

static DBusMessage *add_remote_data(DBusConnection *conn, DBusMessage *msg,
								void *data)
{
	struct btd_adapter *adapter = data;
	uint8_t *hash, *randomizer;
	int32_t hlen, rlen;
	const char *addr;
	bdaddr_t bdaddr;

	if (!dbus_message_get_args(msg, NULL,
			DBUS_TYPE_STRING, &addr,
			DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &hash, &hlen,
			DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &randomizer, &rlen,
			DBUS_TYPE_INVALID))
		return btd_error_invalid_args(msg);

	if (hlen != 16 || rlen != 16 || bachk(addr))
		return btd_error_invalid_args(msg);

	str2ba(addr, &bdaddr);

	if (btd_adapter_add_remote_oob_data(adapter, &bdaddr, hash, randomizer))
		return btd_error_failed(msg, "Request failed");

	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}

static DBusMessage *remove_remote_data(DBusConnection *conn, DBusMessage *msg,
								void *data)
{
	struct btd_adapter *adapter = data;
	const char *addr;
	bdaddr_t bdaddr;

	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &addr,
			DBUS_TYPE_INVALID))
		return btd_error_invalid_args(msg);

	if (bachk(addr))
		return btd_error_invalid_args(msg);

	str2ba(addr, &bdaddr);

	if (btd_adapter_remove_remote_oob_data(adapter, &bdaddr))
		return btd_error_failed(msg, "Request failed");

	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}

static GDBusMethodTable oob_methods[] = {
	{"AddRemoteOobData",	"sayay",	"",	add_remote_data},
	{"RemoveRemoteOobData",	"s",		"",	remove_remote_data},
	{"ReadLocalOobData",	"",		"ayay",	read_local_data,
						G_DBUS_METHOD_FLAG_ASYNC},
	{}
};

static int oob_probe(struct btd_adapter *adapter)
{
	const char *path = adapter_get_path(adapter);

	if (!g_dbus_register_interface(connection, path, OOB_INTERFACE,
				oob_methods, NULL, NULL, adapter, NULL)) {
			error("OOB interface init failed on path %s", path);
			return -EIO;
		}

	return 0;
}

static void oob_remove(struct btd_adapter *adapter)
{
	read_local_data_complete(adapter, NULL, NULL);

	g_dbus_unregister_interface(connection, adapter_get_path(adapter),
							OOB_INTERFACE);
}

static struct btd_adapter_driver oob_driver = {
	.name	= "oob",
	.probe	= oob_probe,
	.remove	= oob_remove,
};

static int dbusoob_init(void)
{
	DBG("Setup dbusoob plugin");

	connection = get_dbus_connection();

	oob_register_cb(read_local_data_complete);

	return btd_register_adapter_driver(&oob_driver);
}

static void dbusoob_exit(void)
{
	DBG("Cleanup dbusoob plugin");

	manager_foreach_adapter((adapter_cb) oob_remove, NULL);

	btd_unregister_adapter_driver(&oob_driver);
}

BLUETOOTH_PLUGIN_DEFINE(dbusoob, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
						dbusoob_init, dbusoob_exit)
