/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2004-2006  Marcel Holtmann <marcel@holtmann.org>
 *  Copyright (C) 2005-2006  Johan Hedberg <johan.hedberg@nokia.com>
 *
 *
 *  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 <sys/socket.h>

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

#include <dbus/dbus.h>

#include "dbus.h"
#include "hcid.h"

#define TIMEOUT (30 * 1000)		/* 30 seconds */

struct pin_request {
	int dev;
	bdaddr_t sba;
	bdaddr_t bda;
};

static struct passkey_agent *default_agent = NULL;

static void default_agent_exited(const char *name, void *data)
{
	debug("%s exited without unregistering the default passkey agent", name);

	if (!default_agent || strcmp(name, default_agent->name)) {
		/* This should never happen (there's a bug in the code if it does) */
		debug("default_agent_exited: mismatch with actual default_agent");
		return;
	}

	free(default_agent->path);
	free(default_agent->name);
	free(default_agent);
	default_agent = NULL;
}

static void passkey_agent_free(struct passkey_agent *agent)
{
	if (!agent)
		return;
	if (agent->name)
		free(agent->name);
	if (agent->path)
		free(agent->path);
	if (agent->addr)
		free(agent->addr);
	free(agent);
}

static struct passkey_agent *passkey_agent_new(const char *name,
					const char *path, const char *addr)
{
	struct passkey_agent *agent;

	agent = malloc(sizeof(struct passkey_agent));
	if (!agent)
		return NULL;

	memset(agent, 0, sizeof(struct passkey_agent));

	agent->name = strdup(name);
	if (!agent->name)
		goto mem_fail;

	agent->path = strdup(path);
	if (!agent->path)
		goto mem_fail;

	if (addr) {
		agent->addr = strdup(addr);
		if (!agent->addr)
			goto mem_fail;
	}

	return agent;

mem_fail:
	passkey_agent_free(agent);
	return NULL;
}

static int agent_cmp(const struct passkey_agent *a, const struct passkey_agent *b)
{
	int ret;

	if (b->name) {
		if (!a->name)
			return -1;
		ret = strcmp(a->name, b->name);
		if (ret)
			return ret;
	}

	if (b->path) {
		if (!a->path)
			return -1;
		ret = strcmp(a->path, b->path);
		if (ret)
			return ret;
	}

	if (b->addr) {
		if (!a->addr)
			return -1;
		ret = strcmp(a->addr, b->addr);
		if (ret)
			return ret;
	}

	return 0;
}

static void agent_exited(const char *name, struct hci_dbus_data *adapter)
{
	struct slist *cur, *next;

	debug("Passkey agent %s exited without calling Unregister", name);

	for (cur = adapter->passkey_agents; cur != NULL; cur = next) {
		struct passkey_agent *agent = cur->data;

		next = cur->next;

		if (strcmp(agent->name, name))
			continue;

		adapter->passkey_agents = slist_remove(adapter->passkey_agents, agent);
		passkey_agent_free(agent);
	}
}

static DBusHandlerResult register_agent(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	char *path, *addr;
	struct passkey_agent *agent, ref;
	struct hci_dbus_data *adapter;
	DBusMessage *reply;

	if (!data) {
		error("register_agent called without any adapter info!");
		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
	}

	adapter = data;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &path,
				DBUS_TYPE_STRING, &addr,
				DBUS_TYPE_INVALID))
		return error_invalid_arguments(conn, msg);

	ref.name = (char *)dbus_message_get_sender(msg);
	ref.addr = addr;
	ref.path = path;

	if (slist_find(adapter->passkey_agents, &ref, (cmp_func_t)agent_cmp))
		return error_passkey_agent_already_exists(conn, msg);

	agent = passkey_agent_new(ref.name, path, addr);
	if (!agent)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	reply = dbus_message_new_method_return(msg);
	if (!reply) {
		passkey_agent_free(agent);
		return DBUS_HANDLER_RESULT_NEED_MEMORY;
	}

	/* Only add a name listener if there isn't one already for this name */
	ref.addr = NULL;
	ref.path = NULL;
	if (!slist_find(adapter->passkey_agents, &ref, (cmp_func_t)agent_cmp))
		name_listener_add(conn, ref.name, (name_cb_t)agent_exited, adapter);

	adapter->passkey_agents = slist_append(adapter->passkey_agents, agent);

	return send_reply_and_unref(conn, reply);
}

