/*
 *
 *  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

#define _GNU_SOURCE
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>

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

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

#include "hcid.h"

#include "adapter.h"
#include "device.h"

#include "textfile.h"
#include "oui.h"
#include "dbus-common.h"
#include "dbus-hci.h"
#include "dbus-sdp.h"
#include "dbus-database.h"
#include "dbus-service.h"
#include "dbus-security.h"
#include "dbus-error.h"
#include "error.h"
#include "glib-helper.h"
#include "logging.h"
#include "agent.h"

#define NUM_ELEMENTS(table) (sizeof(table)/sizeof(const char *))

#define IO_CAPABILITY_DISPLAYONLY	0x00
#define IO_CAPABILITY_DISPLAYYESNO	0x01
#define IO_CAPABILITY_KEYBOARDONLY	0x02
#define IO_CAPABILITY_NOINPUTOUTPUT	0x03
#define IO_CAPABILITY_INVALID		0xFF

struct mode_req {
	struct adapter	*adapter;
	DBusConnection	*conn;		/* Connection reference */
	DBusMessage	*msg;		/* Message reference */
	uint8_t		mode;		/* Requested mode */
	guint		id;		/* Listener id */
};

static const char *service_cls[] = {
	"positioning",
	"networking",
	"rendering",
	"capturing",
	"object transfer",
	"audio",
	"telephony",
	"information"
};

static const char *major_cls[] = {
	"miscellaneous",
	"computer",
	"phone",
	"access point",
	"audio/video",
	"peripheral",
	"imaging",
	"wearable",
	"toy",
	"uncategorized"
};

static const char *computer_minor_cls[] = {
	"uncategorized",
	"desktop",
	"server",
	"laptop",
	"handheld",
	"palm",
	"wearable"
};

static const char *phone_minor_cls[] = {
	"uncategorized",
	"cellular",
	"cordless",
	"smart phone",
	"modem",
	"isdn"
};

static const char *access_point_minor_cls[] = {
	"fully",
	"1-17 percent",
	"17-33 percent",
	"33-50 percent",
	"50-67 percent",
	"67-83 percent",
	"83-99 percent",
	"not available"
};

static const char *audio_video_minor_cls[] = {
	"uncategorized",
	"headset",
	"handsfree",
	"unknown",
	"microphone",
	"loudspeaker",
	"headphones",
	"portable audio",
	"car audio",
	"set-top box",
	"hifi audio",
	"vcr",
	"video camera",
	"camcorder",
	"video monitor",
	"video display and loudspeaker",
	"video conferencing",
	"unknown",
	"gaming/toy"
};

static const char *peripheral_minor_cls[] = {
	"uncategorized",
	"keyboard",
	"pointing",
	"combo"
};

#if 0
static const char *peripheral_2_minor_cls[] = {
	"uncategorized",
	"joystick",
	"gamepad",
	"remote control",
	"sensing",
	"digitizer tablet",
	"card reader"
};
#endif

static const char *imaging_minor_cls[] = {
	"display",
	"camera",
	"scanner",
	"printer"
};

static const char *wearable_minor_cls[] = {
	"wrist watch",
	"pager",
	"jacket",
	"helmet",
	"glasses"
};

static const char *toy_minor_cls[] = {
	"robot",
	"vehicle",
	"doll",
	"controller",
	"game"
};

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

static inline DBusMessage *not_available(DBusMessage *msg)
{
	return g_dbus_create_error(msg, ERROR_INTERFACE ".NotAvailable",
			"Not Available");
}

static inline DBusMessage *adapter_not_ready(DBusMessage *msg)
{
	return g_dbus_create_error(msg, ERROR_INTERFACE ".NotReady",
			"Adapter is not ready");
}

static inline DBusMessage *no_such_adapter(DBusMessage *msg)
{
	return g_dbus_create_error(msg, ERROR_INTERFACE ".NoSuchAdapter",
							"No such adapter");
}

static inline DBusMessage *failed_strerror(DBusMessage *msg, int err)
{
	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
			strerror(err));
}

static inline DBusMessage *in_progress(DBusMessage *msg, const char *str)
{
	return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress", str);
}

static inline DBusMessage *not_in_progress(DBusMessage *msg, const char *str)
{
	return g_dbus_create_error(msg, ERROR_INTERFACE ".NotInProgress", str);
}

static inline DBusMessage *not_authorized(DBusMessage *msg)
{
	return g_dbus_create_error(msg, ERROR_INTERFACE ".NotAuthorized",
			"Not authorized");
}

static inline DBusMessage *unsupported_major_class(DBusMessage *msg)
{
	return g_dbus_create_error(msg,
			ERROR_INTERFACE ".UnsupportedMajorClass",
			"Unsupported Major Class");
}

static int auth_req_cmp(const void *p1, const void *p2)
{
	const struct pending_auth_info *pb1 = p1;
	const bdaddr_t *bda = p2;

	return bda ? bacmp(&pb1->bdaddr, bda) : -1;
}

void adapter_auth_request_replied(struct adapter *adapter, bdaddr_t *dba)
{
	GSList *l;
	struct pending_auth_info *auth;

	l = g_slist_find_custom(adapter->auth_reqs, dba, auth_req_cmp);
	if (!l)
		return;

	auth = l->data;

	auth->replied = TRUE;
}

struct pending_auth_info *adapter_find_auth_request(struct adapter *adapter,
							bdaddr_t *dba)
{
	GSList *l;

	l = g_slist_find_custom(adapter->auth_reqs, dba, auth_req_cmp);
	if (l)
		return l->data;

	return NULL;
}

void adapter_remove_auth_request(struct adapter *adapter, bdaddr_t *dba)
{
	GSList *l;
	struct pending_auth_info *auth;

	l = g_slist_find_custom(adapter->auth_reqs, dba, auth_req_cmp);
	if (!l)
		return;

	auth = l->data;

	adapter->auth_reqs = g_slist_remove(adapter->auth_reqs, auth);

	g_free(auth);
}

struct pending_auth_info *adapter_new_auth_request(struct adapter *adapter,
							bdaddr_t *dba,
							auth_type_t type)
{
	struct pending_auth_info *info;

	debug("hcid_dbus_new_auth_request");

	info = g_new0(struct pending_auth_info, 1);

	bacpy(&info->bdaddr, dba);
	info->type = type;
	adapter->auth_reqs = g_slist_append(adapter->auth_reqs, info);

	if (adapter->bonding && !bacmp(dba, &adapter->bonding->bdaddr))
		adapter->bonding->auth_active = 1;

	return info;
}

int pending_remote_name_cancel(struct adapter *adapter)
{
	struct remote_dev_info *dev, match;
	GSList *l;
	int dd, err = 0;

	/* find the pending remote name request */
	memset(&match, 0, sizeof(struct remote_dev_info));
	bacpy(&match.bdaddr, BDADDR_ANY);
	match.name_status = NAME_REQUESTED;

	l = g_slist_find_custom(adapter->found_devices, &match,
			(GCompareFunc) found_device_cmp);
	if (!l) /* no pending request */
		return 0;

	dd = hci_open_dev(adapter->dev_id);
	if (dd < 0)
		return -ENODEV;

	dev = l->data;

	if (hci_read_remote_name_cancel(dd, &dev->bdaddr, 1000) < 0) {
		error("Remote name cancel failed: %s(%d)", strerror(errno), errno);
		err = -errno;
	}

	/* free discovered devices list */
	g_slist_foreach(adapter->found_devices, (GFunc) g_free, NULL);
	g_slist_free(adapter->found_devices);
	adapter->found_devices = NULL;

	hci_close_dev(dd);
	return err;
}

static int auth_info_agent_cmp(const void *a, const void *b)
{
	const struct pending_auth_info *auth = a;
	const struct agent *agent = b;

	if (auth->agent == agent)
		return 0;

	return -1;
}

static void device_agent_removed(struct agent *agent, void *user_data)
{
	struct device *device = user_data;
	struct pending_auth_info *auth;
	GSList *l;

	device->agent = NULL;

	l = g_slist_find_custom(device->adapter->auth_reqs, agent,
					auth_info_agent_cmp);
	if (!l)
		return;

	auth = l->data;
	auth->agent = NULL;
}

static struct bonding_request_info *bonding_request_new(DBusConnection *conn,
							DBusMessage *msg,
							struct adapter *adapter,
							const char *address,
							const char *agent_path,
							uint8_t capability)
{
	struct bonding_request_info *bonding;
	struct device *device;

	debug("bonding_request_new(%s)", address);

	if (hcid_dbus_use_experimental() && agent_path) {
		const char *name = dbus_message_get_sender(msg);

		device = adapter_get_device(conn, adapter, address);
		if (!device)
			return NULL;

		device->agent = agent_create(adapter, name, agent_path,
						capability,
						device_agent_removed,
						device);
		debug("Temporary agent registered for hci%d/%s at %s:%s",
				adapter->dev_id, device->address, name,
				agent_path);
	}

	bonding = g_new0(struct bonding_request_info, 1);

	bonding->conn = dbus_connection_ref(conn);
	bonding->msg = dbus_message_ref(msg);
	bonding->adapter = adapter;

	str2ba(address, &bonding->bdaddr);

	return bonding;
}

const char *mode2str(uint8_t mode)
{
	switch(mode) {
	case MODE_OFF:
		return "off";
	case MODE_CONNECTABLE:
		return "connectable";
	case MODE_DISCOVERABLE:
		return "discoverable";
	case MODE_LIMITED:
		return "limited";
	default:
		return "unknown";
	}
}

static uint8_t on_mode(const char *addr)
{
	char mode[14];
	bdaddr_t sba;

	str2ba(addr, &sba);

	if (read_on_mode(&sba, mode, sizeof(mode)) < 0)
		return MODE_CONNECTABLE;

	return str2mode(addr, mode);
}

uint8_t str2mode(const char *addr, const char *mode)
{
	if (strcasecmp("off", mode) == 0)
		return MODE_OFF;
	else if (strcasecmp("connectable", mode) == 0)
		return MODE_CONNECTABLE;
	else if (strcasecmp("discoverable", mode) == 0)
		return MODE_DISCOVERABLE;
	else if (strcasecmp("limited", mode) == 0)
		return MODE_LIMITED;
	else if (strcasecmp("on", mode) == 0)
		return on_mode(addr);
	else
		return MODE_UNKNOWN;
}

static DBusMessage *adapter_get_info(DBusConnection *conn,
				DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	const char *property;
	DBusMessage *reply;
	DBusMessageIter iter;
	DBusMessageIter dict;
	bdaddr_t ba;
	char str[249];
	uint8_t cls[3];

	if (check_address(adapter->address) < 0)
		return adapter_not_ready(msg);

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

	dbus_message_iter_init_append(reply, &iter);

	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, &dict);

	property = adapter->address;
	dbus_message_iter_append_dict_entry(&dict, "address",
			DBUS_TYPE_STRING, &property);

	memset(str, 0, sizeof(str));
	property = str;
	str2ba(adapter->address, &ba);

	if (!read_local_name(&ba, str))
		dbus_message_iter_append_dict_entry(&dict, "name",
			DBUS_TYPE_STRING, &property);

	get_device_version(adapter->dev_id, str, sizeof(str));
	dbus_message_iter_append_dict_entry(&dict, "version",
			DBUS_TYPE_STRING, &property);

	get_device_revision(adapter->dev_id, str, sizeof(str));
	dbus_message_iter_append_dict_entry(&dict, "revision",
			DBUS_TYPE_STRING, &property);

	get_device_manufacturer(adapter->dev_id, str, sizeof(str));
	dbus_message_iter_append_dict_entry(&dict, "manufacturer",
			DBUS_TYPE_STRING, &property);

	get_device_company(adapter->dev_id, str, sizeof(str));
	dbus_message_iter_append_dict_entry(&dict, "company",
			DBUS_TYPE_STRING, &property);

	property = mode2str(adapter->mode);

	dbus_message_iter_append_dict_entry(&dict, "mode",
			DBUS_TYPE_STRING, &property);

	dbus_message_iter_append_dict_entry(&dict, "discoverable_timeout",
				DBUS_TYPE_UINT32, &adapter->discov_timeout);

	if (!read_local_class(&ba, cls)) {
		uint32_t class;

		memcpy(&class, cls, 3);
		dbus_message_iter_append_dict_entry(&dict, "class",
			DBUS_TYPE_UINT32, &class);

		property = major_class_str(class);
		dbus_message_iter_append_dict_entry(&dict, "major_class",
			DBUS_TYPE_STRING, &property);

		property = minor_class_str(class);
		dbus_message_iter_append_dict_entry(&dict, "minor_class",
			DBUS_TYPE_STRING, &property);
	}

	dbus_message_iter_close_container(&iter, &dict);

	return reply;
}

static DBusMessage *adapter_get_address(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	const char *paddr = adapter->address;
	DBusMessage *reply;

	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
		return invalid_args(msg);

	if (check_address(paddr) < 0)
		return adapter_not_ready(msg);

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

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

	return reply;
}

static DBusMessage *adapter_get_version(DBusConnection *conn,
				DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	DBusMessage *reply;
	char str[20], *str_ptr = str;
	int err;

	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
		return invalid_args(msg);

	err = get_device_version(adapter->dev_id, str, sizeof(str));
	if (err < 0)
		return failed_strerror(msg, -err);

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

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

	return reply;
}

static DBusMessage *adapter_get_revision(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	DBusMessage *reply;
	char str[64], *str_ptr = str;
	int err;

	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
		return invalid_args(msg);

	err = get_device_revision(adapter->dev_id, str, sizeof(str));
	if (err < 0)
		return failed_strerror(msg, -err);

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

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

	return reply;
}

static DBusMessage *adapter_get_manufacturer(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	DBusMessage *reply;
	char str[64], *str_ptr = str;
	int err;

	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
		return invalid_args(msg);

	err = get_device_manufacturer(adapter->dev_id, str, sizeof(str));
	if (err < 0)
		return failed_strerror(msg, -err);

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

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

	return reply;
}

static DBusMessage *adapter_get_company(DBusConnection *conn,
				DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	DBusMessage *reply;
	char str[64], *str_ptr = str;
	int err;

	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
		return invalid_args(msg);

	err = get_device_company(adapter->dev_id, str, sizeof(str));
	if (err < 0)
		return failed_strerror(msg, -err);

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

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

	return reply;
}

