/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2010  Nokia Corporation
 *  Copyright (C) 2010  Marcel Holtmann <marcel@holtmann.org>
 *  Copyright (C) 2011-2012  Intel Corporation. All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <sys/stat.h>

#include <glib.h>

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

#include "log.h"
#include "adapter.h"
#include "manager.h"
#include "device.h"
#include "eir.h"
#include "storage.h"
#include "mgmt.h"

#define MGMT_BUF_SIZE 1024

struct pending_uuid {
	bool add;
	uuid_t uuid;
	uint8_t svc_hint;
};

static int max_index = -1;
static struct controller_info {
	gboolean valid;
	bdaddr_t bdaddr;
	uint32_t supported_settings;
	uint32_t current_settings;
	GSList *connections;
	uint8_t discov_type;

	gboolean pending_uuid;
	GSList *pending_uuids;

	gboolean pending_class;
	uint8_t major;
	uint8_t minor;

	gboolean pending_powered;
	gboolean pending_cod_change;
} *controllers = NULL;

static int mgmt_sock = -1;
static guint mgmt_watch = 0;

static uint8_t mgmt_version = 0;
static uint16_t mgmt_revision = 0;

static bool get_adapter_and_device(const bdaddr_t *src,
					struct mgmt_addr_info *addr,
					struct btd_adapter **adapter,
					struct btd_device **device,
					bool create)
{
	char peer_addr[18];

	*adapter = manager_find_adapter(src);
	if (!*adapter) {
		error("Unable to find matching adapter");
		return false;
	}

	ba2str(&addr->bdaddr, peer_addr);

	if (create)
		*device = adapter_get_device(*adapter, peer_addr, addr->type);
	else
		*device = adapter_find_device(*adapter, peer_addr);

	if (create && !*device) {
		error("Unable to get device object!");
		return false;
	}

	return true;
}

static void read_version_complete(int sk, void *buf, size_t len)
{
	struct mgmt_hdr hdr;
	struct mgmt_rp_read_version *rp = buf;

	if (len < sizeof(*rp)) {
		error("Too small read version complete event"
				" (probably an old kernel)");
		abort();
	}

	mgmt_revision = bt_get_le16(&rp->revision);
	mgmt_version = rp->version;

	info("Bluetooth management interface %u.%u initialized",
						mgmt_version, mgmt_revision);

	if (mgmt_version < 1) {
		error("Version 1.0 or later of management interface is needed");
		abort();
	}

	memset(&hdr, 0, sizeof(hdr));
	hdr.opcode = htobs(MGMT_OP_READ_INDEX_LIST);
	hdr.index = htobs(MGMT_INDEX_NONE);
	if (write(sk, &hdr, sizeof(hdr)) < 0)
		error("Unable to read controller index list: %s (%d)",
						strerror(errno), errno);
}

static void add_controller(uint16_t index)
{
	struct controller_info *info;

	if (index > max_index) {
		size_t size = sizeof(struct controller_info) * (index + 1);
		max_index = index;
		controllers = g_realloc(controllers, size);
	}

	info = &controllers[index];

	memset(info, 0, sizeof(*info));

	info->valid = TRUE;

	DBG("Added controller %u", index);
}

static void read_info(int sk, uint16_t index)
{
	struct mgmt_hdr hdr;

	memset(&hdr, 0, sizeof(hdr));
	hdr.opcode = htobs(MGMT_OP_READ_INFO);
	hdr.index = htobs(index);

	if (write(sk, &hdr, sizeof(hdr)) < 0)
		error("Unable to send read_info command: %s (%d)",
						strerror(errno), errno);
}

static void get_connections(int sk, uint16_t index)
{
	struct mgmt_hdr hdr;

	memset(&hdr, 0, sizeof(hdr));
	hdr.opcode = htobs(MGMT_OP_GET_CONNECTIONS);
	hdr.index = htobs(index);

	if (write(sk, &hdr, sizeof(hdr)) < 0)
		error("Unable to send get_connections command: %s (%d)",
						strerror(errno), errno);
}

static void mgmt_index_added(int sk, uint16_t index)
{
	add_controller(index);
	read_info(sk, index);
}

static void remove_controller(uint16_t index)
{
	if (index > max_index)
		return;

	if (!controllers[index].valid)
		return;

	btd_manager_unregister_adapter(index);

	g_slist_free_full(controllers[index].pending_uuids, g_free);
	controllers[index].pending_uuids = NULL;

	memset(&controllers[index], 0, sizeof(struct controller_info));

	DBG("Removed controller %u", index);
}

static void mgmt_index_removed(int sk, uint16_t index)
{
	remove_controller(index);
}

static int mgmt_set_mode(int index, uint16_t opcode, uint8_t val)
{
	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_mode)];
	struct mgmt_hdr *hdr = (void *) buf;
	struct mgmt_mode *cp = (void *) &buf[sizeof(*hdr)];

	memset(buf, 0, sizeof(buf));
	hdr->opcode = htobs(opcode);
	hdr->index = htobs(index);
	hdr->len = htobs(sizeof(*cp));

	cp->val = val;

	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
		return -errno;

	return 0;
}

int mgmt_set_connectable(int index, gboolean connectable)
{
	DBG("index %d connectable %d", index, connectable);
	return mgmt_set_mode(index, MGMT_OP_SET_CONNECTABLE, connectable);
}

int mgmt_set_discoverable(int index, gboolean discoverable, uint16_t timeout)
{
	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_set_discoverable)];
	struct mgmt_hdr *hdr = (void *) buf;
	struct mgmt_cp_set_discoverable *cp = (void *) &buf[sizeof(*hdr)];

	DBG("index %d discoverable %d timeout %d", index,
					discoverable, timeout);

	memset(buf, 0, sizeof(buf));
	hdr->opcode = htobs(MGMT_OP_SET_DISCOVERABLE);
	hdr->index = htobs(index);
	hdr->len = htobs(sizeof(*cp));

	cp->val = discoverable;
	cp->timeout = timeout;

	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
		return -errno;

	return 0;
}

int mgmt_set_pairable(int index, gboolean pairable)
{
	DBG("index %d pairable %d", index, pairable);
	return mgmt_set_mode(index, MGMT_OP_SET_PAIRABLE, pairable);
}

static int mgmt_set_ssp(int index, gboolean ssp)
{
	DBG("index %d ssp %d", index, ssp);
	return mgmt_set_mode(index, MGMT_OP_SET_SSP, ssp);
}

static int mgmt_set_low_energy(int index, gboolean le)
{
	DBG("index %d le %d", index, le);
	return mgmt_set_mode(index, MGMT_OP_SET_LE, le);
}

static inline int mgmt_powered(uint32_t settings)
{
	return (settings & MGMT_SETTING_POWERED) != 0;
}

static inline int mgmt_connectable(uint32_t settings)
{
	return (settings & MGMT_SETTING_CONNECTABLE) != 0;
}

static inline int mgmt_fast_connectable(uint32_t settings)
{
	return (settings & MGMT_SETTING_FAST_CONNECTABLE) != 0;
}

static inline int mgmt_discoverable(uint32_t settings)
{
	return (settings & MGMT_SETTING_DISCOVERABLE) != 0;
}

static inline int mgmt_pairable(uint32_t settings)
{
	return (settings & MGMT_SETTING_PAIRABLE) != 0;
}

static inline int mgmt_ssp(uint32_t settings)
{
	return (settings & MGMT_SETTING_SSP) != 0;
}

static inline int mgmt_bredr(uint32_t settings)
{
	return (settings & MGMT_SETTING_BREDR) != 0;
}

static inline int mgmt_high_speed(uint32_t settings)
{
	return (settings & MGMT_SETTING_HS) != 0;
}

static inline int mgmt_low_energy(uint32_t settings)
{
	return (settings & MGMT_SETTING_LE) != 0;
}

static void update_settings(struct btd_adapter *adapter, uint32_t settings)
{
	DBG("new settings %x", settings);

	adapter_update_connectable(adapter, mgmt_connectable(settings));
	adapter_update_discoverable(adapter, mgmt_discoverable(settings));
	adapter_update_pairable(adapter, mgmt_pairable(settings));
}

static void mgmt_update_powered(struct btd_adapter *adapter,
						struct controller_info *info,
						uint32_t settings)
{
	if (!mgmt_powered(settings)) {
		btd_adapter_stop(adapter);
		g_slist_free_full(info->pending_uuids, g_free);
		info->pending_uuids = NULL;
		info->pending_uuid = FALSE;
		info->pending_class = FALSE;
		info->pending_cod_change = FALSE;
		return;
	}

	btd_adapter_start(adapter);

	update_settings(adapter, settings);
}

static void mgmt_new_settings(int sk, uint16_t index, void *buf, size_t len)
{
	uint32_t settings, *ev = buf;
	struct controller_info *info;
	struct btd_adapter *adapter;
	gboolean old_power, new_power;

	if (len < sizeof(*ev)) {
		error("Too small new settings event");
		return;
	}

	DBG("hci%u new settings", index);

	if (index > max_index) {
		error("Unexpected index %u in new_settings event", index);
		return;
	}

	info = &controllers[index];

	adapter = manager_find_adapter(&info->bdaddr);
	if (adapter == NULL) {
		DBG("Adapter not found");
		return;
	}

	settings = bt_get_le32(ev);

	old_power = mgmt_powered(info->current_settings);
	new_power = mgmt_powered(settings);

	if (new_power != old_power)
		mgmt_update_powered(adapter, info, settings);
	else
		update_settings(adapter, settings);

	info->current_settings = settings;
}

static void bonding_complete(struct controller_info *info,
					const struct mgmt_addr_info *addr,
					uint8_t status)
{
	struct btd_adapter *adapter;

	adapter = manager_find_adapter(&info->bdaddr);
	if (adapter != NULL)
		adapter_bonding_complete(adapter, &addr->bdaddr, addr->type,
								status);
}

