/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2006-2007  Nokia Corporation
 *  Copyright (C) 2004-2008  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 <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <unistd.h>
#include <stdint.h>
#include <sys/stat.h>
#include <dirent.h>
#include <ctype.h>
#include <signal.h>

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

#include <glib.h>
#include <dbus/dbus.h>
#include <gdbus.h>

#include "glib-helper.h"

#include "dbus-service.h"
#include "logging.h"
#include "textfile.h"
#include "ipc.h"
#include "device.h"
#include "error.h"
#include "avdtp.h"
#include "a2dp.h"
#include "headset.h"
#include "gateway.h"
#include "sink.h"
#include "control.h"
#include "manager.h"
#include "sdpd.h"

typedef enum {
	HEADSET	= 1 << 0,
	GATEWAY	= 1 << 1,
	SINK	= 1 << 2,
	SOURCE	= 1 << 3,
	CONTROL	= 1 << 4,
	TARGET	= 1 << 5,
	INVALID	= 1 << 6
} audio_service_type;

typedef enum {
		GENERIC_AUDIO = 0,
		ADVANCED_AUDIO,
		AV_REMOTE,
		GET_RECORDS
} audio_sdp_state_t;

struct audio_sdp_data {
	struct device *device;

	DBusMessage *msg;	/* Method call or NULL */

	GSList *records;	/* sdp_record_t * */

	audio_sdp_state_t state;

	create_dev_cb_t cb;
	void *cb_data;
};

static DBusConnection *connection = NULL;

static struct device *default_hs = NULL;
static struct device *default_dev = NULL;

static GSList *devices = NULL;

static uint32_t hsp_ag_record_id = 0;
static uint32_t hfp_ag_record_id = 0;

static uint32_t hsp_hs_record_id = 0;

static GIOChannel *hsp_ag_server = NULL;
static GIOChannel *hfp_ag_server = NULL;

static GIOChannel *hsp_hs_server = NULL;

static struct enabled_interfaces enabled = {
	.headset	= TRUE,
	.gateway	= FALSE,
	.sink		= TRUE,
	.source		= FALSE,
	.control	= TRUE,
};

static DBusHandlerResult get_records(uuid_t *uuid, struct audio_sdp_data *data);

static struct device *create_device(const bdaddr_t *bda)
{
	static int device_id = 0;
	char path[128];

	snprintf(path, sizeof(path) - 1,
			"%s/device%d", AUDIO_MANAGER_PATH, device_id++);

	return device_register(connection, path, bda);
}

static void destroy_device(struct device *device)
{
	dbus_connection_destroy_object_path(connection, device->path);
}

static void remove_device(struct device *device)
{
	if (device == default_dev) {
		debug("Removing default device");
		default_dev = NULL;
	}

	if (device == default_hs) {
		debug("Removing default headset");
		default_hs = NULL;
	}

	devices = g_slist_remove(devices, device);

	destroy_device(device);
}

static gboolean add_device(struct device *device, gboolean send_signals)
{
	if (!send_signals)
		goto add;

	dbus_connection_emit_signal(connection, AUDIO_MANAGER_PATH,
					AUDIO_MANAGER_INTERFACE,
					"DeviceCreated",
					DBUS_TYPE_STRING, &device->path,
					DBUS_TYPE_INVALID);

	if (device->headset)
		dbus_connection_emit_signal(connection,
				AUDIO_MANAGER_PATH,
				AUDIO_MANAGER_INTERFACE,
				"HeadsetCreated",
				DBUS_TYPE_STRING, &device->path,
				DBUS_TYPE_INVALID);
add:

	if (default_dev == NULL && g_slist_length(devices) == 0) {
		debug("Selecting default device");
		default_dev = device;
	}

	if (!default_hs && device->headset && !devices)
		default_hs = device;

	devices = g_slist_append(devices, device);

	return TRUE;
}

static uint16_t get_service_uuid(const sdp_record_t *record)
{
	sdp_list_t *classes;
	uuid_t uuid;
	uint16_t uuid16 = 0;

	if (sdp_get_service_classes(record, &classes) < 0) {
		error("Unable to get service classes from record");
		return 0;
	}

	memcpy(&uuid, classes->data, sizeof(uuid));

	if (!sdp_uuid128_to_uuid(&uuid)) {
		error("Not a 16 bit UUID");
		sdp_list_free(classes, free);
		return 0;
	}

	if (uuid.type == SDP_UUID32) {
		if (uuid.value.uuid32 > 0xFFFF) {
			error("Not a 16 bit UUID");
			goto done;
		}
		uuid16 = (uint16_t) uuid.value.uuid32;
	} else
		uuid16 = uuid.value.uuid16;

done:
	sdp_list_free(classes, free);

	return uuid16;
}

gboolean server_is_enabled(uint16_t svc)
{
	gboolean ret;

	switch (svc) {
	case HEADSET_SVCLASS_ID:
		ret = (hsp_ag_server != NULL);
		break;
	case HEADSET_AGW_SVCLASS_ID:
		ret = (hsp_hs_server != NULL);
		break;
	case HANDSFREE_SVCLASS_ID:
		ret = (hfp_ag_server != NULL);
		break;
	case HANDSFREE_AGW_SVCLASS_ID:
		ret = FALSE;
		break;
	case AUDIO_SINK_SVCLASS_ID:
		return enabled.sink;
	case AV_REMOTE_TARGET_SVCLASS_ID:
	case AV_REMOTE_SVCLASS_ID:
		return enabled.control;
	default:
		ret = FALSE;
		break;
	}

	return ret;
}