static DBusMessage *adapter_list_modes(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	DBusMessage *reply;
	DBusMessageIter iter;
	DBusMessageIter array_iter;
	const char *mode_ptr[] = { "off", "connectable", "discoverable", "limited" };
	int i;

	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
		return invalid_args(msg);

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

	dbus_message_iter_init_append(reply, &iter);
	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
						DBUS_TYPE_STRING_AS_STRING, &array_iter);
	for (i = 0; i < 4; i++)
		dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING,
								&mode_ptr[i]);

	dbus_message_iter_close_container(&iter, &array_iter);

	return reply;
}

static DBusMessage *adapter_get_mode(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	const struct adapter *adapter = data;
	DBusMessage *reply = NULL;
	const char *mode;

	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
		return invalid_args(msg);

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

	mode = mode2str(adapter->mode);

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

	return reply;
}

static DBusMessage *set_mode(DBusConnection *conn, DBusMessage *msg,
				uint8_t new_mode, void *data)
{
	struct adapter *adapter = data;
	uint8_t scan_enable;
	uint8_t current_scan = adapter->scan_enable;
	bdaddr_t local;
	gboolean limited;
	int err, dd;
	const char *mode;

	switch(new_mode) {
	case MODE_OFF:
		scan_enable = SCAN_DISABLED;
		break;
	case MODE_CONNECTABLE:
		scan_enable = SCAN_PAGE;
		break;
	case MODE_DISCOVERABLE:
	case MODE_LIMITED:
		scan_enable = (SCAN_PAGE | SCAN_INQUIRY);
		break;
	default:
		return invalid_args(msg);
	}

	/* Do reverse resolution in case of "on" mode */
	mode = mode2str(new_mode);

	dd = hci_open_dev(adapter->dev_id);
	if (dd < 0)
		return no_such_adapter(msg);

	if (!adapter->up &&
			(hcid.offmode == HCID_OFFMODE_NOSCAN ||
			 (hcid.offmode == HCID_OFFMODE_DEVDOWN &&
			  scan_enable != SCAN_DISABLED))) {
		/* Start HCI device */
		if (ioctl(dd, HCIDEVUP, adapter->dev_id) == 0)
			goto done; /* on success */

		if (errno != EALREADY) {
			err = errno;
			error("Can't init device hci%d: %s (%d)\n",
				adapter->dev_id, strerror(errno), errno);

			hci_close_dev(dd);
			return failed_strerror(msg, err);
		}
	}

	if (adapter->up && scan_enable == SCAN_DISABLED &&
			hcid.offmode == HCID_OFFMODE_DEVDOWN) {
		if (ioctl(dd, HCIDEVDOWN, adapter->dev_id) < 0) {
			hci_close_dev(dd);
			return failed_strerror(msg, errno);
		}

		goto done;
	}

	limited = (new_mode == MODE_LIMITED ? TRUE : FALSE);
	err = set_limited_discoverable(dd, adapter->class, limited);
	if (err < 0) {
		hci_close_dev(dd);
		return failed_strerror(msg, -err);
	}

	if (current_scan != scan_enable) {
		struct hci_request rq;
		uint8_t status = 0;

		memset(&rq, 0, sizeof(rq));
		rq.ogf    = OGF_HOST_CTL;
		rq.ocf    = OCF_WRITE_SCAN_ENABLE;
		rq.cparam = &scan_enable;
		rq.clen   = sizeof(scan_enable);
		rq.rparam = &status;
		rq.rlen   = sizeof(status);
		rq.event = EVT_CMD_COMPLETE;

		if (hci_send_req(dd, &rq, 1000) < 0) {
			err = errno;
			error("Sending write scan enable command failed: %s (%d)",
					strerror(errno), errno);
			hci_close_dev(dd);
			return failed_strerror(msg, err);
		}

		if (status) {
			error("Setting scan enable failed with status 0x%02x",
					status);
			hci_close_dev(dd);
			return failed_strerror(msg, bt_error(status));
		}
	} else {
		/* discoverable or limited */
		if ((scan_enable & SCAN_INQUIRY) && (new_mode != adapter->mode)) {
			g_dbus_emit_signal(conn,
					dbus_message_get_path(msg),
					ADAPTER_INTERFACE,
					"ModeChanged",
					DBUS_TYPE_STRING, &mode,
					DBUS_TYPE_INVALID);

			if (adapter->timeout_id)
				g_source_remove(adapter->timeout_id);

			if (!adapter->sessions && !adapter->discov_timeout)
				adapter->timeout_id = g_timeout_add(adapter->discov_timeout * 1000,
						discov_timeout_handler, adapter);
		}
	}
done:
	str2ba(adapter->address, &local);
	write_device_mode(&local, mode);

	hci_close_dev(dd);

	adapter->mode = new_mode;

	return dbus_message_new_method_return(msg);
}

gint find_session(struct mode_req *req, DBusMessage *msg)
{
	const char *name = dbus_message_get_sender(req->msg);
	const char *sender = dbus_message_get_sender(msg);

	return strcmp(name, sender);
}

static void confirm_mode_cb(struct agent *agent, DBusError *err, void *data)
{
	struct mode_req *req = data;
	DBusMessage *reply;

	if (err && dbus_error_is_set(err)) {
		reply = dbus_message_new_error(req->msg, err->name, err->message);
		dbus_connection_send(req->conn, reply, NULL);
		dbus_message_unref(reply);
		goto cleanup;
	}

	reply = set_mode(req->conn, req->msg, req->mode, req->adapter);
	dbus_connection_send(req->conn, reply, NULL);
	dbus_message_unref(reply);

	if (!g_slist_find_custom(req->adapter->sessions, req->msg,
			(GCompareFunc) find_session))
		goto cleanup;

	return;

cleanup:
	dbus_message_unref(req->msg);
	if (req->id)
		g_dbus_remove_watch(req->conn, req->id);
	dbus_connection_unref(req->conn);
	g_free(req);
}

static DBusMessage *confirm_mode(DBusConnection *conn, DBusMessage *msg,
					const char *mode, void *data)
{
	struct adapter *adapter = data;
	struct mode_req *req;
	int ret;

	if (!adapter->agent)
		return dbus_message_new_method_return(msg);

	req = g_new0(struct mode_req, 1);
	req->adapter = adapter;
	req->conn = dbus_connection_ref(conn);
	req->msg = dbus_message_ref(msg);
	req->mode = str2mode(adapter->address, mode);

	ret = agent_confirm_mode_change(adapter->agent, mode, confirm_mode_cb,
					req);
	if (ret < 0) {
		dbus_connection_unref(req->conn);
		dbus_message_unref(req->msg);
		g_free(req);
		return invalid_args(msg);
	}

	return NULL;
}

static DBusMessage *adapter_set_mode(DBusConnection *conn,
				DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	const char *mode;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &mode,
				DBUS_TYPE_INVALID))
		return invalid_args(msg);

	if (!mode)
		return invalid_args(msg);

	adapter->global_mode = str2mode(adapter->address, mode);

	if (adapter->global_mode == adapter->mode)
		return dbus_message_new_method_return(msg);

	if (adapter->sessions && adapter->global_mode < adapter->mode)
		return confirm_mode(conn, msg, mode, data);

	return set_mode(conn, msg, str2mode(adapter->address, mode), data);
}

static DBusMessage *adapter_get_discoverable_to(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	const struct adapter *adapter = data;
	DBusMessage *reply;

	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
		return invalid_args(msg);

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

	dbus_message_append_args(reply, DBUS_TYPE_UINT32, &adapter->discov_timeout,
					DBUS_TYPE_INVALID);

	return reply;
}

static void resolve_paths(DBusMessage *msg, char **old_path, char **new_path)
{
	const char *path = dbus_message_get_path(msg);

	if (!path)
		return;

	if (old_path)
		*old_path = NULL;

	if (new_path)
		*new_path = NULL;

	/* old path calls */
	if (g_str_has_prefix(path, BASE_PATH)) {
		if (old_path)
			*old_path = g_strdup(path);

		if (hcid_dbus_use_experimental() && new_path)
			*new_path = g_strdup(path + ADAPTER_PATH_INDEX);

		return;
	}

	if (old_path)
		*old_path = g_strconcat(BASE_PATH, path, NULL);

	if (new_path)
		*new_path = g_strdup(path);
}

static DBusMessage *set_discoverable_timeout(DBusConnection *conn,
							DBusMessage *msg,
							uint32_t timeout,
							void *data)
{
	struct adapter *adapter = data;
	bdaddr_t bdaddr;
	char *old_path, *new_path;

	if (adapter->timeout_id) {
		g_source_remove(adapter->timeout_id);
		adapter->timeout_id = 0;
	}

	if ((timeout != 0) && (adapter->scan_enable & SCAN_INQUIRY))
		adapter->timeout_id = g_timeout_add(timeout * 1000,
						discov_timeout_handler,
						adapter);

	adapter->discov_timeout = timeout;

	str2ba(adapter->address, &bdaddr);
	write_discoverable_timeout(&bdaddr, timeout);

	resolve_paths(msg, &old_path, &new_path);

	g_dbus_emit_signal(conn, old_path,
					ADAPTER_INTERFACE,
					"DiscoverableTimeoutChanged",
					DBUS_TYPE_UINT32, &timeout,
					DBUS_TYPE_INVALID);
	if (new_path) {
		dbus_connection_emit_property_changed(conn, new_path,
						ADAPTER_INTERFACE,
						"DiscoverableTimeout",
						DBUS_TYPE_UINT32, &timeout);
	}

	g_free(old_path);
	g_free(new_path);

	return dbus_message_new_method_return(msg);
}

static DBusMessage *adapter_set_discoverable_to(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	uint32_t timeout;

	if (!adapter->up)
		return adapter_not_ready(msg);

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_UINT32, &timeout,
				DBUS_TYPE_INVALID))
		return invalid_args(msg);

	return set_discoverable_timeout(conn, msg, timeout, data);
}

static DBusMessage *adapter_is_connectable(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	const struct adapter *adapter = data;
	DBusMessage *reply;
	const uint8_t scan_enable = adapter->scan_enable;
	dbus_bool_t connectable = FALSE;

	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
		return invalid_args(msg);

	if (scan_enable & SCAN_PAGE)
		connectable = TRUE;

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

	dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &connectable,
					DBUS_TYPE_INVALID);

	return reply;
}

static DBusMessage *adapter_is_discoverable(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	const struct adapter *adapter = data;
	DBusMessage *reply;
	const uint8_t scan_enable = adapter->scan_enable;
	dbus_bool_t discoverable = FALSE;

	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
		return invalid_args(msg);

	if (scan_enable & SCAN_INQUIRY)
		discoverable = TRUE;

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

	dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &discoverable,
					DBUS_TYPE_INVALID);

	return reply;
}

static DBusMessage *adapter_is_connected(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	DBusMessage *reply;
	dbus_bool_t connected = FALSE;

	struct adapter *adapter = data;
	GSList *l = adapter->active_conn;

	const char *peer_addr;
	bdaddr_t peer_bdaddr;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &peer_addr,
				DBUS_TYPE_INVALID))
		return invalid_args(msg);

	if (check_address(peer_addr) < 0)
		return invalid_args(msg);

	str2ba(peer_addr, &peer_bdaddr);

	l = g_slist_find_custom(l, &peer_bdaddr, active_conn_find_by_bdaddr);
	if (l)
		connected = TRUE;

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

	dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &connected,
					DBUS_TYPE_INVALID);

	return reply;
}

static DBusMessage *adapter_list_connections(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	DBusMessage *reply;
	DBusMessageIter iter;
	DBusMessageIter array_iter;
	struct adapter *adapter = data;
	GSList *l = adapter->active_conn;

	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
		return invalid_args(msg);

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

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

	while (l) {
		char peer_addr[18];
		const char *paddr = peer_addr;
		struct active_conn_info *dev = l->data;

		ba2str(&dev->bdaddr, peer_addr);

		dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING,
						&paddr);

		l = l->next;
	}

	dbus_message_iter_close_container(&iter, &array_iter);

	return reply;
}

static DBusMessage *adapter_get_major_class(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	const struct adapter *adapter = data;
	DBusMessage *reply;
	const char *str_ptr = "computer";

	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
		return invalid_args(msg);

	/* FIXME: Currently, only computer major class is supported */
	if ((adapter->class[1] & 0x1f) != 1)
		return unsupported_major_class(msg);

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

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

	return reply;
}

static DBusMessage *adapter_list_minor_classes(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	const struct adapter *adapter = data;
	DBusMessage *reply;
	DBusMessageIter iter;
	DBusMessageIter array_iter;
	const char **minor_ptr;
	uint8_t major_class;
	int size, i;

	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
		return invalid_args(msg);

	major_class = adapter->class[1] & 0x1F;

	switch (major_class) {
	case 1: /* computer */
		minor_ptr = computer_minor_cls;
		size = sizeof(computer_minor_cls) / sizeof(*computer_minor_cls);
		break;
	case 2: /* phone */
		minor_ptr = phone_minor_cls;
		size = sizeof(phone_minor_cls) / sizeof(*phone_minor_cls);
		break;
	default:
		return unsupported_major_class(msg);
	}

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

	dbus_message_iter_init_append(reply, &iter);
	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
						DBUS_TYPE_STRING_AS_STRING, &array_iter);
	for (i = 0; i < size; i++)
		dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING,
						&minor_ptr[i]);

	dbus_message_iter_close_container(&iter, &array_iter);

	return reply;
}

static DBusMessage *adapter_get_minor_class(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	DBusMessage *reply;
	const char *str_ptr = "";
	uint8_t minor_class;

	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
		return invalid_args(msg);

	/* FIXME: Currently, only computer major class is supported */
	if ((adapter->class[1] & 0x1f) != 1)
		return unsupported_major_class(msg);

	minor_class = adapter->class[0] >> 2;

	/* Validate computer minor class */
	if (minor_class > (sizeof(computer_minor_cls) / sizeof(*computer_minor_cls)))
		goto failed;

	str_ptr = computer_minor_cls[minor_class];

failed:
	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return NULL;

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

	return reply;
}