static void store_link_key(struct btd_adapter *adapter,
				struct btd_device *device, uint8_t *key,
				uint8_t type, uint8_t pin_length)
{
	char adapter_addr[18];
	char device_addr[18];
	char filename[PATH_MAX + 1];
	GKeyFile *key_file;
	char key_str[35];
	char *str;
	int i;
	gsize length = 0;

	ba2str(adapter_get_address(adapter), adapter_addr);
	ba2str(device_get_address(device), device_addr);

	snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", adapter_addr,
								device_addr);
	filename[PATH_MAX] = '\0';

	key_file = g_key_file_new();
	g_key_file_load_from_file(key_file, filename, 0, NULL);

	key_str[0] = '0';
	key_str[1] = 'x';
	for (i = 0; i < 16; i++)
		sprintf(key_str + 2 + (i * 2), "%2.2X", key[i]);

	g_key_file_set_string(key_file, "LinkKey", "Key", key_str);

	g_key_file_set_integer(key_file, "LinkKey", "Type", type);
	g_key_file_set_integer(key_file, "LinkKey", "PINLength", pin_length);

	create_file(filename, S_IRUSR | S_IWUSR);

	str = g_key_file_to_data(key_file, &length, NULL);
	g_file_set_contents(filename, str, length, NULL);
	g_free(str);

	g_key_file_free(key_file);
}

static void mgmt_new_link_key(int sk, uint16_t index, void *buf, size_t len)
{
	struct mgmt_ev_new_link_key *ev = buf;
	struct controller_info *info;
	struct btd_adapter *adapter;
	struct btd_device *device;

	if (len != sizeof(*ev)) {
		error("mgmt_new_link_key event size mismatch (%zu != %zu)",
							len, sizeof(*ev));
		return;
	}

	DBG("Controller %u new key of type %u pin_len %u", index,
					ev->key.type, ev->key.pin_len);

	if (index > max_index) {
		error("Unexpected index %u in new_key event", index);
		return;
	}

	if (ev->key.pin_len > 16) {
		error("Invalid PIN length (%u) in new_key event",
							ev->key.pin_len);
		return;
	}

	info = &controllers[index];

	if (!get_adapter_and_device(&info->bdaddr, &ev->key.addr,
						&adapter, &device, true))
		return;

	if (ev->store_hint) {
		struct mgmt_link_key_info *key = &ev->key;

		store_link_key(adapter, device, key->val, key->type,
								key->pin_len);

		device_set_bonded(device, TRUE);

		if (device_is_temporary(device))
			device_set_temporary(device, FALSE);
	}

	bonding_complete(info, &ev->key.addr, 0);
}

static void mgmt_device_connected(int sk, uint16_t index, void *buf, size_t len)
{
	struct mgmt_ev_device_connected *ev = buf;
	struct eir_data eir_data;
	struct controller_info *info;
	struct btd_adapter *adapter;
	struct btd_device *device;
	uint16_t eir_len;
	char addr[18];

	if (len < sizeof(*ev)) {
		error("Too small device_connected event");
		return;
	}

	eir_len = bt_get_le16(&ev->eir_len);
	if (len < sizeof(*ev) + eir_len) {
		error("Too small device_connected event");
		return;
	}

	ba2str(&ev->addr.bdaddr, addr);

	DBG("hci%u device %s connected eir_len %u", index, addr, eir_len);

	if (index > max_index) {
		error("Unexpected index %u in device_connected event", index);
		return;
	}

	info = &controllers[index];

	if (!get_adapter_and_device(&info->bdaddr, &ev->addr, &adapter,
								&device, true))
		return;

	memset(&eir_data, 0, sizeof(eir_data));
	if (eir_len > 0)
		eir_parse(&eir_data, ev->eir, eir_len);

	if (eir_data.class != 0)
		device_set_class(device, eir_data.class);

	adapter_add_connection(adapter, device);

	if (eir_data.name != NULL) {
		adapter_store_cached_name(&info->bdaddr, &ev->addr.bdaddr,
								eir_data.name);
		device_set_name(device, eir_data.name);
	}

	eir_data_free(&eir_data);
}

static void mgmt_device_disconnected(int sk, uint16_t index, void *buf,
								size_t len)
{
	struct mgmt_ev_device_disconnected *ev = buf;
	struct controller_info *info;
	struct btd_adapter *adapter;
	struct btd_device *device;
	char addr[18];
	uint8_t reason;

	if (len < sizeof(struct mgmt_addr_info)) {
		error("Too small device_disconnected event");
		return;
	}

	if (len < sizeof(*ev))
		reason = MGMT_DEV_DISCONN_UNKNOWN;
	else
		reason = ev->reason;

	ba2str(&ev->addr.bdaddr, addr);

	DBG("hci%u device %s disconnected reason %u", index, addr, reason);

	if (index > max_index) {
		error("Unexpected index %u in device_disconnected event", index);
		return;
	}

	info = &controllers[index];

	if (!get_adapter_and_device(&info->bdaddr, &ev->addr,
						&adapter, &device, false))
		return;

	if (device)
		adapter_remove_connection(adapter, device);
}

static void mgmt_connect_failed(int sk, uint16_t index, void *buf, size_t len)
{
	struct mgmt_ev_connect_failed *ev = buf;
	struct controller_info *info;
	struct btd_adapter *adapter;
	struct btd_device *device;
	char addr[18];

	if (len < sizeof(*ev)) {
		error("Too small connect_failed event");
		return;
	}

	ba2str(&ev->addr.bdaddr, addr);

	DBG("hci%u %s status %u", index, addr, ev->status);

	if (index > max_index) {
		error("Unexpected index %u in connect_failed event", index);
		return;
	}

	info = &controllers[index];

	if (!get_adapter_and_device(&info->bdaddr, &ev->addr,
						&adapter, &device, false))
		return;

	if (device) {
		if (device_is_bonding(device, NULL))
			device_bonding_failed(device, ev->status);
		if (device_is_temporary(device))
			adapter_remove_device(adapter, device, TRUE);
	}

	/* In the case of security mode 3 devices */
	adapter_bonding_complete(adapter, &ev->addr.bdaddr, ev->addr.type,
								ev->status);
}

int mgmt_pincode_reply(int index, const bdaddr_t *bdaddr, const char *pin,
								size_t pin_len)
{
	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_pin_code_reply)];
	struct mgmt_hdr *hdr = (void *) buf;
	size_t buf_len;
	char addr[18];

	ba2str(bdaddr, addr);
	DBG("index %d addr %s pinlen %zu", index, addr, pin_len);

	memset(buf, 0, sizeof(buf));

	if (pin == NULL) {
		struct mgmt_cp_pin_code_neg_reply *cp;

		hdr->opcode = htobs(MGMT_OP_PIN_CODE_NEG_REPLY);
		hdr->len = htobs(sizeof(*cp));
		hdr->index = htobs(index);

		cp = (void *) &buf[sizeof(*hdr)];
		bacpy(&cp->addr.bdaddr, bdaddr);
		cp->addr.type = BDADDR_BREDR;

		buf_len = sizeof(*hdr) + sizeof(*cp);
	} else {
		struct mgmt_cp_pin_code_reply *cp;

		if (pin_len > 16)
			return -EINVAL;

		hdr->opcode = htobs(MGMT_OP_PIN_CODE_REPLY);
		hdr->len = htobs(sizeof(*cp));
		hdr->index = htobs(index);

		cp = (void *) &buf[sizeof(*hdr)];
		bacpy(&cp->addr.bdaddr, bdaddr);
		cp->addr.type = BDADDR_BREDR;
		cp->pin_len = pin_len;
		memcpy(cp->pin_code, pin, pin_len);

		buf_len = sizeof(*hdr) + sizeof(*cp);
	}

	if (write(mgmt_sock, buf, buf_len) < 0)
		return -errno;

	return 0;
}

static void mgmt_pin_code_request(int sk, uint16_t index, void *buf, size_t len)
{
	struct mgmt_ev_pin_code_request *ev = buf;
	struct controller_info *info;
	struct btd_adapter *adapter;
	struct btd_device *device;
	gboolean display = FALSE;
	char pin[17];
	ssize_t pinlen;
	char addr[18];
	int err;

	if (len < sizeof(*ev)) {
		error("Too small pin_code_request event");
		return;
	}

	ba2str(&ev->addr.bdaddr, addr);

	DBG("hci%u %s", index, addr);

	if (index > max_index) {
		error("Unexpected index %u in pin_code_request event", index);
		return;
	}

	info = &controllers[index];

	if (!get_adapter_and_device(&info->bdaddr, &ev->addr,
						&adapter, &device, true))
		return;

	memset(pin, 0, sizeof(pin));
	pinlen = btd_adapter_get_pin(adapter, device, pin, &display);
	if (pinlen > 0 && (!ev->secure || pinlen == 16)) {
		if (display && device_is_bonding(device, NULL)) {
			err = device_notify_pincode(device, ev->secure, pin);
			if (err < 0) {
				error("device_notify_pin: %s", strerror(-err));
				mgmt_pincode_reply(index, &ev->addr.bdaddr,
								NULL, 0);
			}
		} else {
			mgmt_pincode_reply(index, &ev->addr.bdaddr, pin, pinlen);
		}
		return;
	}

	err = device_request_pincode(device, ev->secure);
	if (err < 0) {
		error("device_request_pin: %s", strerror(-err));
		mgmt_pincode_reply(index, &ev->addr.bdaddr, NULL, 0);
	}
}

int mgmt_confirm_reply(int index, const bdaddr_t *bdaddr, uint8_t bdaddr_type,
							gboolean success)
{
	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_user_confirm_reply)];
	struct mgmt_hdr *hdr = (void *) buf;
	struct mgmt_cp_user_confirm_reply *cp;
	char addr[18];

	ba2str(bdaddr, addr);
	DBG("index %d addr %s success %d", index, addr, success);

	memset(buf, 0, sizeof(buf));

	if (success)
		hdr->opcode = htobs(MGMT_OP_USER_CONFIRM_REPLY);
	else
		hdr->opcode = htobs(MGMT_OP_USER_CONFIRM_NEG_REPLY);

	hdr->len = htobs(sizeof(*cp));
	hdr->index = htobs(index);

	cp = (void *) &buf[sizeof(*hdr)];
	bacpy(&cp->addr.bdaddr, bdaddr);
	cp->addr.type = bdaddr_type;

	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
		return -errno;

	return 0;
}