static void handle_record(sdp_record_t *record, struct device *device)
{
	gboolean is_default;
	uint16_t uuid16;

	uuid16 = get_service_uuid(record);

	if (!server_is_enabled(uuid16))
		return;

	switch (uuid16) {
	case HEADSET_SVCLASS_ID:
		debug("Found Headset record");
		if (device->headset)
			headset_update(device, record, uuid16);
		else
			device->headset = headset_init(device,
							record, uuid16);
		break;
	case HEADSET_AGW_SVCLASS_ID:
		debug("Found Headset AG record");
		break;
	case HANDSFREE_SVCLASS_ID:
		debug("Found Hansfree record");
		if (device->headset)
			headset_update(device, record, uuid16);
		else
			device->headset = headset_init(device,
							record, uuid16);
		break;
	case HANDSFREE_AGW_SVCLASS_ID:
		debug("Found Handsfree AG record");
		break;
	case AUDIO_SINK_SVCLASS_ID:
		debug("Found Audio Sink");
		if (device->sink == NULL)
			device->sink = sink_init(device);
		break;
	case AUDIO_SOURCE_SVCLASS_ID:
		debug("Found Audio Source");
		break;
	case AV_REMOTE_SVCLASS_ID:
		debug("Found AV Remote");
		if (device->control == NULL)
			device->control = control_init(device);
		if (device->sink && sink_is_active(device))
			avrcp_connect(device);
		break;
	case AV_REMOTE_TARGET_SVCLASS_ID:
		debug("Found AV Target");
		if (device->control == NULL)
			device->control = control_init(device);
		if (device->sink && sink_is_active(device))
			avrcp_connect(device);
		break;
	default:
		debug("Unrecognized UUID: 0x%04X", uuid16);
		break;
	}

	is_default = (default_dev == device) ? TRUE : FALSE;

	device_store(device, is_default);
}

static void finish_sdp(struct audio_sdp_data *data, gboolean success)
{
	const char *addr;
	DBusMessage *reply = NULL;
	DBusError derr;

	debug("Audio service discovery completed with %s",
			success ? "success" : "failure");

	if (!success)
		goto done;

	if (!data->msg)
		goto update;

	dbus_error_init(&derr);
	dbus_message_get_args(data->msg, &derr,
				DBUS_TYPE_STRING, &addr,
				DBUS_TYPE_INVALID);

	if (dbus_error_is_set(&derr)) {
		error("Unable to get message args");
		success = FALSE;
		error_failed(connection, data->msg, derr.message);
		dbus_error_free(&derr);
		goto done;
	}

	/* Return error if no audio related service records were found */
	if (!data->records) {
		debug("No audio audio related service records were found");
		success = FALSE;
		error_not_supported(connection, data->msg);
		goto done;
	}

	reply = dbus_message_new_method_return(data->msg);
	if (!reply) {
		success = FALSE;
		error_failed(connection, data->msg, "Out of memory");
		goto done;
	}

update:
	g_slist_foreach(data->records, (GFunc) handle_record, data->device);

	if (!g_slist_find(devices, data->device))
		add_device(data->device, TRUE);

	if (reply) {
		dbus_message_append_args(reply, DBUS_TYPE_STRING,
					&data->device->path,
					DBUS_TYPE_INVALID);
		send_message_and_unref(connection, reply);
	}

done:
	if (success) {
		if (data->cb)
			data->cb(data->device, data->cb_data);
	} else {
		if (data->cb)
			data->cb(NULL, data->cb_data);
		if (!g_slist_find(devices, data->device))
			destroy_device(data->device);
	}
	if (data->msg)
		dbus_message_unref(data->msg);
	g_slist_foreach(data->records, (GFunc) sdp_record_free, NULL);
	g_slist_free(data->records);
	g_free(data);
}

static void get_records_cb(sdp_list_t *recs, int err, gpointer user_data)
{
	struct audio_sdp_data *data = user_data;
	sdp_list_t *seq;
	uuid_t uuid;

	if (err < 0) {
		error_connection_attempt_failed(connection, data->msg, -err);
		finish_sdp(data, FALSE);
		return;
	}

	for (seq = recs; seq; seq = seq->next) {
		sdp_record_t *rec = (sdp_record_t *) seq->data;

		if (!rec)
			break;

		data->records = g_slist_append(data->records, rec);
	}

	sdp_list_free(recs, NULL);

	data->state++;

	switch (data->state) {
	case ADVANCED_AUDIO:
		sdp_uuid16_create(&uuid, ADVANCED_AUDIO_SVCLASS_ID);
		break;
	case AV_REMOTE:
		sdp_uuid16_create(&uuid, AV_REMOTE_SVCLASS_ID);
		break;
	default:
		finish_sdp(data, TRUE);
		return;
	}

	get_records(&uuid, data);
}

static DBusHandlerResult get_records(uuid_t *uuid, struct audio_sdp_data *data)
{
	struct device *device = data->device;
	int err;

	err = bt_search_service(&device->src, &device->dst, uuid,
				get_records_cb, data, NULL);
	if (!err)
		return DBUS_HANDLER_RESULT_HANDLED;

	if (data->msg)
		error_connection_attempt_failed(connection, data->msg, -err);

	finish_sdp(data, FALSE);

	return DBUS_HANDLER_RESULT_HANDLED;
}

static DBusHandlerResult resolve_services(DBusMessage *msg,
						struct device *device,
						create_dev_cb_t cb,
						void *user_data)
{
	struct audio_sdp_data *sdp_data;
	uuid_t uuid;

	sdp_data = g_new0(struct audio_sdp_data, 1);
	if (msg)
		sdp_data->msg = dbus_message_ref(msg);
	sdp_data->device = device;
	sdp_data->cb = cb;
	sdp_data->cb_data = user_data;

	sdp_uuid16_create(&uuid, GENERIC_AUDIO_SVCLASS_ID);

	return get_records(&uuid, sdp_data);
}