static DBusMessage *adapter_set_minor_class(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	const char *minor;
	uint32_t dev_class = 0xFFFFFFFF;
	int i, dd;

	if (!adapter->up)
		return adapter_not_ready(msg);

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &minor,
				DBUS_TYPE_INVALID))
		return invalid_args(msg);

	if (!minor)
		return invalid_args(msg);

	dd = hci_open_dev(adapter->dev_id);
	if (dd < 0)
		return no_such_adapter(msg);

	/* Currently, only computer major class is supported */
	if ((adapter->class[1] & 0x1f) != 1) {
		hci_close_dev(dd);
		return unsupported_major_class(msg);
	}
	for (i = 0; i < sizeof(computer_minor_cls) / sizeof(*computer_minor_cls); i++)
		if (!strcasecmp(minor, computer_minor_cls[i])) {
			/* Remove the format type */
			dev_class = i << 2;
			break;
		}

	/* Check if it's a valid minor class */
	if (dev_class == 0xFFFFFFFF) {
		hci_close_dev(dd);
		return invalid_args(msg);
	}

	/* set the service class and major class  */
	dev_class |= (adapter->class[2] << 16) | (adapter->class[1] << 8);

	if (hci_write_class_of_dev(dd, dev_class, 2000) < 0) {
		int err = errno;
		error("Can't write class of device on hci%d: %s(%d)",
				adapter->dev_id, strerror(errno), errno);
		hci_close_dev(dd);
		return failed_strerror(msg, err);
	}

	g_dbus_emit_signal(conn, dbus_message_get_path(msg),
					ADAPTER_INTERFACE, "MinorClassChanged",
					DBUS_TYPE_STRING, &minor,
					DBUS_TYPE_INVALID);

	hci_close_dev(dd);

	return dbus_message_new_method_return(msg);
}

static DBusMessage *adapter_get_service_classes(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	DBusMessage *reply;
	DBusMessageIter iter;
	DBusMessageIter array_iter;
	const char *str_ptr;
	int i;

	if (!adapter->up)
		return adapter_not_ready(msg);

	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
		return invalid_args(msg);

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

	dbus_message_iter_init_append(reply, &iter);

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

	for (i = 0; i < (sizeof(service_cls) / sizeof(*service_cls)); i++) {
		if (adapter->class[2] & (1 << i)) {
			str_ptr = service_cls[i];
			dbus_message_iter_append_basic(&array_iter,
						DBUS_TYPE_STRING, &str_ptr);
		}
	}

	dbus_message_iter_close_container(&iter, &array_iter);

	return reply;
}

static DBusMessage *adapter_get_name(DBusConnection *conn,
				DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	DBusMessage *reply;
	char str[249], *str_ptr = str;
	int err;
	bdaddr_t ba;

	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
		return invalid_args(msg);

	str2ba(adapter->address, &ba);

	err = read_local_name(&ba, str);
	if (err < 0) {
		if (!adapter->up)
			return adapter_not_ready(msg);

		err = get_device_name(adapter->dev_id, str, sizeof(str));
		if (err < 0)
			return failed_strerror(msg, -err);
	}

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

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

	return reply;
}

static DBusMessage *set_name(DBusConnection *conn, DBusMessage *msg,
					const char *name, void *data)
{
	struct adapter *adapter = data;
	bdaddr_t bdaddr;
	int ecode;
	char *new_path;

	if (!g_utf8_validate(name, -1, NULL)) {
		error("Name change failed: the supplied name isn't valid UTF-8");
		return invalid_args(msg);
	}

	str2ba(adapter->address, &bdaddr);

	write_local_name(&bdaddr, (char *) name);

	if (!adapter->up)
		goto done;

	ecode = set_device_name(adapter->dev_id, name);
	if (ecode < 0)
		return failed_strerror(msg, -ecode);
done:
	resolve_paths(msg, NULL, &new_path);

	if (new_path) {
		dbus_connection_emit_property_changed(conn, new_path,
						ADAPTER_INTERFACE,
						"Name", DBUS_TYPE_STRING,
						&name);
	}

	g_free(new_path);
	return dbus_message_new_method_return(msg);
}

static DBusMessage *adapter_set_name(DBusConnection *conn,
				DBusMessage *msg, void *data)
{
	char *str_ptr;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &str_ptr,
				DBUS_TYPE_INVALID))
		return invalid_args(msg);

	return set_name(conn, msg, str_ptr, data);
}

static DBusMessage *adapter_get_remote_info(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	DBusMessage *reply;
	DBusMessageIter iter;
	DBusMessageIter dict;
	bdaddr_t src, dst;
	const char *addr_ptr;
	char filename[PATH_MAX + 1];
	char buf[64];
	const char *ptr;
	char *str;
	dbus_bool_t boolean;
	uint32_t class;
	int compid, ver, subver;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &addr_ptr,
				DBUS_TYPE_INVALID))
		return invalid_args(msg);

	if (check_address(addr_ptr) < 0)
		return invalid_args(msg);

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

	dbus_message_iter_init_append(reply, &iter);

	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, &dict);

	/* Name */
	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "names");
	str = textfile_caseget(filename, addr_ptr);
	if (str) {
		dbus_message_iter_append_dict_entry(&dict, "name",
				DBUS_TYPE_STRING, &str);
		free(str);
	}

	str2ba(adapter->address, &src);
	str2ba(addr_ptr, &dst);

	/* Remote device class */
	if (read_remote_class(&src, &dst, &class) == 0) {

		dbus_message_iter_append_dict_entry(&dict, "class",
				DBUS_TYPE_UINT32, &class);

		ptr = major_class_str(class);
		dbus_message_iter_append_dict_entry(&dict, "major_class",
				DBUS_TYPE_STRING, &ptr);

		ptr = minor_class_str(class);
		dbus_message_iter_append_dict_entry(&dict, "minor_class",
				DBUS_TYPE_STRING, &ptr);
	}

	/* Alias */
	if (get_device_alias(adapter->dev_id, &dst, buf, sizeof(buf)) > 0) {
		ptr = buf;
		dbus_message_iter_append_dict_entry(&dict, "alias",
				DBUS_TYPE_STRING, &ptr);
	}

	/* Bonded */
	create_name(filename, PATH_MAX, STORAGEDIR,
			adapter->address, "linkkeys");
	str = textfile_caseget(filename, addr_ptr);
	if (str) {
		boolean = TRUE;
		free(str);
	} else {
		boolean = FALSE;
	}

	dbus_message_iter_append_dict_entry(&dict, "bonded",
			DBUS_TYPE_BOOLEAN, &boolean);

	/* Trusted */
	boolean = read_trust(&src, addr_ptr, GLOBAL_TRUST);
	dbus_message_iter_append_dict_entry(&dict, "trusted",
			DBUS_TYPE_BOOLEAN, &boolean);

	/* Connected */
	if (g_slist_find_custom(adapter->active_conn, &dst,
				active_conn_find_by_bdaddr))
		boolean = TRUE;
	else
		boolean = FALSE;

	dbus_message_iter_append_dict_entry(&dict, "connected",
			DBUS_TYPE_BOOLEAN, &boolean);

	/* HCI Revision/Manufacturer/Version */
	create_name(filename, PATH_MAX, STORAGEDIR,
			adapter->address, "manufacturers");

	str = textfile_caseget(filename, addr_ptr);
	if (!str)
		goto done;

	if (sscanf(str, "%d %d %d", &compid, &ver, &subver) != 3) {
		/* corrupted file data */
		free(str);
		goto done;
	}

	free(str);

	ptr = buf;
	snprintf(buf, 16, "HCI 0x%X", subver);
	dbus_message_iter_append_dict_entry(&dict, "revision",
			DBUS_TYPE_STRING, &ptr);

	ptr = bt_compidtostr(compid);
	dbus_message_iter_append_dict_entry(&dict, "manufacturer",
			DBUS_TYPE_STRING, &ptr);

	str = lmp_vertostr(ver);
	snprintf(buf, 64, "Bluetooth %s", str);
	bt_free(str);

	create_name(filename, PATH_MAX, STORAGEDIR,
			adapter->address, "features");

	str = textfile_caseget(filename, addr_ptr);
	if (str) {
		if (strlen(str) == 16) {
			uint8_t features;
			/* Getting the third byte */
			features  = ((str[6] - 48) << 4) | (str[7] - 48);
			if (features & (LMP_EDR_ACL_2M | LMP_EDR_ACL_3M))
				snprintf(buf, 64, "Bluetooth %s + EDR", ptr);

		}
		free(str);
	}
	ptr = buf;
	dbus_message_iter_append_dict_entry(&dict, "version",
			DBUS_TYPE_STRING, &ptr);

done:
	dbus_message_iter_close_container(&iter, &dict);

	return reply;
}

static DBusMessage *adapter_get_remote_svc(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	return get_remote_svc_rec(conn, msg, data, SDP_FORMAT_BINARY);
}

static DBusMessage *adapter_get_remote_svc_xml(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	return get_remote_svc_rec(conn, msg, data, SDP_FORMAT_XML);
}

static DBusMessage *adapter_get_remote_svc_handles(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	return get_remote_svc_handles(conn, msg, data);
}

static DBusMessage *adapter_get_remote_svc_identifiers(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	return get_remote_svc_identifiers(conn, msg, data);
}

static DBusMessage *adapter_finish_sdp_transact(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	return finish_remote_svc_transact(conn, msg, data);
}

static DBusMessage *adapter_get_remote_version(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	DBusMessage *reply;
	char filename[PATH_MAX + 1];
	char *addr_ptr, *str;
	char *str_ver = NULL;
	char info_array[64], *info = info_array;
	int compid, ver, subver;

	memset(info_array, 0, 64);

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &addr_ptr,
				DBUS_TYPE_INVALID))
		return invalid_args(msg);

	if (check_address(addr_ptr) < 0)
		return invalid_args(msg);

	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address,
			"manufacturers");

	str = textfile_caseget(filename, addr_ptr);
	if (!str)
		return not_available(msg);

	if (sscanf(str, "%d %d %d", &compid, &ver, &subver) != 3) {
		/* corrupted file data */
		free(str);
		goto failed;
	}

	free(str);

	str_ver = lmp_vertostr(ver);

	/* Default value */
	snprintf(info, 64, "Bluetooth %s", str_ver);

	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address,
			"features");

	str = textfile_caseget(filename, addr_ptr);
	if (!str)
		goto failed;

	/* Check if the data is not corrupted */
	if (strlen(str) == 16) {
		uint8_t features;
		/* Getting the third byte */
		features  = ((str[6] - 48) << 4) | (str[7] - 48);
		if (features & (LMP_EDR_ACL_2M | LMP_EDR_ACL_3M))
			snprintf(info, 64, "Bluetooth %s + EDR", str_ver);
	}

	free(str);

failed:
	if (str_ver)
		bt_free(str_ver);

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

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

	return reply;
}

static DBusMessage *adapter_get_remote_revision(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	DBusMessage *reply;
	char filename[PATH_MAX + 1];
	char *addr_ptr, *str;
	char info_array[16], *info = info_array;
	int compid, ver, subver;

	memset(info_array, 0, 16);

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &addr_ptr,
				DBUS_TYPE_INVALID))
		return invalid_args(msg);

	if (check_address(addr_ptr) < 0)
		return invalid_args(msg);

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

	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address,
			"manufacturers");

	str = textfile_caseget(filename, addr_ptr);
	if (!str)
		return not_available(msg);

	if (sscanf(str, "%d %d %d", &compid, &ver, &subver) == 3)
		snprintf(info, 16, "HCI 0x%X", subver);

	free(str);

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

	return reply;
}

static DBusMessage *adapter_get_remote_manufacturer(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	DBusMessage *reply;
	char filename[PATH_MAX + 1];
	char *addr_ptr, *str;
	char info_array[64], *info = info_array;
	int compid, ver, subver;

	memset(info_array, 0, 64);

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &addr_ptr,
				DBUS_TYPE_INVALID))
		return invalid_args(msg);

	if (check_address(addr_ptr) < 0)
		return invalid_args(msg);

	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address,
			"manufacturers");

	str = textfile_caseget(filename, addr_ptr);
	if (!str)
		return not_available(msg);

	if (sscanf(str, "%d %d %d", &compid, &ver, &subver) == 3)
		info = bt_compidtostr(compid);

	free(str);

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

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

	return reply;
}

static DBusMessage *adapter_get_remote_company(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	DBusMessage *reply;
	bdaddr_t bdaddr;
	char oui[9], *str_bdaddr, *tmp;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &str_bdaddr,
				DBUS_TYPE_INVALID))
		return invalid_args(msg);

	str2ba(str_bdaddr, &bdaddr);
	ba2oui(&bdaddr, oui);

	tmp = ouitocomp(oui);
	if (!tmp)
		return not_available(msg);

	reply = dbus_message_new_method_return(msg);
	if (!reply) {
		free(tmp);
		return NULL;
	}

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

	free(tmp);

	return reply;
}

static DBusMessage *get_remote_class(DBusConnection *conn, DBusMessage *msg,
						void *data, uint32_t *class)
{
	struct adapter *adapter = data;
	char *addr_peer;
	bdaddr_t local, peer;
	int ecode;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &addr_peer,
				DBUS_TYPE_INVALID)) {
		return invalid_args(msg);
	}

	if (check_address(addr_peer) < 0)
		return invalid_args(msg);

	str2ba(addr_peer, &peer);
	str2ba(adapter->address, &local);

	ecode = read_remote_class(&local, &peer, class);
	if (ecode < 0)
		return not_available(msg);

	return NULL;
}

static DBusMessage *adapter_get_remote_major_class(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	DBusMessage *reply;
	const char *major_class;
	uint32_t class;

	reply = get_remote_class(conn, msg, data, &class);
	if (reply)
		return reply;

	major_class = major_class_str(class);

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

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

	return reply;
}

static DBusMessage *adapter_get_remote_minor_class(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	DBusMessage *reply;
	const char *minor_class;
	uint32_t class;

	reply = get_remote_class(conn, msg, data, &class);
	if (reply)
		return reply;

	minor_class = minor_class_str(class);

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

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

	return reply;
}

static void append_class_string(const char *class, DBusMessageIter *iter)
{
	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &class);
}

