/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2004-2007  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 <stdlib.h>
#include <string.h>

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

#include <glib.h>

#include <dbus/dbus.h>

#include "dbus.h"
#include "dbus-helper.h"
#include "hcid.h"
#include "sdpd.h"
#include "sdp-xml.h"
#include "manager.h"
#include "adapter.h"
#include "dbus-hci.h"
#include "dbus-common.h"
#include "dbus-error.h"
#include "dbus-service.h"
#include "dbus-security.h"
#include "dbus-database.h"

static int sdp_server_enable = 0;

static GSList *records = NULL;

struct record_data {
	uint32_t handle;
	char *sender;
};

static struct record_data *find_record(uint32_t handle, const char *sender)
{
	GSList *list;

	for (list = records; list; list = list->next) {
		struct record_data *data = list->data;
		if (handle == data->handle && !strcmp(sender, data->sender))
			return data;
	}

	return NULL;
}

static void exit_callback(const char *name, void *user_data)
{
	struct record_data *user_record = user_data;

	records = g_slist_remove(records, user_record);

	if (sdp_server_enable)
		remove_record_from_server(user_record->handle);
	else
		unregister_sdp_record(user_record->handle);

	if (user_record->sender)
		g_free(user_record->sender);

	g_free(user_record);
}

static DBusHandlerResult add_service_record(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	DBusMessage *reply;
	DBusMessageIter iter, array;
	const char *sender;
	struct record_data *user_record;
	sdp_record_t *sdp_record;
	const uint8_t *record;
	int scanned, len = -1;

	dbus_message_iter_init(msg, &iter);
	dbus_message_iter_recurse(&iter, &array);

	dbus_message_iter_get_fixed_array(&array, &record, &len);
	if (len <= 0)
		return error_invalid_arguments(conn, msg);

	user_record = g_new0(struct record_data, 1);

	if (sdp_server_enable) {
		sdp_record = sdp_extract_pdu(record, &scanned);
		if (!sdp_record) {
			error("Parsing of service record failed");
			g_free(user_record);
			return error_failed(conn, msg, EIO);
		}

		if (scanned != len) {
			error("Size mismatch of service record");
			g_free(user_record);
			sdp_record_free(sdp_record);
			return error_failed(conn, msg, EIO);
		}

		if (add_record_to_server(sdp_record) < 0) {
			error("Failed to register service record");
			g_free(user_record);
			sdp_record_free(sdp_record);
			return error_failed(conn, msg, EIO);
		}

		user_record->handle = sdp_record->handle;
	} else {
		uint32_t size = len;

		if (register_sdp_binary((uint8_t *) record, size,
						&user_record->handle) < 0) {
			error("Failed to register service record");
			g_free(user_record);
			return error_failed(conn, msg, errno);
		}
	}

	sender = dbus_message_get_sender(msg);

	user_record->sender = g_strdup(sender);

	records = g_slist_append(records, user_record);

	name_listener_add(conn, sender, exit_callback, user_record);

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

	dbus_message_append_args(reply, DBUS_TYPE_UINT32, &user_record->handle,
					DBUS_TYPE_INVALID);

	return send_message_and_unref(conn, reply);
}

static DBusHandlerResult add_service_record_from_xml(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	DBusMessage *reply;
	const char *sender, *record;
	struct record_data *user_record;
	sdp_record_t *sdp_record;

	if (dbus_message_get_args(msg, NULL,
			DBUS_TYPE_STRING, &record, DBUS_TYPE_INVALID) == FALSE)
		return error_invalid_arguments(conn, msg);

	user_record = g_new0(struct record_data, 1);

	sdp_record = sdp_xml_parse_record(record, strlen(record));
	if (!sdp_record) {
		error("Parsing of XML service record failed");
		g_free(user_record);
		return error_failed(conn, msg, EIO);
	}

	if (sdp_server_enable) {
		if (add_record_to_server(sdp_record) < 0) {
			error("Failed to register service record");
			g_free(user_record);
			sdp_record_free(sdp_record);
			return error_failed(conn, msg, EIO);
		}

		user_record->handle = sdp_record->handle;
	} else {
		if (register_sdp_record(sdp_record) < 0) {
			error("Failed to register service record");
			g_free(user_record);
			sdp_record_free(sdp_record);
			return error_failed(conn, msg, EIO);
		}

		user_record->handle = sdp_record->handle;

		sdp_record_free(sdp_record);
	}

	sender = dbus_message_get_sender(msg);

	user_record->sender = g_strdup(sender);

	records = g_slist_append(records, user_record);

	name_listener_add(conn, sender, exit_callback, user_record);

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

	dbus_message_append_args(reply, DBUS_TYPE_UINT32, &user_record->handle,
					DBUS_TYPE_INVALID);

	return send_message_and_unref(conn, reply);
}