int mgmt_passkey_reply(int index, const bdaddr_t *bdaddr, uint8_t bdaddr_type,
							uint32_t passkey)
{
	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_user_passkey_reply)];
	struct mgmt_hdr *hdr = (void *) buf;
	size_t buf_len;
	char addr[18];

	ba2str(bdaddr, addr);
	DBG("index %d addr %s passkey %06u", index, addr, passkey);

	memset(buf, 0, sizeof(buf));

	hdr->index = htobs(index);
	if (passkey == INVALID_PASSKEY) {
		struct mgmt_cp_user_passkey_neg_reply *cp;

		hdr->opcode = htobs(MGMT_OP_USER_PASSKEY_NEG_REPLY);
		hdr->len = htobs(sizeof(*cp));

		cp = (void *) &buf[sizeof(*hdr)];
		bacpy(&cp->addr.bdaddr, bdaddr);
		cp->addr.type = bdaddr_type;

		buf_len = sizeof(*hdr) + sizeof(*cp);
	} else {
		struct mgmt_cp_user_passkey_reply *cp;

		hdr->opcode = htobs(MGMT_OP_USER_PASSKEY_REPLY);
		hdr->len = htobs(sizeof(*cp));

		cp = (void *) &buf[sizeof(*hdr)];
		bacpy(&cp->addr.bdaddr, bdaddr);
		cp->addr.type = bdaddr_type;
		cp->passkey = htobl(passkey);

		buf_len = sizeof(*hdr) + sizeof(*cp);
	}

	if (write(mgmt_sock, buf, buf_len) < 0)
		return -errno;

	return 0;
}

static void mgmt_passkey_request(int sk, uint16_t index, void *buf, size_t len)
{
	struct mgmt_ev_user_passkey_request *ev = buf;
	struct controller_info *info;
	struct btd_adapter *adapter;
	struct btd_device *device;
	char addr[18];
	int err;

	if (len < sizeof(*ev)) {
		error("Too small passkey_request event");
		return;
	}

	ba2str(&ev->addr.bdaddr, addr);

	DBG("hci%u %s", index, addr);

	if (index > max_index) {
		error("Unexpected index %u in passkey_request event", index);
		return;
	}

	info = &controllers[index];

	if (!get_adapter_and_device(&info->bdaddr, &ev->addr,
						&adapter, &device, true))
		return;

	err = device_request_passkey(device);
	if (err < 0) {
		error("device_request_passkey: %s", strerror(-err));
		mgmt_passkey_reply(index, &ev->addr.bdaddr, ev->addr.type,
							INVALID_PASSKEY);
	}
}

static void mgmt_passkey_notify(int sk, uint16_t index, void *buf, size_t len)
{
	struct mgmt_ev_passkey_notify *ev = buf;
	struct controller_info *info;
	struct btd_adapter *adapter;
	struct btd_device *device;
	uint32_t passkey;
	char addr[18];
	int err;

	if (len < sizeof(*ev)) {
		error("Too small passkey_notify event");
		return;
	}

	ba2str(&ev->addr.bdaddr, addr);

	DBG("hci%u %s", index, addr);

	if (index > max_index) {
		error("Unexpected index %u in passkey_notify event", index);
		return;
	}

	info = &controllers[index];

	if (!get_adapter_and_device(&info->bdaddr, &ev->addr,
						&adapter, &device, true))
		return;

	passkey = bt_get_le32(&ev->passkey);

	DBG("passkey %06u entered %u", passkey, ev->entered);

	err = device_notify_passkey(device, passkey, ev->entered);
	if (err < 0)
		error("device_notify_passkey: %s", strerror(-err));
}

static void mgmt_user_confirm_request(int sk, uint16_t index, void *buf,
								size_t len)
{
	struct mgmt_ev_user_confirm_request *ev = buf;
	struct controller_info *info;
	struct btd_adapter *adapter;
	struct btd_device *device;
	char addr[18];
	int err;

	if (len < sizeof(*ev)) {
		error("Too small user_confirm_request event");
		return;
	}

	ba2str(&ev->addr.bdaddr, addr);

	DBG("hci%u %s confirm_hint %u", index, addr, ev->confirm_hint);

	if (index > max_index) {
		error("Unexpected index %u in user_confirm_request event",
									index);
		return;
	}

	info = &controllers[index];

	if (!get_adapter_and_device(&info->bdaddr, &ev->addr,
						&adapter, &device, true))
		return;

	err = device_confirm_passkey(device, btohl(ev->value),
							ev->confirm_hint);
	if (err < 0) {
		error("device_confirm_passkey: %s", strerror(-err));
		mgmt_confirm_reply(index, &ev->addr.bdaddr, ev->addr.type,
									FALSE);
	}
}

static void uuid_to_uuid128(uuid_t *uuid128, const uuid_t *uuid)
{
	if (uuid->type == SDP_UUID16)
		sdp_uuid16_to_uuid128(uuid128, uuid);
	else if (uuid->type == SDP_UUID32)
		sdp_uuid32_to_uuid128(uuid128, uuid);
	else
		memcpy(uuid128, uuid, sizeof(*uuid));
}

static bool is_16bit_uuid(const uuid_t *uuid)
{
	static uint8_t any[16] = { 0, 0, 0, 0, 0, 0, 0, 0,
					0, 0, 0, 0, 0, 0, 0, 0 };
	uuid_t tmp;

	if (uuid->type == SDP_UUID128 &&
			memcmp(&uuid->value.uuid128, any, sizeof(any)) == 0)
		return true;

	uuid_to_uuid128(&tmp, uuid);

	if (!sdp_uuid128_to_uuid(&tmp))
		return false;

	if (tmp.type != SDP_UUID16)
		return false;

	return true;
}

int mgmt_add_uuid(int index, uuid_t *uuid, uint8_t svc_hint)
{
	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_add_uuid)];
	struct mgmt_hdr *hdr = (void *) buf;
	struct mgmt_cp_add_uuid *cp = (void *) &buf[sizeof(*hdr)];
	struct controller_info *info = &controllers[index];
	uuid_t uuid128;
	uint128_t uint128;

	DBG("index %d", index);

	if (!is_16bit_uuid(uuid)) {
		warn("mgmt_add_uuid: Ignoring non-16-bit UUID");
		return 0;
	}

	if (info->pending_uuid) {
		struct pending_uuid *pending = g_new0(struct pending_uuid, 1);

		memcpy(&pending->uuid, uuid, sizeof(*uuid));
		pending->add = true;
		pending->svc_hint = svc_hint;

		info->pending_uuids = g_slist_append(info->pending_uuids,
								pending);
		return 0;
	}

	uuid_to_uuid128(&uuid128, uuid);

	memset(buf, 0, sizeof(buf));
	hdr->opcode = htobs(MGMT_OP_ADD_UUID);
	hdr->len = htobs(sizeof(*cp));
	hdr->index = htobs(index);

	ntoh128((uint128_t *) uuid128.value.uuid128.data, &uint128);
	htob128(&uint128, (uint128_t *) cp->uuid);

	cp->svc_hint = svc_hint;

	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
		return -errno;

	info->pending_uuid = TRUE;

	return 0;
}

int mgmt_remove_uuid(int index, uuid_t *uuid)
{
	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_remove_uuid)];
	struct mgmt_hdr *hdr = (void *) buf;
	struct mgmt_cp_remove_uuid *cp = (void *) &buf[sizeof(*hdr)];
	struct controller_info *info = &controllers[index];
	uuid_t uuid128;
	uint128_t uint128;

	DBG("index %d", index);

	if (!is_16bit_uuid(uuid)) {
		warn("mgmt_remove_uuid: Ignoring non-16-bit UUID");
		return 0;
	}

	if (info->pending_uuid) {
		struct pending_uuid *pending = g_new0(struct pending_uuid, 1);

		memcpy(&pending->uuid, uuid, sizeof(*uuid));
		pending->add = false;

		info->pending_uuids = g_slist_append(info->pending_uuids,
								pending);
		return 0;
	}

	uuid_to_uuid128(&uuid128, uuid);

	memset(buf, 0, sizeof(buf));
	hdr->opcode = htobs(MGMT_OP_REMOVE_UUID);
	hdr->len = htobs(sizeof(*cp));
	hdr->index = htobs(index);

	ntoh128((uint128_t *) uuid128.value.uuid128.data, &uint128);
	htob128(&uint128, (uint128_t *) cp->uuid);

	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
		return -errno;

	info->pending_uuid = TRUE;

	return 0;
}

static int clear_uuids(int index)
{
	uuid_t uuid_any;

	memset(&uuid_any, 0, sizeof(uuid_any));
	uuid_any.type = SDP_UUID128;

	return mgmt_remove_uuid(index, &uuid_any);
}

static void read_index_list_complete(int sk, void *buf, size_t len)
{
	struct mgmt_rp_read_index_list *rp = buf;
	uint16_t num;
	int i;

	if (len < sizeof(*rp)) {
		error("Too small read index list complete event");
		return;
	}

	num = bt_get_le16(&rp->num_controllers);

	if (num * sizeof(uint16_t) + sizeof(*rp) != len) {
		error("Incorrect packet size for index list event");
		return;
	}

	for (i = 0; i < num; i++) {
		uint16_t index;

		index = bt_get_le16(&rp->index[i]);

		add_controller(index);
		read_info(sk, index);
	}
}

int mgmt_set_powered(int index, gboolean powered)
{
	struct controller_info *info = &controllers[index];

	DBG("index %d powered %d pending_uuid %u", index, powered,
							info->pending_uuid);

	if (powered) {
		if (info->pending_uuid) {
			info->pending_powered = TRUE;
			return 0;
		}
	} else {
		info->pending_powered = FALSE;
	}

	return mgmt_set_mode(index, MGMT_OP_SET_POWERED, powered);
}