static DBusMessage *adapter_get_remote_service_cls(DBusConnection *conn,
							DBusMessage *msg,
							void *data)
{
	DBusMessage *reply;
	DBusMessageIter iter, array_iter;
	GSList *service_classes;
	uint32_t class;

	reply = get_remote_class(conn, msg, data, &class);
	if (reply)
		return reply;

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

	service_classes = service_classes_str(class);

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

	g_slist_foreach(service_classes, (GFunc) append_class_string,
			&array_iter);

	dbus_message_iter_close_container(&iter, &array_iter);

	g_slist_free(service_classes);

	return reply;
}

static DBusMessage *adapter_get_remote_class(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	DBusMessage *reply;
	uint32_t class;

	reply = get_remote_class(conn, msg, data, &class);
	if (reply)
		return reply;

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

	dbus_message_append_args(reply, DBUS_TYPE_UINT32, &class,
					DBUS_TYPE_INVALID);

	return reply;
}

static DBusMessage *adapter_get_remote_features(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	char filename[PATH_MAX + 1];
	struct adapter *adapter = data;
	DBusMessage *reply = NULL;
	DBusMessageIter iter, array_iter;
	uint8_t features[8], *ptr = features;
	const char *addr;
	char *str;
	int i;

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

	if (check_address(addr) < 0)
		return invalid_args(msg);

	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "features");

	str = textfile_caseget(filename, addr);
	if (!str)
		return not_available(msg);

	memset(features, 0, sizeof(features));
	for (i = 0; i < sizeof(features); i++) {
		char tmp[3];

		memcpy(tmp, str + (i * 2), 2);
		tmp[2] = '\0';

		features[i] = (uint8_t) strtol(tmp, NULL, 16);
	}

	reply = dbus_message_new_method_return(msg);
	if (!reply) {
		free(str);
		return NULL;
	}

	dbus_message_iter_init_append(reply, &iter);
	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
				DBUS_TYPE_BYTE_AS_STRING, &array_iter);

	dbus_message_iter_append_fixed_array(&array_iter,
				DBUS_TYPE_BYTE, &ptr, sizeof(features));

	dbus_message_iter_close_container(&iter, &array_iter);

	free(str);

	return reply;
}

static DBusMessage *adapter_get_remote_name(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	char filename[PATH_MAX + 1];
	struct adapter *adapter = data;
	DBusMessage *reply = NULL;
	const char *peer_addr;
	bdaddr_t peer_bdaddr;
	char *str;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &peer_addr,
				DBUS_TYPE_INVALID))
		return invalid_args(msg);

	if (check_address(peer_addr) < 0)
		return invalid_args(msg);

	/* check if it is in the cache */
	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "names");

	str = textfile_caseget(filename, peer_addr);

	if (str) {
		reply = dbus_message_new_method_return(msg);
		if (!reply) {
			free(str);
			return NULL;
		}

		/* send the cached name */
		dbus_message_append_args(reply, DBUS_TYPE_STRING, &str,
						DBUS_TYPE_INVALID);

		free(str);
		return reply;
	}

	if (!adapter->up)
		return adapter_not_ready(msg);

	/* If the discover process is not running, return an error */
	if (!adapter->discov_active && !adapter->pdiscov_active)
		return not_available(msg);

	/* Queue the request when there is a discovery running */
	str2ba(peer_addr, &peer_bdaddr);
	found_device_add(&adapter->found_devices, &peer_bdaddr, 0, NAME_REQUIRED);

        return g_dbus_create_error(msg,
			ERROR_INTERFACE ".RequestDeferred",
			"Request Deferred");
}

static DBusMessage *adapter_get_remote_alias(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	DBusMessage *reply;
	char str[249], *str_ptr = str, *addr_ptr;
	bdaddr_t bdaddr;
	int ecode;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &addr_ptr,
				DBUS_TYPE_INVALID))
		return invalid_args(msg);

	if (check_address(addr_ptr) < 0)
		return invalid_args(msg);

	str2ba(addr_ptr, &bdaddr);

	ecode = get_device_alias(adapter->dev_id, &bdaddr, str, sizeof(str));
	if (ecode < 0)
		return not_available(msg);

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

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

	return reply;
}

static DBusMessage *adapter_set_remote_alias(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	char *alias, *addr, *old_path, *new_path;
	bdaddr_t bdaddr;
	int ecode;

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

	if ((strlen(alias) == 0) || (check_address(addr) < 0)) {
		error("Alias change failed: Invalid parameter");
		return invalid_args(msg);
	}

	str2ba(addr, &bdaddr);

	ecode = set_device_alias(adapter->dev_id, &bdaddr, alias);
	if (ecode < 0)
		return failed_strerror(msg, -ecode);

	resolve_paths(msg, &old_path, &new_path);

	g_dbus_emit_signal(conn, old_path,
					ADAPTER_INTERFACE, "RemoteAliasChanged",
					DBUS_TYPE_STRING, &addr,
					DBUS_TYPE_STRING, &alias,
					DBUS_TYPE_INVALID);

	if (new_path) {
		struct device *device;

		device = adapter_find_device(adapter, addr);
		if (device) {
			dbus_connection_emit_property_changed(conn,
					device->path, DEVICE_INTERFACE,
					"Alias", DBUS_TYPE_STRING, &alias);
		}
	}

	g_free(old_path);
	g_free(new_path);

	return dbus_message_new_method_return(msg);
}

static DBusMessage *adapter_clear_remote_alias(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	char *addr_ptr;
	bdaddr_t bdaddr;
	int ecode, had_alias = 1;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &addr_ptr,
				DBUS_TYPE_INVALID))
		return invalid_args(msg);

	if (check_address(addr_ptr) < 0) {
		error("Alias clear failed: Invalid parameter");
		return invalid_args(msg);
	}

	str2ba(addr_ptr, &bdaddr);

	ecode = get_device_alias(adapter->dev_id, &bdaddr, NULL, 0);
	if (ecode == -ENXIO)
		had_alias = 0;

	ecode = set_device_alias(adapter->dev_id, &bdaddr, NULL);
	if (ecode < 0)
		return failed_strerror(msg, -ecode);

	if (had_alias)
		g_dbus_emit_signal(conn, dbus_message_get_path(msg),
						ADAPTER_INTERFACE,
						"RemoteAliasCleared",
						DBUS_TYPE_STRING, &addr_ptr,
						DBUS_TYPE_INVALID);

	return dbus_message_new_method_return(msg);
}

static DBusMessage *adapter_last_seen(DBusConnection *conn,
				DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	DBusMessage *reply;
	char filename[PATH_MAX + 1];
	char *addr_ptr, *str;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &addr_ptr,
				DBUS_TYPE_INVALID))
		return invalid_args(msg);

	if (check_address(addr_ptr) < 0)
		return invalid_args(msg);

	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address,
			"lastseen");

	str = textfile_caseget(filename, addr_ptr);
	if (!str)
		return not_available(msg);

	reply = dbus_message_new_method_return(msg);
	if (!reply) {
		free(str);
		return NULL;
	}

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

	free(str);

	return reply;
}

static DBusMessage *adapter_last_used(DBusConnection *conn,
				DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	DBusMessage *reply;
	char filename[PATH_MAX + 1];
	char *addr_ptr, *str;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &addr_ptr,
				DBUS_TYPE_INVALID))
		return invalid_args(msg);

	if (check_address(addr_ptr) < 0)
		return invalid_args(msg);

	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address,
			"lastused");

	str = textfile_caseget(filename, addr_ptr);
	if (!str)
		return not_available(msg);

	reply = dbus_message_new_method_return(msg);
	if (!reply) {
		free(str);
		return NULL;
	}

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

	free(str);

	return reply;
}

gboolean dc_pending_timeout_handler(void *data)
{
	int dd;
	struct adapter *adapter = data;
	struct pending_dc_info *pending_dc = adapter->pending_dc;
	DBusMessage *reply;

	dd = hci_open_dev(adapter->dev_id);

	if (dd < 0) {
		error_no_such_adapter(pending_dc->conn,
				      pending_dc->msg);
		dc_pending_timeout_cleanup(adapter);
		return FALSE;
	}

	/* Send the HCI disconnect command */
	if (hci_disconnect(dd, htobs(pending_dc->conn_handle),
				HCI_OE_USER_ENDED_CONNECTION,
				500) < 0) {
		int err = errno;
		error("Disconnect failed");
		error_failed_errno(pending_dc->conn, pending_dc->msg, err);
	} else {
		reply = dbus_message_new_method_return(pending_dc->msg);
		if (reply) {
			dbus_connection_send(pending_dc->conn, reply, NULL);
			dbus_message_unref(reply);
		} else
			error("Failed to allocate disconnect reply");
	}

	hci_close_dev(dd);
	dc_pending_timeout_cleanup(adapter);

	return FALSE;
}

void dc_pending_timeout_cleanup(struct adapter *adapter)
{
	dbus_connection_unref(adapter->pending_dc->conn);
	dbus_message_unref(adapter->pending_dc->msg);
	g_free(adapter->pending_dc);
	adapter->pending_dc = NULL;
}

static DBusMessage *adapter_dc_remote_device(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	GSList *l = adapter->active_conn;
	const char *peer_addr;
	bdaddr_t peer_bdaddr;

	if (!adapter->up)
		return adapter_not_ready(msg);

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &peer_addr,
				DBUS_TYPE_INVALID))
		return invalid_args(msg);

	if (check_address(peer_addr) < 0)
		return invalid_args(msg);

	str2ba(peer_addr, &peer_bdaddr);

	l = g_slist_find_custom(l, &peer_bdaddr, active_conn_find_by_bdaddr);
	if (!l)
		return g_dbus_create_error(msg,
				ERROR_INTERFACE ".NotConnected",
				"Device not connected");

	if (adapter->pending_dc)
		return in_progress(msg, "Disconnection in progress");

	adapter->pending_dc = g_new0(struct pending_dc_info, 1);

	/* Start waiting... */
	adapter->pending_dc->timeout_id =
		g_timeout_add(DC_PENDING_TIMEOUT,
			      dc_pending_timeout_handler,
			      adapter);

	if (!adapter->pending_dc->timeout_id) {
		g_free(adapter->pending_dc);
		adapter->pending_dc = NULL;
		return NULL;
	}

	adapter->pending_dc->conn = dbus_connection_ref(conn);
	adapter->pending_dc->msg = dbus_message_ref(msg);
	adapter->pending_dc->conn_handle =
		((struct active_conn_info *) l->data)->handle;

	g_dbus_emit_signal(conn, dbus_message_get_path(msg),
					ADAPTER_INTERFACE,
					"RemoteDeviceDisconnectRequested",
					DBUS_TYPE_STRING, &peer_addr,
					DBUS_TYPE_INVALID);

	return NULL;
}

static void reply_authentication_failure(struct bonding_request_info *bonding)
{
	DBusMessage *reply;
	int status;

	status = bonding->hci_status ?
			bonding->hci_status : HCI_AUTHENTICATION_FAILURE;

	reply = new_authentication_return(bonding->msg, status);
	if (reply) {
		dbus_connection_send(bonding->conn, reply, NULL);
		dbus_message_unref(reply);
	}
}

struct device *adapter_find_device(struct adapter *adapter, const char *dest)
{
	struct device *device;
	GSList *l;

	if (!adapter)
		return NULL;

	l = g_slist_find_custom(adapter->devices,
				dest, (GCompareFunc) device_address_cmp);
	if (!l)
		return NULL;

	device = l->data;

	return device;
}

struct device *adapter_create_device(DBusConnection *conn,
				struct adapter *adapter, const char *address)
{
	struct device *device;

	debug("adapter_create_device(%s)", address);

	device = device_create(conn, adapter, address, NULL);
	if (!device)
		return NULL;

	device->temporary = TRUE;

	adapter->devices = g_slist_append(adapter->devices, device);

	return device;
}

static DBusMessage *remove_bonding(DBusConnection *conn, DBusMessage *msg,
					const char *address, void *data)
{
	struct adapter *adapter = data;
	struct device *device;
	char path[MAX_PATH_LENGTH], filename[PATH_MAX + 1];
	char *str;
	bdaddr_t src, dst;
	GSList *l;
	int dev, err;
	gboolean paired;

	str2ba(adapter->address, &src);
	str2ba(address, &dst);

	dev = hci_open_dev(adapter->dev_id);
	if (dev < 0 && msg)
		return no_such_adapter(msg);

	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address,
			"linkkeys");

	/* textfile_del doesn't return an error when the key is not found */
	str = textfile_caseget(filename, address);
	paired = str ? TRUE : FALSE;
	g_free(str);

	if (!paired && msg) {
		hci_close_dev(dev);
		return g_dbus_create_error(msg,
				ERROR_INTERFACE ".DoesNotExist",
				"Bonding does not exist");
	}

	/* Delete the link key from storage */
	if (textfile_casedel(filename, address) < 0 && msg) {
		hci_close_dev(dev);
		err = errno;
		return failed_strerror(msg, err);
	}

	/* Delete the link key from the Bluetooth chip */
	hci_delete_stored_link_key(dev, &dst, 0, 1000);

	/* find the connection */
	l = g_slist_find_custom(adapter->active_conn, &dst,
				active_conn_find_by_bdaddr);
	if (l) {
		struct active_conn_info *con = l->data;
		/* Send the HCI disconnect command */
		if ((hci_disconnect(dev, htobs(con->handle),
					HCI_OE_USER_ENDED_CONNECTION, 500) < 0)
					&& msg){
			int err = errno;
			error("Disconnect failed");
			hci_close_dev(dev);
			return failed_strerror(msg, err);
		}
	}

	hci_close_dev(dev);

	if (paired) {
		snprintf(path, MAX_PATH_LENGTH, BASE_PATH "/hci%d",
			adapter->dev_id);
		g_dbus_emit_signal(conn, path,
					ADAPTER_INTERFACE, "BondingRemoved",
					DBUS_TYPE_STRING, &address,
					DBUS_TYPE_INVALID);
	}

	device = adapter_find_device(adapter, address);
	if (!device)
		goto proceed;

	if (paired) {
		gboolean paired = FALSE;
		dbus_connection_emit_property_changed(conn, device->path,
					DEVICE_INTERFACE, "Paired",
					DBUS_TYPE_BOOLEAN, &paired);
	}