static DBusHandlerResult update_record(DBusConnection *conn, DBusMessage *msg,
				dbus_uint32_t handle, sdp_record_t *sdp_record)
{
	int err;

	if (sdp_server_enable) {
		if (remove_record_from_server(handle) < 0) {
			sdp_record_free(sdp_record);
			return error_not_available(conn, msg);
		}

		sdp_record->handle = handle;
		err = add_record_to_server(sdp_record);
		if (err < 0) {
			sdp_record_free(sdp_record);
			error("Failed to update the service record");
			return error_failed(conn, msg, EIO);
		}
	} else {
		sdp_data_t *d = sdp_data_alloc(SDP_UINT32, &handle);
		sdp_attr_replace(sdp_record, SDP_ATTR_RECORD_HANDLE, d);

		err = update_sdp_record(handle, sdp_record);
		sdp_record_free(sdp_record);
		if (err < 0) {
			error("Failed to update the service record");
			return error_failed(conn, msg, EIO);
		}
	}

	return send_message_and_unref(conn,
			dbus_message_new_method_return(msg));
}

static DBusHandlerResult update_service_record(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct record_data *user_record;
	DBusMessageIter iter, array;
	sdp_record_t *sdp_record;
	dbus_uint32_t handle;
	const uint8_t *bin_record;
	int scanned, size = -1;

	dbus_message_iter_init(msg, &iter);
	dbus_message_iter_get_basic(&iter, &handle);
	dbus_message_iter_next(&iter);
	dbus_message_iter_recurse(&iter, &array);

	dbus_message_iter_get_fixed_array(&array, &bin_record, &size);
	if (size <= 0)
		return error_invalid_arguments(conn, msg);

	user_record = find_record(handle, dbus_message_get_sender(msg));
	if (!user_record)
		return error_not_available(conn, msg);

	sdp_record = sdp_extract_pdu(bin_record, &scanned);
	if (!sdp_record) {
		error("Parsing of service record failed");
		return error_invalid_arguments(conn, msg);
	}

	if (scanned != size) {
		error("Size mismatch of service record");
		sdp_record_free(sdp_record);
		return error_invalid_arguments(conn, msg);
	}

	return update_record(conn, msg, handle, sdp_record);
}

static DBusHandlerResult update_service_record_from_xml(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	const char *record;
	struct record_data *user_record;
	sdp_record_t *sdp_record;
	dbus_uint32_t handle;
	int len;

	if (dbus_message_get_args(msg, NULL,
			DBUS_TYPE_UINT32, &handle,
			DBUS_TYPE_STRING, &record,
			DBUS_TYPE_INVALID) == FALSE)
		return error_invalid_arguments(conn, msg);

	len = (record ? strlen(record) : 0);
	if (len == 0)
		return error_invalid_arguments(conn, msg);

	user_record = find_record(handle, dbus_message_get_sender(msg));
	if (!user_record)
		return error_not_available(conn, msg);

	sdp_record = sdp_xml_parse_record(record, len);
	if (!sdp_record) {
		error("Parsing of XML service record failed");
		sdp_record_free(sdp_record);
		return error_failed(conn, msg, EIO);
	}

	return update_record(conn, msg, handle, sdp_record);
}

static DBusHandlerResult remove_service_record(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	DBusMessage *reply;
	dbus_uint32_t handle;
	const char *sender;
	struct record_data *user_record;

	if (dbus_message_get_args(msg, NULL,
			DBUS_TYPE_UINT32, &handle, DBUS_TYPE_INVALID) == FALSE)
		return error_invalid_arguments(conn, msg);

	sender = dbus_message_get_sender(msg);

	user_record = find_record(handle, sender);
	if (!user_record)
		return error_not_available(conn, msg);

	name_listener_remove(conn, sender, exit_callback, user_record);

	records = g_slist_remove(records, user_record);

	if (sdp_server_enable)
		remove_record_from_server(handle);
	else
		unregister_sdp_record(handle);

	if (user_record->sender)
		g_free(user_record->sender);

	g_free(user_record);

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

	return send_message_and_unref(conn, reply);
}