struct device *manager_device_connected(const bdaddr_t *bda, const char *uuid)
{
	struct device *device;
	const char *path;
	gboolean headset = FALSE, created = FALSE;

	device = manager_find_device(bda, NULL, FALSE);
	if (!device) {
		device = create_device(bda);
		if (!device)
			return NULL;
		if (!add_device(device, TRUE)) {
			destroy_device(device);
			return NULL;
		}
		created = TRUE;
	}

	if (!strcmp(uuid, HSP_AG_UUID) || !strcmp(uuid, HFP_AG_UUID)) {
		if (device->headset)
			return device;

		device->headset = headset_init(device, NULL, 0);

		if (!device->headset)
			return NULL;

		headset = TRUE;
	} else if (!strcmp(uuid, A2DP_SOURCE_UUID)) {
		if (device->sink)
			return device;

		device->sink = sink_init(device);

		if (!device->sink)
			return NULL;
	} else if (!strcmp(uuid, AVRCP_TARGET_UUID)) {
		if (device->control)
			return device;

		device->control = control_init(device);

		if (!device->control)
			return NULL;
	} else
		return NULL;

	path = device->path;

	if (created) {
		dbus_connection_emit_signal(connection, AUDIO_MANAGER_PATH,
						AUDIO_MANAGER_INTERFACE,
						"DeviceCreated",
						DBUS_TYPE_STRING, &path,
						DBUS_TYPE_INVALID);
		resolve_services(NULL, device, NULL, NULL);
	}

	if (headset)
		dbus_connection_emit_signal(connection, AUDIO_MANAGER_PATH,
						AUDIO_MANAGER_INTERFACE,
						"HeadsetCreated",
						DBUS_TYPE_STRING, &path,
						DBUS_TYPE_INVALID);

	if (headset && !default_hs) {
		default_hs = device;
		dbus_connection_emit_signal(connection, AUDIO_MANAGER_PATH,
						AUDIO_MANAGER_INTERFACE,
						"DefaultHeadsetChanged",
						DBUS_TYPE_STRING, &path,
						DBUS_TYPE_INVALID);
	}

	if (!default_dev) {
		default_dev = device;
		dbus_connection_emit_signal(connection, AUDIO_MANAGER_PATH,
						AUDIO_MANAGER_INTERFACE,
						"DefaultDeviceChanged",
						DBUS_TYPE_STRING, &path,
						DBUS_TYPE_INVALID);
	}

	return device;
}

gboolean manager_create_device(bdaddr_t *bda, create_dev_cb_t cb,
				void *user_data)
{
	struct device *dev;

	dev = create_device(bda);
	if (!dev)
		return FALSE;

	resolve_services(NULL, dev, cb, user_data);

	return TRUE;
}

static DBusHandlerResult am_create_device(DBusConnection *conn,
						DBusMessage *msg,
						void *data)
{
	const char *address, *path;
	bdaddr_t bda;
	struct device *device;
	DBusMessage *reply;
	DBusError derr;

	dbus_error_init(&derr);
	dbus_message_get_args(msg, &derr,
				DBUS_TYPE_STRING, &address,
				DBUS_TYPE_INVALID);

	if (dbus_error_is_set(&derr)) {
		error_invalid_arguments(connection, msg, derr.message);
		dbus_error_free(&derr);
		return DBUS_HANDLER_RESULT_HANDLED;
	}

	str2ba(address, &bda);

	device = manager_find_device(&bda, NULL, FALSE);
	if (!device) {
		device = create_device(&bda);
		return resolve_services(msg, device, NULL, NULL);
	}

	path = device->path;

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

	dbus_message_append_args(reply, DBUS_TYPE_STRING, &path,
					DBUS_TYPE_INVALID);

	return send_message_and_unref(conn, reply);
}

static DBusHandlerResult am_list_devices(DBusConnection *conn,
						DBusMessage *msg,
						void *data)
{
	DBusMessageIter iter, array_iter;
	DBusMessage *reply;
	DBusError derr;
	GSList *l;
	gboolean hs_only = FALSE;


	dbus_error_init(&derr);

	if (dbus_message_is_method_call(msg, AUDIO_MANAGER_INTERFACE,
					"ListHeadsets"))
		hs_only = TRUE;
	else
		hs_only = FALSE;

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

	dbus_message_iter_init_append(reply, &iter);

	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
				DBUS_TYPE_STRING_AS_STRING, &array_iter);

	for (l = devices; l != NULL; l = l->next) {
		struct device *device = l->data;

		if (hs_only && !device->headset)
			continue;

		dbus_message_iter_append_basic(&array_iter,
						DBUS_TYPE_STRING, &device->path);
	}

	dbus_message_iter_close_container(&iter, &array_iter);

	return send_message_and_unref(connection, reply);
}

static gint device_path_cmp(gconstpointer a, gconstpointer b)
{
	const struct device *device = a;
	const char *path = b;

	return strcmp(device->path, path);
}