proceed:
	if(!msg)
		goto done;

	return dbus_message_new_method_return(msg);

done:
	return NULL;
}


void adapter_remove_device(DBusConnection *conn, struct adapter *adapter,
				struct device *device)
{
	bdaddr_t src;
	char path[MAX_PATH_LENGTH];

	str2ba(adapter->address, &src);
	delete_entry(&src, "profiles", device->address);

	remove_bonding(conn, NULL, device->address, adapter);

	if (!device->temporary) {
		snprintf(path, MAX_PATH_LENGTH, "/hci%d", adapter->dev_id);
		g_dbus_emit_signal(conn, path,
				ADAPTER_INTERFACE,
				"DeviceRemoved",
				DBUS_TYPE_OBJECT_PATH, &device->path,
				DBUS_TYPE_INVALID);
	}

	if (device->agent) {
		agent_destroy(device->agent, FALSE);
		device->agent = NULL;
	}

	adapter->devices = g_slist_remove(adapter->devices, device);

	device_remove(conn, device);
}

struct device *adapter_get_device(DBusConnection *conn,
				struct adapter *adapter, const gchar *address)
{
	struct device *device;

	debug("adapter_get_device(%s)", address);

	if (!adapter)
		return NULL;

	device = adapter_find_device(adapter, address);
	if (device)
		return device;

	return adapter_create_device(conn, adapter, address);
}

void remove_pending_device(struct adapter *adapter)
{
	struct device *device;
	char address[18];

	ba2str(&adapter->bonding->bdaddr, address);
	device = adapter_find_device(adapter, address);
	if (!device)
		return;

	if (device->temporary)
		adapter_remove_device(adapter->bonding->conn, adapter, device);
}

static gboolean create_bonding_conn_complete(GIOChannel *io, GIOCondition cond,
						struct adapter *adapter)
{
	struct hci_request rq;
	auth_requested_cp cp;
	evt_cmd_status rp;
	struct l2cap_conninfo cinfo;
	socklen_t len;
	int sk, dd, ret;

	if (!adapter->bonding) {
		/* If we come here it implies a bug somewhere */
		debug("create_bonding_conn_complete: no pending bonding!");
		g_io_channel_close(io);
		g_io_channel_unref(io);
		return FALSE;
	}

	if (cond & G_IO_NVAL) {
		error_authentication_canceled(adapter->bonding->conn,
						adapter->bonding->msg);
		goto cleanup;
	}

	if (cond & (G_IO_HUP | G_IO_ERR)) {
		debug("Hangup or error on bonding IO channel");

		if (!adapter->bonding->auth_active)
			error_connection_attempt_failed(adapter->bonding->conn,
							adapter->bonding->msg,
							ENETDOWN);
		else
			reply_authentication_failure(adapter->bonding);

		goto failed;
	}

	sk = g_io_channel_unix_get_fd(io);

	len = sizeof(ret);
	if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &ret, &len) < 0) {
		error("Can't get socket error: %s (%d)",
				strerror(errno), errno);
		error_failed_errno(adapter->bonding->conn, adapter->bonding->msg,
				errno);
		goto failed;
	}

	if (ret != 0) {
		if (adapter->bonding->auth_active)
			reply_authentication_failure(adapter->bonding);
		else
			error_connection_attempt_failed(adapter->bonding->conn,
							adapter->bonding->msg,
							ret);
		goto failed;
	}

	len = sizeof(cinfo);
	if (getsockopt(sk, SOL_L2CAP, L2CAP_CONNINFO, &cinfo, &len) < 0) {
		error("Can't get connection info: %s (%d)",
				strerror(errno), errno);
		error_failed_errno(adapter->bonding->conn, adapter->bonding->msg,
				errno);
		goto failed;
	}

	dd = hci_open_dev(adapter->dev_id);
	if (dd < 0) {
		error_no_such_adapter(adapter->bonding->conn,
					adapter->bonding->msg);
		goto failed;
	}

	memset(&rp, 0, sizeof(rp));

	memset(&cp, 0, sizeof(cp));
	cp.handle = htobs(cinfo.hci_handle);

	memset(&rq, 0, sizeof(rq));
	rq.ogf    = OGF_LINK_CTL;
	rq.ocf    = OCF_AUTH_REQUESTED;
	rq.cparam = &cp;
	rq.clen   = AUTH_REQUESTED_CP_SIZE;
	rq.rparam = &rp;
	rq.rlen   = EVT_CMD_STATUS_SIZE;
	rq.event  = EVT_CMD_STATUS;

	if (hci_send_req(dd, &rq, 500) < 0) {
		error("Unable to send HCI request: %s (%d)",
					strerror(errno), errno);
		error_failed_errno(adapter->bonding->conn, adapter->bonding->msg,
				errno);
		hci_close_dev(dd);
		goto failed;
	}

	if (rp.status) {
		error("HCI_Authentication_Requested failed with status 0x%02x",
				rp.status);
		error_failed_errno(adapter->bonding->conn, adapter->bonding->msg,
				bt_error(rp.status));
		hci_close_dev(dd);
		goto failed;
	}

	hci_close_dev(dd);

	adapter->bonding->auth_active = 1;

	adapter->bonding->io_id = g_io_add_watch(io,
						G_IO_NVAL | G_IO_HUP | G_IO_ERR,
						(GIOFunc) create_bonding_conn_complete,
						adapter);

	return FALSE;

failed:
	g_io_channel_close(io);
	remove_pending_device(adapter);

cleanup:
	g_dbus_remove_watch(adapter->bonding->conn,
				adapter->bonding->listener_id);
	bonding_request_free(adapter->bonding);
	adapter->bonding = NULL;

	return FALSE;
}

static void cancel_auth_request(struct pending_auth_info *auth, int dev_id)
{
	int dd;

	if (auth->replied)
		return;

	dd = hci_open_dev(dev_id);
	if (dd < 0) {
		error("hci_open_dev: %s (%d)", strerror(errno), errno);
		return;
	}

	switch (auth->type) {
	case AUTH_TYPE_PINCODE:
		hci_send_cmd(dd, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY,
				6, &auth->bdaddr);
		break;
	case AUTH_TYPE_CONFIRM:
		hci_send_cmd(dd, OGF_LINK_CTL, OCF_USER_CONFIRM_NEG_REPLY,
				6, &auth->bdaddr);
		break;
	case AUTH_TYPE_PASSKEY:
		hci_send_cmd(dd, OGF_LINK_CTL, OCF_USER_PASSKEY_NEG_REPLY,
				6, &auth->bdaddr);
		break;
	case AUTH_TYPE_NOTIFY:
		/* User Notify doesn't require any reply */
		break;
	}

	auth->replied = TRUE;

	hci_close_dev(dd);
}

static void create_bond_req_exit(void *user_data)
{
	struct adapter *adapter = user_data;
	struct pending_auth_info *auth;
	char path[MAX_PATH_LENGTH];

	snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, adapter->dev_id);

	debug("CreateConnection requestor exited before bonding was completed");

	cancel_passkey_agent_requests(adapter->passkey_agents, path,
					&adapter->bonding->bdaddr);
	release_passkey_agents(adapter, &adapter->bonding->bdaddr);

	auth = adapter_find_auth_request(adapter, &adapter->bonding->bdaddr);
	if (auth) {
		cancel_auth_request(auth, adapter->dev_id);
		if (auth->agent)
			agent_cancel(auth->agent);
		adapter_remove_auth_request(adapter, &adapter->bonding->bdaddr);
	}

	remove_pending_device(adapter);

	g_io_channel_close(adapter->bonding->io);
	if (adapter->bonding->io_id)
		g_source_remove(adapter->bonding->io_id);
	bonding_request_free(adapter->bonding);
	adapter->bonding = NULL;
}

static DBusMessage *create_bonding(DBusConnection *conn, DBusMessage *msg,
				const char *address, const char *agent_path,
				uint8_t capability, void *data)
{
	char filename[PATH_MAX + 1];
	char *str;
	struct adapter *adapter = data;
	struct bonding_request_info *bonding;
	bdaddr_t bdaddr;
	int sk;

	str2ba(address, &bdaddr);

	/* check if there is a pending discover: requested by D-Bus/non clients */
	if (adapter->discov_active || (adapter->pdiscov_active && !adapter->pinq_idle))
		return in_progress(msg, "Discover in progress");

	pending_remote_name_cancel(adapter);

	if (adapter->bonding)
		return in_progress(msg, "Bonding in progress");

	if (adapter_find_auth_request(adapter, &bdaddr))
		return in_progress(msg, "Bonding in progress");

	/* check if a link key already exists */
	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address,
			"linkkeys");

	str = textfile_caseget(filename, address);
	if (str) {
		free(str);
		return g_dbus_create_error(msg,
				ERROR_INTERFACE ".AlreadyExists",
				"Bonding already exists");
	}

	sk = l2raw_connect(adapter->address, &bdaddr);
	if (sk < 0)
		return g_dbus_create_error(msg,
				ERROR_INTERFACE ".ConnectionAttemptFailed",
				"Connection attempt failed");

	bonding = bonding_request_new(conn, msg, adapter, address, agent_path,
					capability);
	if (!bonding) {
		close(sk);
		return NULL;
	}

	bonding->io = g_io_channel_unix_new(sk);
	bonding->io_id = g_io_add_watch(bonding->io,
					G_IO_OUT | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
					(GIOFunc) create_bonding_conn_complete,
					adapter);

	bonding->listener_id = g_dbus_add_disconnect_watch(conn,
						dbus_message_get_sender(msg),
						create_bond_req_exit, adapter,
						NULL);

	adapter->bonding = bonding;

	return NULL;
}

static DBusMessage *adapter_create_bonding(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	char *address;

	if (!adapter->up)
		return adapter_not_ready(msg);

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &address,
				DBUS_TYPE_INVALID))
		return invalid_args(msg);

	if (check_address(address) < 0)
		return invalid_args(msg);

	return create_bonding(conn, msg, address, NULL,
				IO_CAPABILITY_INVALID, data);
}
static DBusMessage *adapter_cancel_bonding(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	const char *address;
	bdaddr_t bdaddr;
	struct bonding_request_info *bonding = adapter->bonding;
	struct pending_auth_info *auth_req;

	if (!adapter->up)
		return adapter_not_ready(msg);

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &address,
				DBUS_TYPE_INVALID))
		return invalid_args(msg);

	if (check_address(address) < 0)
		return invalid_args(msg);

	str2ba(address, &bdaddr);
	if (!bonding || bacmp(&bonding->bdaddr, &bdaddr))
		return not_in_progress(msg, "Bonding is not in progress");

	if (strcmp(dbus_message_get_sender(adapter->bonding->msg),
				dbus_message_get_sender(msg)))
		return not_authorized(msg);

	adapter->bonding->cancel = 1;

	auth_req = adapter_find_auth_request(adapter, &bdaddr);
	if (auth_req) {
		if (auth_req->replied) {
			/*
			 * If disconnect can't be applied and the PIN code
			 * request was already replied it doesn't make sense
			 * cancel the remote passkey: return not authorized.
			 */
			g_io_channel_close(adapter->bonding->io);
			return not_authorized(msg);
		}

		cancel_auth_request(auth_req, adapter->dev_id);
		if (auth_req->agent)
			agent_cancel(auth_req->agent);
		adapter_remove_auth_request(adapter, &bdaddr);
	}

	g_io_channel_close(adapter->bonding->io);

	return dbus_message_new_method_return(msg);
}

static DBusMessage *adapter_remove_bonding(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	char *address;

	if (!adapter->up)
		return adapter_not_ready(msg);

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &address,
				DBUS_TYPE_INVALID))
		return invalid_args(msg);

	if (check_address(address) < 0)
		return invalid_args(msg);

	return remove_bonding(conn, msg, address, data);
}

static DBusMessage *adapter_has_bonding(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	DBusMessage *reply;
	char filename[PATH_MAX + 1];
	char *addr_ptr, *str;
	dbus_bool_t result;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &addr_ptr,
				DBUS_TYPE_INVALID))
		return invalid_args(msg);

	if (check_address(addr_ptr) < 0)
		return invalid_args(msg);

	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address,
			"linkkeys");

	str = textfile_caseget(filename, addr_ptr);
	if (str) {
		result = TRUE;
		free(str);
	} else
		result = FALSE;

	reply = dbus_message_new_method_return(msg);

	dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &result,
					DBUS_TYPE_INVALID);

	return reply;
}

static void list_bondings_do_append(char *key, char *value, void *data)
{
	DBusMessageIter *iter = data;
	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &key);
}

static DBusMessage *adapter_list_bondings(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	DBusMessageIter iter;
	DBusMessageIter array_iter;
	DBusMessage *reply;
	char filename[PATH_MAX + 1];

	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
		return invalid_args(msg);

	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address,
			"linkkeys");

	reply = dbus_message_new_method_return(msg);

	dbus_message_iter_init_append(reply, &iter);

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

	textfile_foreach(filename, list_bondings_do_append, &array_iter);

	dbus_message_iter_close_container(&iter, &array_iter);

	return reply;
}

static DBusMessage *adapter_get_pin_code_length(DBusConnection *conn,
							DBusMessage *msg,
							void *data)
{
	struct adapter *adapter = data;
	DBusMessage *reply;
	bdaddr_t local, peer;
	char *addr_ptr;
	uint8_t length;
	int len;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &addr_ptr,
				DBUS_TYPE_INVALID))
		return invalid_args(msg);

	if (check_address(addr_ptr) < 0)
		return invalid_args(msg);

	str2ba(adapter->address, &local);

	str2ba(addr_ptr, &peer);

	len = read_pin_length(&local, &peer);
	if (len < 0)
		return g_dbus_create_error(msg,
				ERROR_INTERFACE ".DoesNotExist",
				"Record does not exist");

	reply = dbus_message_new_method_return(msg);

	length = len;

	dbus_message_append_args(reply, DBUS_TYPE_BYTE, &length,
					DBUS_TYPE_INVALID);

	return reply;
}