static DBusHandlerResult register_service(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	DBusMessage *reply;
	const char *sender, *ident, *name, *desc;

	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &ident,
			DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &desc,
						DBUS_TYPE_INVALID) == FALSE)
		return error_invalid_arguments(conn, msg);

	sender = dbus_message_get_sender(msg);

	if (service_register(conn, sender, ident, name, desc) < 0)
		return error_failed(conn, msg, EIO);

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

	return send_message_and_unref(conn, reply);
}

static DBusHandlerResult unregister_service(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	DBusMessage *reply;
	const char *sender, *ident;
	struct service *service;

	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &ident,
						DBUS_TYPE_INVALID) == FALSE)
		return error_invalid_arguments(conn, msg);

	sender = dbus_message_get_sender(msg);

	service = search_service(conn, ident);
	if (!service)
		return error_service_does_not_exist(conn, msg);

	if (!service->external || strcmp(sender, service->bus_name))
		return error_not_authorized(conn, msg);

	if (service_unregister(conn, service) < 0)
		return error_failed(conn, msg, EIO);

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

	return send_message_and_unref(conn, reply);
}

static DBusHandlerResult request_authorization(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	const char *sender, *address, *path;
	struct service *service;
	bdaddr_t bdaddr;
	gboolean trusted;
	int adapter_id;

	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,
			DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID) == FALSE)
		return error_invalid_arguments(conn, msg);

	sender = dbus_message_get_sender(msg);

	service = search_service(conn, sender);
	if (!service) {
		debug("Got RequestAuthorization from non-service owner %s",
				sender);
		return error_not_authorized(conn, msg);
	}

	str2ba(address, &bdaddr);
	adapter_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
	if (adapter_id < 0)
		return error_not_connected(conn, msg);

	hci_devba(adapter_id, &bdaddr);

	trusted = read_trust(&bdaddr, address, GLOBAL_TRUST);
	if (!trusted)
		trusted = read_trust(BDADDR_ANY, address, service->ident);

	if (trusted) {
		DBusMessage *reply;

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

		return send_message_and_unref(conn, reply);
	}

	return handle_authorize_request(conn, msg, service, address, path);
}

static DBusHandlerResult cancel_authorization_request(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	const char *sender, *address, *path;
	struct service *service;

	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,
			DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID) == FALSE)
		return error_invalid_arguments(conn, msg);

	sender = dbus_message_get_sender(msg);

	service = search_service(conn, sender);
	if (!service)
		return error_not_authorized(conn, msg);

	return cancel_authorize_request(conn, msg, service, address, path);
}

static DBusMethodVTable database_methods[] = {
	{ "AddServiceRecord",			add_service_record,		"ay",	"u"	},	
	{ "AddServiceRecordFromXML",		add_service_record_from_xml,	"s",	"u"	},
	{ "UpdateServiceRecord",		update_service_record,		"uay",	""	},
	{ "UpdateServiceRecordFromXML",		update_service_record_from_xml,	"us",	""	},
	{ "RemoveServiceRecord",		remove_service_record,		"u",	""	},
	{ "RegisterService",			register_service,		"sss",	""	},
	{ "UnregisterService",			unregister_service,		"s",	""	},
	{ "RequestAuthorization",		request_authorization,		"ss",	""	},
	{ "CancelAuthorizationRequest",		cancel_authorization_request,	"ss",	""	},
	{ NULL, NULL, NULL, NULL }
};

dbus_bool_t database_init(DBusConnection *conn, const char *path)
{
	return dbus_connection_register_interface(conn, path,
							DATABASE_INTERFACE,
							database_methods,
							NULL, NULL);
}

DBusHandlerResult database_message(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	DBusMethodVTable *current;

	for (current = database_methods;
			current->name && current->message_function; current++) {
		if (!dbus_message_is_method_call(msg, DATABASE_INTERFACE,
								current->name))
			continue;

		if (dbus_message_has_signature(msg, current->signature)) {
			debug("%s: %s.%s()", dbus_message_get_path(msg),
					DATABASE_INTERFACE, current->name);
			return current->message_function(conn, msg, data);
		}
	}

	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

void set_sdp_server_enable(void)
{
	sdp_server_enable = 1;
}