static DBusHandlerResult am_remove_device(DBusConnection *conn,
						DBusMessage *msg,
						void *data)
{
	DBusError derr;
	DBusMessage *reply;
	GSList *match;
	const char *path;
	struct device *device;

	dbus_error_init(&derr);
	if (!dbus_message_get_args(msg, &derr,
					DBUS_TYPE_STRING, &path,
					DBUS_TYPE_INVALID)) {
		error_invalid_arguments(connection, msg, derr.message);
		return DBUS_HANDLER_RESULT_HANDLED;
	}
	if (dbus_error_is_set(&derr)) {
		error_invalid_arguments(connection, msg, derr.message);
		dbus_error_free(&derr);
		return DBUS_HANDLER_RESULT_HANDLED;
	}

	match = g_slist_find_custom(devices, path, device_path_cmp);
	if (!match)
		return error_device_does_not_exist(connection, msg);

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

	device = match->data;
	device_remove_stored(device);
	remove_device(device);

	/* Fallback to a valid default */
	if (default_dev == NULL) {
		const char *param;
		GSList *l;

		default_dev = manager_find_device(BDADDR_ANY, NULL, TRUE);

		if (!default_dev && devices) {
			l = devices;
			default_dev = (g_slist_last(l))->data;
		}

		param = default_dev ? default_dev->path : "";

		dbus_connection_emit_signal(conn, AUDIO_MANAGER_PATH,
						AUDIO_MANAGER_INTERFACE,
						"DefaultHeadsetChanged",
						DBUS_TYPE_STRING, &param,
						DBUS_TYPE_INVALID);

		dbus_connection_emit_signal(conn, AUDIO_MANAGER_PATH,
						AUDIO_MANAGER_INTERFACE,
						"DefaultDeviceChanged",
						DBUS_TYPE_STRING, &param,
						DBUS_TYPE_INVALID);

		if (default_dev)
			device_store(default_dev, TRUE);
	}

	dbus_connection_emit_signal(conn, AUDIO_MANAGER_PATH,
					AUDIO_MANAGER_INTERFACE,
					"HeadsetRemoved",
					DBUS_TYPE_STRING, &path,
					DBUS_TYPE_INVALID);

	dbus_connection_emit_signal(conn, AUDIO_MANAGER_PATH,
					AUDIO_MANAGER_INTERFACE,
					"DeviceRemoved",
					DBUS_TYPE_STRING, &path,
					DBUS_TYPE_INVALID);

	return send_message_and_unref(connection, reply);
}

static DBusHandlerResult am_find_by_addr(DBusConnection *conn,
						DBusMessage *msg,
						void *data)
{
	const char *address;
	DBusMessage *reply;
	DBusError derr;
	struct device *device;
	bdaddr_t bda;

	dbus_error_init(&derr);
	dbus_message_get_args(msg, &derr,
				DBUS_TYPE_STRING, &address,
				DBUS_TYPE_INVALID);
	if (dbus_error_is_set(&derr)) {
		error_invalid_arguments(connection, msg, derr.message);
		dbus_error_free(&derr);
		return DBUS_HANDLER_RESULT_HANDLED;
	}

	str2ba(address, &bda);
	device = manager_find_device(&bda, NULL, FALSE);

	if (!device)
		return error_device_does_not_exist(conn, msg);

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

	dbus_message_append_args(reply, DBUS_TYPE_STRING, &device->path,
					DBUS_TYPE_INVALID);

	return send_message_and_unref(conn, reply);
}

static DBusHandlerResult am_default_device(DBusConnection *conn,
						DBusMessage *msg,
						void *data)
{
	DBusMessage *reply;

	if (!default_dev)
		return error_device_does_not_exist(connection, msg);

	if (default_dev->headset == NULL &&
		dbus_message_is_method_call(msg, AUDIO_MANAGER_INTERFACE,
							"DefaultHeadset"))
		return error_device_does_not_exist(connection, msg);

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

	dbus_message_append_args(reply, DBUS_TYPE_STRING, &default_dev->path,
					DBUS_TYPE_INVALID);

	return send_message_and_unref(connection, reply);
}

static DBusHandlerResult am_change_default_device(DBusConnection *conn,
							DBusMessage *msg,
							void *data)
{
	DBusError derr;
	DBusMessage *reply;
	GSList *match;
	const char *path;
	struct device *device;

	dbus_error_init(&derr);
	if (!dbus_message_get_args(msg, &derr,
					DBUS_TYPE_STRING, &path,
					DBUS_TYPE_INVALID)) {
		error_invalid_arguments(connection, msg, derr.message);
		return DBUS_HANDLER_RESULT_HANDLED;
	}
	if (dbus_error_is_set(&derr)) {
		error_invalid_arguments(connection, msg, derr.message);
		dbus_error_free(&derr);
		return DBUS_HANDLER_RESULT_HANDLED;
	}

	match = g_slist_find_custom(devices, path, device_path_cmp);
	if (!match)
		return error_device_does_not_exist(connection, msg);

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

	device = match->data;

	if (!dbus_message_is_method_call(msg, AUDIO_MANAGER_INTERFACE,
		"ChangeDefaultHeadset"))
		dbus_connection_emit_signal(conn, AUDIO_MANAGER_PATH,
						AUDIO_MANAGER_INTERFACE,
						"DefaultDeviceChanged",
						DBUS_TYPE_STRING, &device->path,
						DBUS_TYPE_INVALID);
	else if (device->headset)
		dbus_connection_emit_signal(conn, AUDIO_MANAGER_PATH,
						AUDIO_MANAGER_INTERFACE,
						"DefaultHeadsetChanged",
						DBUS_TYPE_STRING, &device->path,
						DBUS_TYPE_INVALID);
	else
		return error_device_does_not_exist(connection, msg);

	default_dev = device;
	device_store(device, TRUE);
	return send_message_and_unref(connection, reply);
}

static DBusMethodVTable manager_methods[] = {
	{ "CreateDevice",		am_create_device,
		"s",	"s"		},
	{ "RemoveDevice",		am_remove_device,
		"s",	""		},
	{ "ListDevices",		am_list_devices,
		"",	"as"		},
	{ "DefaultDevice",		am_default_device,
		"",	"s"		},
	{ "ChangeDefaultDevice",	am_change_default_device,
		"s",	""		},
	{ "CreateHeadset",		am_create_device,
		"s",	"s"		},
	{ "RemoveHeadset",		am_remove_device,
		"s",	""		},
	{ "ListHeadsets",		am_list_devices,
		"",	"as"		},
	{ "FindDeviceByAddress",	am_find_by_addr,
		"s",	"s"		},
	{ "DefaultHeadset",		am_default_device,
		"",	"s"		},
	{ "ChangeDefaultHeadset",	am_change_default_device,
		"s",	""		},
	{ NULL, NULL, NULL, NULL },
};