static DBusMessage *adapter_get_encryption_key_size(DBusConnection *conn,
							DBusMessage *msg,
							void *data)
{
	struct adapter *adapter = data;
	DBusMessage *reply;
	bdaddr_t bdaddr;
	char *addr_ptr;
	uint8_t size;
	int val;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &addr_ptr,
				DBUS_TYPE_INVALID))
		return invalid_args(msg);

	if (check_address(addr_ptr) < 0)
		return invalid_args(msg);

	str2ba(addr_ptr, &bdaddr);

	val = get_encryption_key_size(adapter->dev_id, &bdaddr);
	if (val < 0)
		return failed_strerror(msg, -val);

	reply = dbus_message_new_method_return(msg);

	size = val;

	dbus_message_append_args(reply, DBUS_TYPE_BYTE, &size,
					DBUS_TYPE_INVALID);

	return reply;
}

static void periodic_discover_req_exit(void *user_data)
{
	struct adapter *adapter = user_data;

	debug("PeriodicDiscovery requestor exited");

	/* Cleanup the discovered devices list and send the cmd to exit from
	 * periodic inquiry or cancel remote name request. The return value can
	 * be ignored. */

	cancel_periodic_discovery(adapter);
}

static DBusMessage *adapter_start_periodic(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	periodic_inquiry_cp cp;
	struct hci_request rq;
	struct adapter *adapter = data;
	uint8_t lap[3] = { 0x33, 0x8b, 0x9e };
	uint8_t status;
	int dd;

	if (!adapter->up)
		return adapter_not_ready(msg);

	if (dbus_message_is_method_call(msg, ADAPTER_INTERFACE,
				"StartPeriodicDiscovery")) {
		if (!dbus_message_has_signature(msg,
					DBUS_TYPE_INVALID_AS_STRING))
			return invalid_args(msg);
	}

	if (adapter->discov_active || adapter->pdiscov_active)
		return in_progress(msg, "Discover in progress");

	pending_remote_name_cancel(adapter);

	dd = hci_open_dev(adapter->dev_id);
	if (dd < 0)
		return no_such_adapter(msg);

	memset(&cp, 0, sizeof(cp));
	memcpy(&cp.lap, lap, 3);
	cp.max_period = htobs(24);
	cp.min_period = htobs(16);
	cp.length  = 0x08;
	cp.num_rsp = 0x00;

	memset(&rq, 0, sizeof(rq));
	rq.ogf    = OGF_LINK_CTL;
	rq.ocf    = OCF_PERIODIC_INQUIRY;
	rq.cparam = &cp;
	rq.clen   = PERIODIC_INQUIRY_CP_SIZE;
	rq.rparam = &status;
	rq.rlen   = sizeof(status);
	rq.event  = EVT_CMD_COMPLETE;

	if (hci_send_req(dd, &rq, 1000) < 0) {
		int err = errno;
		error("Unable to start periodic inquiry: %s (%d)",
				strerror(errno), errno);
		hci_close_dev(dd);
		return failed_strerror(msg, err);
	}

	if (status) {
		error("HCI_Periodic_Inquiry_Mode failed with status 0x%02x",
				status);
		hci_close_dev(dd);
		return failed_strerror(msg, bt_error(status));
	}

	adapter->pdiscov_requestor = g_strdup(dbus_message_get_sender(msg));

	if (adapter->pdiscov_resolve_names)
		adapter->discov_type = PERIODIC_INQUIRY | RESOLVE_NAME;
	else
		adapter->discov_type = PERIODIC_INQUIRY;

	hci_close_dev(dd);

	/* track the request owner to cancel it automatically if the owner
	 * exits */
	adapter->pdiscov_listener = g_dbus_add_disconnect_watch(conn,
						dbus_message_get_sender(msg),
						periodic_discover_req_exit,
						adapter, NULL);

	return dbus_message_new_method_return(msg);
}

static DBusMessage *adapter_stop_periodic(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	int err;

	if (!adapter->up)
		return adapter_not_ready(msg);

	if (dbus_message_is_method_call(msg, ADAPTER_INTERFACE,
				"StopPeriodicDiscovery")) {
		if (!dbus_message_has_signature(msg,
					DBUS_TYPE_INVALID_AS_STRING))
			return invalid_args(msg);
	}

	if (!adapter->pdiscov_active)
		return g_dbus_create_error(msg,
				ERROR_INTERFACE ".NotAuthorized",
				"Not authorized");
	/*
	 * Cleanup the discovered devices list and send the cmd to exit
	 * from periodic inquiry mode or cancel remote name request.
	 */
	err = cancel_periodic_discovery(adapter);
	if (err < 0) {
		if (err == -ENODEV)
			return no_such_adapter(msg);

		else
			return failed_strerror(msg, -err);
	}

	return dbus_message_new_method_return(msg);
}

static DBusMessage *adapter_is_periodic(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	DBusMessage *reply;
	struct adapter *adapter = data;
	dbus_bool_t active = adapter->pdiscov_active;

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

	dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &active,
					DBUS_TYPE_INVALID);

	return reply;
}

static DBusMessage *adapter_set_pdiscov_resolve(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	dbus_bool_t resolve;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_BOOLEAN, &resolve,
				DBUS_TYPE_INVALID))
		return invalid_args(msg);

	debug("SetPeriodicDiscoveryNameResolving(%s)",
			resolve ? "TRUE" : "FALSE");

	adapter->pdiscov_resolve_names = resolve;

	if (adapter->pdiscov_active) {
		if (resolve)
			adapter->discov_type |= RESOLVE_NAME;
		else
			adapter->discov_type &= ~RESOLVE_NAME;
	}

	return dbus_message_new_method_return(msg);
}

static DBusMessage *adapter_get_pdiscov_resolve(DBusConnection *conn,
							DBusMessage *msg,
							void *data)
{
	DBusMessage *reply;
	struct adapter *adapter = data;
	dbus_bool_t resolve = adapter->pdiscov_resolve_names;

	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
		return invalid_args(msg);

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

	dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &resolve,
					DBUS_TYPE_INVALID);

	return reply;
}

static void discover_devices_req_exit(void *user_data)
{
	struct adapter *adapter = user_data;

	debug("DiscoverDevices requestor exited");

	/* Cleanup the discovered devices list and send the command to cancel
	 * inquiry or cancel remote name request. The return can be ignored. */
	cancel_discovery(adapter);
}

static DBusMessage *adapter_discover_devices(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	const char *method;
	inquiry_cp cp;
	evt_cmd_status rp;
	struct hci_request rq;
	struct adapter *adapter = data;
	uint8_t lap[3] = { 0x33, 0x8b, 0x9e };
	int dd;

	if (!adapter->up)
		return adapter_not_ready(msg);

	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
		return invalid_args(msg);

	if (adapter->discov_active)
		return in_progress(msg, "Discover in progress");

	pending_remote_name_cancel(adapter);

	if (adapter->bonding)
		return in_progress(msg, "Bonding in progress");

	dd = hci_open_dev(adapter->dev_id);
	if (dd < 0)
		return no_such_adapter(msg);

	memset(&cp, 0, sizeof(cp));
	memcpy(&cp.lap, lap, 3);
	cp.length  = 0x08;
	cp.num_rsp = 0x00;

	memset(&rq, 0, sizeof(rq));
	rq.ogf    = OGF_LINK_CTL;
	rq.ocf    = OCF_INQUIRY;
	rq.cparam = &cp;
	rq.clen   = INQUIRY_CP_SIZE;
	rq.rparam = &rp;
	rq.rlen   = EVT_CMD_STATUS_SIZE;
	rq.event  = EVT_CMD_STATUS;

	if (hci_send_req(dd, &rq, 500) < 0) {
		int err = errno;
		error("Unable to start inquiry: %s (%d)",
				strerror(errno), errno);
		hci_close_dev(dd);
		return failed_strerror(msg, err);
	}

	if (rp.status) {
		error("HCI_Inquiry command failed with status 0x%02x",
				rp.status);
		hci_close_dev(dd);
		return failed_strerror(msg, bt_error(rp.status));
	}

	method = dbus_message_get_member(msg);
	if (strcmp("DiscoverDevicesWithoutNameResolving", method) == 0)
		adapter->discov_type |= STD_INQUIRY;
	else
		adapter->discov_type |= (STD_INQUIRY | RESOLVE_NAME);

	adapter->discov_requestor = g_strdup(dbus_message_get_sender(msg));


	hci_close_dev(dd);

	/* track the request owner to cancel it automatically if the owner
	 * exits */
	adapter->discov_listener = g_dbus_add_disconnect_watch(conn,
						dbus_message_get_sender(msg),
						discover_devices_req_exit,
						adapter, NULL);

	return dbus_message_new_method_return(msg);
}

static DBusMessage *adapter_cancel_discovery(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	int err;

	if (!adapter->up)
		return adapter_not_ready(msg);

	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
		return invalid_args(msg);

	/* is there discover pending? or discovery cancel was requested
	 * previously */
	if (!adapter->discov_active || adapter->discovery_cancel)
		return g_dbus_create_error(msg,
				ERROR_INTERFACE ".NotAuthorized",
				"Not Authorized");

	/* only the discover requestor can cancel the inquiry process */
	if (!adapter->discov_requestor ||
			strcmp(adapter->discov_requestor, dbus_message_get_sender(msg)))
		return g_dbus_create_error(msg,
				ERROR_INTERFACE ".NotAuthorized",
				"Not Authorized");

	/* Cleanup the discovered devices list and send the cmd to cancel
	 * inquiry or cancel remote name request */
	err = cancel_discovery(adapter);
	if (err < 0) {
		if (err == -ENODEV)
			return no_such_adapter(msg);
		else
			return failed_strerror(msg, -err);
	}

	/* Reply before send DiscoveryCompleted */
	adapter->discovery_cancel = dbus_message_ref(msg);

	return NULL;
}

struct remote_device_list_t {
	GSList *list;
	time_t time;
};

static void list_remote_devices_do_append(char *key, char *value, void *data)
{
	struct remote_device_list_t *param = data;
	char *address;
	struct tm date;

	if (g_slist_find_custom(param->list, key, (GCompareFunc) strcasecmp))
		return;

	if (param->time){
		strptime(value, "%Y-%m-%d %H:%M:%S %Z", &date);
		if (difftime(mktime(&date), param->time) < 0)
			return;
	}

	address = g_strdup(key);

	param->list = g_slist_append(param->list, address);
}

static void remote_devices_do_append(void *data, void *user_data)
{
	DBusMessageIter *iter = user_data;

	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &data);
}

static DBusMessage *adapter_list_remote_devices(DBusConnection *conn,
							DBusMessage *msg,
							void *data)
{
	struct adapter *adapter = data;
	DBusMessageIter iter;
	DBusMessageIter array_iter;
	DBusMessage *reply;
	char filename[PATH_MAX + 1];
	struct remote_device_list_t param = { NULL, 0 };

	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
		return invalid_args(msg);

	/* Add Bonded devices to the list */
	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "linkkeys");
	textfile_foreach(filename, list_remote_devices_do_append, &param);

	/* Add Trusted devices to the list */
	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "trusts");
	textfile_foreach(filename, list_remote_devices_do_append, &param);

	/* Add Last Used devices to the list */
	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "lastused");
	textfile_foreach(filename, list_remote_devices_do_append, &param);

	reply = dbus_message_new_method_return(msg);

	dbus_message_iter_init_append(reply, &iter);

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

	g_slist_foreach(param.list, remote_devices_do_append, &array_iter);

	g_slist_foreach(param.list, (GFunc) free, NULL);
	g_slist_free(param.list);

	dbus_message_iter_close_container(&iter, &array_iter);

	return reply;
}

static void append_connected(struct active_conn_info *dev, GSList *list)
{
	char address[18];

	ba2str(&dev->bdaddr, address);
	if (g_slist_find_custom(list, address, (GCompareFunc) strcasecmp))
		return;

	list = g_slist_append(list, g_strdup(address));
}

static DBusMessage *adapter_list_recent_remote_devices(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	struct tm date;
	const char *string;
	DBusMessageIter iter;
	DBusMessageIter array_iter;
	DBusMessage *reply;
	char filename[PATH_MAX + 1];
	struct remote_device_list_t param = { NULL, 0 };
	int len;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &string,
				DBUS_TYPE_INVALID))
		return invalid_args(msg);

	/* Date format is "YYYY-MM-DD HH:MM:SS GMT" */
	len = strlen(string);
	if (len && (strptime(string, "%Y-%m-%d %H:%M:%S", &date) == NULL))
		return invalid_args(msg);

	/* Bonded and trusted: mandatory entries(no matter the date/time) */
	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "linkkeys");
	textfile_foreach(filename, list_remote_devices_do_append, &param);

	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "trusts");
	textfile_foreach(filename, list_remote_devices_do_append, &param);

	/* Last seen/used: append devices since the date informed */
	if (len)
		param.time = mktime(&date);

	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "lastseen");
	textfile_foreach(filename, list_remote_devices_do_append, &param);

	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "lastused");
	textfile_foreach(filename, list_remote_devices_do_append, &param);

	/* connected: force appending connected devices, lastused might not match */
	g_slist_foreach(adapter->active_conn, (GFunc) append_connected, param.list);

	reply = dbus_message_new_method_return(msg);

	dbus_message_iter_init_append(reply, &iter);

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

	g_slist_foreach(param.list, remote_devices_do_append, &array_iter);

	g_slist_foreach(param.list, (GFunc) free, NULL);
	g_slist_free(param.list);

	dbus_message_iter_close_container(&iter, &array_iter);

	return reply;
}


static DBusMessage *adapter_set_trusted(DBusConnection *conn,
				DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	bdaddr_t local;
	const char *address;
	char *old_path, *new_path;

	if (!dbus_message_get_args(msg, NULL,
			DBUS_TYPE_STRING, &address,
			DBUS_TYPE_INVALID))
		return invalid_args(msg);

	if (check_address(address) < 0)
		return invalid_args(msg);

	str2ba(adapter->address, &local);

	write_trust(&local, address, GLOBAL_TRUST, TRUE);

	resolve_paths(msg, &old_path, &new_path);

	g_dbus_emit_signal(conn, old_path,
					ADAPTER_INTERFACE, "TrustAdded",
					DBUS_TYPE_STRING, &address,
					DBUS_TYPE_INVALID);

	if (new_path) {
		struct device *device;
		gboolean trust = TRUE;

		device = adapter_find_device(adapter, address);
		if (device) {
			dbus_connection_emit_property_changed(conn,
					device->path, DEVICE_INTERFACE,
					"Trusted", DBUS_TYPE_BOOLEAN, &trust);
		}
	}

	return dbus_message_new_method_return(msg);
}