int mgmt_set_name(int index, const char *name)
{
	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_set_local_name)];
	struct mgmt_hdr *hdr = (void *) buf;
	struct mgmt_cp_set_local_name *cp = (void *) &buf[sizeof(*hdr)];

	DBG("index %d, name %s", index, name);

	memset(buf, 0, sizeof(buf));
	hdr->opcode = htobs(MGMT_OP_SET_LOCAL_NAME);
	hdr->len = htobs(sizeof(*cp));
	hdr->index = htobs(index);

	strncpy((char *) cp->name, name, sizeof(cp->name) - 1);

	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
		return -errno;

	return 0;
}

int mgmt_set_dev_class(int index, uint8_t major, uint8_t minor)
{
	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_set_dev_class)];
	struct mgmt_hdr *hdr = (void *) buf;
	struct mgmt_cp_set_dev_class *cp = (void *) &buf[sizeof(*hdr)];
	struct controller_info *info = &controllers[index];

	DBG("index %d major %u minor %u", index, major, minor);

	if (info->pending_uuid) {
		info->major = major;
		info->minor = minor;
		info->pending_class = TRUE;
		return 0;
	}

	memset(buf, 0, sizeof(buf));
	hdr->opcode = htobs(MGMT_OP_SET_DEV_CLASS);
	hdr->len = htobs(sizeof(*cp));
	hdr->index = htobs(index);

	cp->major = major;
	cp->minor = minor;

	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
		return -errno;

	return 0;
}

static void read_info_complete(int sk, uint16_t index, void *buf, size_t len)
{
	struct mgmt_rp_read_info *rp = buf;
	struct controller_info *info;
	struct btd_adapter *adapter;
	const char *name;
	uint8_t major, minor;
	char addr[18];

	if (len < sizeof(*rp)) {
		error("Too small read info complete event");
		return;
	}

	if (index > max_index) {
		error("Unexpected index %u in read info complete", index);
		return;
	}

	info = &controllers[index];

	bacpy(&info->bdaddr, &rp->bdaddr);

	memcpy(&info->supported_settings, &rp->supported_settings,
					sizeof(info->supported_settings));
	memcpy(&info->current_settings, &rp->current_settings,
					sizeof(info->current_settings));

	ba2str(&info->bdaddr, addr);
	DBG("hci%u addr %s version %u manufacturer %u class 0x%02x%02x%02x\n",
		index, addr, rp->version, bt_get_le16(&rp->manufacturer),
		rp->dev_class[2], rp->dev_class[1], rp->dev_class[0]);
	DBG("hci%u settings", index);
	DBG("hci%u name %s", index, (char *) rp->name);
	DBG("hci%u short name %s", index, (char *) rp->short_name);

	clear_uuids(index);

	adapter = btd_manager_register_adapter(index,
				mgmt_powered(info->current_settings),
				mgmt_connectable(info->current_settings),
				mgmt_discoverable(info->current_settings));

	if (adapter == NULL) {
		error("mgmt: unable to register adapter");
		return;
	}

	update_settings(adapter, info->current_settings);

	name = btd_adapter_get_name(adapter);

	if (name)
		mgmt_set_name(index, name);
	else
		adapter_name_changed(adapter, (char *) rp->name);

	btd_adapter_get_major_minor(adapter, &major, &minor);
	mgmt_set_dev_class(index, major, minor);

	if (!mgmt_pairable(info->current_settings))
		mgmt_set_pairable(index, TRUE);

	if (mgmt_ssp(info->supported_settings) &&
					!mgmt_ssp(info->current_settings))
		mgmt_set_ssp(index, TRUE);

	if (mgmt_low_energy(info->supported_settings) &&
				!mgmt_low_energy(info->current_settings))
		mgmt_set_low_energy(index, TRUE);

	if (mgmt_powered(info->current_settings)) {
		get_connections(sk, index);
		btd_adapter_start(adapter);
	}

	btd_adapter_unref(adapter);
}

static void disconnect_complete(int sk, uint16_t index, uint8_t status,
							void *buf, size_t len)
{
	struct mgmt_rp_disconnect *rp = buf;
	struct controller_info *info;
	struct btd_adapter *adapter;
	struct btd_device *device;
	char addr[18];

	if (len < sizeof(*rp)) {
		error("Too small disconnect complete event");
		return;
	}

	ba2str(&rp->addr.bdaddr, addr);

	if (status != 0) {
		error("Disconnecting %s failed with status %u", addr, status);
		return;
	}

	DBG("hci%d %s disconnected", index, addr);

	if (index > max_index) {
		error("Unexpected index %u in disconnect complete", index);
		return;
	}

	info = &controllers[index];

	if (!get_adapter_and_device(&info->bdaddr, &rp->addr,
						&adapter, &device, false))
		return;

	if (device)
		adapter_remove_connection(adapter, device);

	adapter_bonding_complete(adapter, &rp->addr.bdaddr, rp->addr.type,
						MGMT_STATUS_DISCONNECTED);
}

static void pair_device_complete(int sk, uint16_t index, uint8_t status,
							void *buf, size_t len)
{
	struct mgmt_rp_pair_device *rp = buf;
	struct controller_info *info;
	char addr[18];

	if (len < sizeof(*rp)) {
		error("Too small pair_device complete event");
		return;
	}

	ba2str(&rp->addr.bdaddr, addr);

	DBG("hci%d %s pairing complete status %u", index, addr, status);

	if (index > max_index) {
		error("Unexpected index %u in pair_device complete", index);
		return;
	}

	info = &controllers[index];

	bonding_complete(info, &rp->addr, status);
}

static void get_connections_complete(int sk, uint16_t index, void *buf,
								size_t len)
{
	struct mgmt_rp_get_connections *rp = buf;
	struct controller_info *info;
	int i;

	if (len < sizeof(*rp)) {
		error("Too small get_connections complete event");
		return;
	}

	if (len < (sizeof(*rp) + (rp->conn_count * sizeof(bdaddr_t)))) {
		error("Too small get_connections complete event");
		return;
	}

	if (index > max_index) {
		error("Unexpected index %u in get_connections complete",
								index);
		return;
	}

	info = &controllers[index];

	for (i = 0; i < rp->conn_count; i++) {
		struct mgmt_addr_info *addr;

		addr = g_memdup(&rp->addr[i], sizeof(*addr));

		info->connections = g_slist_append(info->connections, addr);
	}
}

static void set_local_name_complete(int sk, uint16_t index, void *buf,
								size_t len)
{
	struct mgmt_cp_set_local_name *rp = buf;
	struct controller_info *info;
	struct btd_adapter *adapter;

	if (len < sizeof(*rp)) {
		error("Too small set_local_name complete event");
		return;
	}

	DBG("hci%d name %s", index, (char *) rp->name);

	if (index > max_index) {
		error("Unexpected index %u in set_local_name complete", index);
		return;
	}

	info = &controllers[index];

	adapter = manager_find_adapter(&info->bdaddr);
	if (adapter == NULL) {
		DBG("Adapter not found");
		return;
	}

	adapter_name_changed(adapter, (char *) rp->name);
}

static void read_local_oob_data_complete(int sk, uint16_t index, void *buf,
								size_t len)
{
	struct mgmt_rp_read_local_oob_data *rp = buf;
	struct btd_adapter *adapter;

	if (len != sizeof(*rp)) {
		error("read_local_oob_data_complete event size mismatch "
					"(%zu != %zu)", len, sizeof(*rp));
		return;
	}

	if (index > max_index) {
		error("Unexpected index %u in read_local_oob_data_complete",
								index);
		return;
	}

	DBG("hci%u", index);

	adapter = manager_find_adapter_by_id(index);
	if (adapter)
		adapter_read_local_oob_data_complete(adapter, rp->hash,
							rp->randomizer);
}

static void start_discovery_complete(int sk, uint16_t index, uint8_t status,
						     void *buf, size_t len)
{
	uint8_t *type = buf;
	struct btd_adapter *adapter;

	if (len != sizeof(*type)) {
		error("start_discovery_complete event size mismatch "
					"(%zu != %zu)", len, sizeof(*type));
		return;
	}

	DBG("hci%u type %u status %u", index, *type, status);

	if (index > max_index) {
		error("Invalid index %u in start_discovery_complete", index);
		return;
	}

	if (!status)
		return;

	adapter = manager_find_adapter_by_id(index);
	if (adapter)
		/* Start discovery failed, inform upper layers. */
		adapter_set_discovering(adapter, FALSE);
}

static void read_local_oob_data_failed(int sk, uint16_t index)
{
	struct btd_adapter *adapter;

	if (index > max_index) {
		error("Unexpected index %u in read_local_oob_data_failed",
								index);
		return;
	}

	DBG("hci%u", index);

	adapter = manager_find_adapter_by_id(index);
	if (adapter)
		adapter_read_local_oob_data_complete(adapter, NULL, NULL);
}

static void handle_pending_uuids(uint16_t index)
{
	struct controller_info *info;
	struct pending_uuid *pending;

	DBG("index %d", index);

	info = &controllers[index];

	info->pending_uuid = FALSE;

	if (g_slist_length(info->pending_uuids) == 0) {
		if (info->pending_class) {
			info->pending_class = FALSE;
			mgmt_set_dev_class(index, info->major, info->minor);
		}

		if (info->pending_powered) {
			info->pending_powered = FALSE;
			mgmt_set_powered(index, TRUE);
		}

		return;
	}

	pending = info->pending_uuids->data;

	if (pending->add)
		mgmt_add_uuid(index, &pending->uuid, pending->svc_hint);
	else
		mgmt_remove_uuid(index, &pending->uuid);

	info->pending_uuids = g_slist_remove(info->pending_uuids, pending);
	g_free(pending);
}

static void mgmt_update_cod(uint16_t index, void *buf, size_t len)
{
	struct mgmt_cod *rp = buf;
	struct controller_info *info;
	struct btd_adapter *adapter;

	DBG("index %d", index);

	if (len < sizeof(*rp)) {
		error("Too small class of device reply");
		return;
	}

	info = &controllers[index];

	adapter = manager_find_adapter(&info->bdaddr);
	if (adapter == NULL) {
		DBG("Adapter not found");
		return;
	}

	btd_adapter_class_changed(adapter, rp->val);
}