static DBusHandlerResult unregister_agent(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	char *path, *addr;
	struct hci_dbus_data *adapter;
	struct slist *match;
	struct passkey_agent ref, *agent;
	DBusMessage *reply;

	if (!data) {
		error("uregister_agent called without any adapter info!");
		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
	}

	adapter = data;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &path,
				DBUS_TYPE_STRING, &addr,
				DBUS_TYPE_INVALID))
		return error_invalid_arguments(conn, msg);

	ref.name = (char *)dbus_message_get_sender(msg);
	ref.path = path;
	ref.addr = addr;

	match = slist_find(adapter->passkey_agents, &ref, (cmp_func_t)agent_cmp);
	if (!match)
		return error_passkey_agent_does_not_exist(conn, msg);

	agent = match->data;

	adapter->passkey_agents = slist_remove(adapter->passkey_agents, agent);
	passkey_agent_free(agent);

	/* Only remove the name listener if there are no more agents for this name */
	ref.addr = NULL;
	ref.path = NULL;
	if (!slist_find(adapter->passkey_agents, &ref, (cmp_func_t)agent_cmp))
		name_listener_remove(conn, ref.name, (name_cb_t)agent_exited, adapter);

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	return send_reply_and_unref(conn, reply);
}

static DBusHandlerResult register_default_agent(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	char *path;
	DBusMessage *reply;

	if (default_agent)
		return error_passkey_agent_already_exists(conn, msg);

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &path,
				DBUS_TYPE_INVALID))
		return error_invalid_arguments(conn, msg);

	default_agent = passkey_agent_new(dbus_message_get_sender(msg), path, NULL);
	if (!default_agent)
		goto need_memory;

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		goto need_memory;

	name_listener_add(conn, default_agent->name,
			(name_cb_t)default_agent_exited, NULL);

	info("Default passkey agent (%s, %s) registered",
			default_agent->name, default_agent->path);

	return send_reply_and_unref(conn, reply);

need_memory:
	if (default_agent) {
		passkey_agent_free(default_agent);
		default_agent = NULL;
	}

	return DBUS_HANDLER_RESULT_NEED_MEMORY;
}

static DBusHandlerResult unregister_default_agent(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	DBusMessage *reply;
	char *path;
	const char *name;

	if (!default_agent)
		return error_passkey_agent_does_not_exist(conn, msg);

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &path,
				DBUS_TYPE_INVALID))
		return error_invalid_arguments(conn, msg);

	name = dbus_message_get_sender(msg);

	if (strcmp(name, default_agent->name) || strcmp(path, default_agent->path))
		return error_passkey_agent_does_not_exist(conn, msg);

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	name_listener_remove(conn, default_agent->name,
			(name_cb_t)default_agent_exited, NULL);

	info("Default passkey agent (%s, %s) unregistered",
			default_agent->name, default_agent->path);

	passkey_agent_free(default_agent);
	default_agent = NULL;

	return send_reply_and_unref(conn, reply);
}

static struct service_data sec_services[] = {
	{ "RegisterDefaultPasskeyAgent",	register_default_agent		},
	{ "UnregisterDefaultPasskeyAgent",	unregister_default_agent	},
	{ "RegisterPasskeyAgent",		register_agent			},
	{ "UnregisterPasskeyAgent",		unregister_agent		},
	{ NULL, NULL }
};