static DBusMessage *adapter_is_trusted(DBusConnection *conn,
				DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	DBusMessage *reply;
	const char *address;
	dbus_bool_t trusted;
	bdaddr_t local;

	if (!dbus_message_get_args(msg, NULL,
			DBUS_TYPE_STRING, &address,
			DBUS_TYPE_INVALID))
		return invalid_args(msg);

	if (check_address(address) < 0)
		return invalid_args(msg);

	str2ba(adapter->address, &local);

	trusted = read_trust(&local, address, GLOBAL_TRUST);

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

	dbus_message_append_args(reply,
				DBUS_TYPE_BOOLEAN, &trusted,
				DBUS_TYPE_INVALID);

	return reply;
}

static DBusMessage *adapter_remove_trust(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	const char *address;
	bdaddr_t local;
	char *old_path, *new_path;

	if (!dbus_message_get_args(msg, NULL,
			DBUS_TYPE_STRING, &address,
			DBUS_TYPE_INVALID))
		return invalid_args(msg);

	if (check_address(address) < 0)
		return invalid_args(msg);

	str2ba(adapter->address, &local);

	write_trust(&local, address, GLOBAL_TRUST, FALSE);

	resolve_paths(msg, &old_path, &new_path);

	g_dbus_emit_signal(conn, old_path,
					ADAPTER_INTERFACE, "TrustRemoved",
					DBUS_TYPE_STRING, &address,
					DBUS_TYPE_INVALID);

	if (new_path) {
		struct device *device;
		gboolean trust = FALSE;

		device = adapter_find_device(adapter, address);
		if (device) {
			dbus_connection_emit_property_changed(conn,
					device->path, DEVICE_INTERFACE,
					"Trusted", DBUS_TYPE_BOOLEAN, &trust);
		}
	}

	return dbus_message_new_method_return(msg);
}

static DBusMessage *adapter_list_trusts(DBusConnection *conn,
						DBusMessage *msg,
						void *data)
{
	struct adapter *adapter = data;
	DBusMessage *reply;
	GSList *trusts, *l;
	char **addrs;
	bdaddr_t local;
	int len;

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

	str2ba(adapter->address, &local);

	trusts = list_trusts(&local, GLOBAL_TRUST);

	addrs = g_new(char *, g_slist_length(trusts));

	for (l = trusts, len = 0; l; l = l->next, len++)
		addrs[len] = l->data;

	dbus_message_append_args(reply,
			DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
			&addrs, len,
			DBUS_TYPE_INVALID);

	g_free(addrs);
	g_slist_foreach(trusts, (GFunc) g_free, NULL);
	g_slist_free(trusts);

	return reply;
}

static DBusMessage *get_properties(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	const char *property;
	DBusMessage *reply;
	DBusMessageIter iter;
	DBusMessageIter dict;
	bdaddr_t ba;
	char str[249];

	if (check_address(adapter->address) < 0)
		return adapter_not_ready(msg);

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

	dbus_message_iter_init_append(reply, &iter);

	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, &dict);

	/* Address */
	property = adapter->address;
	dbus_message_iter_append_dict_entry(&dict, "Address",
			DBUS_TYPE_STRING, &property);

	/* Name */
	memset(str, 0, sizeof(str));
	property = str;
	str2ba(adapter->address, &ba);

	if (!read_local_name(&ba, str))
		dbus_message_iter_append_dict_entry(&dict, "Name",
			DBUS_TYPE_STRING, &property);

	/* Mode */
	property = mode2str(adapter->mode);

	dbus_message_iter_append_dict_entry(&dict, "Mode",
			DBUS_TYPE_STRING, &property);

	/* DiscoverableTimeout */
	dbus_message_iter_append_dict_entry(&dict, "DiscoverableTimeout",
				DBUS_TYPE_UINT32, &adapter->discov_timeout);

	/* PeriodicDiscovery */
	dbus_message_iter_append_dict_entry(&dict, "PeriodicDiscovery",
				DBUS_TYPE_BOOLEAN, &adapter->pdiscov_active);

	dbus_message_iter_close_container(&iter, &dict);

	return reply;
}

static DBusMessage *set_property(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	DBusMessageIter iter;
	DBusMessageIter sub;
	const char *property;

	if (!dbus_message_iter_init(msg, &iter))
		return invalid_args(msg);

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
		return invalid_args(msg);

	dbus_message_iter_get_basic(&iter, &property);
	dbus_message_iter_next(&iter);

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
		return invalid_args(msg);
	dbus_message_iter_recurse(&iter, &sub);

	if (g_str_equal("Name", property)) {
		const char *name;

		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING)
			return invalid_args(msg);
		dbus_message_iter_get_basic(&sub, &name);

		return set_name(conn, msg, name, data);
	} else if (g_str_equal("DiscoverableTimeout", property)) {
		uint32_t timeout;

		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_UINT32)
			return invalid_args(msg);
		dbus_message_iter_get_basic(&sub, &timeout);

		return set_discoverable_timeout(conn, msg, timeout, data);
	} else if (g_str_equal("PeriodicDiscovery", property)) {
		dbus_bool_t value;

		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
			return invalid_args(msg);
		dbus_message_iter_get_basic(&sub, &value);

		if (value)
			return adapter_start_periodic(conn, msg, data);
		else
			return adapter_stop_periodic(conn, msg, data);
	} else if (g_str_equal("Mode", property)) {
		const char *mode;

		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING)
			return invalid_args(msg);

		dbus_message_iter_get_basic(&sub, &mode);

		adapter->global_mode = str2mode(adapter->address, mode);

		if (adapter->global_mode == adapter->mode)
			return dbus_message_new_method_return(msg);

		if (adapter->sessions && adapter->global_mode < adapter->mode)
			return confirm_mode(conn, msg, mode, data);

		return set_mode(conn, msg, str2mode(adapter->address, mode),
				data);
	}

	return invalid_args(msg);
}

static void session_exit(void *data)
{
	struct mode_req *req = data;
	struct adapter *adapter = req->adapter;

	adapter->sessions = g_slist_remove(adapter->sessions, req);

	if (!adapter->sessions) {
		debug("Falling back to '%s' mode", mode2str(adapter->global_mode));
		/* FIXME: fallback to previous mode
		set_mode(req->conn, req->msg, adapter->global_mode, adapter);
		*/
	}
	dbus_connection_unref(req->conn);
	dbus_message_unref(req->msg);
	g_free(req);
}

static DBusMessage *request_mode(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	const char *mode;
	struct adapter *adapter = data;
	struct mode_req *req;
	uint8_t new_mode;
	int ret;

	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &mode,
						DBUS_TYPE_INVALID))
		return invalid_args(msg);

	new_mode = str2mode(adapter->address, mode);
	if (new_mode != MODE_CONNECTABLE && new_mode != MODE_DISCOVERABLE)
		return invalid_args(msg);

	if (!adapter->agent)
		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
				"No agent registered");

	if (g_slist_find_custom(adapter->sessions, msg,
			(GCompareFunc) find_session))
		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
				"Mode already requested");

	req = g_new0(struct mode_req, 1);
	req->adapter = adapter;
	req->conn = dbus_connection_ref(conn);
	req->msg = dbus_message_ref(msg);
	req->mode = new_mode;
	req->id = g_dbus_add_disconnect_watch(conn,
					dbus_message_get_sender(msg),
					session_exit, req, NULL);

	if (!adapter->sessions)
		adapter->global_mode = adapter->mode;
	adapter->sessions = g_slist_append(adapter->sessions, req);

	/* No need to change mode */
	if (adapter->mode >= new_mode)
		return dbus_message_new_method_return(msg);

	ret = agent_confirm_mode_change(adapter->agent, mode, confirm_mode_cb,
					req);
	if (ret < 0) {
		dbus_message_unref(req->msg);
		g_dbus_remove_watch(req->conn, req->id);
		dbus_connection_unref(req->conn);
		g_free(req);
		return invalid_args(msg);
	}

	return NULL;
}

static DBusMessage *release_mode(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	GSList *l;

	l = g_slist_find_custom(adapter->sessions, msg,
			(GCompareFunc) find_session);
	if (!l)
		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
				"No Mode to release");

	session_exit(l->data);

	return dbus_message_new_method_return(msg);
}

static DBusMessage *list_devices(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	DBusMessage *reply;
	GSList *l;
	DBusMessageIter iter;
	DBusMessageIter array_iter;

	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
		return invalid_args(msg);

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

	dbus_message_iter_init_append(reply, &iter);
	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
				DBUS_TYPE_OBJECT_PATH_AS_STRING, &array_iter);

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

		if (device->temporary)
			continue;

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

	dbus_message_iter_close_container(&iter, &array_iter);

	return reply;
}

static DBusMessage *create_device(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	struct device *device;
	const gchar *address;

	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,
						DBUS_TYPE_INVALID) == FALSE)
		return invalid_args(msg);

	if (check_address(address) < 0)
		return invalid_args(msg);

	if (adapter_find_device(adapter, address))
		return g_dbus_create_error(msg,
				ERROR_INTERFACE ".AlreadyExists",
				"Device already exists");

	debug("create_device(%s)", address);

	device = device_create(conn, adapter, address, NULL);
	if (!device)
		return NULL;

	device->temporary = FALSE;

	device_browse(device, conn, msg, FALSE, 0);

	adapter->devices = g_slist_append(adapter->devices, device);

	return NULL;
}

static uint8_t parse_io_capability(const char *capability)
{
	if (g_str_equal(capability, ""))
		return IO_CAPABILITY_DISPLAYYESNO;
	if (g_str_equal(capability, "DisplayOnly"))
		return IO_CAPABILITY_DISPLAYONLY;
	if (g_str_equal(capability, "DisplayYesNo"))
		return IO_CAPABILITY_DISPLAYYESNO;
	if (g_str_equal(capability, "KeyboardOnly"))
		return IO_CAPABILITY_KEYBOARDONLY;
	if (g_str_equal(capability, "NoInputOutput"))
		return IO_CAPABILITY_NOINPUTOUTPUT;
	return IO_CAPABILITY_INVALID;
}

static DBusMessage *create_paired_device(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	const gchar *address, *agent_path, *capability;
	uint8_t cap;

	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,
					DBUS_TYPE_OBJECT_PATH, &agent_path,
					DBUS_TYPE_STRING, &capability,
						DBUS_TYPE_INVALID) == FALSE)
		return invalid_args(msg);

	if (check_address(address) < 0)
		return invalid_args(msg);

	cap = parse_io_capability(capability);
	if (cap == IO_CAPABILITY_INVALID)
		return invalid_args(msg);

	return create_bonding(conn, msg, address, agent_path, cap, data);
}

static gint device_path_cmp(struct device *device, const gchar *path)
{
	return strcasecmp(device->path, path);
}

static DBusMessage *remove_device(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	struct device *device;
	const char *path;
	GSList *l;

	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
						DBUS_TYPE_INVALID) == FALSE)
		return invalid_args(msg);

	l = g_slist_find_custom(adapter->devices,
			path, (GCompareFunc) device_path_cmp);
	if (!l)
		return g_dbus_create_error(msg,
				ERROR_INTERFACE ".DoesNotExist",
				"Device does not exist");
	device = l->data;

	if (device->temporary || device->discov_active)
		return g_dbus_create_error(msg,
				ERROR_INTERFACE ".DoesNotExist",
				"Device creation in progress");

	adapter_remove_device(conn, adapter, device);

	return dbus_message_new_method_return(msg);
}

static DBusMessage *find_device(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	struct device *device;
	DBusMessage *reply;
	const gchar *address;
	GSList *l;

	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,
						DBUS_TYPE_INVALID))
		return invalid_args(msg);

	l = g_slist_find_custom(adapter->devices,
			address, (GCompareFunc) device_address_cmp);
	if (!l)
		return g_dbus_create_error(msg,
				ERROR_INTERFACE ".DoesNotExist",
				"Device does not exist");

	device = l->data;

	if (device->temporary)
		return g_dbus_create_error(msg,
				ERROR_INTERFACE ".DoesNotExist",
				"Device creation in progress");

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

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

	return reply;
}

static void agent_removed(struct agent *agent, struct adapter *adapter)
{
	struct pending_auth_info *auth;
	GSList *l;

	adapter->agent = NULL;

	l = g_slist_find_custom(adapter->auth_reqs, agent,
					auth_info_agent_cmp);
	if (!l)
		return;

	auth = l->data;
	auth->agent = NULL;
}

static DBusMessage *register_agent(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	const char *path, *name, *capability;
	struct agent *agent;
	struct adapter *adapter = data;
	uint8_t cap;

	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
			DBUS_TYPE_STRING, &capability, DBUS_TYPE_INVALID))
		return NULL;

	if (adapter->agent)
		return g_dbus_create_error(msg,
				ERROR_INTERFACE ".AlreadyExists",
				"Agent already exists");

	cap = parse_io_capability(capability);
	if (cap == IO_CAPABILITY_INVALID)
		return invalid_args(msg);

	name = dbus_message_get_sender(msg);

	agent = agent_create(adapter, name, path, cap,
				(agent_remove_cb) agent_removed, adapter);
	if (!agent)
		return g_dbus_create_error(msg,
				ERROR_INTERFACE ".Failed",
				"Failed to create a new agent");

	adapter->agent = agent;

	debug("Agent registered for hci%d at %s:%s", adapter->dev_id, name,
			path);

	return dbus_message_new_method_return(msg);
}

static DBusMessage *unregister_agent(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	const char *path, *name;
	struct adapter *adapter = data;

	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
						DBUS_TYPE_INVALID))
		return NULL;

	name = dbus_message_get_sender(msg);

	if (!adapter->agent || !agent_matches(adapter->agent, name, path))
		return g_dbus_create_error(msg,
				ERROR_INTERFACE ".DoesNotExist",
				"No such agent");

	agent_destroy(adapter->agent, FALSE);
	adapter->agent = NULL;

	return dbus_message_new_method_return(msg);
}