static void mgmt_add_uuid_complete(int sk, uint16_t index, void *buf,
								size_t len)
{
	DBG("index %d", index);

	if (index > max_index) {
		error("Unexpected index %u in add_uuid_complete event", index);
		return;
	}

	mgmt_update_cod(index, buf, len);
	handle_pending_uuids(index);
}

static void mgmt_remove_uuid_complete(int sk, uint16_t index, void *buf,
								size_t len)
{
	DBG("index %d", index);

	if (index > max_index) {
		error("Unexpected index %u in remove_uuid_complete event",
									index);
		return;
	}

	mgmt_update_cod(index, buf, len);
	handle_pending_uuids(index);
}

static void mgmt_cmd_complete(int sk, uint16_t index, void *buf, size_t len)
{
	struct mgmt_ev_cmd_complete *ev = buf;
	uint16_t opcode;

	DBG("");

	if (len < sizeof(*ev)) {
		error("Too small management command complete event packet");
		return;
	}

	opcode = bt_get_le16(&ev->opcode);

	len -= sizeof(*ev);

	switch (opcode) {
	case MGMT_OP_READ_VERSION:
		read_version_complete(sk, ev->data, len);
		break;
	case MGMT_OP_READ_INDEX_LIST:
		read_index_list_complete(sk, ev->data, len);
		break;
	case MGMT_OP_READ_INFO:
		read_info_complete(sk, index, ev->data, len);
		break;
	case MGMT_OP_SET_POWERED:
		mgmt_new_settings(sk, index, ev->data, len);
		break;
	case MGMT_OP_SET_DISCOVERABLE:
		mgmt_new_settings(sk, index, ev->data, len);
		break;
	case MGMT_OP_SET_CONNECTABLE:
		mgmt_new_settings(sk, index, ev->data, len);
		break;
	case MGMT_OP_SET_PAIRABLE:
		mgmt_new_settings(sk, index, ev->data, len);
		break;
	case MGMT_OP_SET_SSP:
		mgmt_new_settings(sk, index, ev->data, len);
		break;
	case MGMT_OP_SET_LE:
		mgmt_new_settings(sk, index, ev->data, len);
		break;
	case MGMT_OP_ADD_UUID:
		mgmt_add_uuid_complete(sk, index, ev->data, len);
		break;
	case MGMT_OP_REMOVE_UUID:
		DBG("remove_uuid complete");
		mgmt_remove_uuid_complete(sk, index, ev->data, len);
		break;
	case MGMT_OP_SET_DEV_CLASS:
		DBG("set_dev_class complete");
		mgmt_update_cod(index, buf, len);
		break;
	case MGMT_OP_LOAD_LINK_KEYS:
		DBG("load_link_keys complete");
		break;
	case MGMT_OP_CANCEL_PAIR_DEVICE:
		DBG("cancel_pair_device complete");
		break;
	case MGMT_OP_UNPAIR_DEVICE:
		DBG("unpair_device complete");
		break;
	case MGMT_OP_DISCONNECT:
		DBG("disconnect complete");
		disconnect_complete(sk, index, ev->status, ev->data, len);
		break;
	case MGMT_OP_GET_CONNECTIONS:
		get_connections_complete(sk, index, ev->data, len);
		break;
	case MGMT_OP_PIN_CODE_REPLY:
		DBG("pin_code_reply complete");
		break;
	case MGMT_OP_PIN_CODE_NEG_REPLY:
		DBG("pin_code_neg_reply complete");
		break;
	case MGMT_OP_SET_IO_CAPABILITY:
		DBG("set_io_capability complete");
		break;
	case MGMT_OP_PAIR_DEVICE:
		pair_device_complete(sk, index, ev->status, ev->data, len);
		break;
	case MGMT_OP_USER_CONFIRM_REPLY:
		DBG("user_confirm_reply complete");
		break;
	case MGMT_OP_USER_CONFIRM_NEG_REPLY:
		DBG("user_confirm_net_reply complete");
		break;
	case MGMT_OP_SET_LOCAL_NAME:
		set_local_name_complete(sk, index, ev->data, len);
		break;
	case MGMT_OP_READ_LOCAL_OOB_DATA:
		read_local_oob_data_complete(sk, index, ev->data, len);
		break;
	case MGMT_OP_ADD_REMOTE_OOB_DATA:
		DBG("add_remote_oob_data complete");
		break;
	case MGMT_OP_REMOVE_REMOTE_OOB_DATA:
		DBG("remove_remote_oob_data complete");
		break;
	case MGMT_OP_BLOCK_DEVICE:
		DBG("block_device complete");
		break;
	case MGMT_OP_UNBLOCK_DEVICE:
		DBG("unblock_device complete");
		break;
	case MGMT_OP_SET_FAST_CONNECTABLE:
		DBG("set_fast_connectable complete");
		break;
	case MGMT_OP_START_DISCOVERY:
		start_discovery_complete(sk, index, ev->status, ev->data, len);
		break;
	case MGMT_OP_STOP_DISCOVERY:
		DBG("stop_discovery complete");
		break;
	case MGMT_OP_SET_DEVICE_ID:
		DBG("set_did complete");
		break;
	default:
		error("Unknown command complete for opcode %u", opcode);
		break;
	}
}

static void mgmt_add_uuid_busy(int sk, uint16_t index)
{
	struct controller_info *info;

	DBG("index %d", index);

	info = &controllers[index];
	info->pending_cod_change = TRUE;
}

static void mgmt_cmd_status(int sk, uint16_t index, void *buf, size_t len)
{
	struct mgmt_ev_cmd_status *ev = buf;
	uint16_t opcode;

	if (len < sizeof(*ev)) {
		error("Too small management command status event packet");
		return;
	}

	opcode = bt_get_le16(&ev->opcode);

	if (!ev->status) {
		DBG("%s (0x%04x) cmd_status %u", mgmt_opstr(opcode), opcode,
								ev->status);
		return;
	}

	switch (opcode) {
	case MGMT_OP_READ_LOCAL_OOB_DATA:
		read_local_oob_data_failed(sk, index);
		break;
	case MGMT_OP_ADD_UUID:
		if (ev->status == MGMT_STATUS_BUSY) {
			mgmt_add_uuid_busy(sk, index);
			return;
		}
		break;
	}

	error("hci%u: %s (0x%04x) failed: %s (0x%02x)", index,
			mgmt_opstr(opcode), opcode, mgmt_errstr(ev->status),
			ev->status);
}

static void mgmt_controller_error(int sk, uint16_t index, void *buf, size_t len)
{
	struct mgmt_ev_controller_error *ev = buf;

	if (len < sizeof(*ev)) {
		error("Too small management controller error event packet");
		return;
	}

	DBG("index %u error_code %u", index, ev->error_code);
}

static void mgmt_auth_failed(int sk, uint16_t index, void *buf, size_t len)
{
	struct controller_info *info;
	struct mgmt_ev_auth_failed *ev = buf;

	if (len < sizeof(*ev)) {
		error("Too small mgmt_auth_failed event packet");
		return;
	}

	DBG("hci%u auth failed status %u", index, ev->status);

	if (index > max_index) {
		error("Unexpected index %u in auth_failed event", index);
		return;
	}

	info = &controllers[index];

	bonding_complete(info, &ev->addr, ev->status);
}

static void mgmt_local_name_changed(int sk, uint16_t index, void *buf, size_t len)
{
	struct mgmt_cp_set_local_name *ev = buf;
	struct controller_info *info;
	struct btd_adapter *adapter;

	if (len < sizeof(*ev)) {
		error("Too small mgmt_local_name_changed event packet");
		return;
	}

	DBG("hci%u local name changed: %s", index, (char *) ev->name);

	if (index > max_index) {
		error("Unexpected index %u in name_changed event", index);
		return;
	}

	info = &controllers[index];

	adapter = manager_find_adapter(&info->bdaddr);
	if (adapter)
		adapter_name_changed(adapter, (char *) ev->name);
}

static void mgmt_device_found(int sk, uint16_t index, void *buf, size_t len)
{
	struct mgmt_ev_device_found *ev = buf;
	struct controller_info *info;
	struct btd_adapter *adapter;
	char addr[18];
	uint32_t flags;
	uint16_t eir_len;
	uint8_t *eir;
	bool confirm_name;
	bool legacy;

	if (len < sizeof(*ev)) {
		error("mgmt_device_found too short (%zu bytes)", len);
		return;
	}

	eir_len = bt_get_le16(&ev->eir_len);
	if (len != sizeof(*ev) + eir_len) {
		error("mgmt_device_found event size mismatch (%zu != %zu)",
						len, sizeof(*ev) + eir_len);
		return;
	}

	if (index > max_index) {
		error("Unexpected index %u in device_found event", index);
		return;
	}

	info = &controllers[index];

	adapter = manager_find_adapter(&info->bdaddr);
	if (!adapter)
		return;

	if (eir_len == 0)
		eir = NULL;
	else
		eir = ev->eir;

	flags = btohl(ev->flags);

	ba2str(&ev->addr.bdaddr, addr);
	DBG("hci%u addr %s, rssi %d flags 0x%04x eir_len %u",
			index, addr, ev->rssi, flags, eir_len);

	confirm_name = (flags & MGMT_DEV_FOUND_CONFIRM_NAME);
	legacy = (flags & MGMT_DEV_FOUND_LEGACY_PAIRING);

	adapter_update_found_devices(adapter, &ev->addr.bdaddr, ev->addr.type,
					ev->rssi, confirm_name, legacy,
					eir, eir_len);
}

static void mgmt_discovering(int sk, uint16_t index, void *buf, size_t len)
{
	struct mgmt_ev_discovering *ev = buf;
	struct controller_info *info;
	struct btd_adapter *adapter;

	if (len < sizeof(*ev)) {
		error("Too small discovering event");
		return;
	}

	DBG("Controller %u type %u discovering %u", index,
					ev->type, ev->discovering);

	if (index > max_index) {
		error("Unexpected index %u in discovering event", index);
		return;
	}

	info = &controllers[index];

	adapter = manager_find_adapter(&info->bdaddr);
	if (!adapter)
		return;

	adapter_set_discovering(adapter, ev->discovering);
}