static void passkey_agent_reply(DBusPendingCall *call, void *user_data)
{
	struct pin_request *req = (struct pin_request *) user_data;
	pin_code_reply_cp pr;
	DBusMessage *message;
	DBusError err;
	size_t len;
	char *pin;

	/* steal_reply will always return non-NULL since the callback
	 * is only called after a reply has been received */
	message = dbus_pending_call_steal_reply(call);

	dbus_error_init(&err);
	if (dbus_set_error_from_message(&err, message)) {
		error("Passkey agent replied with an error: %s, %s",
				err.name, err.message);
		dbus_error_free(&err);
		hci_send_cmd(req->dev, OGF_LINK_CTL,
				OCF_PIN_CODE_NEG_REPLY, 6, &req->bda);
		goto done;
	}

	dbus_error_init(&err);
	if (!dbus_message_get_args(message, &err,
				DBUS_TYPE_STRING, &pin,
				DBUS_TYPE_INVALID)) {
		error("Wrong passkey reply signature: %s", err.message);
		dbus_error_free(&err);
		hci_send_cmd(req->dev, OGF_LINK_CTL,
				OCF_PIN_CODE_NEG_REPLY, 6, &req->bda);
		goto done;
	}

	len = strlen(pin);

	if (len > 16) {
		error("Too long (%d char) passkey from handler", len);
		goto done;
	}

	set_pin_length(&req->sba, len);

	memset(&pr, 0, sizeof(pr));
	bacpy(&pr.bdaddr, &req->bda);
	memcpy(pr.pin_code, pin, len);
	pr.pin_len = len;
	hci_send_cmd(req->dev, OGF_LINK_CTL,
			OCF_PIN_CODE_REPLY, PIN_CODE_REPLY_CP_SIZE, &pr);

done:
	if (message)
		dbus_message_unref(message);

	dbus_pending_call_unref(call);
}

static int call_passkey_agent(DBusConnection *conn, struct passkey_agent *agent,
		int dev, const char *path, bdaddr_t *sba, bdaddr_t *dba)
{
	DBusMessage *message = NULL;
	DBusPendingCall *pending = NULL;
	struct pin_request *req;
	char bda[18];
	char *ptr = bda;

	ba2str(dba, bda);

	if (!agent) {
		debug("call_passkey_agent(): no agent registered");
		goto failed;
	}

	debug("Calling PasskeyAgent.Request: name=%s, path=%s",
						agent->name, agent->path);

	message = dbus_message_new_method_call(agent->name, agent->path,
					"org.bluez.PasskeyAgent", "Request");
	if (message == NULL) {
		error("Couldn't allocate D-Bus message");
		goto failed;
	}

	req = malloc(sizeof(*req));
	if (!req)
		goto failed;
	req->dev = dev;
	bacpy(&req->sba, sba);
	bacpy(&req->bda, dba);

	dbus_message_append_args(message,
					DBUS_TYPE_STRING, &path,
					DBUS_TYPE_STRING, &ptr,
					DBUS_TYPE_INVALID);

	if (dbus_connection_send_with_reply(conn, message,
				&pending, TIMEOUT) == FALSE) {
		error("D-Bus send failed");
		goto failed;
	}

	dbus_pending_call_set_notify(pending, passkey_agent_reply, req, free);

	dbus_message_unref(message);

	return 0;

failed:
	if (message)
		dbus_message_unref(message);

	hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, dba);

	return -1;
}

DBusHandlerResult handle_security_method(DBusConnection *conn, DBusMessage *msg, void *data)
{
	service_handler_func_t handler;

	handler = find_service_handler(sec_services, msg);

	if (handler)
		return handler(conn, msg, data);

	return error_unknown_method(conn, msg);
}

int handle_passkey_request(DBusConnection *conn, int dev, const char *path, bdaddr_t *sba, bdaddr_t *dba)
{
	struct passkey_agent *agent = default_agent;
	struct hci_dbus_data *adapter = NULL;
	struct slist *l;
	char addr[18];
	void *data;

	dbus_connection_get_object_path_data(conn, path, &data);

	if (!data)
		goto done;

	adapter = data;

	ba2str(dba, addr);

	for (l = adapter->passkey_agents; l != NULL; l = l->next) {
		struct passkey_agent *a = l->data;
		if (!strcmp(a->addr, addr)) {
			agent = a;
			break;
		}
	}

done:
	return call_passkey_agent(conn, agent, dev, path, sba, dba);
}