static DBusSignalVTable manager_signals[] = {
	{ "DeviceCreated",		"s"	},
	{ "DeviceRemoved",		"s"	},
	{ "HeadsetCreated",		"s"	},
	{ "HeadsetRemoved",		"s"	},
	{ "DefaultDeviceChanged",	"s"	},
	{ "DefaultHeadsetChanged",	"s"	},
	{ NULL, NULL }
};

static void parse_stored_devices(char *key, char *value, void *data)
{
	bdaddr_t *src = data;
	struct device *device;
	bdaddr_t dst;

	if (!key || !value || strcmp(key, "default") == 0)
		return;

	str2ba(key, &dst);
	device = manager_find_device(&dst, NULL, FALSE);

	if (device)
		return;

	info("Loading device %s (%s)", key, value);

	device = create_device(&dst);
	if (!device)
		return;

	/* Change storage to source adapter */
	bacpy(&device->store, src);

	if (enabled.headset && strstr(value, "headset"))
		device->headset = headset_init(device, NULL, 0);
	if (enabled.sink && strstr(value, "sink"))
		device->sink = sink_init(device);
	if (enabled.control && strstr(value, "control"))
		device->control = control_init(device);
	add_device(device, FALSE);
}

static void register_devices_stored(const char *adapter)
{
	char filename[PATH_MAX + 1];
	struct stat st;
	struct device *device;
	bdaddr_t default_src;
	bdaddr_t dst;
	bdaddr_t src;
	char *addr;
	int dev_id;

	create_name(filename, PATH_MAX, STORAGEDIR, adapter, "audio");

	str2ba(adapter, &src);

	if (stat(filename, &st) < 0)
		return;

	if (!(st.st_mode & __S_IFREG))
		return;

	textfile_foreach(filename, parse_stored_devices, &src);

	bacpy(&default_src, BDADDR_ANY);
	dev_id = hci_get_route(&default_src);
	if (dev_id < 0 || hci_devba(dev_id, &default_src) < 0)
		return;

	if (bacmp(&default_src, &src) != 0)
		return;

	addr = textfile_get(filename, "default");
	if (!addr)
		return;

	str2ba(addr, &dst);
	device = manager_find_device(&dst, NULL, FALSE);

	if (device) {
		info("Setting %s as default device", addr);
		default_dev = device;
	}

	free(addr);
}

static void register_stored(void)
{
	char dirname[PATH_MAX + 1];
	struct dirent *de;
	DIR *dir;

	snprintf(dirname, PATH_MAX, "%s", STORAGEDIR);

	dir = opendir(dirname);
	if (!dir)
		return;

	while ((de = readdir(dir)) != NULL) {
		if (!isdigit(de->d_name[0]))
			continue;

		/* Device objects */
		register_devices_stored(de->d_name);
	}

	closedir(dir);
}

static void manager_unregister(DBusConnection *conn, void *data)
{
	info("Unregistered manager path");

	if (devices) {
		g_slist_foreach(devices, (GFunc) remove_device, NULL);
		g_slist_free(devices);
		devices = NULL;
	}
}

static sdp_record_t *hsp_ag_record(uint8_t ch)
{
	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid;
	uuid_t l2cap_uuid, rfcomm_uuid;
	sdp_profile_desc_t profile;
	sdp_record_t *record;
	sdp_list_t *aproto, *proto[2];
	sdp_data_t *channel;

	record = sdp_record_alloc();
	if (!record)
		return NULL;

	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
	root = sdp_list_append(0, &root_uuid);
	sdp_set_browse_groups(record, root);

	sdp_uuid16_create(&svclass_uuid, HEADSET_AGW_SVCLASS_ID);
	svclass_id = sdp_list_append(0, &svclass_uuid);
	sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID);
	svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid);
	sdp_set_service_classes(record, svclass_id);

	sdp_uuid16_create(&profile.uuid, HEADSET_PROFILE_ID);
	profile.version = 0x0100;
	pfseq = sdp_list_append(0, &profile);
	sdp_set_profile_descs(record, pfseq);

	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
	proto[0] = sdp_list_append(0, &l2cap_uuid);
	apseq = sdp_list_append(0, proto[0]);

	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
	proto[1] = sdp_list_append(0, &rfcomm_uuid);
	channel = sdp_data_alloc(SDP_UINT8, &ch);
	proto[1] = sdp_list_append(proto[1], channel);
	apseq = sdp_list_append(apseq, proto[1]);

	aproto = sdp_list_append(0, apseq);
	sdp_set_access_protos(record, aproto);

	sdp_set_info_attr(record, "Headset Audio Gateway", 0, 0);

	sdp_data_free(channel);
	sdp_list_free(proto[0], 0);
	sdp_list_free(proto[1], 0);
	sdp_list_free(apseq, 0);
	sdp_list_free(pfseq, 0);
	sdp_list_free(aproto, 0);
	sdp_list_free(root, 0);
	sdp_list_free(svclass_id, 0);

	return record;
}