static void mgmt_device_blocked(int sk, uint16_t index, void *buf, size_t len)
{
	struct controller_info *info;
	struct btd_adapter *adapter;
	struct btd_device *device;
	struct mgmt_ev_device_blocked *ev = buf;
	char addr[18];

	if (len < sizeof(*ev)) {
		error("Too small mgmt_device_blocked event packet");
		return;
	}

	ba2str(&ev->addr.bdaddr, addr);
	DBG("Device blocked, index %u, addr %s", index, addr);

	if (index > max_index) {
		error("Unexpected index %u in device_blocked event", index);
		return;
	}

	info = &controllers[index];

	if (!get_adapter_and_device(&info->bdaddr, &ev->addr,
						&adapter, &device, false))
		return;

	if (device)
		device_block(device, TRUE);
}

static void mgmt_device_unblocked(int sk, uint16_t index, void *buf, size_t len)
{
	struct controller_info *info;
	struct btd_adapter *adapter;
	struct btd_device *device;
	struct mgmt_ev_device_unblocked *ev = buf;
	char addr[18];

	if (len < sizeof(*ev)) {
		error("Too small mgmt_device_unblocked event packet");
		return;
	}

	ba2str(&ev->addr.bdaddr, addr);
	DBG("Device unblocked, index %u, addr %s", index, addr);

	if (index > max_index) {
		error("Unexpected index %u in device_unblocked event", index);
		return;
	}

	info = &controllers[index];

	if (!get_adapter_and_device(&info->bdaddr, &ev->addr,
						&adapter, &device, false))
		return;

	if (device)
		device_unblock(device, FALSE, TRUE);
}

static void mgmt_device_unpaired(int sk, uint16_t index, void *buf, size_t len)
{
	struct controller_info *info;
	struct btd_adapter *adapter;
	struct btd_device *device;
	struct mgmt_ev_device_unpaired *ev = buf;
	char addr[18];

	if (len < sizeof(*ev)) {
		error("Too small mgmt_device_unpaired event packet");
		return;
	}

	ba2str(&ev->addr.bdaddr, addr);
	DBG("Device upaired, index %u, addr %s", index, addr);

	if (index > max_index) {
		error("Unexpected index %u in device_unpaired event", index);
		return;
	}

	info = &controllers[index];

	if (!get_adapter_and_device(&info->bdaddr, &ev->addr,
						&adapter, &device, false))
		return;

	if (!device)
		return;

	device_set_temporary(device, TRUE);

	if (device_is_connected(device))
		device_request_disconnect(device, NULL);
	else
		adapter_remove_device(adapter, device, TRUE);
}

static void store_longtermkey(bdaddr_t *local, bdaddr_t *peer,
				uint8_t bdaddr_type, unsigned char *key,
				uint8_t master, uint8_t authenticated,
				uint8_t enc_size, uint16_t ediv,
				uint8_t rand[8])
{
	char adapter_addr[18];
	char device_addr[18];
	char filename[PATH_MAX + 1];
	GKeyFile *key_file;
	char key_str[35];
	char rand_str[19];
	char *str;
	int i;
	gsize length = 0;

	ba2str(local, adapter_addr);
	ba2str(peer, device_addr);

	snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", adapter_addr,
								device_addr);
	filename[PATH_MAX] = '\0';

	key_file = g_key_file_new();
	g_key_file_load_from_file(key_file, filename, 0, NULL);

	key_str[0] = '0';
	key_str[1] = 'x';
	for (i = 0; i < 16; i++)
		sprintf(key_str + 2 + (i * 2), "%2.2X", key[i]);

	g_key_file_set_string(key_file, "LongTermKey", "Key", key_str);

	g_key_file_set_integer(key_file, "LongTermKey", "Authenticated",
				authenticated);
	g_key_file_set_integer(key_file, "LongTermKey", "Master", master);
	g_key_file_set_integer(key_file, "LongTermKey", "EncSize", enc_size);
	g_key_file_set_integer(key_file, "LongTermKey", "EDiv", ediv);

	rand_str[0] = '0';
	rand_str[1] = 'x';
	for (i = 0; i < 8; i++)
		sprintf(rand_str + 2 + (i * 2), "%2.2X", rand[i]);

	g_key_file_set_string(key_file, "LongTermKey", "Rand", rand_str);

	create_file(filename, S_IRUSR | S_IWUSR);

	str = g_key_file_to_data(key_file, &length, NULL);
	g_file_set_contents(filename, str, length, NULL);
	g_free(str);

	g_key_file_free(key_file);
}

static void mgmt_new_ltk(int sk, uint16_t index, void *buf, size_t len)
{
	struct mgmt_ev_new_long_term_key *ev = buf;
	struct controller_info *info;
	struct btd_adapter *adapter;
	struct btd_device *device;

	if (len != sizeof(*ev)) {
		error("mgmt_new_ltk event size mismatch (%zu != %zu)",
							len, sizeof(*ev));
		return;
	}

	DBG("Controller %u new LTK authenticated %u enc_size %u", index,
				ev->key.authenticated, ev->key.enc_size);

	if (index > max_index) {
		error("Unexpected index %u in new_key event", index);
		return;
	}

	info = &controllers[index];

	if (!get_adapter_and_device(&info->bdaddr, &ev->key.addr,
						&adapter, &device, true))
		return;

	if (ev->store_hint) {
		struct mgmt_ltk_info *key = &ev->key;

		store_longtermkey(&info->bdaddr, &key->addr.bdaddr,
					key->addr.type, key->val, key->master,
					key->authenticated, key->enc_size,
					key->ediv, key->rand);

		device_set_bonded(device, TRUE);

		if (device_is_temporary(device))
			device_set_temporary(device, FALSE);
	}

	if (ev->key.master)
		bonding_complete(info, &ev->key.addr, 0);
}

static void mgmt_cod_changed(int sk, uint16_t index, void *buf, size_t len)
{
	struct controller_info *info;

	DBG("index %d", index);

	if (index > max_index) {
		error("Unexpected index %u in mgmt_cod_changed event", index);
		return;
	}

	info = &controllers[index];

	if (info->pending_cod_change) {
		info->pending_cod_change = FALSE;
		handle_pending_uuids(index);
	}

	mgmt_update_cod(index, buf, len);
}

static gboolean mgmt_event(GIOChannel *io, GIOCondition cond, gpointer user_data)
{
	char buf[MGMT_BUF_SIZE];
	struct mgmt_hdr *hdr = (void *) buf;
	int sk;
	ssize_t ret;
	uint16_t len, opcode, index;

	DBG("cond %d", cond);

	if (cond & G_IO_NVAL)
		return FALSE;

	sk = g_io_channel_unix_get_fd(io);

	if (cond & (G_IO_ERR | G_IO_HUP)) {
		error("Error on management socket");
		return FALSE;
	}

	ret = read(sk, buf, sizeof(buf));
	if (ret < 0) {
		error("Unable to read from management socket: %s (%d)",
						strerror(errno), errno);
		return TRUE;
	}

	DBG("Received %zd bytes from management socket", ret);

	if (ret < MGMT_HDR_SIZE) {
		error("Too small Management packet");
		return TRUE;
	}

	opcode = bt_get_le16(&hdr->opcode);
	len = bt_get_le16(&hdr->len);
	index = bt_get_le16(&hdr->index);

	if (ret != MGMT_HDR_SIZE + len) {
		error("Packet length mismatch. ret %zd len %u", ret, len);
		return TRUE;
	}

	switch (opcode) {
	case MGMT_EV_CMD_COMPLETE:
		mgmt_cmd_complete(sk, index, buf + MGMT_HDR_SIZE, len);
		break;
	case MGMT_EV_CMD_STATUS:
		mgmt_cmd_status(sk, index, buf + MGMT_HDR_SIZE, len);
		break;
	case MGMT_EV_CONTROLLER_ERROR:
		mgmt_controller_error(sk, index, buf + MGMT_HDR_SIZE, len);
		break;
	case MGMT_EV_INDEX_ADDED:
		mgmt_index_added(sk, index);
		break;
	case MGMT_EV_INDEX_REMOVED:
		mgmt_index_removed(sk, index);
		break;
	case MGMT_EV_NEW_SETTINGS:
		mgmt_new_settings(sk, index, buf + MGMT_HDR_SIZE, len);
		break;
	case MGMT_EV_CLASS_OF_DEV_CHANGED:
		mgmt_cod_changed(sk, index, buf + MGMT_HDR_SIZE, len);
		break;
	case MGMT_EV_NEW_LINK_KEY:
		mgmt_new_link_key(sk, index, buf + MGMT_HDR_SIZE, len);
		break;
	case MGMT_EV_DEVICE_CONNECTED:
		mgmt_device_connected(sk, index, buf + MGMT_HDR_SIZE, len);
		break;
	case MGMT_EV_DEVICE_DISCONNECTED:
		mgmt_device_disconnected(sk, index, buf + MGMT_HDR_SIZE, len);
		break;
	case MGMT_EV_CONNECT_FAILED:
		mgmt_connect_failed(sk, index, buf + MGMT_HDR_SIZE, len);
		break;
	case MGMT_EV_PIN_CODE_REQUEST:
		mgmt_pin_code_request(sk, index, buf + MGMT_HDR_SIZE, len);
		break;
	case MGMT_EV_USER_CONFIRM_REQUEST:
		mgmt_user_confirm_request(sk, index, buf + MGMT_HDR_SIZE, len);
		break;
	case MGMT_EV_AUTH_FAILED:
		mgmt_auth_failed(sk, index, buf + MGMT_HDR_SIZE, len);
		break;
	case MGMT_EV_LOCAL_NAME_CHANGED:
		mgmt_local_name_changed(sk, index, buf + MGMT_HDR_SIZE, len);
		break;
	case MGMT_EV_DEVICE_FOUND:
		mgmt_device_found(sk, index, buf + MGMT_HDR_SIZE, len);
		break;
	case MGMT_EV_DISCOVERING:
		mgmt_discovering(sk, index, buf + MGMT_HDR_SIZE, len);
		break;
	case MGMT_EV_DEVICE_BLOCKED:
		mgmt_device_blocked(sk, index, buf + MGMT_HDR_SIZE, len);
		break;
	case MGMT_EV_DEVICE_UNBLOCKED:
		mgmt_device_unblocked(sk, index, buf + MGMT_HDR_SIZE, len);
		break;
	case MGMT_EV_DEVICE_UNPAIRED:
		mgmt_device_unpaired(sk, index, buf + MGMT_HDR_SIZE, len);
		break;
	case MGMT_EV_USER_PASSKEY_REQUEST:
		mgmt_passkey_request(sk, index, buf + MGMT_HDR_SIZE, len);
		break;
	case MGMT_EV_PASSKEY_NOTIFY:
		mgmt_passkey_notify(sk, index, buf + MGMT_HDR_SIZE, len);
		break;
	case MGMT_EV_NEW_LONG_TERM_KEY:
		mgmt_new_ltk(sk, index, buf + MGMT_HDR_SIZE, len);
		break;
	default:
		error("Unknown Management opcode %u (index %u)", opcode, index);
		break;
	}

	return TRUE;
}