static DBusMessage *add_service_record(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	DBusMessage *reply;
	const char *sender, *record;
	dbus_uint32_t handle;
	bdaddr_t src;
	int err;

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

	sender = dbus_message_get_sender(msg);
	str2ba(adapter->address, &src);
	err = add_xml_record(conn, sender, &src, record, &handle);
	if (err < 0)
		return failed_strerror(msg, err);

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

	dbus_message_append_args(reply, DBUS_TYPE_UINT32, &handle,
							DBUS_TYPE_INVALID);

	return reply;
}

static DBusMessage *update_service_record(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	bdaddr_t src;

	str2ba(adapter->address, &src);

	return update_xml_record(conn, msg, &src);
}

static DBusMessage *remove_service_record(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	dbus_uint32_t handle;
	const char *sender;

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

	sender = dbus_message_get_sender(msg);

	if (remove_record(conn, sender, handle) < 0)
		return not_available(msg);

	return dbus_message_new_method_return(msg);
}

static DBusMessage *request_authorization(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	/* FIXME implement the request */

	return NULL;
}

static DBusMessage *cancel_authorization(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	/* FIXME implement cancel request */

	return dbus_message_new_method_return(msg);
}

/* BlueZ 4.0 API */
static GDBusMethodTable adapter_methods[] = {
	{ "GetProperties",	"",	"a{sv}",get_properties		},
	{ "SetProperty",	"sv",	"",	set_property,
						G_DBUS_METHOD_FLAG_ASYNC},
	{ "RequestMode",	"s",	"",	request_mode,
						G_DBUS_METHOD_FLAG_ASYNC},
	{ "ReleaseMode",	"",	"",	release_mode		},
	{ "DiscoverDevices",	"",	"",	adapter_discover_devices},
	{ "CancelDiscovery",	"",	"",	adapter_cancel_discovery,
						G_DBUS_METHOD_FLAG_ASYNC},
	{ "ListDevices",	"",	"ao",	list_devices		},
	{ "CreateDevice",	"s",	"o",	create_device,
						G_DBUS_METHOD_FLAG_ASYNC},
	{ "CreatePairedDevice",	"sos",	"o",	create_paired_device,
						G_DBUS_METHOD_FLAG_ASYNC},
	{ "RemoveDevice",	"o",	"",	remove_device		},
	{ "FindDevice",		"s",	"o",	find_device		},
	{ "RegisterAgent",	"os",	"",	register_agent		},
	{ "UnregisterAgent",	"o",	"",	unregister_agent	},
	{ "AddServiceRecord",	"s",	"u",	add_service_record	},
	{ "UpdateServiceRecord","us",	"",	update_service_record	},
	{ "RemoveServiceRecord","u",	"",	remove_service_record	},
	{ "RequestAuthorization","su",	"",	request_authorization,
						G_DBUS_METHOD_FLAG_ASYNC},
	{ "CancelAuthorization","",	"",	cancel_authorization	},
	{ }
};

/* Deprecated */
static GDBusMethodTable old_adapter_methods[] = {
	{ "GetInfo",			"",	"a{sv}",
						adapter_get_info		},
	{ "GetAddress",			"",	"s",
						adapter_get_address		},
	{ "GetVersion",			"",	"s",
						adapter_get_version		},
	{ "GetRevision",		"",	"s",
						adapter_get_revision		},
	{ "GetManufacturer",		"",	"s",
						adapter_get_manufacturer	},
	{ "GetCompany",			"",	"s",
						adapter_get_company		},
	{ "ListAvailableModes",		"",	"as",
						adapter_list_modes		},
	{ "GetMode",			"",	"s",
						adapter_get_mode		},
	{ "SetMode",			"s",	"",
						adapter_set_mode		},
	{ "GetDiscoverableTimeout",	"",	"u",
						adapter_get_discoverable_to	},
	{ "SetDiscoverableTimeout",	"u",	"",
						adapter_set_discoverable_to	},
	{ "IsConnectable",		"",	"b",
						adapter_is_connectable		},
	{ "IsDiscoverable",		"",	"b",
						adapter_is_discoverable		},
	{ "IsConnected",		"s",	"b",
						adapter_is_connected		},
	{ "ListConnections",		"",	"as",
						adapter_list_connections	},
	{ "GetMajorClass",		"",	"s",
						adapter_get_major_class		},
	{ "ListAvailableMinorClasses",	"",	"as",
						adapter_list_minor_classes	},
	{ "GetMinorClass",		"",	"s",
						adapter_get_minor_class		},
	{ "SetMinorClass",		"s",	"",
						adapter_set_minor_class		},
	{ "GetServiceClasses",		"",	"as",
						adapter_get_service_classes	},
	{ "GetName",			"",	"s",
						adapter_get_name		},
	{ "SetName",			"s",	"",
						adapter_set_name		},

	{ "GetRemoteInfo",			"s",	"a{sv}",
						adapter_get_remote_info		},
	{ "GetRemoteServiceRecord",		"su",	"ay",
		adapter_get_remote_svc,		G_DBUS_METHOD_FLAG_ASYNC	},
	{ "GetRemoteServiceRecordAsXML",	"su",	"s",
		adapter_get_remote_svc_xml,	G_DBUS_METHOD_FLAG_ASYNC	},
	{ "GetRemoteServiceHandles",		"ss",	"au",
		adapter_get_remote_svc_handles,	G_DBUS_METHOD_FLAG_ASYNC	},
	{ "GetRemoteServiceIdentifiers",	"s",	"as",
		adapter_get_remote_svc_identifiers, G_DBUS_METHOD_FLAG_ASYNC	},
	{ "FinishRemoteServiceTransaction",	"s",	"",
						adapter_finish_sdp_transact	},
	{ "GetRemoteVersion",			"s",	"s",
						adapter_get_remote_version	},
	{ "GetRemoteRevision",			"s",	"s",
						adapter_get_remote_revision	},
	{ "GetRemoteManufacturer",		"s",	"s",
						adapter_get_remote_manufacturer	},
	{ "GetRemoteCompany",			"s",	"s",
						adapter_get_remote_company	},
	{ "GetRemoteMajorClass",		"s",	"s",
						adapter_get_remote_major_class	},
	{ "GetRemoteMinorClass",		"s",	"s",
						adapter_get_remote_minor_class	},
	{ "GetRemoteServiceClasses",		"s",	"as",
						adapter_get_remote_service_cls	},
	{ "GetRemoteClass",			"s",	"u",
						adapter_get_remote_class	},
	{ "GetRemoteFeatures",			"s",	"ay",
						adapter_get_remote_features	},
	{ "GetRemoteName",			"s",	"s",
						adapter_get_remote_name		},
	{ "GetRemoteAlias",			"s",	"s",
						adapter_get_remote_alias	},
	{ "SetRemoteAlias",			"ss",	"",
						adapter_set_remote_alias	},
	{ "ClearRemoteAlias",			"s",	"",
						adapter_clear_remote_alias	},

	{ "LastSeen",		"s",	"s",
						adapter_last_seen		},
	{ "LastUsed",		"s",	"s",
						adapter_last_used		},

	{ "DisconnectRemoteDevice",	"s",	"",
			adapter_dc_remote_device,	G_DBUS_METHOD_FLAG_ASYNC},

	{ "CreateBonding",		"s",	"",
			adapter_create_bonding,		G_DBUS_METHOD_FLAG_ASYNC},
	{ "CancelBondingProcess",	"s",	"",
						adapter_cancel_bonding		},
	{ "RemoveBonding",		"s",	"",
						adapter_remove_bonding		},
	{ "HasBonding",			"s",	"b",
						adapter_has_bonding		},
	{ "ListBondings",		"",	"as",
						adapter_list_bondings		},
	{ "GetPinCodeLength",		"s",	"y",
						adapter_get_pin_code_length	},
	{ "GetEncryptionKeySize",	"s",	"y",
						adapter_get_encryption_key_size	},

	{ "StartPeriodicDiscovery",	"",	"",
						adapter_start_periodic		},
	{ "StopPeriodicDiscovery",	"",	"",
						adapter_stop_periodic		},
	{ "IsPeriodicDiscovery",	"",	"b",
						adapter_is_periodic		},
	{ "SetPeriodicDiscoveryNameResolving",	"b",	"",
						adapter_set_pdiscov_resolve	},
	{ "GetPeriodicDiscoveryNameResolving",	"",	"b",
						adapter_get_pdiscov_resolve	},
	{ "DiscoverDevices",			"",	"",
						adapter_discover_devices	},
	{ "CancelDiscovery",			"",	"",
			adapter_cancel_discovery, G_DBUS_METHOD_FLAG_ASYNC	},
	{ "DiscoverDevicesWithoutNameResolving","",	"",
						adapter_discover_devices	},
	{ "ListRemoteDevices",			"",	"as",
						adapter_list_remote_devices	},
	{ "ListRecentRemoteDevices",		"s",	"as",
						adapter_list_recent_remote_devices},

	{ "SetTrusted",		"s",	"",
						adapter_set_trusted		},
	{ "IsTrusted",		"s",	"b",
						adapter_is_trusted		},
	{ "RemoveTrust",	"s",	"",
						adapter_remove_trust		},
	{ "ListTrusts",		"",	"as",
						adapter_list_trusts		},

	{ }
};

/* BlueZ 4.X */
static GDBusSignalTable adapter_signals[] = {
	{ "DiscoveryStarted",		""		},
	{ "DiscoveryCompleted",		""		},
	{ "DeviceCreated",		"o"		},
	{ "DeviceRemoved",		"o"		},
	{ "DeviceFound",		"sa{sv}"	},
	{ "PropertyChanged",		"sv"		},
	{ "DeviceDisappeared",		"s"		},
	{ }
};

/* Deprecated */
static GDBusSignalTable old_adapter_signals[] = {
	{ "DiscoveryStarted",			""	},
	{ "DiscoveryCompleted",			""	},
	{ "ModeChanged",			"s"	},
	{ "DiscoverableTimeoutChanged",		"u"	},
	{ "MinorClassChanged",			"s"	},
	{ "NameChanged",			"s"	},
	{ "PeriodicDiscoveryStarted",		""	},
	{ "PeriodicDiscoveryStopped",		""	},
	{ "RemoteDeviceFound",			"sun"	},
	{ "RemoteDeviceDisappeared",		"s"	},
	{ "RemoteClassUpdated",			"su"	},
	{ "RemoteNameUpdated",			"ss"	},
	{ "RemoteNameFailed",			"s"	},
	{ "RemoteNameRequested",		"s"	},
	{ "RemoteAliasChanged",			"ss"	},
	{ "RemoteAliasCleared",			"s"	},
	{ "RemoteDeviceConnected",		"s"	},
	{ "RemoteDeviceDisconnectRequested",	"s"	},
	{ "RemoteDeviceDisconnected",		"s"	},
	{ "RemoteIdentifiersUpdated",		"sas"	},
	{ "BondingCreated",			"s"	},
	{ "BondingRemoved",			"s"	},
	{ "TrustAdded",				"s"	},
	{ "TrustRemoved",			"s"	},
	{ }
};

dbus_bool_t adapter_init(DBusConnection *conn,
		const char *path, struct adapter *adapter)
{
	if (hcid_dbus_use_experimental())
		g_dbus_register_interface(conn, path + ADAPTER_PATH_INDEX,
				ADAPTER_INTERFACE, adapter_methods,
				adapter_signals, NULL, adapter, NULL);

	return g_dbus_register_interface(conn,
			path, ADAPTER_INTERFACE,
			old_adapter_methods, old_adapter_signals,
			NULL, adapter, NULL);
}

dbus_bool_t adapter_cleanup(DBusConnection *conn, const char *path)
{
	return g_dbus_unregister_interface(conn, path, ADAPTER_INTERFACE);
}

const char *major_class_str(uint32_t class)
{
	uint8_t index = (class >> 8) & 0x1F;

	if (index > 8)
		return major_cls[9]; /* uncategorized */

	return major_cls[index];
}

const char *minor_class_str(uint32_t class)
{
	uint8_t major_index = (class >> 8) & 0x1F;
	uint8_t minor_index;

	switch (major_index) {
	case 1: /* computer */
		minor_index = (class >> 2) & 0x3F;
		if (minor_index < NUM_ELEMENTS(computer_minor_cls))
			return computer_minor_cls[minor_index];
		else
			return "";
	case 2: /* phone */
		minor_index = (class >> 2) & 0x3F;
		if (minor_index < NUM_ELEMENTS(phone_minor_cls))
			return phone_minor_cls[minor_index];
		return "";
	case 3: /* access point */
		minor_index = (class >> 5) & 0x07;
		if (minor_index < NUM_ELEMENTS(access_point_minor_cls))
			return access_point_minor_cls[minor_index];
		else
			return "";
	case 4: /* audio/video */
		minor_index = (class >> 2) & 0x3F;
		if (minor_index < NUM_ELEMENTS(audio_video_minor_cls))
			return audio_video_minor_cls[minor_index];
		else
			return "";
	case 5: /* peripheral */
		minor_index = (class >> 6) & 0x03;
		if (minor_index < NUM_ELEMENTS(peripheral_minor_cls))
			return peripheral_minor_cls[minor_index];
		else
			return "";
	case 6: /* imaging */
		{
			uint8_t shift_minor = 0;

			minor_index = (class >> 4) & 0x0F;
			while (shift_minor < (sizeof(imaging_minor_cls) / sizeof(*imaging_minor_cls))) {
				if (((minor_index >> shift_minor) & 0x01) == 0x01)
					return imaging_minor_cls[shift_minor];
				shift_minor++;
			}
		}
		break;
	case 7: /* wearable */
		minor_index = (class >> 2) & 0x3F;
		if (minor_index < NUM_ELEMENTS(wearable_minor_cls))
			return wearable_minor_cls[minor_index];
		else
			return "";
	case 8: /* toy */
		minor_index = (class >> 2) & 0x3F;
		if (minor_index < NUM_ELEMENTS(toy_minor_cls))
			return toy_minor_cls[minor_index];
		else
			return "";
	}

	return "";
}

GSList *service_classes_str(uint32_t class)
{
	uint8_t services = class >> 16;
	GSList *l = NULL;
	int i;

	for (i = 0; i < (sizeof(service_cls) / sizeof(*service_cls)); i++) {
		if (!(services & (1 << i)))
			continue;

		l = g_slist_append(l, (void *) service_cls[i]);
	}

	return l;
}