static sdp_record_t *hsp_hs_record(uint8_t ch)
{
	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid;
	uuid_t l2cap_uuid, rfcomm_uuid;
	sdp_profile_desc_t profile;
	sdp_record_t *record;
	sdp_list_t *aproto, *proto[2];
	sdp_data_t *channel;

	record = sdp_record_alloc();
	if (!record)
		return NULL;

	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
	root = sdp_list_append(0, &root_uuid);
	sdp_set_browse_groups(record, root);

	sdp_uuid16_create(&svclass_uuid, HEADSET_SVCLASS_ID);
	svclass_id = sdp_list_append(0, &svclass_uuid);
	sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID);
	svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid);
	sdp_set_service_classes(record, svclass_id);

	sdp_uuid16_create(&profile.uuid, HEADSET_PROFILE_ID);
	profile.version = 0x0100;
	pfseq = sdp_list_append(0, &profile);
	sdp_set_profile_descs(record, pfseq);

	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
	proto[0] = sdp_list_append(0, &l2cap_uuid);
	apseq = sdp_list_append(0, proto[0]);

	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
	proto[1] = sdp_list_append(0, &rfcomm_uuid);
	channel = sdp_data_alloc(SDP_UINT8, &ch);
	proto[1] = sdp_list_append(proto[1], channel);
	apseq = sdp_list_append(apseq, proto[1]);

	aproto = sdp_list_append(0, apseq);
	sdp_set_access_protos(record, aproto);

	sdp_set_info_attr(record, "Headset", 0, 0);

	sdp_data_free(channel);
	sdp_list_free(proto[0], 0);
	sdp_list_free(proto[1], 0);
	sdp_list_free(apseq, 0);
	sdp_list_free(pfseq, 0);
	sdp_list_free(aproto, 0);
	sdp_list_free(root, 0);
	sdp_list_free(svclass_id, 0);

	return record;
}

static sdp_record_t *hfp_ag_record(uint8_t ch, uint32_t feat)
{
	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid;
	uuid_t l2cap_uuid, rfcomm_uuid;
	sdp_profile_desc_t profile;
	sdp_list_t *aproto, *proto[2];
	sdp_record_t *record;
	sdp_data_t *channel, *features;
	uint8_t netid = 0x01;
	uint16_t sdpfeat;
	sdp_data_t *network = sdp_data_alloc(SDP_UINT8, &netid);

	record = sdp_record_alloc();
	if (!record)
		return NULL;

	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
	root = sdp_list_append(0, &root_uuid);
	sdp_set_browse_groups(record, root);

	sdp_uuid16_create(&svclass_uuid, HANDSFREE_AGW_SVCLASS_ID);
	svclass_id = sdp_list_append(0, &svclass_uuid);
	sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID);
	svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid);
	sdp_set_service_classes(record, svclass_id);

	sdp_uuid16_create(&profile.uuid, HANDSFREE_PROFILE_ID);
	profile.version = 0x0105;
	pfseq = sdp_list_append(0, &profile);
	sdp_set_profile_descs(record, pfseq);

	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
	proto[0] = sdp_list_append(0, &l2cap_uuid);
	apseq = sdp_list_append(0, proto[0]);

	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
	proto[1] = sdp_list_append(0, &rfcomm_uuid);
	channel = sdp_data_alloc(SDP_UINT8, &ch);
	proto[1] = sdp_list_append(proto[1], channel);
	apseq = sdp_list_append(apseq, proto[1]);

	sdpfeat = (uint16_t) feat & 0xF;
	features = sdp_data_alloc(SDP_UINT16, &sdpfeat);
	sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features);

	aproto = sdp_list_append(0, apseq);
	sdp_set_access_protos(record, aproto);

	sdp_set_info_attr(record, "Hands-Free Audio Gateway", 0, 0);

	sdp_attr_add(record, SDP_ATTR_EXTERNAL_NETWORK, network);

	sdp_data_free(channel);
	sdp_list_free(proto[0], 0);
	sdp_list_free(proto[1], 0);
	sdp_list_free(apseq, 0);
	sdp_list_free(pfseq, 0);
	sdp_list_free(aproto, 0);
	sdp_list_free(root, 0);
	sdp_list_free(svclass_id, 0);

	return record;
}

static void auth_cb(DBusError *derr, void *user_data)
{
	struct device *device = user_data;
	const char *uuid;

	if (get_hfp_active(device))
		uuid = HFP_AG_UUID;
	else
		uuid = HSP_AG_UUID;

	if (derr && dbus_error_is_set(derr)) {
		error("Access denied: %s", derr->message);
		if (dbus_error_has_name(derr, DBUS_ERROR_NO_REPLY)) {
			debug("Canceling authorization request");
			if (service_cancel_auth(&device->dst) < 0)
				manager_cancel_authorize(&device->dst, uuid,
							NULL);
		}

		headset_set_state(device, HEADSET_STATE_DISCONNECTED);
	} else {
		char hs_address[18];

		headset_set_authorized(device);

		ba2str(&device->dst, hs_address);

		debug("Accepted headset connection from %s for %s",
						hs_address, device->path);
		headset_set_state(device, HEADSET_STATE_CONNECTED);
	}
}

static void auth_cb_old(DBusPendingCall *call, void *data)
{
	DBusMessage *reply = dbus_pending_call_steal_reply(call);
	DBusError err;

	dbus_error_init(&err);
	dbus_set_error_from_message(&err, reply);
	auth_cb(&err, data);
	dbus_error_free(&err);

	dbus_message_unref(reply);
}

static void ag_io_cb(GIOChannel *chan, int err, const bdaddr_t *src,
			const bdaddr_t *dst, gpointer data)
{
	const char *uuid;
	struct device *device;
	gboolean hfp_active;

	if (err < 0) {
		error("accept: %s (%d)", strerror(-err), -err);
		return;
	}

	if (chan == hsp_ag_server) {
		hfp_active = FALSE;
		uuid = HSP_AG_UUID;
	} else {
		hfp_active = TRUE;
		uuid = HFP_AG_UUID;
	}

	device = manager_device_connected(dst, uuid);
	if (!device)
		goto drop;

	if (headset_get_state(device) > HEADSET_STATE_DISCONNECTED) {
		debug("Refusing new connection since one already exists");
		goto drop;
	}

	set_hfp_active(device, hfp_active);

	if (headset_connect_rfcomm(device, chan) < 0) {
		error("Allocating new GIOChannel failed!");
		goto drop;
	}

	if (service_req_auth(&device->src, &device->dst, uuid, auth_cb,
				device) == 0)
		headset_set_state(device, HEADSET_STATE_CONNECT_IN_PROGRESS);
	else if (!manager_authorize(&device->dst, uuid, auth_cb_old, device,
				NULL))
		headset_close_rfcomm(device);

	return;

drop:
	g_io_channel_close(chan);
	g_io_channel_unref(chan);
	return;
}