int mgmt_setup(void)
{
	struct mgmt_hdr hdr;
	struct sockaddr_hci addr;
	GIOChannel *io;
	GIOCondition condition;
	int dd, err;

	dd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
	if (dd < 0)
		return -errno;

	memset(&addr, 0, sizeof(addr));
	addr.hci_family = AF_BLUETOOTH;
	addr.hci_dev = HCI_DEV_NONE;
	addr.hci_channel = HCI_CHANNEL_CONTROL;

	if (bind(dd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		err = -errno;
		goto fail;
	}

	memset(&hdr, 0, sizeof(hdr));
	hdr.opcode = htobs(MGMT_OP_READ_VERSION);
	hdr.index = htobs(MGMT_INDEX_NONE);
	if (write(dd, &hdr, sizeof(hdr)) < 0) {
		err = -errno;
		goto fail;
	}

	io = g_io_channel_unix_new(dd);
	condition = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
	mgmt_watch = g_io_add_watch(io, condition, mgmt_event, NULL);
	g_io_channel_unref(io);

	mgmt_sock = dd;

	return 0;

fail:
	close(dd);
	return err;
}

void mgmt_cleanup(void)
{
	int index;

	for (index = 0; index <= max_index; index++) {
		struct controller_info *info = &controllers[index];

		if (!info->valid)
			continue;

		g_slist_free_full(info->pending_uuids, g_free);
	}

	g_free(controllers);
	controllers = NULL;
	max_index = -1;

	if (mgmt_sock >= 0) {
		close(mgmt_sock);
		mgmt_sock = -1;
	}

	if (mgmt_watch > 0) {
		g_source_remove(mgmt_watch);
		mgmt_watch = 0;
	}
}

int mgmt_start_discovery(int index)
{
	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_start_discovery)];
	struct mgmt_hdr *hdr = (void *) buf;
	struct mgmt_cp_start_discovery *cp = (void *) &buf[sizeof(*hdr)];
	struct controller_info *info = &controllers[index];

	DBG("index %d", index);

	info->discov_type = 0;

	if (mgmt_bredr(info->current_settings))
		hci_set_bit(BDADDR_BREDR, &info->discov_type);

	if (mgmt_low_energy(info->current_settings)) {
		hci_set_bit(BDADDR_LE_PUBLIC, &info->discov_type);
		hci_set_bit(BDADDR_LE_RANDOM, &info->discov_type);
	}

	memset(buf, 0, sizeof(buf));
	hdr->opcode = htobs(MGMT_OP_START_DISCOVERY);
	hdr->len = htobs(sizeof(*cp));
	hdr->index = htobs(index);

	cp->type = info->discov_type;

	if (write(mgmt_sock, buf, sizeof(buf)) < 0) {
		int err = -errno;
		error("failed to write to MGMT socket: %s", strerror(-err));
		return err;
	}

	return 0;
}

int mgmt_start_le_scanning(int index)
{
	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_start_discovery)];
	struct mgmt_hdr *hdr = (void *) buf;
	struct mgmt_cp_start_discovery *cp = (void *) &buf[sizeof(*hdr)];
	struct controller_info *info = &controllers[index];

	DBG("index %d", index);

	if (!mgmt_low_energy(info->current_settings)) {
		error("scanning failed: Low Energy not enabled/supported");
		return -ENOTSUP;
	}

	info->discov_type = 0;
	hci_set_bit(BDADDR_LE_PUBLIC, &info->discov_type);
	hci_set_bit(BDADDR_LE_RANDOM, &info->discov_type);

	memset(buf, 0, sizeof(buf));
	hdr->opcode = htobs(MGMT_OP_START_DISCOVERY);
	hdr->len = htobs(sizeof(*cp));
	hdr->index = htobs(index);

	cp->type = info->discov_type;

	if (write(mgmt_sock, buf, sizeof(buf)) < 0) {
		int err = -errno;
		error("failed to write to MGMT socket: %s", strerror(-err));
		return err;
	}

	return 0;
}

int mgmt_stop_discovery(int index)
{
	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_start_discovery)];
	struct mgmt_hdr *hdr = (void *) buf;
	struct mgmt_cp_start_discovery *cp = (void *) &buf[sizeof(*hdr)];
	struct controller_info *info = &controllers[index];

	DBG("index %d", index);

	memset(buf, 0, sizeof(buf));
	hdr->opcode = htobs(MGMT_OP_STOP_DISCOVERY);
	hdr->len = htobs(sizeof(*cp));
	hdr->index = htobs(index);

	cp->type = info->discov_type;

	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
		return -errno;

	return 0;
}

int mgmt_set_fast_connectable(int index, gboolean enable)
{
	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_mode)];
	struct mgmt_hdr *hdr = (void *) buf;
	struct mgmt_mode *cp = (void *) &buf[sizeof(*hdr)];

	DBG("index %d enable %d", index, enable);

	memset(buf, 0, sizeof(buf));
	hdr->opcode = htobs(MGMT_OP_SET_FAST_CONNECTABLE);
	hdr->len = htobs(sizeof(*cp));
	hdr->index = htobs(index);

	cp->val = enable;

	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
		return -errno;

	return 0;
}

int mgmt_read_clock(int index, const bdaddr_t *bdaddr, int which, int timeout,
					uint32_t *clock, uint16_t *accuracy)
{
	char addr[18];

	ba2str(bdaddr, addr);
	DBG("index %d addr %s which %d timeout %d", index, addr, which,
								timeout);

	return -ENOSYS;
}

int mgmt_read_bdaddr(int index, bdaddr_t *bdaddr)
{
	char addr[18];
	struct controller_info *info = &controllers[index];

	ba2str(&info->bdaddr, addr);
	DBG("index %d addr %s", index, addr);

	if (!info->valid)
		return -ENODEV;

	bacpy(bdaddr, &info->bdaddr);

	return 0;
}

int mgmt_block_device(int index, const bdaddr_t *bdaddr, uint8_t bdaddr_type)
{
	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_block_device)];
	struct mgmt_hdr *hdr = (void *) buf;
	struct mgmt_cp_block_device *cp;
	size_t buf_len;
	char addr[18];

	ba2str(bdaddr, addr);
	DBG("index %d addr %s", index, addr);

	memset(buf, 0, sizeof(buf));

	hdr->opcode = htobs(MGMT_OP_BLOCK_DEVICE);
	hdr->len = htobs(sizeof(*cp));
	hdr->index = htobs(index);

	cp = (void *) &buf[sizeof(*hdr)];
	bacpy(&cp->addr.bdaddr, bdaddr);
	cp->addr.type = bdaddr_type;

	buf_len = sizeof(*hdr) + sizeof(*cp);

	if (write(mgmt_sock, buf, buf_len) < 0)
		return -errno;

	return 0;
}

int mgmt_unblock_device(int index, const bdaddr_t *bdaddr, uint8_t bdaddr_type)
{
	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_unblock_device)];
	struct mgmt_hdr *hdr = (void *) buf;
	struct mgmt_cp_unblock_device *cp;
	size_t buf_len;
	char addr[18];

	ba2str(bdaddr, addr);
	DBG("index %d addr %s", index, addr);

	memset(buf, 0, sizeof(buf));

	hdr->opcode = htobs(MGMT_OP_UNBLOCK_DEVICE);
	hdr->len = htobs(sizeof(*cp));
	hdr->index = htobs(index);

	cp = (void *) &buf[sizeof(*hdr)];
	bacpy(&cp->addr.bdaddr, bdaddr);
	cp->addr.type = bdaddr_type;

	buf_len = sizeof(*hdr) + sizeof(*cp);

	if (write(mgmt_sock, buf, buf_len) < 0)
		return -errno;

	return 0;
}

int mgmt_get_conn_list(int index, GSList **conns)
{
	struct controller_info *info = &controllers[index];

	DBG("index %d", index);

	*conns = info->connections;
	info->connections = NULL;

	return 0;
}

int mgmt_disconnect(int index, const bdaddr_t *bdaddr, uint8_t bdaddr_type)
{
	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_disconnect)];
	struct mgmt_hdr *hdr = (void *) buf;
	struct mgmt_cp_disconnect *cp = (void *) &buf[sizeof(*hdr)];
	char addr[18];

	ba2str(bdaddr, addr);
	DBG("index %d %s", index, addr);

	memset(buf, 0, sizeof(buf));
	hdr->opcode = htobs(MGMT_OP_DISCONNECT);
	hdr->len = htobs(sizeof(*cp));
	hdr->index = htobs(index);

	bacpy(&cp->addr.bdaddr, bdaddr);
	cp->addr.type = bdaddr_type;

	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
		error("write: %s (%d)", strerror(errno), errno);

	return 0;
}

int mgmt_unpair_device(int index, const bdaddr_t *bdaddr, uint8_t bdaddr_type)
{
	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_unpair_device)];
	struct mgmt_hdr *hdr = (void *) buf;
	struct mgmt_cp_unpair_device *cp = (void *) &buf[sizeof(*hdr)];
	char addr[18];

	ba2str(bdaddr, addr);
	DBG("index %d addr %s", index, addr);

	memset(buf, 0, sizeof(buf));
	hdr->opcode = htobs(MGMT_OP_UNPAIR_DEVICE);
	hdr->len = htobs(sizeof(*cp));
	hdr->index = htobs(index);

	bacpy(&cp->addr.bdaddr, bdaddr);
	cp->addr.type = bdaddr_type;
	cp->disconnect = 1;

	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
		return -errno;

	return 0;
}

int mgmt_set_did(int index, uint16_t vendor, uint16_t product,
					uint16_t version, uint16_t source)
{
	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_set_device_id)];
	struct mgmt_hdr *hdr = (void *) buf;
	struct mgmt_cp_set_device_id *cp = (void *) &buf[sizeof(*hdr)];

	DBG("index %d source %x vendor %x product %x version %x",
				index, source, vendor, product, version);

	memset(buf, 0, sizeof(buf));
	hdr->opcode = htobs(MGMT_OP_SET_DEVICE_ID);
	hdr->len = htobs(sizeof(*cp));
	hdr->index = htobs(index);

	cp->source = htobs(source);
	cp->vendor = htobs(vendor);
	cp->product = htobs(product);
	cp->version = htobs(version);

	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
		return -errno;

	return 0;
}

int mgmt_load_link_keys(int index, GSList *keys, gboolean debug_keys)
{
	char *buf;
	struct mgmt_hdr *hdr;
	struct mgmt_cp_load_link_keys *cp;
	struct mgmt_link_key_info *key;
	size_t key_count, cp_size;
	GSList *l;
	int err;

	key_count = g_slist_length(keys);

	DBG("index %d keys %zu debug_keys %d", index, key_count, debug_keys);

	cp_size = sizeof(*cp) + (key_count * sizeof(*key));

	buf = g_try_malloc0(sizeof(*hdr) + cp_size);
	if (buf == NULL)
		return -ENOMEM;

	hdr = (void *) buf;
	hdr->opcode = htobs(MGMT_OP_LOAD_LINK_KEYS);
	hdr->len = htobs(cp_size);
	hdr->index = htobs(index);

	cp = (void *) (buf + sizeof(*hdr));
	cp->debug_keys = debug_keys;
	cp->key_count = htobs(key_count);

	for (l = keys, key = cp->keys; l != NULL; l = g_slist_next(l), key++) {
		struct link_key_info *info = l->data;

		bacpy(&key->addr.bdaddr, &info->bdaddr);
		key->addr.type = BDADDR_BREDR;
		key->type = info->type;
		memcpy(key->val, info->key, 16);
		key->pin_len = info->pin_len;
	}

	if (write(mgmt_sock, buf, sizeof(*hdr) + cp_size) < 0)
		err = -errno;
	else
		err = 0;

	g_free(buf);

	return err;
}

int mgmt_set_io_capability(int index, uint8_t io_capability)
{
	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_set_io_capability)];
	struct mgmt_hdr *hdr = (void *) buf;
	struct mgmt_cp_set_io_capability *cp = (void *) &buf[sizeof(*hdr)];

	DBG("hci%d io_capability 0x%02x", index, io_capability);

	memset(buf, 0, sizeof(buf));
	hdr->opcode = htobs(MGMT_OP_SET_IO_CAPABILITY);
	hdr->len = htobs(sizeof(*cp));
	hdr->index = htobs(index);

	cp->io_capability = io_capability;

	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
		return -errno;

	return 0;
}

int mgmt_create_bonding(int index, const bdaddr_t *bdaddr, uint8_t addr_type,
								uint8_t io_cap)
{
	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_pair_device)];
	struct mgmt_hdr *hdr = (void *) buf;
	struct mgmt_cp_pair_device *cp = (void *) &buf[sizeof(*hdr)];
	char addr[18];

	ba2str(bdaddr, addr);
	DBG("hci%d bdaddr %s type %d io_cap 0x%02x",
					index, addr, addr_type, io_cap);

	memset(buf, 0, sizeof(buf));
	hdr->opcode = htobs(MGMT_OP_PAIR_DEVICE);
	hdr->len = htobs(sizeof(*cp));
	hdr->index = htobs(index);

	bacpy(&cp->addr.bdaddr, bdaddr);
	cp->addr.type = addr_type;
	cp->io_cap = io_cap;

	if (write(mgmt_sock, &buf, sizeof(buf)) < 0)
		return -errno;

	return 0;
}

int mgmt_cancel_bonding(int index, const bdaddr_t *bdaddr, uint8_t addr_type)
{
	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_addr_info)];
	struct mgmt_hdr *hdr = (void *) buf;
	struct mgmt_addr_info *cp = (void *) &buf[sizeof(*hdr)];
	char addr[18];

	ba2str(bdaddr, addr);
	DBG("hci%d bdaddr %s type %d", index, addr, addr_type);

	memset(buf, 0, sizeof(buf));
	hdr->opcode = htobs(MGMT_OP_CANCEL_PAIR_DEVICE);
	hdr->len = htobs(sizeof(*cp));
	hdr->index = htobs(index);

	bacpy(&cp->bdaddr, bdaddr);
	cp->type = addr_type;

	if (write(mgmt_sock, &buf, sizeof(buf)) < 0)
		return -errno;

	return 0;
}

int mgmt_read_local_oob_data(int index)
{
	struct mgmt_hdr hdr;

	DBG("hci%d", index);

	hdr.opcode = htobs(MGMT_OP_READ_LOCAL_OOB_DATA);
	hdr.len = 0;
	hdr.index = htobs(index);

	if (write(mgmt_sock, &hdr, sizeof(hdr)) < 0)
		return -errno;

	return 0;
}

int mgmt_add_remote_oob_data(int index, const bdaddr_t *bdaddr,
					uint8_t *hash, uint8_t *randomizer)
{
	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_add_remote_oob_data)];
	struct mgmt_hdr *hdr = (void *) buf;
	struct mgmt_cp_add_remote_oob_data *cp = (void *) &buf[sizeof(*hdr)];
	char addr[18];

	ba2str(bdaddr, addr);
	DBG("hci%d bdaddr %s", index, addr);

	memset(buf, 0, sizeof(buf));

	hdr->opcode = htobs(MGMT_OP_ADD_REMOTE_OOB_DATA);
	hdr->index = htobs(index);
	hdr->len = htobs(sizeof(*cp));

	bacpy(&cp->addr.bdaddr, bdaddr);
	memcpy(cp->hash, hash, 16);

	if (randomizer)
		memcpy(cp->randomizer, randomizer, 16);

	if (write(mgmt_sock, &buf, sizeof(buf)) < 0)
		return -errno;

	return 0;
}

int mgmt_remove_remote_oob_data(int index, const bdaddr_t *bdaddr)
{
	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_remove_remote_oob_data)];
	struct mgmt_hdr *hdr = (void *) buf;
	struct mgmt_cp_remove_remote_oob_data *cp = (void *) &buf[sizeof(*hdr)];
	char addr[18];

	ba2str(bdaddr, addr);
	DBG("hci%d bdaddr %s", index, addr);

	memset(buf, 0, sizeof(buf));

	hdr->opcode = htobs(MGMT_OP_REMOVE_REMOTE_OOB_DATA);
	hdr->index = htobs(index);
	hdr->len = htobs(sizeof(*cp));

	bacpy(&cp->addr.bdaddr, bdaddr);

	if (write(mgmt_sock, &buf, sizeof(buf)) < 0)
		return -errno;

	return 0;
}

int mgmt_confirm_name(int index, const bdaddr_t *bdaddr, uint8_t bdaddr_type,
							gboolean name_known)
{
	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_confirm_name)];
	struct mgmt_hdr *hdr = (void *) buf;
	struct mgmt_cp_confirm_name *cp = (void *) &buf[sizeof(*hdr)];
	char addr[18];

	ba2str(bdaddr, addr);
	DBG("hci%d bdaddr %s name_known %u", index, addr, name_known);

	memset(buf, 0, sizeof(buf));

	hdr->opcode = htobs(MGMT_OP_CONFIRM_NAME);
	hdr->index = htobs(index);
	hdr->len = htobs(sizeof(*cp));

	bacpy(&cp->addr.bdaddr, bdaddr);
	cp->addr.type = bdaddr_type;
	cp->name_known = name_known;

	if (write(mgmt_sock, &buf, sizeof(buf)) < 0)
		return -errno;

	return 0;
}

int mgmt_load_ltks(int index, GSList *keys)
{
	char *buf;
	struct mgmt_hdr *hdr;
	struct mgmt_cp_load_long_term_keys *cp;
	struct mgmt_ltk_info *key;
	size_t key_count, cp_size;
	GSList *l;
	int err;

	key_count = g_slist_length(keys);

	DBG("index %d keys %zu", index, key_count);

	cp_size = sizeof(*cp) + (key_count * sizeof(*key));

	buf = g_try_malloc0(sizeof(*hdr) + cp_size);
	if (buf == NULL)
		return -ENOMEM;

	hdr = (void *) buf;
	hdr->opcode = htobs(MGMT_OP_LOAD_LONG_TERM_KEYS);
	hdr->len = htobs(cp_size);
	hdr->index = htobs(index);

	cp = (void *) (buf + sizeof(*hdr));
	cp->key_count = htobs(key_count);

	for (l = keys, key = cp->keys; l != NULL; l = g_slist_next(l), key++) {
		struct smp_ltk_info *info = l->data;

		bacpy(&key->addr.bdaddr, &info->bdaddr);
		key->addr.type = info->bdaddr_type;
		memcpy(key->val, info->val, sizeof(info->val));
		memcpy(key->rand, info->rand, sizeof(info->rand));
		memcpy(&key->ediv, &info->ediv, sizeof(key->ediv));
		key->authenticated = info->authenticated;
		key->master = info->master;
		key->enc_size = info->enc_size;
	}

	if (write(mgmt_sock, buf, sizeof(*hdr) + cp_size) < 0)
		err = -errno;
	else
		err = 0;

	g_free(buf);

	return err;
}

int mgmt_ssp_enabled(int index)
{
	struct controller_info *info = &controllers[index];

	return mgmt_ssp(info->current_settings);
}