static void hs_io_cb(GIOChannel *chan, int err, const bdaddr_t *src,
		const bdaddr_t *dst, void *data)
{
	/*Stub*/
	return;
}

static int headset_server_init(DBusConnection *conn, GKeyFile *config)
{
	uint8_t chan = DEFAULT_HS_AG_CHANNEL;
	sdp_record_t *record;
	gboolean hfp = TRUE, master = TRUE;
	GError *err = NULL;
	uint32_t features, flags;

	if (!enabled.headset)
		return 0;

	if (config) {
		gboolean tmp;

		tmp = g_key_file_get_boolean(config, "General", "Master",
						&err);
		if (err) {
			debug("audio.conf: %s", err->message);
			g_error_free(err);
			err = NULL;
		} else
			master = tmp;

		tmp = g_key_file_get_boolean(config, "Headset", "HFP",
						&err);
		if (err) {
			debug("audio.conf: %s", err->message);
			g_error_free(err);
			err = NULL;
		} else
			hfp = tmp;
	}

	flags = RFCOMM_LM_SECURE;

	if (master)
		flags |= RFCOMM_LM_MASTER;

	hsp_ag_server = bt_rfcomm_listen(BDADDR_ANY, chan, flags, ag_io_cb,
				NULL);
	if (!hsp_ag_server)
		return -1;

	record = hsp_ag_record(chan);
	if (!record) {
		error("Unable to allocate new service record");
		return -1;
	}

	if (add_record_to_server(BDADDR_ANY, record) < 0) {
		error("Unable to register HS AG service record");
		sdp_record_free(record);
		g_io_channel_unref(hsp_ag_server);
		hsp_ag_server = NULL;
		return -1;
	}
	hsp_ag_record_id = record->handle;

	features = headset_config_init(config);

	if (!hfp)
		return 0;

	chan = DEFAULT_HF_AG_CHANNEL;

	hfp_ag_server = bt_rfcomm_listen(BDADDR_ANY, chan, flags, ag_io_cb,
				NULL);
	if (!hfp_ag_server)
		return -1;

	record = hfp_ag_record(chan, features);
	if (!record) {
		error("Unable to allocate new service record");
		return -1;
	}

	if (add_record_to_server(BDADDR_ANY, record) < 0) {
		error("Unable to register HF AG service record");
		sdp_record_free(record);
		g_io_channel_unref(hfp_ag_server);
		hfp_ag_server = NULL;
		return -1;
	}
	hfp_ag_record_id = record->handle;

	return 0;
}

static int gateway_server_init(DBusConnection *conn, GKeyFile *config)
{
	uint8_t chan = DEFAULT_HSP_HS_CHANNEL;
	sdp_record_t *record;
	gboolean master = TRUE;
	GError *err = NULL;
	uint32_t flags;

	if (!enabled.gateway)
		return 0;

	if (config) {
		gboolean tmp;

		tmp = g_key_file_get_boolean(config, "General", "Master",
						&err);
		if (err) {
			debug("audio.conf: %s", err->message);
			g_error_free(err);
			err = NULL;
		} else
			master = tmp;
	}

	flags = RFCOMM_LM_SECURE;

	if (master)
		flags |= RFCOMM_LM_MASTER;

	hsp_hs_server = bt_rfcomm_listen(BDADDR_ANY, chan, flags, hs_io_cb,
				NULL);
	if (!hsp_hs_server)
		return -1;

	record = hsp_hs_record(chan);
	if (!record) {
		error("Unable to allocate new service record");
		return -1;
	}

	if (add_record_to_server(BDADDR_ANY, record) < 0) {
		error("Unable to register HSP HS service record");
		sdp_record_free(record);
		g_io_channel_unref(hsp_hs_server);
		hsp_hs_server = NULL;
		return -1;
	}

	hsp_hs_record_id = record->handle;

	return 0;
}

static void server_exit(void)
{
	if (hsp_ag_record_id) {
		remove_record_from_server(hsp_ag_record_id);
		hsp_ag_record_id = 0;
	}

	if (hsp_ag_server) {
		g_io_channel_unref(hsp_ag_server);
		hsp_ag_server = NULL;
	}

	if (hsp_hs_record_id) {
		remove_record_from_server(hsp_hs_record_id);
		hsp_hs_record_id = 0;
	}

	if (hsp_hs_server) {
		g_io_channel_unref(hsp_hs_server);
		hsp_hs_server = NULL;
	}

	if (hfp_ag_record_id) {
		remove_record_from_server(hfp_ag_record_id);
		hfp_ag_record_id = 0;
	}

	if (hfp_ag_server) {
		g_io_channel_unref(hfp_ag_server);
		hfp_ag_server = NULL;
	}
}

int audio_manager_init(DBusConnection *conn, GKeyFile *config)
{
	char **list;
	int i;

	connection = dbus_connection_ref(conn);

	if (!config)
		goto proceed;

	list = g_key_file_get_string_list(config, "General", "Enable",
						NULL, NULL);
	for (i = 0; list && list[i] != NULL; i++) {
		if (g_str_equal(list[i], "Headset"))
			enabled.headset = TRUE;
		else if (g_str_equal(list[i], "Gateway"))
			enabled.gateway = TRUE;
		else if (g_str_equal(list[i], "Sink"))
			enabled.sink = TRUE;
		else if (g_str_equal(list[i], "Source"))
			enabled.source = TRUE;
		else if (g_str_equal(list[i], "Control"))
			enabled.control = TRUE;
	}
	g_strfreev(list);

	list = g_key_file_get_string_list(config, "General", "Disable",
						NULL, NULL);
	for (i = 0; list && list[i] != NULL; i++) {
		if (g_str_equal(list[i], "Headset"))
			enabled.headset = FALSE;
		else if (g_str_equal(list[i], "Gateway"))
			enabled.gateway = FALSE;
		else if (g_str_equal(list[i], "Sink"))
			enabled.sink = FALSE;
		else if (g_str_equal(list[i], "Source"))
			enabled.source = FALSE;
		else if (g_str_equal(list[i], "Control"))
			enabled.control = FALSE;
	}
	g_strfreev(list);

proceed:
	if (!dbus_connection_create_object_path(conn, AUDIO_MANAGER_PATH,
						NULL, manager_unregister)) {
		error("D-Bus failed to register %s path", AUDIO_MANAGER_PATH);
		goto failed;
	}

	if (enabled.headset) {
		if (headset_server_init(conn, config) < 0)
			goto failed;
	}

	if (enabled.gateway) {
		if (gateway_server_init(conn, config) < 0)
			goto failed;
	}

	if (enabled.source || enabled.sink) {
		if (a2dp_init(conn, config) < 0)
			goto failed;
	}

	if (enabled.control && avrcp_init(conn, config) < 0)
		goto failed;

	if (!dbus_connection_register_interface(conn, AUDIO_MANAGER_PATH,
						AUDIO_MANAGER_INTERFACE,
						manager_methods,
						manager_signals, NULL)) {
		error("Failed to register %s interface to %s",
				AUDIO_MANAGER_INTERFACE, AUDIO_MANAGER_PATH);
		goto failed;
	}

	info("Registered manager path:%s", AUDIO_MANAGER_PATH);

	register_stored();

	return 0;
failed:
	audio_manager_exit();
	return -1;
}

void audio_manager_exit(void)
{
	server_exit();

	dbus_connection_destroy_object_path(connection, AUDIO_MANAGER_PATH);

	dbus_connection_unref(connection);

	connection = NULL;
}

struct device *manager_default_device(void)
{
	return default_dev;
}

struct device *manager_get_connected_device(void)
{
	GSList *l;

	for (l = devices; l != NULL; l = g_slist_next(l)) {
		struct device *device = l->data;

		if ((device->sink || device->source) &&
				avdtp_is_connected(&device->src, &device->dst))
			return device;

		if (device->headset && headset_is_active(device))
			return device;
	}

	return NULL;
}

void manager_cancel_authorize(bdaddr_t *dba, const char *uuid,
				DBusPendingCall *pending)
{
	DBusMessage *cancel;
	char addr[18], *address = addr;

	if (pending)
		dbus_pending_call_cancel(pending);

	cancel = dbus_message_new_method_call("org.bluez", "/org/bluez",
						"org.bluez.Database",
						"CancelAuthorizationRequest");
	if (!cancel) {
		error("Unable to allocate new method call");
		return;
	}

	ba2str(dba, addr);

	dbus_message_append_args(cancel, DBUS_TYPE_STRING, &address,
					DBUS_TYPE_STRING, &uuid,
					DBUS_TYPE_INVALID);

	send_message_and_unref(connection, cancel);
}

gboolean manager_authorize(const bdaddr_t *dba, const char *uuid,
				DBusPendingCallNotifyFunction cb,
				void *user_data,
				DBusPendingCall **pending)
{
	DBusMessage *auth;
	char address[18], *addr_ptr = address;
	DBusPendingCall *p;

	ba2str(dba, address);

	debug("Requesting authorization for device %s, UUID %s",
			address, uuid);

	auth = dbus_message_new_method_call("org.bluez", "/org/bluez",
						"org.bluez.Database",
						"RequestAuthorization");
	if (!auth) {
		error("Unable to allocate RequestAuthorization method call");
		return FALSE;
	}

	dbus_message_append_args(auth, DBUS_TYPE_STRING, &addr_ptr,
					DBUS_TYPE_STRING, &uuid,
					DBUS_TYPE_INVALID);

	if (!dbus_connection_send_with_reply(connection, auth, &p, -1)) {
		error("Sending of authorization request failed");
		dbus_message_unref(auth);
		return FALSE;
	}

	dbus_pending_call_set_notify(p, cb, user_data, NULL);
	if (pending)
		*pending = p;
	else
		dbus_pending_call_unref(p);

	dbus_message_unref(auth);

	return TRUE;
}

struct device *manager_find_device(const bdaddr_t *bda, const char *interface,
					gboolean connected)
{
	GSList *l;

	if (!bacmp(bda, BDADDR_ANY) && !interface && !connected)
		return default_dev;

	for (l = devices; l != NULL; l = l->next) {
		struct device *dev = l->data;

		if (bacmp(bda, BDADDR_ANY) && bacmp(&dev->dst, bda))
			continue;

		if (interface && !strcmp(AUDIO_HEADSET_INTERFACE, interface)
				&& !dev->headset)
			continue;

		if (interface && !strcmp(AUDIO_SINK_INTERFACE, interface)
				&& !dev->sink)
			continue;

		if (interface && !strcmp(AUDIO_SOURCE_INTERFACE, interface)
				&& !dev->source)
			continue;

		if (interface && !strcmp(AUDIO_CONTROL_INTERFACE, interface)
				&& !dev->control)
			continue;

		if (connected && !device_is_connected(dev, interface))
			continue;

		return dev;
	}

	return NULL;
}
