/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2013-2014  Intel Corporation. All rights reserved.
 *
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

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

#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <glib.h>

#include "lib/bluetooth.h"
#include "lib/sdp.h"
#include "lib/mgmt.h"
#include "src/shared/util.h"
#include "src/shared/mgmt.h"
#include "src/uuid-helper.h"
#include "src/eir.h"
#include "lib/sdp.h"
#include "lib/sdp_lib.h"
#include "src/sdp-client.h"
#include "src/sdpd.h"
#include "src/log.h"
#include "hal-msg.h"
#include "ipc-common.h"
#include "ipc.h"
#include "utils.h"
#include "bluetooth.h"

/*
 * bits in bitmask as defined in table 6.3 of Multi Profile Specification
 * HFP AG + A2DP SRC + AVRCP TG + PAN (NAP/PANU) + PBAP PSE
 */
#define MPS_DEFAULT_MPSD ((1ULL << 0) | (1ULL << 2) | (1ULL << 4) | \
				(1ULL << 6) | (1ULL << 8) | (1ULL << 10) | \
				(1ULL << 12) | (1ULL << 26) | (1ULL << 28) | \
				(1ULL << 30) | (1ULL << 32) | (1ULL << 34) | \
				(1ULL << 36))

/*
 * bits in bitmask as defined in table 6.4 of Multi Profile Specification
 * HFP AG + A2DP SRC + AVRCP TG + PAN (NAP/PANU) + PBAP PSE
 */
#define MPS_DEFAULT_MPMD ((1ULL << 1) | (1ULL << 3) | (1ULL << 5) | \
				(1ULL << 6) | (1ULL << 8) | (1ULL << 10) | \
				(1ULL << 12) | (1ULL << 15) | (1ULL << 18))

/*
 * bits in bitmask as defined in table 6.5 of Multi Profile Specification
 * Note that in this table spec starts bit positions from 1 (bit 0 unused?)
 */
#define MPS_DEFAULT_DEPS ((1 << 1) | (1 << 2) | (1 << 3))

/* MPSD bit dependent on HFP AG support */
#define MPS_MPSD_HFP_AG_DEP ((1ULL << 0) | (1ULL << 2) | (1ULL << 4) | \
				(1ULL << 6) | (1ULL << 8) | (1ULL << 10) | \
				(1ULL << 12) | (1ULL << 14) | (1ULL << 16) | \
				(1ULL << 18) | (1ULL << 26) | (1ULL << 28) | \
				(1ULL << 30))

/* MPMD bit dependent on HFP AG support */
#define MPS_MPMD_HFP_AG_DEP (1ULL << 6)

#define DEFAULT_ADAPTER_NAME "BlueZ for Android"

#define DUT_MODE_FILE "/sys/kernel/debug/bluetooth/hci%u/dut_mode"

#define SETTINGS_FILE ANDROID_STORAGEDIR"/settings"
#define DEVICES_FILE ANDROID_STORAGEDIR"/devices"
#define CACHE_FILE ANDROID_STORAGEDIR"/cache"

#define DEVICE_ID_SOURCE	0x0002	/* USB */
#define DEVICE_ID_VENDOR	0x1d6b	/* Linux Foundation */
#define DEVICE_ID_PRODUCT	0x0247	/* BlueZ for Android */

#define ADAPTER_MAJOR_CLASS 0x02 /* Phone */
#define ADAPTER_MINOR_CLASS 0x03 /* Smartphone */

/* Default to DisplayYesNo */
#define DEFAULT_IO_CAPABILITY 0x01

/* Default discoverable timeout 120sec as in Android */
#define DEFAULT_DISCOVERABLE_TIMEOUT 120

#define DEVICES_CACHE_MAX 300

#define BASELEN_PROP_CHANGED (sizeof(struct hal_ev_adapter_props_changed) \
					+ sizeof(struct hal_property))

#define BASELEN_REMOTE_DEV_PROP (sizeof(struct hal_ev_remote_device_props) \
					+ sizeof(struct hal_property))

#define SCAN_TYPE_NONE 0
#define SCAN_TYPE_BREDR (1 << BDADDR_BREDR)
#define SCAN_TYPE_LE ((1 << BDADDR_LE_PUBLIC) | (1 << BDADDR_LE_RANDOM))
#define SCAN_TYPE_DUAL (SCAN_TYPE_BREDR | SCAN_TYPE_LE)

#define BDADDR_LE (BDADDR_LE_RANDOM | BDADDR_LE_PUBLIC)

struct device {
	bdaddr_t bdaddr;
	uint8_t bdaddr_type;

	bool le;
	bool bredr;

	bool pairing;

	bool bredr_paired;
	bool bredr_bonded;
	bool le_paired;
	bool le_bonded;

	char *name;
	char *friendly_name;

	uint32_t class;
	int32_t rssi;

	time_t bredr_seen;
	time_t le_seen;

	GSList *uuids;

	bool found; /* if device is found in current discovery session */
	unsigned int confirm_id; /* mgtm command id if command pending */

	bool valid_remote_csrk;
	uint8_t remote_csrk[16];
	uint32_t remote_sign_cnt;

	bool valid_local_csrk;
	uint8_t local_csrk[16];
	uint32_t local_sign_cnt;
	uint16_t gatt_ccc;
};

struct browse_req {
	bdaddr_t bdaddr;
	GSList *uuids;
	int search_uuid;
	int reconnect_attempt;
};

static struct {
	uint16_t index;

	bdaddr_t bdaddr;
	uint32_t dev_class;

	char *name;

	uint32_t current_settings;
	uint32_t supported_settings;

	bool le_scanning;
	uint8_t cur_discovery_type;
	uint8_t exp_discovery_type;
	uint32_t discoverable_timeout;

	GSList *uuids;
} adapter = {
	.index = MGMT_INDEX_NONE,
	.dev_class = 0,
	.name = NULL,
	.current_settings = 0,
	.supported_settings = 0,
	.cur_discovery_type = SCAN_TYPE_NONE,
	.exp_discovery_type = SCAN_TYPE_NONE,
	.discoverable_timeout = DEFAULT_DISCOVERABLE_TIMEOUT,
	.uuids = NULL,
};

static const uint16_t uuid_list[] = {
	L2CAP_UUID,
	PNP_INFO_SVCLASS_ID,
	PUBLIC_BROWSE_GROUP,
	0
};

static uint16_t option_index = MGMT_INDEX_NONE;
static struct mgmt *mgmt_if = NULL;

static GSList *bonded_devices = NULL;
static GSList *cached_devices = NULL;

static bt_le_device_found gatt_device_found_cb = NULL;
static bt_le_discovery_stopped gatt_discovery_stopped_cb = NULL;

/* This list contains addresses which are asked for records */
static GSList *browse_reqs;

static struct ipc *hal_ipc = NULL;

static void mgmt_debug(const char *str, void *user_data)
{
	const char *prefix = user_data;
	info("%s%s", prefix, str);
}

static void store_adapter_config(void)
{
	GKeyFile *key_file;
	gsize length = 0;
	char addr[18];
	char *data;

	key_file = g_key_file_new();

	g_key_file_load_from_file(key_file, SETTINGS_FILE, 0, NULL);

	ba2str(&adapter.bdaddr, addr);

	g_key_file_set_string(key_file, "General", "Address", addr);
	g_key_file_set_string(key_file, "General", "Name", adapter.name);
	g_key_file_set_integer(key_file, "General", "DiscoverableTimeout",
						adapter.discoverable_timeout);

	data = g_key_file_to_data(key_file, &length, NULL);

	g_file_set_contents(SETTINGS_FILE, data, length, NULL);

	g_free(data);
	g_key_file_free(key_file);
}

static void load_adapter_config(void)
{
	GError *gerr = NULL;
	GKeyFile *key_file;
	char *str;

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

	str = g_key_file_get_string(key_file, "General", "Address", NULL);
	if (!str) {
		g_key_file_free(key_file);
		return;
	}

	str2ba(str, &adapter.bdaddr);
	g_free(str);

	adapter.name = g_key_file_get_string(key_file, "General", "Name", NULL);

	adapter.discoverable_timeout = g_key_file_get_integer(key_file,
				"General", "DiscoverableTimeout", &gerr);
	if (gerr) {
		adapter.discoverable_timeout = DEFAULT_DISCOVERABLE_TIMEOUT;
		g_error_free(gerr);
		gerr = NULL;
	}

	g_key_file_free(key_file);
}

static void store_device_info(struct device *dev, const char *path)
{
	GKeyFile *key_file;
	char addr[18];
	gsize length = 0;
	char **uuids = NULL;
	char *str;

	ba2str(&dev->bdaddr, addr);

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

	g_key_file_set_boolean(key_file, addr, "BREDR", dev->bredr);

	if (dev->le)
		g_key_file_set_integer(key_file, addr, "AddressType",
							dev->bdaddr_type);

	g_key_file_set_string(key_file, addr, "Name", dev->name);

	if (dev->friendly_name)
		g_key_file_set_string(key_file, addr, "FriendlyName",
							dev->friendly_name);
	else
		g_key_file_remove_key(key_file, addr, "FriendlyName", NULL);

	if (dev->class)
		g_key_file_set_integer(key_file, addr, "Class", dev->class);
	else
		g_key_file_remove_key(key_file, addr, "Class", NULL);

	if (dev->bredr_seen > dev->le_seen)
		g_key_file_set_integer(key_file, addr, "Timestamp",
							dev->bredr_seen);
	else
		g_key_file_set_integer(key_file, addr, "Timestamp",
								dev->le_seen);

	if (dev->uuids) {
		GSList *l;
		int i;

		uuids = g_new0(char *, g_slist_length(dev->uuids) + 1);

		for (i = 0, l = dev->uuids; l; l = g_slist_next(l), i++) {
			int j;
			uint8_t *u = l->data;
			char *uuid_str = g_malloc0(33);

			for (j = 0; j < 16; j++)
				sprintf(uuid_str + (j * 2), "%2.2X", u[j]);

			uuids[i] = uuid_str;
		}

		g_key_file_set_string_list(key_file, addr, "Services",
						(const char **)uuids, i);
	} else {
		g_key_file_remove_key(key_file, addr, "Services", NULL);
	}

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

	g_key_file_free(key_file);
	g_strfreev(uuids);
}

static void remove_device_info(struct device *dev, const char *path)
{
	GKeyFile *key_file;
	gsize length = 0;
	char addr[18];
	char *str;

	ba2str(&dev->bdaddr, addr);

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

	g_key_file_remove_group(key_file, addr, NULL);

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

	g_key_file_free(key_file);
}

static int device_match(gconstpointer a, gconstpointer b)
{
	const struct device *dev = a;
	const bdaddr_t *bdaddr = b;

	return bacmp(&dev->bdaddr, bdaddr);
}

static struct device *find_device(const bdaddr_t *bdaddr)
{
	GSList *l;

	l = g_slist_find_custom(bonded_devices, bdaddr, device_match);
	if (l)
		return l->data;

	l = g_slist_find_custom(cached_devices, bdaddr, device_match);
	if (l)
		return l->data;

	return NULL;
}

static void free_device(struct device *dev)
{
	if (dev->confirm_id)
		mgmt_cancel(mgmt_if, dev->confirm_id);

	g_free(dev->name);
	g_free(dev->friendly_name);
	g_slist_free_full(dev->uuids, g_free);
	g_free(dev);
}

static void cache_device(struct device *new_dev)
{
	struct device *dev;
	GSList *l;

	l = g_slist_find(cached_devices, new_dev);
	if (l) {
		cached_devices = g_slist_remove(cached_devices, new_dev);
		goto cache;
	}

	if (g_slist_length(cached_devices) < DEVICES_CACHE_MAX)
		goto cache;

	l = g_slist_last(cached_devices);
	dev = l->data;

	cached_devices = g_slist_remove(cached_devices, dev);
	remove_device_info(dev, CACHE_FILE);
	free_device(dev);

cache:
	cached_devices = g_slist_prepend(cached_devices, new_dev);
	store_device_info(new_dev, CACHE_FILE);
}

static struct device *create_device(const bdaddr_t *bdaddr, uint8_t bdaddr_type)
{
	struct device *dev;
	char addr[18];

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

	dev = g_new0(struct device, 1);

	bacpy(&dev->bdaddr, bdaddr);

	if (bdaddr_type == BDADDR_BREDR) {
		dev->bredr = true;
		dev->bredr_seen = time(NULL);
	} else {
		dev->le = true;
		dev->bdaddr_type = bdaddr_type;
		dev->le_seen = time(NULL);
	}

	/*
	 * Use address for name, will be change if one is present
	 * eg. in EIR or set by set_property.
	 */
	dev->name = g_strdup(addr);

	return dev;
}

static struct device *get_device(const bdaddr_t *bdaddr, uint8_t type)
{
	struct device *dev;

	dev = find_device(bdaddr);
	if (dev)
		return dev;

	dev = create_device(bdaddr, type);

	cache_device(dev);

	return dev;
}

static  void send_adapter_property(uint8_t type, uint16_t len, const void *val)
{
	uint8_t buf[BASELEN_PROP_CHANGED + len];
	struct hal_ev_adapter_props_changed *ev = (void *) buf;

	ev->status = HAL_STATUS_SUCCESS;
	ev->num_props = 1;
	ev->props[0].type = type;
	ev->props[0].len = len;
	memcpy(ev->props[0].val, val, len);

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
				HAL_EV_ADAPTER_PROPS_CHANGED, sizeof(buf), buf);
}

static void adapter_name_changed(const uint8_t *name)
{
	/* Android expects string value without NULL terminator */
	send_adapter_property(HAL_PROP_ADAPTER_NAME,
					strlen((const char *) name), name);
}

static void adapter_set_name(const uint8_t *name)
{
	if (!g_strcmp0(adapter.name, (const char *) name))
		return;

	DBG("%s", name);

	g_free(adapter.name);
	adapter.name = g_strdup((const char *) name);

	store_adapter_config();

	adapter_name_changed(name);
}

static void mgmt_local_name_changed_event(uint16_t index, uint16_t length,
					const void *param, void *user_data)
{
	const struct mgmt_cp_set_local_name *rp = param;

	if (length < sizeof(*rp)) {
		error("Wrong size of local name changed parameters");
		return;
	}

	adapter_set_name(rp->name);

	/* TODO Update services if needed */
}

static void powered_changed(void)
{
	struct hal_ev_adapter_state_changed ev;

	ev.state = (adapter.current_settings & MGMT_SETTING_POWERED) ?
						HAL_POWER_ON : HAL_POWER_OFF;

	DBG("%u", ev.state);

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
				HAL_EV_ADAPTER_STATE_CHANGED, sizeof(ev), &ev);
}

static uint8_t settings2scan_mode(void)
{
	bool connectable, discoverable;

	connectable = adapter.current_settings & MGMT_SETTING_CONNECTABLE;
	discoverable = adapter.current_settings & MGMT_SETTING_DISCOVERABLE;

	if (connectable && discoverable)
		return HAL_ADAPTER_SCAN_MODE_CONN_DISC;

	if (connectable)
		return HAL_ADAPTER_SCAN_MODE_CONN;

	return HAL_ADAPTER_SCAN_MODE_NONE;
}

static void scan_mode_changed(void)
{
	uint8_t mode;

	mode = settings2scan_mode();

	DBG("mode %u", mode);

	send_adapter_property(HAL_PROP_ADAPTER_SCAN_MODE, sizeof(mode), &mode);
}

static void adapter_class_changed(void)
{
	send_adapter_property(HAL_PROP_ADAPTER_CLASS, sizeof(adapter.dev_class),
							&adapter.dev_class);
}

static void settings_changed(uint32_t settings)
{
	uint32_t changed_mask;
	uint32_t scan_mode_mask;

	changed_mask = adapter.current_settings ^ settings;

	adapter.current_settings = settings;

	DBG("0x%08x", changed_mask);

	if (changed_mask & MGMT_SETTING_POWERED)
		powered_changed();

	scan_mode_mask = MGMT_SETTING_CONNECTABLE |
					MGMT_SETTING_DISCOVERABLE;

	/*
	 * Only when powered, the connectable and discoverable
	 * state changes should be communicated.
	 */
	if (adapter.current_settings & MGMT_SETTING_POWERED)
		if (changed_mask & scan_mode_mask)
			scan_mode_changed();
}

static void new_settings_callback(uint16_t index, uint16_t length,
					const void *param, void *user_data)
{
	uint32_t settings;

	if (length < sizeof(settings)) {
		error("Wrong size of new settings parameters");
		return;
	}

	settings = get_le32(param);

	DBG("settings: 0x%8.8x -> 0x%8.8x", adapter.current_settings,
								settings);

	if (settings == adapter.current_settings)
		return;

	settings_changed(settings);
}

static void mgmt_dev_class_changed_event(uint16_t index, uint16_t length,
					const void *param, void *user_data)
{
	const struct mgmt_cod *rp = param;
	uint32_t dev_class;

	if (length < sizeof(*rp)) {
		error("Wrong size of class of device changed parameters");
		return;
	}

	dev_class = rp->val[0] | (rp->val[1] << 8) | (rp->val[2] << 16);

	if (dev_class == adapter.dev_class)
		return;

	DBG("Class: 0x%06x", dev_class);

	adapter.dev_class = dev_class;

	adapter_class_changed();

	/* TODO: Gatt attrib set*/
}

void bt_store_gatt_ccc(const bdaddr_t *dst, uint16_t value)
{
	struct device *dev;
	GKeyFile *key_file;
	gsize length = 0;
	char addr[18];
	char *data;

	dev = find_device(dst);
	if (!dev)
		return;

	key_file = g_key_file_new();

	if (!g_key_file_load_from_file(key_file, DEVICES_FILE, 0, NULL)) {
		g_key_file_free(key_file);
		return;
	}

	ba2str(dst, addr);

	DBG("%s Gatt CCC %d", addr, value);

	g_key_file_set_integer(key_file, addr, "GattCCC", value);

	data = g_key_file_to_data(key_file, &length, NULL);
	g_file_set_contents(DEVICES_FILE, data, length, NULL);
	g_free(data);

	g_key_file_free(key_file);

	dev->gatt_ccc = value;
}

uint16_t bt_get_gatt_ccc(const bdaddr_t *addr)
{
	struct device *dev;

	dev = find_device(addr);
	if (!dev)
		return 0;

	return dev->gatt_ccc;
}

static void store_link_key(const bdaddr_t *dst, const uint8_t *key,
					uint8_t type, uint8_t pin_length)
{
	GKeyFile *key_file;
	char key_str[33];
	gsize length = 0;
	char addr[18];
	char *data;
	int i;

	key_file = g_key_file_new();

	if (!g_key_file_load_from_file(key_file, DEVICES_FILE, 0, NULL)) {
		g_key_file_free(key_file);
		return;
	}

	ba2str(dst, addr);

	DBG("%s type %u pin_len %u", addr, type, pin_length);

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

	g_key_file_set_string(key_file, addr, "LinkKey", key_str);
	g_key_file_set_integer(key_file, addr, "LinkKeyType", type);
	g_key_file_set_integer(key_file, addr, "LinkKeyPinLength", pin_length);

	data = g_key_file_to_data(key_file, &length, NULL);
	g_file_set_contents(DEVICES_FILE, data, length, NULL);
	g_free(data);

	g_key_file_free(key_file);
}

static void send_bond_state_change(const bdaddr_t *addr, uint8_t status,
								uint8_t state)
{
	struct hal_ev_bond_state_changed ev;

	ev.status = status;
	ev.state = state;
	bdaddr2android(addr, ev.bdaddr);

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
				HAL_EV_BOND_STATE_CHANGED, sizeof(ev), &ev);
}

static void update_bredr_state(struct device *dev, bool pairing, bool paired,
								bool bonded)
{
	if (pairing == dev->pairing && paired == dev->bredr_paired &&
						bonded == dev->bredr_bonded)
		return;

	/* avoid unpairing device on incoming pairing request */
	if (pairing && dev->bredr_paired)
		goto done;

	/* avoid unpairing device if pairing failed */
	if (!pairing && !paired && dev->pairing && dev->bredr_paired)
		goto done;

	if (paired && !dev->le_paired) {
		cached_devices = g_slist_remove(cached_devices, dev);
		bonded_devices = g_slist_prepend(bonded_devices, dev);
		remove_device_info(dev, CACHE_FILE);
		store_device_info(dev, DEVICES_FILE);
	} else if (!paired && !dev->le_paired) {
		bonded_devices = g_slist_remove(bonded_devices, dev);
		remove_device_info(dev, DEVICES_FILE);
		cache_device(dev);
	}

	dev->bredr_paired = paired;
	dev->bredr_bonded = bonded;

done:
	dev->pairing = pairing;
}

static void update_le_state(struct device *dev, bool pairing, bool paired,
								bool bonded)
{
	if (pairing == dev->pairing && paired == dev->le_paired &&
						bonded == dev->le_bonded)
		return;

	/* avoid unpairing device on incoming pairing request */
	if (pairing && dev->le_paired)
		goto done;

	/* avoid unpairing device if pairing failed */
	if (!pairing && !paired && dev->pairing && dev->le_paired)
		goto done;

	if (paired && !dev->bredr_paired) {
		cached_devices = g_slist_remove(cached_devices, dev);
		bonded_devices = g_slist_prepend(bonded_devices, dev);
		remove_device_info(dev, CACHE_FILE);
		store_device_info(dev, DEVICES_FILE);
	} else if (!paired && !dev->bredr_paired) {
		bonded_devices = g_slist_remove(bonded_devices, dev);
		remove_device_info(dev, DEVICES_FILE);
		dev->valid_local_csrk = false;
		dev->valid_remote_csrk = false;
		dev->local_sign_cnt = 0;
		dev->remote_sign_cnt = 0;
		memset(dev->local_csrk, 0, sizeof(dev->local_csrk));
		memset(dev->remote_csrk, 0, sizeof(dev->remote_csrk));
		cache_device(dev);
	}

	dev->le_paired = paired;
	dev->le_bonded = bonded;

done:
	dev->pairing = pairing;
}

static uint8_t device_bond_state(struct device *dev)
{
	if (dev->pairing)
		return HAL_BOND_STATE_BONDING;

	/*
	 * We are checking for paired here instead of bonded as HAL API is
	 * using BOND state also if there was no bonding pairing.
	 */
	if (dev->bredr_paired || dev->le_paired)
		return HAL_BOND_STATE_BONDED;

	return HAL_BOND_STATE_NONE;
}

static void update_device_state(struct device *dev, uint8_t addr_type,
				uint8_t status, bool pairing, bool paired,
				bool bonded)
{
	uint8_t old_bond, new_bond;

	old_bond = device_bond_state(dev);

	if (addr_type == BDADDR_BREDR)
		update_bredr_state(dev, pairing, paired, bonded);
	else
		update_le_state(dev, pairing, paired, bonded);

	new_bond = device_bond_state(dev);

	if (old_bond != new_bond)
		send_bond_state_change(&dev->bdaddr, status, new_bond);
}

static void send_device_property(struct device *dev, uint8_t type,
						uint16_t len, const void *val)
{
	uint8_t buf[BASELEN_REMOTE_DEV_PROP + len];
	struct hal_ev_remote_device_props *ev = (void *) buf;

	ev->status = HAL_STATUS_SUCCESS;
	bdaddr2android(&dev->bdaddr, ev->bdaddr);
	ev->num_props = 1;
	ev->props[0].type = type;
	ev->props[0].len = len;
	memcpy(ev->props[0].val, val, len);

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
				HAL_EV_REMOTE_DEVICE_PROPS, sizeof(buf), buf);
}

static void send_device_uuids_notif(struct device *dev)
{
	uint8_t buf[sizeof(uint128_t) * g_slist_length(dev->uuids)];
	uint8_t *ptr = buf;
	GSList *l;

	for (l = dev->uuids; l; l = g_slist_next(l)) {
		memcpy(ptr, l->data, sizeof(uint128_t));
		ptr += sizeof(uint128_t);
	}

	send_device_property(dev, HAL_PROP_DEVICE_UUIDS, sizeof(buf), buf);
}

static void set_device_uuids(struct device *dev, GSList *uuids)
{
	g_slist_free_full(dev->uuids, g_free);
	dev->uuids = uuids;

	if (dev->le_paired || dev->bredr_paired)
		store_device_info(dev, DEVICES_FILE);
	else
		store_device_info(dev, CACHE_FILE);

	send_device_uuids_notif(dev);
}

static void browse_req_free(struct browse_req *req)
{
	g_slist_free_full(req->uuids, g_free);
	g_free(req);
}

static int uuid_128_cmp(gconstpointer a, gconstpointer b)
{
	return memcmp(a, b, sizeof(uint128_t));
}

static void update_records(struct browse_req *req, sdp_list_t *recs)
{
	for (; recs; recs = recs->next) {
		sdp_record_t *rec = (sdp_record_t *) recs->data;
		sdp_list_t *svcclass = NULL;
		uuid_t uuid128;
		uuid_t *tmp;
		uint8_t *new_uuid;

		if (!rec)
			break;

		if (sdp_get_service_classes(rec, &svcclass) < 0)
			continue;

		if (!svcclass)
			continue;

		tmp = svcclass->data;

		switch (tmp->type) {
		case SDP_UUID16:
			sdp_uuid16_to_uuid128(&uuid128, tmp);
			break;
		case SDP_UUID32:
			sdp_uuid32_to_uuid128(&uuid128, tmp);
			break;
		case SDP_UUID128:
			memcpy(&uuid128, tmp, sizeof(uuid_t));
			break;
		default:
			sdp_list_free(svcclass, free);
			continue;
		}

		new_uuid = g_malloc(16);/* size of 128 bit uuid */
		memcpy(new_uuid, &uuid128.value.uuid128,
				sizeof(uuid128.value.uuid128));

		/* Check if uuid is already added */
		if (g_slist_find_custom(req->uuids, new_uuid, uuid_128_cmp))
			g_free(new_uuid);
		else
			req->uuids = g_slist_append(req->uuids, new_uuid);

		sdp_list_free(svcclass, free);
	}
}

static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
{
	struct browse_req *req = user_data;
	struct device *dev;
	uuid_t uuid;

	/*
	 * If we have a valid response and req->search_uuid == 2, then L2CAP
	 * UUID & PNP searching was successful -- we are done
	 */
	if (err < 0 || req->search_uuid == 2) {
		if (err == -ECONNRESET && req->reconnect_attempt < 1) {
			req->search_uuid--;
			req->reconnect_attempt++;
		} else {
			goto done;
		}
	}

	update_records(req, recs);

	/* Search for mandatory uuids */
	if (uuid_list[req->search_uuid]) {
		sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
		bt_search_service(&adapter.bdaddr, &req->bdaddr, &uuid,
						browse_cb, user_data, NULL, 0);
		return;
	}

done:
	dev = find_device(&req->bdaddr);
	if (dev) {
		set_device_uuids(dev, req->uuids);
		req->uuids = NULL;
	}

	browse_reqs = g_slist_remove(browse_reqs, req);
	browse_req_free(req);
}

static int req_cmp(gconstpointer a, gconstpointer b)
{
	const struct browse_req *req = a;
	const bdaddr_t *bdaddr = b;

	return bacmp(&req->bdaddr, bdaddr);
}

static uint8_t browse_remote_sdp(const bdaddr_t *addr)
{
	struct browse_req *req;
	uuid_t uuid;

	if (g_slist_find_custom(browse_reqs, addr, req_cmp))
		return HAL_STATUS_SUCCESS;

	req = g_new0(struct browse_req, 1);
	bacpy(&req->bdaddr, addr);
	sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);

	if (bt_search_service(&adapter.bdaddr,
			&req->bdaddr, &uuid, browse_cb, req, NULL , 0) < 0) {
		browse_req_free(req);
		return HAL_STATUS_FAILED;
	}

	browse_reqs = g_slist_append(browse_reqs, req);

	return HAL_STATUS_SUCCESS;
}

static void new_link_key_callback(uint16_t index, uint16_t length,
					const void *param, void *user_data)
{
	const struct mgmt_ev_new_link_key *ev = param;
	const struct mgmt_addr_info *addr = &ev->key.addr;
	struct device *dev;
	char dst[18];

	if (length < sizeof(*ev)) {
		error("Too small new link key event");
		return;
	}

	ba2str(&addr->bdaddr, dst);

	DBG("new key for %s type %u pin_len %u",
					dst, ev->key.type, ev->key.pin_len);

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

	dev = find_device(&ev->key.addr.bdaddr);
	if (!dev)
		return;

	update_device_state(dev, ev->key.addr.type, HAL_STATUS_SUCCESS, false,
							true, !!ev->store_hint);

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

		store_link_key(&addr->bdaddr, key->val, key->type,
								key->pin_len);
	}

	browse_remote_sdp(&addr->bdaddr);
}

static uint8_t get_device_name(struct device *dev)
{
	send_device_property(dev, HAL_PROP_DEVICE_NAME,
						strlen(dev->name), dev->name);

	return HAL_STATUS_SUCCESS;
}

static void pin_code_request_callback(uint16_t index, uint16_t length,
					const void *param, void *user_data)
{
	const struct mgmt_ev_pin_code_request *ev = param;
	struct hal_ev_pin_request hal_ev;
	struct device *dev;
	char dst[18];

	if (length < sizeof(*ev)) {
		error("Too small PIN code request event");
		return;
	}

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

	dev = get_device(&ev->addr.bdaddr, BDADDR_BREDR);

	/*
	 * Workaround for Android Bluetooth.apk issue: send remote
	 * device property
	 */
	get_device_name(dev);

	update_device_state(dev, ev->addr.type, HAL_STATUS_SUCCESS, true,
								false, false);

	DBG("%s type %u secure %u", dst, ev->addr.type, ev->secure);

	/* Name already sent in remote device prop */
	memset(&hal_ev, 0, sizeof(hal_ev));
	bdaddr2android(&ev->addr.bdaddr, hal_ev.bdaddr);
	hal_ev.class_of_dev = dev->class;

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_EV_PIN_REQUEST,
						sizeof(hal_ev), &hal_ev);
}

static void send_ssp_request(struct device *dev, uint8_t variant,
							uint32_t passkey)
{
	struct hal_ev_ssp_request ev;

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

	bdaddr2android(&dev->bdaddr, ev.bdaddr);
	memcpy(ev.name, dev->name, strlen(dev->name));
	ev.class_of_dev = dev->class;

	ev.pairing_variant = variant;
	ev.passkey = passkey;

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_EV_SSP_REQUEST,
							sizeof(ev), &ev);
}

static void user_confirm_request_callback(uint16_t index, uint16_t length,
					const void *param, void *user_data)
{
	const struct mgmt_ev_user_confirm_request *ev = param;
	struct device *dev;
	char dst[18];

	if (length < sizeof(*ev)) {
		error("Too small user confirm request event");
		return;
	}

	ba2str(&ev->addr.bdaddr, dst);
	DBG("%s confirm_hint %u", dst, ev->confirm_hint);

	dev = find_device(&ev->addr.bdaddr);
	if (!dev)
		return;

	update_device_state(dev, ev->addr.type, HAL_STATUS_SUCCESS, true,
								false, false);

	if (ev->confirm_hint)
		send_ssp_request(dev, HAL_SSP_VARIANT_CONSENT, 0);
	else
		send_ssp_request(dev, HAL_SSP_VARIANT_CONFIRM, ev->value);
}

static void user_passkey_request_callback(uint16_t index, uint16_t length,
					const void *param, void *user_data)
{
	const struct mgmt_ev_user_passkey_request *ev = param;
	struct device *dev;
	char dst[18];

	if (length < sizeof(*ev)) {
		error("Too small passkey request event");
		return;
	}

	ba2str(&ev->addr.bdaddr, dst);
	DBG("%s", dst);

	dev = find_device(&ev->addr.bdaddr);
	if (!dev)
		return;

	update_device_state(dev, ev->addr.type, HAL_STATUS_SUCCESS, true,
								false, false);

	send_ssp_request(dev, HAL_SSP_VARIANT_ENTRY, 0);
}

static void user_passkey_notify_callback(uint16_t index, uint16_t length,
							const void *param,
							void *user_data)
{
	const struct mgmt_ev_passkey_notify *ev = param;
	struct device *dev;
	char dst[18];

	if (length < sizeof(*ev)) {
		error("Too small passkey notify event");
		return;
	}

	ba2str(&ev->addr.bdaddr, dst);
	DBG("%s entered %u", dst, ev->entered);

	/* HAL seems to not support entered characters */
	if (ev->entered)
		return;

	dev = find_device(&ev->addr.bdaddr);
	if (!dev)
		return;

	update_device_state(dev, ev->addr.type, HAL_STATUS_SUCCESS, true,
								false, false);

	send_ssp_request(dev, HAL_SSP_VARIANT_NOTIF, ev->passkey);
}

static void clear_device_found(gpointer data, gpointer user_data)
{
	struct device *dev = data;

	dev->found = false;
}

static uint8_t get_supported_discovery_type(void)
{
	uint8_t type = SCAN_TYPE_NONE;

	if (adapter.current_settings & MGMT_SETTING_BREDR)
		type |= SCAN_TYPE_BREDR;

	if (adapter.current_settings & MGMT_SETTING_LE)
		type |= SCAN_TYPE_LE;

	return type;
}

static bool start_discovery(uint8_t type)
{
	struct mgmt_cp_start_discovery cp;

	cp.type = get_supported_discovery_type() & type;

	DBG("type=0x%x", cp.type);

	if (cp.type == SCAN_TYPE_NONE)
		return false;

	if (mgmt_send(mgmt_if, MGMT_OP_START_DISCOVERY, adapter.index,
				sizeof(cp), &cp, NULL, NULL, NULL) > 0)
		return true;

	error("Failed to start discovery");

	return false;
}

/*
 * Send discovery state change event only if it is related to dual type
 * discovery session (triggered by start/cancel discovery commands)
 */
static void check_discovery_state(uint8_t new_type, uint8_t old_type)
{
	struct hal_ev_discovery_state_changed ev;

	DBG("%u %u", new_type, old_type);

	if (new_type == get_supported_discovery_type()) {
		g_slist_foreach(bonded_devices, clear_device_found, NULL);
		g_slist_foreach(cached_devices, clear_device_found, NULL);
		ev.state = HAL_DISCOVERY_STATE_STARTED;
		goto done;
	}

	if (old_type != get_supported_discovery_type())
		return;

	ev.state = HAL_DISCOVERY_STATE_STOPPED;

done:
	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
			HAL_EV_DISCOVERY_STATE_CHANGED, sizeof(ev), &ev);
}

static void mgmt_discovering_event(uint16_t index, uint16_t length,
					const void *param, void *user_data)
{
	const struct mgmt_ev_discovering *ev = param;
	uint8_t type;

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

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

	if (!!adapter.cur_discovery_type == !!ev->discovering)
		return;

	type = ev->discovering ? ev->type : SCAN_TYPE_NONE;

	check_discovery_state(type, adapter.cur_discovery_type);

	adapter.cur_discovery_type = type;

	if (ev->discovering) {
		adapter.exp_discovery_type = adapter.le_scanning ?
						SCAN_TYPE_LE : SCAN_TYPE_NONE;
		return;
	}

	/* One shot notification about discovery stopped */
	if (gatt_discovery_stopped_cb) {
		gatt_discovery_stopped_cb();
		gatt_discovery_stopped_cb = NULL;
	}

	type = adapter.exp_discovery_type;
	adapter.exp_discovery_type = adapter.le_scanning ? SCAN_TYPE_LE :
								SCAN_TYPE_NONE;

	if (type != SCAN_TYPE_NONE)
		start_discovery(type);
}

static void confirm_device_name_cb(uint8_t status, uint16_t length,
					const void *param, void *user_data)
{
	const struct mgmt_rp_confirm_name *rp = param;
	struct device *dev;

	DBG("Confirm name status: %s (0x%02x)", mgmt_errstr(status), status);

	if (length < sizeof(*rp)) {
		error("Wrong size of confirm name response");
		return;
	}

	dev = find_device(&rp->addr.bdaddr);
	if (!dev)
		return;

	dev->confirm_id = 0;
}

static unsigned int confirm_device_name(const bdaddr_t *addr, uint8_t addr_type,
							bool resolve_name)
{
	struct mgmt_cp_confirm_name cp;
	unsigned int res;

	memset(&cp, 0, sizeof(cp));
	bacpy(&cp.addr.bdaddr, addr);
	cp.addr.type = addr_type;

	if (!resolve_name)
		cp.name_known = 1;

	res = mgmt_send(mgmt_if, MGMT_OP_CONFIRM_NAME, adapter.index,
				sizeof(cp), &cp, confirm_device_name_cb,
				NULL, NULL);
	if (!res)
		error("Failed to send confirm name request");

	return res;
}

static int fill_hal_prop(void *buf, uint8_t type, uint16_t len,
							const void *val)
{
	struct hal_property *prop = buf;

	prop->type = type;
	prop->len = len;

	if (len)
		memcpy(prop->val, val, len);

	return sizeof(*prop) + len;
}

static uint8_t get_device_android_type(struct device *dev)
{
	if (dev->bredr && dev->le)
		return HAL_TYPE_DUAL;

	if (dev->le)
		return HAL_TYPE_LE;

	return HAL_TYPE_BREDR;
}

uint8_t bt_get_device_android_type(const bdaddr_t *addr)
{
	struct device *dev;

	dev = get_device(addr, BDADDR_BREDR);

	return get_device_android_type(dev);
}

bool bt_is_device_le(const bdaddr_t *addr)
{
	struct device *dev;

	dev = find_device(addr);
	if (!dev)
		return false;

	return dev->le;
}

const char *bt_get_adapter_name(void)
{
	return adapter.name;
}

bool bt_device_is_bonded(const bdaddr_t *bdaddr)
{
	if (g_slist_find_custom(bonded_devices, bdaddr, device_match))
		return true;

	return false;
}

bool bt_device_set_uuids(const bdaddr_t *addr, GSList *uuids)
{
	struct device *dev;

	dev = find_device(addr);
	if (!dev)
		return false;

	set_device_uuids(dev, uuids);

	return true;
}

static bool rssi_above_threshold(int old, int new)
{
	/* only 8 dBm or more */
	return abs(old - new) >= 8;
}

static void update_new_device(struct device *dev, int8_t rssi,
						const struct eir_data *eir)
{
	uint8_t buf[IPC_MTU];
	struct hal_ev_device_found *ev = (void *) buf;
	bdaddr_t android_bdaddr;
	uint8_t android_type;
	int size;

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

	if (adapter.cur_discovery_type)
		dev->found = true;

	size = sizeof(*ev);

	bdaddr2android(&dev->bdaddr, &android_bdaddr);
	size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_ADDR,
						sizeof(android_bdaddr),
						&android_bdaddr);
	ev->num_props++;

	android_type = get_device_android_type(dev);
	size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_TYPE,
				sizeof(android_type), &android_type);
	ev->num_props++;

	if (eir->class)
		dev->class = eir->class;

	if (dev->class) {
		size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_CLASS,
					sizeof(dev->class), &dev->class);
		ev->num_props++;
	}

	if (rssi && rssi_above_threshold(dev->rssi, rssi))
		dev->rssi = rssi;

	if (dev->rssi) {
		size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_RSSI,
						sizeof(dev->rssi), &dev->rssi);
		ev->num_props++;
	}

	if (eir->name && strlen(eir->name)) {
		g_free(dev->name);
		dev->name = g_strdup(eir->name);
	}

	if (dev->name) {
		size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_NAME,
						strlen(dev->name), dev->name);
		ev->num_props++;

		/* when updating name also send stored friendly name */
		if (dev->friendly_name) {
			size += fill_hal_prop(buf + size,
						HAL_PROP_DEVICE_FRIENDLY_NAME,
						strlen(dev->friendly_name),
						dev->friendly_name);
			ev->num_props++;
		}
	}

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_EV_DEVICE_FOUND,
								size, buf);
}

static void update_device(struct device *dev, int8_t rssi,
				const struct eir_data *eir, uint8_t bdaddr_type)
{
	uint8_t buf[IPC_MTU];
	struct hal_ev_remote_device_props *ev = (void *) buf;
	uint8_t old_type, new_type;
	int size;

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

	size = sizeof(*ev);

	ev->status = HAL_STATUS_SUCCESS;
	bdaddr2android(&dev->bdaddr, ev->bdaddr);

	old_type = get_device_android_type(dev);

	if (bdaddr_type == BDADDR_BREDR) {
		dev->bredr = true;
	} else {
		dev->le = true;
		dev->bdaddr_type = bdaddr_type;
	}

	new_type = get_device_android_type(dev);

	if (old_type != new_type) {
		size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_TYPE,
						sizeof(new_type), &new_type);
		ev->num_props++;
	}

	if (eir->class && dev->class != eir->class) {
		dev->class = eir->class;
		size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_CLASS,
					sizeof(dev->class), &dev->class);
		ev->num_props++;
	}

	if (rssi && rssi_above_threshold(dev->rssi, rssi)) {
		dev->rssi = rssi;
		size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_RSSI,
						sizeof(dev->rssi), &dev->rssi);
		ev->num_props++;
	}

	if (eir->name && strlen(eir->name) && strcmp(dev->name, eir->name)) {
		g_free(dev->name);
		dev->name = g_strdup(eir->name);
		size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_NAME,
						strlen(dev->name), dev->name);
		ev->num_props++;

		/* when updating name also send stored friendly name */
		if (dev->friendly_name) {
			size += fill_hal_prop(buf + size,
						HAL_PROP_DEVICE_FRIENDLY_NAME,
						strlen(dev->friendly_name),
						dev->friendly_name);
			ev->num_props++;
		}
	}

	if (ev->num_props)
		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
					HAL_EV_REMOTE_DEVICE_PROPS, size, buf);
}

static bool is_new_device(const struct device *dev, unsigned int flags)
{
	if (dev->found)
		return false;

	if (dev->bredr_paired || dev->le_paired)
		return false;

	if (dev->bdaddr_type != BDADDR_BREDR &&
				!(flags & (EIR_LIM_DISC | EIR_GEN_DISC)))
		return false;

	return true;
}

static void update_found_device(const bdaddr_t *bdaddr, uint8_t bdaddr_type,
					int8_t rssi, bool confirm,
					const uint8_t *data, uint8_t data_len)
{
	struct eir_data eir;
	struct device *dev;

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

	eir_parse(&eir, data, data_len);

	dev = get_device(bdaddr, bdaddr_type);

	if (bdaddr_type == BDADDR_BREDR)
		dev->bredr_seen = time(NULL);
	else
		dev->le_seen = time(NULL);

	/*
	 * Device found event needs to be send also for known device if this is
	 * new discovery session. Otherwise framework will ignore it.
	 */
	if (is_new_device(dev, eir.flags))
		update_new_device(dev, rssi, &eir);
	else
		update_device(dev, rssi, &eir, bdaddr_type);

	eir_data_free(&eir);

	/* Notify Gatt if its registered for LE events */
	if (bdaddr_type != BDADDR_BREDR && gatt_device_found_cb) {
		bool discoverable;

		discoverable = eir.flags & (EIR_LIM_DISC | EIR_GEN_DISC);

		gatt_device_found_cb(bdaddr, bdaddr_type, rssi, data_len, data,
								discoverable,
								dev->le_bonded);
	}

	if (!dev->bredr_paired && !dev->le_paired)
		cache_device(dev);

	if (confirm) {
		char addr[18];
		bool resolve_name = true;

		ba2str(bdaddr, addr);

		/*
		 * Don't need to confirm name if we have it already in cache
		 * Just check if device name is different than bdaddr
		 */
		if (g_strcmp0(dev->name, addr)) {
			get_device_name(dev);
			resolve_name = false;
		}

		info("Device %s needs name confirmation (resolve_name=%d)",
							addr, resolve_name);
		dev->confirm_id = confirm_device_name(bdaddr, bdaddr_type,
								resolve_name);
	}
}

static void mgmt_device_found_event(uint16_t index, uint16_t length,
					const void *param, void *user_data)
{
	const struct mgmt_ev_device_found *ev = param;
	const uint8_t *eir;
	uint16_t eir_len;
	uint32_t flags;
	bool confirm_name;
	char addr[18];

	if (length < sizeof(*ev)) {
		error("Too short device found event (%u bytes)", length);
		return;
	}

	eir_len = btohs(ev->eir_len);
	if (length != sizeof(*ev) + eir_len) {
		error("Device found event size mismatch (%u != %zu)",
					length, sizeof(*ev) + eir_len);
		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;

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

static void mgmt_device_connected_event(uint16_t index, uint16_t length,
					const void *param, void *user_data)
{
	const struct mgmt_ev_device_connected *ev = param;
	struct hal_ev_acl_state_changed hal_ev;

	if (length < sizeof(*ev)) {
		error("Too short device connected event (%u bytes)", length);
		return;
	}

	update_found_device(&ev->addr.bdaddr, ev->addr.type, 0, false,
					&ev->eir[0], btohs(ev->eir_len));

	hal_ev.status = HAL_STATUS_SUCCESS;
	hal_ev.state = HAL_ACL_STATE_CONNECTED;
	bdaddr2android(&ev->addr.bdaddr, hal_ev.bdaddr);

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
			HAL_EV_ACL_STATE_CHANGED, sizeof(hal_ev), &hal_ev);
}

static void mgmt_device_disconnected_event(uint16_t index, uint16_t length,
							const void *param,
							void *user_data)
{
	const struct mgmt_ev_device_disconnected *ev = param;
	struct hal_ev_acl_state_changed hal_ev;

	if (length < sizeof(*ev)) {
		error("Too short device disconnected event (%u bytes)", length);
		return;
	}

	hal_ev.status = HAL_STATUS_SUCCESS;
	hal_ev.state = HAL_ACL_STATE_DISCONNECTED;
	bdaddr2android(&ev->addr.bdaddr, hal_ev.bdaddr);

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
			HAL_EV_ACL_STATE_CHANGED, sizeof(hal_ev), &hal_ev);
}

static uint8_t status_mgmt2hal(uint8_t mgmt)
{
	switch (mgmt) {
	case MGMT_STATUS_SUCCESS:
		return HAL_STATUS_SUCCESS;
	case MGMT_STATUS_NO_RESOURCES:
		return HAL_STATUS_NOMEM;
	case MGMT_STATUS_BUSY:
		return HAL_STATUS_BUSY;
	case MGMT_STATUS_NOT_SUPPORTED:
		return HAL_STATUS_UNSUPPORTED;
	case MGMT_STATUS_INVALID_PARAMS:
		return HAL_STATUS_INVALID;
	case MGMT_STATUS_AUTH_FAILED:
		return HAL_STATUS_AUTH_FAILURE;
	case MGMT_STATUS_NOT_CONNECTED:
		return HAL_STATUS_REMOTE_DEVICE_DOWN;
	default:
		return HAL_STATUS_FAILED;
	}
}

static void mgmt_connect_failed_event(uint16_t index, uint16_t length,
					const void *param, void *user_data)
{
	const struct mgmt_ev_connect_failed *ev = param;
	struct device *dev;

	if (length < sizeof(*ev)) {
		error("Too short connect failed event (%u bytes)", length);
		return;
	}

	DBG("");

	dev = find_device(&ev->addr.bdaddr);
	if (!dev)
		return;

	/*
	 * In case security mode 3 pairing we will get connect failed event
	 * in case e.g wrong PIN code entered. Let's check if device is
	 * bonding, if so update bond state
	 */

	if (!dev->pairing)
		return;

	update_device_state(dev, ev->addr.type, status_mgmt2hal(ev->status),
							false, false, false);
}

static void mgmt_auth_failed_event(uint16_t index, uint16_t length,
					const void *param, void *user_data)
{
	const struct mgmt_ev_auth_failed *ev = param;
	struct device *dev;

	if (length < sizeof(*ev)) {
		error("Too small auth failed mgmt event (%u bytes)", length);
		return;
	}

	DBG("");

	dev = find_device(&ev->addr.bdaddr);
	if (!dev)
		return;

	if (!dev->pairing)
		return;

	update_device_state(dev, ev->addr.type, status_mgmt2hal(ev->status),
							false, false, false);
}

static void mgmt_device_unpaired_event(uint16_t index, uint16_t length,
					const void *param, void *user_data)
{
	const struct mgmt_ev_device_unpaired *ev = param;
	struct device *dev;

	if (length < sizeof(*ev)) {
		error("Too small device unpaired event (%u bytes)", length);
		return;
	}

	DBG("");

	/* TODO should device be disconnected ? */

	dev = find_device(&ev->addr.bdaddr);
	if (!dev)
		return;

	update_device_state(dev, ev->addr.type, HAL_STATUS_SUCCESS, false,
								false, false);
}

static void store_ltk(const bdaddr_t *dst, uint8_t bdaddr_type, bool master,
			const uint8_t *key, uint8_t key_type, uint8_t enc_size,
			uint16_t ediv, uint64_t rand)
{
	const char *key_s, *keytype_s, *encsize_s, *ediv_s, *rand_s;
	GKeyFile *key_file;
	char key_str[33];
	gsize length = 0;
	char addr[18];
	char *data;
	int i;

	key_file = g_key_file_new();
	if (!g_key_file_load_from_file(key_file, DEVICES_FILE, 0, NULL)) {
		g_key_file_free(key_file);
		return;
	}

	ba2str(dst, addr);

	key_s = master ? "LongTermKey" : "SlaveLongTermKey";
	keytype_s = master ? "LongTermKeyType" : "SlaveLongTermKeyType";
	encsize_s = master ? "LongTermKeyEncSize" : "SlaveLongTermKeyEncSize";
	ediv_s = master ? "LongTermKeyEDiv" : "SlaveLongTermKeyEDiv";
	rand_s = master ? "LongTermKeyRand" : "SlaveLongTermKeyRand";

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

	g_key_file_set_string(key_file, addr, key_s, key_str);

	g_key_file_set_integer(key_file, addr, keytype_s, key_type);

	g_key_file_set_integer(key_file, addr, encsize_s, enc_size);

	g_key_file_set_integer(key_file, addr, ediv_s, ediv);

	g_key_file_set_uint64(key_file, addr, rand_s, rand);

	data = g_key_file_to_data(key_file, &length, NULL);
	g_file_set_contents(DEVICES_FILE, data, length, NULL);
	g_free(data);

	g_key_file_free(key_file);
}

static void new_long_term_key_event(uint16_t index, uint16_t length,
					const void *param, void *user_data)
{
	const struct mgmt_ev_new_long_term_key *ev = param;
	struct device *dev;
	char dst[18];

	if (length < sizeof(*ev)) {
		error("Too small long term key event (%u bytes)", length);
		return;
	}

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

	DBG("new LTK for %s type %u enc_size %u store_hint %u",
			dst, ev->key.type, ev->key.enc_size, ev->store_hint);

	dev = find_device(&ev->key.addr.bdaddr);
	if (!dev)
		return;

	update_device_state(dev, ev->key.addr.type, HAL_STATUS_SUCCESS, false,
							true, !!ev->store_hint);

	if (ev->store_hint) {
		const struct mgmt_ltk_info *key = &ev->key;
		uint16_t ediv;
		uint64_t rand;

		ediv = le16_to_cpu(key->ediv);
		rand = le64_to_cpu(key->rand);

		store_ltk(&key->addr.bdaddr, key->addr.type, key->master,
				key->val, key->type, key->enc_size, ediv, rand);
	}

	/* TODO browse services here? */
}

static void store_csrk(struct device *dev)
{
	GKeyFile *key_file;
	char key_str[33];
	char addr[18];
	int i;
	gsize length = 0;
	char *data;

	ba2str(&dev->bdaddr, addr);

	key_file = g_key_file_new();
	if (!g_key_file_load_from_file(key_file, DEVICES_FILE, 0, NULL)) {
		g_key_file_free(key_file);
		return;
	}

	if (dev->valid_local_csrk) {
		for (i = 0; i < 16; i++)
			sprintf(key_str + (i * 2), "%2.2X",
							dev->local_csrk[i]);

		g_key_file_set_string(key_file, addr, "LocalCSRK", key_str);
	}

	if (dev->valid_remote_csrk) {
		for (i = 0; i < 16; i++)
			sprintf(key_str + (i * 2), "%2.2X",
							dev->remote_csrk[i]);

		g_key_file_set_string(key_file, addr, "RemoteCSRK", key_str);
	}

	data = g_key_file_to_data(key_file, &length, NULL);
	g_file_set_contents(DEVICES_FILE, data, length, NULL);
	g_free(data);

	g_key_file_free(key_file);
}

static void new_csrk_callback(uint16_t index, uint16_t length,
					const void *param, void *user_data)
{
	const struct mgmt_ev_new_csrk *ev = param;
	struct device *dev;
	char dst[18];

	if (length < sizeof(*ev)) {
		error("Too small csrk event (%u bytes)", length);
		return;
	}

	ba2str(&ev->key.addr.bdaddr, dst);
	dev = find_device(&ev->key.addr.bdaddr);
	if (!dev)
		return;

	switch (ev->key.master) {
	case 0x00:
		memcpy(dev->local_csrk, ev->key.val, 16);
		dev->local_sign_cnt = 0;
		dev->valid_local_csrk = true;
		break;
	case 0x01:
		memcpy(dev->remote_csrk, ev->key.val, 16);
		dev->remote_sign_cnt = 0;
		dev->valid_remote_csrk = true;
		break;
	default:
		error("Unknown CSRK key type 02%02x", ev->key.master);
		return;
	}

	update_device_state(dev, ev->key.addr.type, HAL_STATUS_SUCCESS, false,
							true, !!ev->store_hint);

	if (ev->store_hint)
		store_csrk(dev);
}

static void store_irk(struct device *dev, const uint8_t *val)
{
	GKeyFile *key_file;
	char key_str[33];
	char addr[18];
	int i;
	gsize length = 0;
	char *data;

	ba2str(&dev->bdaddr, addr);

	key_file = g_key_file_new();
	if (!g_key_file_load_from_file(key_file, DEVICES_FILE, 0, NULL)) {
		g_key_file_free(key_file);
		return;
	}

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

	g_key_file_set_string(key_file, addr, "IdentityResolvingKey", key_str);

	data = g_key_file_to_data(key_file, &length, NULL);
	g_file_set_contents(DEVICES_FILE, data, length, NULL);
	g_free(data);

	g_key_file_free(key_file);
}

static void new_irk_callback(uint16_t index, uint16_t length,
					const void *param, void *user_data)
{
	const struct mgmt_ev_new_irk *ev = param;
	const struct mgmt_addr_info *addr = &ev->key.addr;
	struct device *dev;
	char dst[18], rpa[18];

	if (length < sizeof(*ev)) {
		error("To small New Irk Event (%u bytes)", length);
		return;
	}

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

	DBG("new IRK for %s, RPA %s", dst, rpa);

	/* TODO: handle new Identity to RPA mapping */
	dev = find_device(&addr->bdaddr);
	if (!dev)
		return;

	if (ev->store_hint)
		store_irk(dev, ev->key.val);
}

static void register_mgmt_handlers(void)
{
	mgmt_register(mgmt_if, MGMT_EV_NEW_SETTINGS, adapter.index,
					new_settings_callback, NULL, NULL);

	mgmt_register(mgmt_if, MGMT_EV_CLASS_OF_DEV_CHANGED, adapter.index,
				mgmt_dev_class_changed_event, NULL, NULL);

	mgmt_register(mgmt_if, MGMT_EV_LOCAL_NAME_CHANGED, adapter.index,
				mgmt_local_name_changed_event, NULL, NULL);

	mgmt_register(mgmt_if, MGMT_EV_NEW_LINK_KEY, adapter.index,
					new_link_key_callback, NULL, NULL);

	mgmt_register(mgmt_if, MGMT_EV_PIN_CODE_REQUEST, adapter.index,
					pin_code_request_callback, NULL, NULL);

	mgmt_register(mgmt_if, MGMT_EV_USER_CONFIRM_REQUEST, adapter.index,
				user_confirm_request_callback, NULL, NULL);

	mgmt_register(mgmt_if, MGMT_EV_USER_PASSKEY_REQUEST, adapter.index,
				user_passkey_request_callback, NULL, NULL);

	mgmt_register(mgmt_if, MGMT_EV_PASSKEY_NOTIFY, adapter.index,
				user_passkey_notify_callback, NULL, NULL);

	mgmt_register(mgmt_if, MGMT_EV_DISCOVERING, adapter.index,
					mgmt_discovering_event, NULL, NULL);

	mgmt_register(mgmt_if, MGMT_EV_DEVICE_FOUND, adapter.index,
					mgmt_device_found_event, NULL, NULL);

	mgmt_register(mgmt_if, MGMT_EV_DEVICE_CONNECTED, adapter.index,
				mgmt_device_connected_event, NULL, NULL);

	mgmt_register(mgmt_if, MGMT_EV_DEVICE_DISCONNECTED, adapter.index,
				mgmt_device_disconnected_event, NULL, NULL);

	mgmt_register(mgmt_if, MGMT_EV_CONNECT_FAILED, adapter.index,
					mgmt_connect_failed_event, NULL, NULL);

	mgmt_register(mgmt_if, MGMT_EV_AUTH_FAILED, adapter.index,
					mgmt_auth_failed_event, NULL, NULL);

	mgmt_register(mgmt_if, MGMT_EV_DEVICE_UNPAIRED, adapter.index,
				mgmt_device_unpaired_event, NULL, NULL);

	mgmt_register(mgmt_if, MGMT_EV_NEW_LONG_TERM_KEY, adapter.index,
					new_long_term_key_event, NULL, NULL);

	mgmt_register(mgmt_if, MGMT_EV_NEW_CSRK, adapter.index,
						new_csrk_callback, NULL, NULL);

	mgmt_register(mgmt_if, MGMT_EV_NEW_IRK, adapter.index, new_irk_callback,
								NULL, NULL);
}

static void load_link_keys_complete(uint8_t status, uint16_t length,
					const void *param, void *user_data)
{
	bt_bluetooth_ready cb = user_data;
	int err;

	if (status) {
		error("Failed to load link keys for index %u: %s (0x%02x)",
				adapter.index, mgmt_errstr(status), status);
		err = -EIO;
		goto failed;
	}

	DBG("status %u", status);

	cb(0, &adapter.bdaddr);
	return;

failed:
	cb(err, NULL);
}

static void load_link_keys(GSList *keys, bt_bluetooth_ready cb)
{
	struct mgmt_cp_load_link_keys *cp;
	struct mgmt_link_key_info *key;
	size_t key_count, cp_size;
	unsigned int id;

	key_count = g_slist_length(keys);

	DBG("keys %zu ", key_count);

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

	cp = g_malloc0(cp_size);

	/*
	 * Even if the list of stored keys is empty, it is important to
	 * load an empty list into the kernel. That way it is ensured
	 * that no old keys from a previous daemon are present.
	 */
	cp->key_count = htobs(key_count);

	for (key = cp->keys; keys != NULL; keys = g_slist_next(keys), key++)
		memcpy(key, keys->data, sizeof(*key));

	id = mgmt_send(mgmt_if, MGMT_OP_LOAD_LINK_KEYS, adapter.index,
			cp_size, cp, load_link_keys_complete, cb, NULL);

	g_free(cp);

	if (id == 0) {
		error("Failed to load link keys");
		cb(-EIO, NULL);
	}
}

static void load_ltks(GSList *ltks)
{
	struct mgmt_cp_load_long_term_keys *cp;
	struct mgmt_ltk_info *ltk;
	size_t ltk_count, cp_size;
	GSList *l;

	ltk_count = g_slist_length(ltks);

	DBG("ltks %zu", ltk_count);

	cp_size = sizeof(*cp) + (ltk_count * sizeof(*ltk));

	cp = g_malloc0(cp_size);

	/*
	 * Even if the list of stored keys is empty, it is important to load
	 * an empty list into the kernel. That way it is ensured that no old
	 * keys from a previous daemon are present.
	 */
	cp->key_count = htobs(ltk_count);

	for (l = ltks, ltk = cp->keys; l != NULL; l = g_slist_next(l), ltk++)
		memcpy(ltk, ltks->data, sizeof(*ltk));

	if (mgmt_send(mgmt_if, MGMT_OP_LOAD_LONG_TERM_KEYS, adapter.index,
					cp_size, cp, NULL, NULL, NULL) == 0)
		error("Failed to load LTKs");

	g_free(cp);
}

static void load_irks(GSList *irks)
{
	struct mgmt_cp_load_irks *cp;
	struct mgmt_irk_info *irk;
	size_t irk_count, cp_size;
	GSList *l;

	irk_count = g_slist_length(irks);

	DBG("irks %zu", irk_count);

	cp_size = sizeof(*cp) + (irk_count * sizeof(*irk));

	cp = g_malloc0(cp_size);

	cp->irk_count = htobs(irk_count);

	for (l = irks, irk = cp->irks; l != NULL; l = g_slist_next(l), irk++)
		memcpy(irk, irks->data, sizeof(*irk));

	if (mgmt_send(mgmt_if, MGMT_OP_LOAD_IRKS, adapter.index, cp_size, cp,
							NULL, NULL, NULL) == 0)
		error("Failed to load IRKs");

	g_free(cp);
}

static uint8_t get_adapter_uuids(void)
{
	struct hal_ev_adapter_props_changed *ev;
	GSList *list = adapter.uuids;
	unsigned int uuid_count = g_slist_length(list);
	int len = uuid_count * sizeof(uint128_t);
	uint8_t buf[BASELEN_PROP_CHANGED + len];
	uint8_t *p;

	memset(buf, 0, sizeof(buf));
	ev = (void *) buf;

	ev->num_props = 1;
	ev->status = HAL_STATUS_SUCCESS;

	ev->props[0].type = HAL_PROP_ADAPTER_UUIDS;
	ev->props[0].len = len;
	p = ev->props->val;

	for (; list; list = g_slist_next(list)) {
		uuid_t *uuid = list->data;

		memcpy(p, &uuid->value.uuid128, sizeof(uint128_t));

		p += sizeof(uint128_t);
	}

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
				HAL_EV_ADAPTER_PROPS_CHANGED, sizeof(buf), ev);

	return HAL_STATUS_SUCCESS;
}

static void remove_uuid_complete(uint8_t status, uint16_t length,
					const void *param, void *user_data)
{
	if (status != MGMT_STATUS_SUCCESS) {
		error("Failed to remove UUID: %s (0x%02x)",
						mgmt_errstr(status), status);
		return;
	}

	mgmt_dev_class_changed_event(adapter.index, length, param, NULL);

	get_adapter_uuids();
}

static void remove_uuid(uuid_t *uuid)
{
	uint128_t uint128;
	struct mgmt_cp_remove_uuid cp;

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

	mgmt_send(mgmt_if, MGMT_OP_REMOVE_UUID, adapter.index, sizeof(cp), &cp,
					remove_uuid_complete, NULL, NULL);
}

static void add_uuid_complete(uint8_t status, uint16_t length,
					const void *param, void *user_data)
{
	if (status != MGMT_STATUS_SUCCESS) {
		error("Failed to add UUID: %s (0x%02x)",
						mgmt_errstr(status), status);
		return;
	}

	mgmt_dev_class_changed_event(adapter.index, length, param, NULL);

	get_adapter_uuids();
}

static void add_uuid(uint8_t svc_hint, uuid_t *uuid)
{
	uint128_t uint128;
	struct mgmt_cp_add_uuid cp;

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

	cp.svc_hint = svc_hint;

	mgmt_send(mgmt_if, MGMT_OP_ADD_UUID, adapter.index, sizeof(cp), &cp,
						add_uuid_complete, NULL, NULL);
}

int bt_adapter_add_record(sdp_record_t *rec, uint8_t svc_hint)
{
	uuid_t *uuid;

	uuid = sdp_uuid_to_uuid128(&rec->svclass);

	if (g_slist_find_custom(adapter.uuids, uuid, sdp_uuid_cmp)) {
		char uuid_str[32];

		sdp_uuid2strn(uuid, uuid_str, sizeof(uuid_str));
		DBG("UUID %s already added", uuid_str);

		bt_free(uuid);
		return -EALREADY;
	}

	adapter.uuids = g_slist_prepend(adapter.uuids, uuid);

	add_uuid(svc_hint, uuid);

	return add_record_to_server(&adapter.bdaddr, rec);
}

void bt_adapter_remove_record(uint32_t handle)
{
	sdp_record_t *rec;
	GSList *uuid_found;

	rec = sdp_record_find(handle);
	if (!rec)
		return;

	uuid_found = g_slist_find_custom(adapter.uuids, &rec->svclass,
								sdp_uuid_cmp);
	if (uuid_found) {
		uuid_t *uuid = uuid_found->data;

		remove_uuid(uuid);

		adapter.uuids = g_slist_remove(adapter.uuids, uuid);

		free(uuid);
	}

	remove_record_from_server(handle);
}

static void set_mode_complete(uint8_t status, uint16_t length,
					const void *param, void *user_data)
{
	if (status != MGMT_STATUS_SUCCESS) {
		error("Failed to set mode: %s (0x%02x)",
						mgmt_errstr(status), status);
		return;
	}

	/*
	 * The parameters are identical and also the task that is
	 * required in both cases. So it is safe to just call the
	 * event handling functions here.
	 */
	new_settings_callback(adapter.index, length, param, NULL);
}

static bool set_mode(uint16_t opcode, uint8_t mode)
{
	struct mgmt_mode cp;

	memset(&cp, 0, sizeof(cp));
	cp.val = mode;

	DBG("opcode=0x%x mode=0x%x", opcode, mode);

	if (mgmt_send(mgmt_if, opcode, adapter.index, sizeof(cp), &cp,
					set_mode_complete, NULL, NULL) > 0)
		return true;

	error("Failed to set mode");

	return false;
}

static void set_io_capability(void)
{
	struct mgmt_cp_set_io_capability cp;

	memset(&cp, 0, sizeof(cp));
	cp.io_capability = DEFAULT_IO_CAPABILITY;

	if (mgmt_send(mgmt_if, MGMT_OP_SET_IO_CAPABILITY, adapter.index,
				sizeof(cp), &cp, NULL, NULL, NULL) == 0)
		error("Failed to set IO capability");
}

static void set_device_id(void)
{
	struct mgmt_cp_set_device_id cp;
	uint8_t major, minor;
	uint16_t version;

	if (sscanf(VERSION, "%hhu.%hhu", &major, &minor) != 2)
		return;

	version = major << 8 | minor;

	memset(&cp, 0, sizeof(cp));
	cp.source = htobs(DEVICE_ID_SOURCE);
	cp.vendor = htobs(DEVICE_ID_VENDOR);
	cp.product = htobs(DEVICE_ID_PRODUCT);
	cp.version = htobs(version);

	if (mgmt_send(mgmt_if, MGMT_OP_SET_DEVICE_ID, adapter.index,
				sizeof(cp), &cp, NULL, NULL, NULL) == 0)
		error("Failed to set device id");

	register_device_id(DEVICE_ID_SOURCE, DEVICE_ID_VENDOR,
						DEVICE_ID_PRODUCT, version);

	bt_adapter_add_record(sdp_record_find(0x10000), 0x00);
}

static void set_adapter_name_complete(uint8_t status, uint16_t length,
					const void *param, void *user_data)
{
	const struct mgmt_cp_set_local_name *rp = param;

	if (status != MGMT_STATUS_SUCCESS) {
		error("Failed to set name: %s (0x%02x)",
						mgmt_errstr(status), status);
		return;
	}

	adapter_set_name(rp->name);
}

static uint8_t set_adapter_name(const uint8_t *name, uint16_t len)
{
	struct mgmt_cp_set_local_name cp;

	memset(&cp, 0, sizeof(cp));
	memcpy(cp.name, name, len);

	if (mgmt_send(mgmt_if, MGMT_OP_SET_LOCAL_NAME, adapter.index,
				sizeof(cp), &cp, set_adapter_name_complete,
				NULL, NULL) > 0)
		return HAL_STATUS_SUCCESS;

	error("Failed to set name");

	return HAL_STATUS_FAILED;
}

static uint8_t set_adapter_discoverable_timeout(const void *buf, uint16_t len)
{
	const uint32_t *timeout = buf;

	if (len != sizeof(*timeout)) {
		error("Invalid set disc timeout size (%u bytes), terminating",
									len);
		raise(SIGTERM);
		return HAL_STATUS_FAILED;
	}

	/*
	 * Android handles discoverable timeout in Settings app.
	 * There is no need to use kernel feature for that.
	 * Just need to store this value here
	 */

	memcpy(&adapter.discoverable_timeout, timeout, sizeof(uint32_t));

	store_adapter_config();

	send_adapter_property(HAL_PROP_ADAPTER_DISC_TIMEOUT,
					sizeof(adapter.discoverable_timeout),
					&adapter.discoverable_timeout);

	return HAL_STATUS_SUCCESS;
}

static void clear_uuids(void)
{
	struct mgmt_cp_remove_uuid cp;

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

	mgmt_send(mgmt_if, MGMT_OP_REMOVE_UUID, adapter.index,
					sizeof(cp), &cp, NULL, NULL, NULL);
}

static struct device *create_device_from_info(GKeyFile *key_file,
							const char *peer)
{
	struct device *dev;
	uint8_t type;
	bdaddr_t bdaddr;
	char **uuids;
	char *str;

	/* BREDR if not present */
	type = g_key_file_get_integer(key_file, peer, "AddressType", NULL);

	str2ba(peer, &bdaddr);
	dev = create_device(&bdaddr, type);

	if (type != BDADDR_BREDR)
		dev->bredr = g_key_file_get_boolean(key_file, peer, "BREDR",
									NULL);

	str = g_key_file_get_string(key_file, peer, "LinkKey", NULL);
	if (str) {
		g_free(str);
		dev->bredr_paired = true;
		dev->bredr_bonded = true;
	}

	str = g_key_file_get_string(key_file, peer, "LongTermKey", NULL);
	if (str) {
		g_free(str);
		dev->le_paired = true;
		dev->le_bonded = true;
	}

	str = g_key_file_get_string(key_file, peer, "SlaveLongTermKey", NULL);
	if (str) {
		g_free(str);
		dev->le_paired = true;
		dev->le_bonded = true;
	}

	str = g_key_file_get_string(key_file, peer, "LocalCSRK", NULL);
	if (str) {
		int i;

		dev->valid_local_csrk = true;
		for (i = 0; i < 16; i++)
			sscanf(str + (i * 2), "%02hhX", &dev->local_csrk[i]);

		g_free(str);

		dev->local_sign_cnt = g_key_file_get_integer(key_file, peer,
						"LocalCSRKSignCounter", NULL);
	}

	str = g_key_file_get_string(key_file, peer, "RemoteCSRK", NULL);
	if (str) {
		int i;

		dev->valid_remote_csrk = true;
		for (i = 0; i < 16; i++)
			sscanf(str + (i * 2), "%02hhX", &dev->remote_csrk[i]);

		g_free(str);

		dev->remote_sign_cnt = g_key_file_get_integer(key_file, peer,
						"RemoteCSRKSignCounter", NULL);
	}

	str = g_key_file_get_string(key_file, peer, "GattCCC", NULL);
	if (str) {
		dev->gatt_ccc = atoi(str);
		g_free(str);
	}

	str = g_key_file_get_string(key_file, peer, "Name", NULL);
	if (str) {
		g_free(dev->name);
		dev->name = str;
	}

	str = g_key_file_get_string(key_file, peer, "FriendlyName", NULL);
	if (str) {
		g_free(dev->friendly_name);
		dev->friendly_name = str;
	}

	dev->class = g_key_file_get_integer(key_file, peer, "Class", NULL);

	if (dev->bredr)
		dev->bredr_seen = g_key_file_get_integer(key_file, peer,
								"Timestamp",
								NULL);
	else
		dev->le_seen = g_key_file_get_integer(key_file, peer,
							"Timestamp", NULL);

	uuids = g_key_file_get_string_list(key_file, peer, "Services", NULL,
									NULL);
	if (uuids) {
		char **uuid;

		for (uuid = uuids; *uuid; uuid++) {
			uint8_t *u = g_malloc0(16);
			int i;

			for (i = 0; i < 16; i++)
				sscanf((*uuid) + (i * 2), "%02hhX", &u[i]);

			dev->uuids = g_slist_append(dev->uuids, u);
		}

		g_strfreev(uuids);
	}

	return dev;
}

static struct mgmt_link_key_info *get_key_info(GKeyFile *key_file,
							const char *peer)
{
	struct mgmt_link_key_info *info = NULL;
	char *str;
	unsigned int i;

	str = g_key_file_get_string(key_file, peer, "LinkKey", NULL);
	if (!str || strlen(str) != 32)
		goto failed;

	info = g_new0(struct mgmt_link_key_info, 1);

	str2ba(peer, &info->addr.bdaddr);

	for (i = 0; i < sizeof(info->val); i++)
		sscanf(str + (i * 2), "%02hhX", &info->val[i]);

	info->type = g_key_file_get_integer(key_file, peer, "LinkKeyType",
									NULL);
	info->pin_len = g_key_file_get_integer(key_file, peer,
						"LinkKeyPinLength", NULL);

failed:
	g_free(str);

	return info;
}

static struct mgmt_ltk_info *get_ltk_info(GKeyFile *key_file, const char *peer,
								bool master)
{
	const char *key_s, *keytype_s, *encsize_s, *ediv_s, *rand_s;
	struct mgmt_ltk_info *info = NULL;
	char *key;
	unsigned int i;

	key_s = master ? "LongTermKey" : "SlaveLongTermKey";
	keytype_s = master ? "LongTermKeyType" : "SlaveLongTermKeyType";
	encsize_s = master ? "LongTermKeyEncSize" : "SlaveLongTermKeyEncSize";
	ediv_s = master ? "LongTermKeyEDiv" : "SlaveLongTermKeyEDiv";
	rand_s = master ? "LongTermKeyRand" : "SlaveLongTermKeyRand";

	key = g_key_file_get_string(key_file, peer, key_s, NULL);
	if (!key || strlen(key) != 32)
		goto failed;

	info = g_new0(struct mgmt_ltk_info, 1);

	str2ba(peer, &info->addr.bdaddr);

	info->addr.type = g_key_file_get_integer(key_file, peer, "AddressType",
									NULL);

	for (i = 0; i < sizeof(info->val); i++)
		sscanf(key + (i * 2), "%02hhX", &info->val[i]);

	info->type = g_key_file_get_integer(key_file, peer, keytype_s, NULL);

	info->enc_size = g_key_file_get_integer(key_file, peer, encsize_s,
									NULL);

	info->rand = g_key_file_get_uint64(key_file, peer, rand_s, NULL);
	info->rand = cpu_to_le64(info->rand);

	info->ediv = g_key_file_get_integer(key_file, peer, ediv_s, NULL);
	info->ediv = cpu_to_le16(info->ediv);

	info->master = master;

failed:
	g_free(key);

	return info;
}

static struct mgmt_irk_info *get_irk_info(GKeyFile *key_file, const char *peer)
{
	struct mgmt_irk_info *info = NULL;
	unsigned int i;
	char *str;

	str = g_key_file_get_string(key_file, peer, "IdentityResolvingKey",
									NULL);
	if (!str || strlen(str) != 32)
		goto failed;

	info = g_new0(struct mgmt_irk_info, 1);

	str2ba(peer, &info->addr.bdaddr);

	info->addr.type = g_key_file_get_integer(key_file, peer, "AddressType",
									NULL);

	for (i = 0; i < sizeof(info->val); i++)
		sscanf(str + (i * 2), "%02hhX", &info->val[i]);

failed:
	g_free(str);

	return info;
}

static time_t device_timestamp(const struct device *dev)
{
	if (dev->bredr && dev->le) {
		if (dev->le_seen > dev->bredr_seen)
			return dev->le_seen;

		return dev->bredr_seen;
	}

	if (dev->bredr)
		return dev->bredr_seen;

	return dev->le_seen;
}

static int device_timestamp_cmp(gconstpointer  a, gconstpointer  b)
{
	const struct device *deva = a;
	const struct device *devb = b;

	return device_timestamp(deva) < device_timestamp(devb);
}

static void load_devices_cache(void)
{
	GKeyFile *key_file;
	gchar **devs;
	gsize len = 0;
	unsigned int i;

	key_file = g_key_file_new();

	g_key_file_load_from_file(key_file, CACHE_FILE, 0, NULL);

	devs = g_key_file_get_groups(key_file, &len);

	for (i = 0; i < len; i++) {
		struct device *dev;

		dev = create_device_from_info(key_file, devs[i]);
		cached_devices = g_slist_prepend(cached_devices, dev);
	}

	cached_devices = g_slist_sort(cached_devices, device_timestamp_cmp);

	g_strfreev(devs);
	g_key_file_free(key_file);
}

static void load_devices_info(bt_bluetooth_ready cb)
{
	GKeyFile *key_file;
	gchar **devs;
	gsize len = 0;
	unsigned int i;
	GSList *keys = NULL;
	GSList *ltks = NULL;
	GSList *irks = NULL;

	key_file = g_key_file_new();

	g_key_file_load_from_file(key_file, DEVICES_FILE, 0, NULL);

	devs = g_key_file_get_groups(key_file, &len);

	for (i = 0; i < len; i++) {
		struct mgmt_link_key_info *key_info;
		struct mgmt_ltk_info *ltk_info;
		struct mgmt_irk_info *irk_info;
		struct mgmt_ltk_info *slave_ltk_info;
		struct device *dev;

		key_info = get_key_info(key_file, devs[i]);
		irk_info = get_irk_info(key_file, devs[i]);
		ltk_info = get_ltk_info(key_file, devs[i], true);
		slave_ltk_info = get_ltk_info(key_file, devs[i], false);

		if (!key_info && !ltk_info && !slave_ltk_info) {
			error("Failed to load keys for %s, skipping", devs[i]);

			continue;
		}

		if (key_info)
			keys = g_slist_prepend(keys, key_info);

		if (irk_info)
			irks = g_slist_prepend(irks, irk_info);

		if (ltk_info)
			ltks = g_slist_prepend(ltks, ltk_info);

		if (slave_ltk_info)
			ltks = g_slist_prepend(ltks, slave_ltk_info);

		dev = create_device_from_info(key_file, devs[i]);

		bonded_devices = g_slist_prepend(bonded_devices, dev);
	}

	load_ltks(ltks);
	g_slist_free_full(ltks, g_free);

	load_irks(irks);
	g_slist_free_full(irks, g_free);

	load_link_keys(keys, cb);
	g_slist_free_full(keys, g_free);

	g_strfreev(devs);
	g_key_file_free(key_file);
}

static void set_adapter_class(void)
{
	struct mgmt_cp_set_dev_class cp;

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

	/*
	 * kernel assign the major and minor numbers straight to dev_class[0]
	 * and dev_class[1] without considering the proper bit shifting.
	 */
	cp.major = ADAPTER_MAJOR_CLASS & 0x1f;
	cp.minor = ADAPTER_MINOR_CLASS << 2;

	if (mgmt_send(mgmt_if, MGMT_OP_SET_DEV_CLASS, adapter.index,
					sizeof(cp), &cp, NULL, NULL, NULL) > 0)
		return;

	error("Failed to set class of device");
}

static sdp_record_t *mps_record(void)
{
	sdp_data_t *mpsd_features, *mpmd_features, *dependencies;
	sdp_list_t *svclass_id, *pfseq, *root;
	uuid_t root_uuid, svclass_uuid;
	sdp_profile_desc_t profile;
	sdp_record_t *record;
	uint64_t mpsd_feat, mpmd_feat;
	uint16_t deps;

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

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

	sdp_uuid16_create(&svclass_uuid, MPS_SVCLASS_ID);
	svclass_id = sdp_list_append(NULL, &svclass_uuid);
	sdp_set_service_classes(record, svclass_id);

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

	mpsd_feat = MPS_DEFAULT_MPSD;
	mpmd_feat = MPS_DEFAULT_MPMD;

	/* TODO should be configurable based on HFP AG support */
	if (false) {
		mpsd_feat &= MPS_MPSD_HFP_AG_DEP;
		mpmd_feat &= MPS_MPMD_HFP_AG_DEP;
	}

	mpsd_features = sdp_data_alloc(SDP_UINT64, &mpsd_feat);
	sdp_attr_add(record, SDP_ATTR_MPSD_SCENARIOS, mpsd_features);

	mpmd_features = sdp_data_alloc(SDP_UINT64, &mpmd_feat);
	sdp_attr_add(record, SDP_ATTR_MPMD_SCENARIOS, mpmd_features);

	deps = MPS_DEFAULT_DEPS;
	dependencies = sdp_data_alloc(SDP_UINT16, &deps);
	sdp_attr_add(record, SDP_ATTR_MPS_DEPENDENCIES, dependencies);

	sdp_set_info_attr(record, "Multi Profile", 0, 0);

	sdp_list_free(pfseq, NULL);
	sdp_list_free(root, NULL);
	sdp_list_free(svclass_id, NULL);

	return record;
}

static void add_mps_record(void)
{
	sdp_record_t *rec;

	rec = mps_record();
	if (!rec) {
		error("Failed to allocate MPS record");
		return;
	}

	if (bt_adapter_add_record(rec, 0) < 0) {
		error("Failed to register MPS record");
		sdp_record_free(rec);
	}
}

static void read_info_complete(uint8_t status, uint16_t length,
					const void *param, void *user_data)
{
	const struct mgmt_rp_read_info *rp = param;
	bt_bluetooth_ready cb = user_data;
	uint32_t missing_settings;
	int err;

	DBG("");

	if (status) {
		error("Failed to read info for index %u: %s (0x%02x)",
				adapter.index, mgmt_errstr(status), status);
		err = -EIO;
		goto failed;
	}

	if (length < sizeof(*rp)) {
		error("Too small read info complete response");
		err = -EIO;
		goto failed;
	}

	if (!bacmp(&rp->bdaddr, BDADDR_ANY)) {
		error("No Bluetooth address");
		err = -ENODEV;
		goto failed;
	}

	load_adapter_config();

	if (!bacmp(&adapter.bdaddr, BDADDR_ANY)) {
		bacpy(&adapter.bdaddr, &rp->bdaddr);
		adapter.name = g_strdup(DEFAULT_ADAPTER_NAME);
		store_adapter_config();
	} else if (bacmp(&adapter.bdaddr, &rp->bdaddr)) {
		error("Bluetooth address mismatch");
		err = -ENODEV;
		goto failed;
	}

	if (g_strcmp0(adapter.name, (const char *) rp->name))
		set_adapter_name((uint8_t *)adapter.name, strlen(adapter.name));

	set_adapter_class();

	/* Store adapter information */
	adapter.dev_class = rp->dev_class[0] | (rp->dev_class[1] << 8) |
						(rp->dev_class[2] << 16);

	adapter.supported_settings = btohs(rp->supported_settings);
	adapter.current_settings = btohs(rp->current_settings);

	/* TODO: Register all event notification handlers */
	register_mgmt_handlers();

	clear_uuids();

	set_io_capability();
	set_device_id();
	add_mps_record();

	missing_settings = adapter.current_settings ^
						adapter.supported_settings;

	if (missing_settings & MGMT_SETTING_SSP)
		set_mode(MGMT_OP_SET_SSP, 0x01);

	if (missing_settings & MGMT_SETTING_SECURE_CONN)
		set_mode(MGMT_OP_SET_SECURE_CONN, 0x01);

	if (missing_settings & MGMT_SETTING_PAIRABLE)
		set_mode(MGMT_OP_SET_PAIRABLE, 0x01);

	load_devices_info(cb);
	load_devices_cache();

	return;

failed:
	cb(err, NULL);
}

static void mgmt_index_added_event(uint16_t index, uint16_t length,
					const void *param, void *user_data)
{
	bt_bluetooth_ready cb = user_data;

	DBG("index %u", index);

	if (adapter.index != MGMT_INDEX_NONE) {
		DBG("skip event for index %u", index);
		return;
	}

	if (option_index != MGMT_INDEX_NONE && option_index != index) {
		DBG("skip event for index %u (option %u)", index, option_index);
		return;
	}

	adapter.index = index;

	if (mgmt_send(mgmt_if, MGMT_OP_READ_INFO, index, 0, NULL,
				read_info_complete, cb, NULL) == 0) {
		cb(-EIO, NULL);
		return;
	}
}

static void mgmt_index_removed_event(uint16_t index, uint16_t length,
					const void *param, void *user_data)
{
	DBG("index %u", index);

	if (index != adapter.index)
		return;

	error("Adapter was removed. Exiting.");
	raise(SIGTERM);
}

static void read_index_list_complete(uint8_t status, uint16_t length,
					const void *param, void *user_data)
{
	const struct mgmt_rp_read_index_list *rp = param;
	bt_bluetooth_ready cb = user_data;
	uint16_t num;
	int i;

	DBG("");

	if (status) {
		error("%s: Failed to read index list: %s (0x%02x)",
					__func__, mgmt_errstr(status), status);
		goto failed;
	}

	if (length < sizeof(*rp)) {
		error("%s: Wrong size of read index list response", __func__);
		goto failed;
	}

	num = btohs(rp->num_controllers);

	DBG("Number of controllers: %u", num);

	if (num * sizeof(uint16_t) + sizeof(*rp) != length) {
		error("%s: Incorrect pkt size for index list rsp", __func__);
		goto failed;
	}

	if (adapter.index != MGMT_INDEX_NONE)
		return;

	for (i = 0; i < num; i++) {
		uint16_t index = btohs(rp->index[i]);

		if (option_index != MGMT_INDEX_NONE && option_index != index)
			continue;

		if (mgmt_send(mgmt_if, MGMT_OP_READ_INFO, index, 0, NULL,
					read_info_complete, cb, NULL) == 0)
			goto failed;

		adapter.index = index;
		return;
	}

	return;

failed:
	cb(-EIO, NULL);
}

static void read_version_complete(uint8_t status, uint16_t length,
					const void *param, void *user_data)
{
	const struct mgmt_rp_read_version *rp = param;
	uint8_t mgmt_version, mgmt_revision;
	bt_bluetooth_ready cb = user_data;

	DBG("");

	if (status) {
		error("Failed to read version information: %s (0x%02x)",
						mgmt_errstr(status), status);
		goto failed;
	}

	if (length < sizeof(*rp)) {
		error("Wrong size response");
		goto failed;
	}

	mgmt_version = rp->version;
	mgmt_revision = btohs(rp->revision);

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

	if (MGMT_VERSION(mgmt_version, mgmt_revision) < MGMT_VERSION(1, 3)) {
		error("Version 1.3 or later of management interface required");
		goto failed;
	}

	mgmt_register(mgmt_if, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE,
					mgmt_index_added_event, cb, NULL);
	mgmt_register(mgmt_if, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE,
					mgmt_index_removed_event, NULL, NULL);

	if (mgmt_send(mgmt_if, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0,
				NULL, read_index_list_complete, cb, NULL) > 0)
		return;

	error("Failed to read controller index list");

failed:
	cb(-EIO, NULL);
}

bool bt_bluetooth_start(int index, bool mgmt_dbg, bt_bluetooth_ready cb)
{
	DBG("index %d", index);

	mgmt_if = mgmt_new_default();
	if (!mgmt_if) {
		error("Failed to access management interface");
		return false;
	}

	if (mgmt_dbg)
		mgmt_set_debug(mgmt_if, mgmt_debug, "mgmt_if: ", NULL);

	if (mgmt_send(mgmt_if, MGMT_OP_READ_VERSION, MGMT_INDEX_NONE, 0, NULL,
				read_version_complete, cb, NULL) == 0) {
		error("Error sending READ_VERSION mgmt command");

		mgmt_unref(mgmt_if);
		mgmt_if = NULL;

		return false;
	}

	if (index >= 0)
		option_index = index;

	return true;
}

static void shutdown_complete(uint8_t status, uint16_t length,
					const void *param, void *user_data)
{
	bt_bluetooth_stopped cb = user_data;

	if (status != MGMT_STATUS_SUCCESS)
		error("Clean controller shutdown failed");

	cb();
}

bool bt_bluetooth_stop(bt_bluetooth_stopped cb)
{
	struct mgmt_mode cp;

	if (adapter.index == MGMT_INDEX_NONE)
		return false;

	info("Switching controller off");

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

	return mgmt_send(mgmt_if, MGMT_OP_SET_POWERED, adapter.index,
				sizeof(cp), &cp, shutdown_complete, (void *)cb,
				NULL) > 0;
}

void bt_bluetooth_cleanup(void)
{
	g_free(adapter.name);
	adapter.name = NULL;

	mgmt_unref(mgmt_if);
	mgmt_if = NULL;
}

static bool set_discoverable(uint8_t mode, uint16_t timeout)
{
	struct mgmt_cp_set_discoverable cp;

	memset(&cp, 0, sizeof(cp));
	cp.val = mode;
	cp.timeout = htobs(timeout);

	DBG("mode %u timeout %u", mode, timeout);

	if (mgmt_send(mgmt_if, MGMT_OP_SET_DISCOVERABLE, adapter.index,
			sizeof(cp), &cp, set_mode_complete, NULL, NULL) > 0)
		return true;

	error("Failed to set mode discoverable");

	return false;
}

static uint8_t get_adapter_address(void)
{
	uint8_t buf[6];

	bdaddr2android(&adapter.bdaddr, buf);

	send_adapter_property(HAL_PROP_ADAPTER_ADDR, sizeof(buf), buf);

	return HAL_STATUS_SUCCESS;
}

static uint8_t get_adapter_name(void)
{
	if (!adapter.name)
		return HAL_STATUS_FAILED;

	adapter_name_changed((uint8_t *) adapter.name);

	return HAL_STATUS_SUCCESS;
}

static uint8_t get_adapter_class(void)
{
	DBG("");

	adapter_class_changed();

	return HAL_STATUS_SUCCESS;
}

static uint8_t settings2type(void)
{
	bool bredr, le;

	bredr = adapter.current_settings & MGMT_SETTING_BREDR;
	le = adapter.current_settings & MGMT_SETTING_LE;

	if (bredr && le)
		return HAL_TYPE_DUAL;

	if (bredr && !le)
		return HAL_TYPE_BREDR;

	if (!bredr && le)
		return HAL_TYPE_LE;

	return 0;
}

static uint8_t get_adapter_type(void)
{
	uint8_t type;

	DBG("");

	type = settings2type();

	if (!type)
		return HAL_STATUS_FAILED;

	send_adapter_property(HAL_PROP_ADAPTER_TYPE, sizeof(type), &type);

	return HAL_STATUS_SUCCESS;
}

static uint8_t get_adapter_service_rec(void)
{
	DBG("Not implemented");

	/* TODO: Add implementation */

	return HAL_STATUS_FAILED;
}

static uint8_t get_adapter_scan_mode(void)
{
	DBG("");

	scan_mode_changed();

	return HAL_STATUS_SUCCESS;
}

static uint8_t get_adapter_bonded_devices(void)
{
	uint8_t buf[sizeof(bdaddr_t) * g_slist_length(bonded_devices)];
	int i = 0;
	GSList *l;

	DBG("");

	for (l = bonded_devices; l; l = g_slist_next(l)) {
		struct device *dev = l->data;

		bdaddr2android(&dev->bdaddr, buf + (i * sizeof(bdaddr_t)));
		i++;
	}

	send_adapter_property(HAL_PROP_ADAPTER_BONDED_DEVICES,
						i * sizeof(bdaddr_t), buf);

	return HAL_STATUS_SUCCESS;
}

static uint8_t get_adapter_discoverable_timeout(void)
{
	send_adapter_property(HAL_PROP_ADAPTER_DISC_TIMEOUT,
					sizeof(adapter.discoverable_timeout),
					&adapter.discoverable_timeout);

	return HAL_STATUS_SUCCESS;
}

static void handle_get_adapter_prop_cmd(const void *buf, uint16_t len)
{
	const struct hal_cmd_get_adapter_prop *cmd = buf;
	uint8_t status;

	switch (cmd->type) {
	case HAL_PROP_ADAPTER_ADDR:
		status = get_adapter_address();
		break;
	case HAL_PROP_ADAPTER_NAME:
		status = get_adapter_name();
		break;
	case HAL_PROP_ADAPTER_UUIDS:
		status = get_adapter_uuids();
		break;
	case HAL_PROP_ADAPTER_CLASS:
		status = get_adapter_class();
		break;
	case HAL_PROP_ADAPTER_TYPE:
		status = get_adapter_type();
		break;
	case HAL_PROP_ADAPTER_SERVICE_REC:
		status = get_adapter_service_rec();
		break;
	case HAL_PROP_ADAPTER_SCAN_MODE:
		status = get_adapter_scan_mode();
		break;
	case HAL_PROP_ADAPTER_BONDED_DEVICES:
		status = get_adapter_bonded_devices();
		break;
	case HAL_PROP_ADAPTER_DISC_TIMEOUT:
		status = get_adapter_discoverable_timeout();
		break;
	default:
		status = HAL_STATUS_FAILED;
		break;
	}

	if (status != HAL_STATUS_SUCCESS)
		error("Failed to get adapter property (type %u status %u)",
							cmd->type, status);

	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_ADAPTER_PROP,
									status);
}

static void get_adapter_properties(void)
{
	uint8_t buf[IPC_MTU];
	struct hal_ev_adapter_props_changed *ev = (void *) buf;
	uint8_t bonded[g_slist_length(bonded_devices) * sizeof(bdaddr_t)];
	uint128_t uuids[g_slist_length(adapter.uuids)];
	uint8_t android_bdaddr[6];
	uint8_t type, mode;
	int size, i;
	GSList *l;

	size = sizeof(*ev);

	ev->status = HAL_STATUS_SUCCESS;
	ev->num_props = 0;

	bdaddr2android(&adapter.bdaddr, &android_bdaddr);
	size += fill_hal_prop(buf + size, HAL_PROP_ADAPTER_ADDR,
					sizeof(android_bdaddr), android_bdaddr);
	ev->num_props++;

	if (adapter.name) {
		size += fill_hal_prop(buf + size, HAL_PROP_ADAPTER_NAME,
					strlen(adapter.name), adapter.name);
		ev->num_props++;
	}

	size += fill_hal_prop(buf + size, HAL_PROP_ADAPTER_CLASS,
				sizeof(adapter.dev_class), &adapter.dev_class);
	ev->num_props++;

	type = settings2type();
	if (type) {
		size += fill_hal_prop(buf + size, HAL_PROP_ADAPTER_TYPE,
							sizeof(type), &type);
		ev->num_props++;
	}

	mode = settings2scan_mode();
	size += fill_hal_prop(buf + size, HAL_PROP_ADAPTER_SCAN_MODE,
							sizeof(mode), &mode);
	ev->num_props++;

	size += fill_hal_prop(buf + size, HAL_PROP_ADAPTER_DISC_TIMEOUT,
					sizeof(adapter.discoverable_timeout),
					&adapter.discoverable_timeout);
	ev->num_props++;

	for (i = 0, l = bonded_devices; l; l = g_slist_next(l), i++) {
		struct device *dev = l->data;

		bdaddr2android(&dev->bdaddr, bonded + (i * sizeof(bdaddr_t)));
	}

	size += fill_hal_prop(buf + size, HAL_PROP_ADAPTER_BONDED_DEVICES,
						sizeof(bonded), bonded);
	ev->num_props++;

	for (i = 0, l = adapter.uuids; l; l = g_slist_next(l), i++) {
		uuid_t *uuid = l->data;

		memcpy(&uuids[i], &uuid->value.uuid128, sizeof(uint128_t));
	}

	size += fill_hal_prop(buf + size, HAL_PROP_ADAPTER_UUIDS, sizeof(uuids),
									uuids);
	ev->num_props++;

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
				HAL_EV_ADAPTER_PROPS_CHANGED, size, buf);
}

static void cancel_pending_confirm_name(gpointer data, gpointer user_data)
{
	struct device *dev = data;

	mgmt_cancel(mgmt_if, dev->confirm_id);
	dev->confirm_id = 0;
}

static bool stop_discovery(uint8_t type)
{
	struct mgmt_cp_stop_discovery cp;

	cp.type = get_supported_discovery_type() & type;

	DBG("type=0x%x", cp.type);

	if (cp.type == SCAN_TYPE_NONE)
		return false;

	/* Lets drop all confirm name request as we don't need it anymore */
	g_slist_foreach(cached_devices, cancel_pending_confirm_name, NULL);

	if (mgmt_send(mgmt_if, MGMT_OP_STOP_DISCOVERY, adapter.index,
					sizeof(cp), &cp, NULL, NULL, NULL) > 0)
		return true;

	error("Failed to stop discovery");
	return false;
}

struct adv_user_data {
	bt_le_set_advertising_done cb;
	void *user_data;
};

static void set_advertising_cb(uint8_t status, uint16_t length,
			const void *param, void *user_data)
{
	struct adv_user_data *data = user_data;

	DBG("");

	if (status)
		error("Failed to set adverising %s (0x%02x))",
						mgmt_errstr(status), status);

	data->cb(status, data->user_data);
}

bool bt_le_set_advertising(bool advertising, bt_le_set_advertising_done cb,
							 void *user_data)
{
	struct adv_user_data *data;
	uint8_t adv = advertising ? 0x01 : 0x00;

	data = new0(struct adv_user_data, 1);
	if (!data)
		return false;

	data->cb = cb;
	data->user_data = user_data;

	if (mgmt_send(mgmt_if, MGMT_OP_SET_ADVERTISING, adapter.index,
			sizeof(adv), &adv, set_advertising_cb, data, free) > 0)
		return true;

	error("Failed to set advertising");
	free(data);
	return false;
}

bool bt_le_register(bt_le_device_found cb)
{
	if (gatt_device_found_cb)
		return false;

	gatt_device_found_cb = cb;

	return true;
}

void bt_le_unregister(void)
{
	gatt_device_found_cb = NULL;
}

bool bt_le_discovery_stop(bt_le_discovery_stopped cb)
{
	if (!(adapter.current_settings & MGMT_SETTING_POWERED))
		return false;

	adapter.le_scanning = false;

	if (adapter.cur_discovery_type != SCAN_TYPE_LE) {
		if (cb)
			cb();

		return true;
	}

	if (!stop_discovery(SCAN_TYPE_LE))
		return false;

	gatt_discovery_stopped_cb = cb;
	adapter.exp_discovery_type = SCAN_TYPE_NONE;

	return true;
}

bool bt_le_discovery_start(void)
{
	if (!(adapter.current_settings & MGMT_SETTING_POWERED))
		return false;

	adapter.le_scanning = true;

	/* If core is discovering, don't bother */
	if (adapter.cur_discovery_type != SCAN_TYPE_NONE)
		return true;

	if (start_discovery(SCAN_TYPE_LE))
		return true;

	return false;
}

struct read_rssi_user_data {
	bt_read_device_rssi_done cb;
	void *user_data;
};

static void read_device_rssi_cb(uint8_t status, uint16_t length,
			const void *param, void *user_data)
{
	const struct mgmt_rp_get_conn_info *rp = param;
	struct read_rssi_user_data *data = user_data;

	DBG("");

	if (status)
		error("Failed to get conn info: %s (0x%02x))",
						mgmt_errstr(status), status);

	if (length < sizeof(*rp)) {
		error("Wrong size of get conn info response");
		return;
	}

	data->cb(status, &rp->addr.bdaddr, rp->rssi, data->user_data);
}

bool bt_read_device_rssi(const bdaddr_t *addr, bt_read_device_rssi_done cb,
							void *user_data)
{
	struct device *dev;
	struct read_rssi_user_data *data;
	struct mgmt_cp_get_conn_info cp;

	dev = find_device(addr);
	if (!dev)
		return false;

	memcpy(&cp.addr.bdaddr, addr, sizeof(cp.addr.bdaddr));
	cp.addr.type = dev->bredr ? BDADDR_BREDR : dev->bdaddr_type;

	data = new0(struct read_rssi_user_data, 1);
	if (!data)
		return false;

	data->cb = cb;
	data->user_data = user_data;

	if (!mgmt_send(mgmt_if, MGMT_OP_GET_CONN_INFO, adapter.index,
			sizeof(cp), &cp, read_device_rssi_cb, data, free)) {
		free(data);
		error("Failed to get conn info");
		return false;
	}

	return true;
}

bool bt_get_csrk(const bdaddr_t *addr, enum bt_csrk_type type, uint8_t key[16],
							uint32_t *sign_cnt)
{
	struct device *dev;
	bool local = (type == LOCAL_CSRK);

	dev = find_device(addr);
	if (!dev)
		return false;

	if (local && dev->valid_local_csrk) {
		memcpy(key, dev->local_csrk, 16);
		*sign_cnt = dev->local_sign_cnt;
	} else if (!local && dev->valid_remote_csrk) {
		memcpy(key, dev->remote_csrk, 16);
		*sign_cnt = dev->remote_sign_cnt;
	} else {
		return false;
	}

	return true;
}

static void store_sign_counter(struct device *dev, enum bt_csrk_type type)
{
	const char *sign_cnt_s;
	uint32_t sign_cnt;
	GKeyFile *key_file;
	bool local = (type == LOCAL_CSRK);

	gsize length = 0;
	char addr[18];
	char *data;

	key_file = g_key_file_new();
	if (!g_key_file_load_from_file(key_file, DEVICES_FILE, 0, NULL)) {
		g_key_file_free(key_file);
		return;
	}

	ba2str(&dev->bdaddr, addr);

	sign_cnt_s = local ? "LocalCSRKSignCounter" : "RemoteCSRKSignCounter";
	sign_cnt = local ? dev->local_sign_cnt : dev->remote_sign_cnt;

	g_key_file_set_integer(key_file, addr, sign_cnt_s, sign_cnt);

	data = g_key_file_to_data(key_file, &length, NULL);
	g_file_set_contents(DEVICES_FILE, data, length, NULL);
	g_free(data);

	g_key_file_free(key_file);
}

void bt_update_sign_counter(const bdaddr_t *addr, enum bt_csrk_type type)
{
	struct device *dev;

	dev = find_device(addr);
	if (!dev)
		return;

	if (type == LOCAL_CSRK)
		dev->local_sign_cnt++;
	else
		dev->remote_sign_cnt++;

	store_sign_counter(dev, type);
}

static uint8_t set_adapter_scan_mode(const void *buf, uint16_t len)
{
	const uint8_t *mode = buf;
	bool conn, disc, cur_conn, cur_disc;

	if (len != sizeof(*mode)) {
		error("Invalid set scan mode size (%u bytes), terminating",
								len);
		raise(SIGTERM);
		return HAL_STATUS_FAILED;
	}

	cur_conn = adapter.current_settings & MGMT_SETTING_CONNECTABLE;
	cur_disc = adapter.current_settings & MGMT_SETTING_DISCOVERABLE;

	DBG("connectable %u discoverable %d mode %u", cur_conn, cur_disc,
								*mode);

	switch (*mode) {
	case HAL_ADAPTER_SCAN_MODE_NONE:
		if (!cur_conn && !cur_disc)
			goto done;

		conn = false;
		disc = false;
		break;
	case HAL_ADAPTER_SCAN_MODE_CONN:
		if (cur_conn && !cur_disc)
			goto done;

		conn = true;
		disc = false;
		break;
	case HAL_ADAPTER_SCAN_MODE_CONN_DISC:
		if (cur_conn && cur_disc)
			goto done;

		conn = true;
		disc = true;
		break;
	default:
		return HAL_STATUS_FAILED;
	}

	if (cur_conn != conn) {
		if (!set_mode(MGMT_OP_SET_CONNECTABLE, conn ? 0x01 : 0x00))
			return HAL_STATUS_FAILED;
	}

	if (cur_disc != disc && conn) {
		if (!set_discoverable(disc ? 0x01 : 0x00, 0))
			return HAL_STATUS_FAILED;
	}

	return HAL_STATUS_SUCCESS;

done:
	/* Android expects property changed callback */
	scan_mode_changed();

	return HAL_STATUS_SUCCESS;
}

static void handle_set_adapter_prop_cmd(const void *buf, uint16_t len)
{
	const struct hal_cmd_set_adapter_prop *cmd = buf;
	uint8_t status;

	if (len != sizeof(*cmd) + cmd->len) {
		error("Invalid set adapter prop cmd (0x%x), terminating",
								cmd->type);
		raise(SIGTERM);
		return;
	}

	switch (cmd->type) {
	case HAL_PROP_ADAPTER_SCAN_MODE:
		status = set_adapter_scan_mode(cmd->val, cmd->len);
		break;
	case HAL_PROP_ADAPTER_NAME:
		status = set_adapter_name(cmd->val, cmd->len);
		break;
	case HAL_PROP_ADAPTER_DISC_TIMEOUT:
		status = set_adapter_discoverable_timeout(cmd->val, cmd->len);
		break;
	default:
		DBG("Unhandled property type 0x%x", cmd->type);
		status = HAL_STATUS_FAILED;
		break;
	}

	if (status != HAL_STATUS_SUCCESS)
		error("Failed to set adapter property (type %u status %u)",
							cmd->type, status);

	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_SET_ADAPTER_PROP,
									status);
}

static void pair_device_complete(uint8_t status, uint16_t length,
					const void *param, void *user_data)
{
	const struct mgmt_rp_pair_device *rp = param;
	struct device *dev;

	DBG("status %u", status);

	/*
	 * On success bond state change will be send when new link key or LTK
	 * event is received
	 */
	if (status == MGMT_STATUS_SUCCESS)
		return;

	dev = find_device(&rp->addr.bdaddr);
	if (!dev)
		return;

	update_device_state(dev, rp->addr.type, status_mgmt2hal(status), false,
								false, false);
}

static uint8_t select_device_bearer(struct device *dev)
{
	if (dev->bredr && dev->le) {
		if (dev->le_seen > dev->bredr_seen)
			return dev->bdaddr_type;

		return BDADDR_BREDR;
	}

	return dev->bredr ? BDADDR_BREDR : dev->bdaddr_type;
}

static bool device_is_paired(struct device *dev, uint8_t addr_type)
{
	if (addr_type == BDADDR_BREDR)
		return dev->bredr_paired;

	return dev->le_paired;
}

static void handle_create_bond_cmd(const void *buf, uint16_t len)
{
	const struct hal_cmd_create_bond *cmd = buf;
	struct device *dev;
	uint8_t status;
	struct mgmt_cp_pair_device cp;

	cp.io_cap = DEFAULT_IO_CAPABILITY;
	android2bdaddr(cmd->bdaddr, &cp.addr.bdaddr);

	/* type is used only as fallback when device is not in cache */
	dev = get_device(&cp.addr.bdaddr, BDADDR_BREDR);

	cp.addr.type = select_device_bearer(dev);

	if (device_is_paired(dev, cp.addr.type)) {
		status = HAL_STATUS_FAILED;
		goto fail;
	}

	if (mgmt_send(mgmt_if, MGMT_OP_PAIR_DEVICE, adapter.index, sizeof(cp),
				&cp, pair_device_complete, NULL, NULL) == 0) {
		status = HAL_STATUS_FAILED;
		goto fail;
	}

	status = HAL_STATUS_SUCCESS;

	update_device_state(dev, cp.addr.type, HAL_STATUS_SUCCESS, true, false,
									false);

fail:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_CREATE_BOND,
									status);
}

static void handle_cancel_bond_cmd(const void *buf, uint16_t len)
{
	const struct hal_cmd_cancel_bond *cmd = buf;
	struct mgmt_addr_info cp;
	struct device *dev;
	uint8_t status;

	android2bdaddr(cmd->bdaddr, &cp.bdaddr);

	dev = find_device(&cp.bdaddr);
	if (!dev) {
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	cp.type = select_device_bearer(dev);

	if (mgmt_reply(mgmt_if, MGMT_OP_CANCEL_PAIR_DEVICE,
					adapter.index, sizeof(cp), &cp,
					NULL, NULL, NULL) == 0) {
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	status = HAL_STATUS_SUCCESS;

failed:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_CANCEL_BOND,
									status);
}

static void unpair_device_complete(uint8_t status, uint16_t length,
					const void *param, void *user_data)
{
	const struct mgmt_rp_unpair_device *rp = param;
	struct device *dev;

	DBG("status %u", status);

	if (status != MGMT_STATUS_SUCCESS && status != MGMT_STATUS_NOT_PAIRED)
		return;

	dev = find_device(&rp->addr.bdaddr);
	if (!dev)
		return;

	update_device_state(dev, rp->addr.type, HAL_STATUS_SUCCESS, false,
								false, false);
}

static void handle_remove_bond_cmd(const void *buf, uint16_t len)
{
	const struct hal_cmd_remove_bond *cmd = buf;
	struct mgmt_cp_unpair_device cp;
	struct device *dev;
	uint8_t status;

	cp.disconnect = 1;
	android2bdaddr(cmd->bdaddr, &cp.addr.bdaddr);

	dev = find_device(&cp.addr.bdaddr);
	if (!dev) {
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	if (dev->le_paired) {
		cp.addr.type = dev->bdaddr_type;

		if (mgmt_send(mgmt_if, MGMT_OP_UNPAIR_DEVICE, adapter.index,
					sizeof(cp), &cp, unpair_device_complete,
					NULL, NULL) == 0) {
			status = HAL_STATUS_FAILED;
			goto failed;
		}
	}

	if (dev->bredr_paired) {
		cp.addr.type = BDADDR_BREDR;

		if (mgmt_send(mgmt_if, MGMT_OP_UNPAIR_DEVICE, adapter.index,
					sizeof(cp), &cp, unpair_device_complete,
					NULL, NULL) == 0) {
			status = HAL_STATUS_FAILED;
			goto failed;
		}
	}

	status = HAL_STATUS_SUCCESS;

failed:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_REMOVE_BOND,
									status);
}

static void handle_pin_reply_cmd(const void *buf, uint16_t len)
{
	const struct hal_cmd_pin_reply *cmd = buf;
	uint8_t status;
	bdaddr_t bdaddr;
	char addr[18];

	android2bdaddr(cmd->bdaddr, &bdaddr);
	ba2str(&bdaddr, addr);

	DBG("%s accept %u pin_len %u", addr, cmd->accept, cmd->pin_len);

	if (!cmd->accept && cmd->pin_len) {
		status = HAL_STATUS_INVALID;
		goto failed;
	}

	if (cmd->accept) {
		struct mgmt_cp_pin_code_reply rp;

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

		bacpy(&rp.addr.bdaddr, &bdaddr);
		rp.addr.type = BDADDR_BREDR;
		rp.pin_len = cmd->pin_len;
		memcpy(rp.pin_code, cmd->pin_code, rp.pin_len);

		if (mgmt_reply(mgmt_if, MGMT_OP_PIN_CODE_REPLY, adapter.index,
				sizeof(rp), &rp, NULL, NULL, NULL) == 0) {
			status = HAL_STATUS_FAILED;
			goto failed;
		}
	} else {
		struct mgmt_cp_pin_code_neg_reply rp;

		bacpy(&rp.addr.bdaddr, &bdaddr);
		rp.addr.type = BDADDR_BREDR;

		if (mgmt_reply(mgmt_if, MGMT_OP_PIN_CODE_NEG_REPLY,
						adapter.index, sizeof(rp), &rp,
						NULL, NULL, NULL) == 0) {
			status = HAL_STATUS_FAILED;
			goto failed;
		}
	}

	status = HAL_STATUS_SUCCESS;
failed:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_PIN_REPLY,
									status);
}

static uint8_t user_confirm_reply(const bdaddr_t *bdaddr, bool accept)
{
	struct mgmt_addr_info cp;
	uint16_t opcode;

	if (accept)
		opcode = MGMT_OP_USER_CONFIRM_REPLY;
	else
		opcode = MGMT_OP_USER_CONFIRM_NEG_REPLY;

	bacpy(&cp.bdaddr, bdaddr);
	cp.type = BDADDR_BREDR;

	if (mgmt_reply(mgmt_if, opcode, adapter.index, sizeof(cp), &cp,
							NULL, NULL, NULL) > 0)
		return HAL_STATUS_SUCCESS;

	return HAL_STATUS_FAILED;
}

static uint8_t user_passkey_reply(const bdaddr_t *bdaddr, bool accept,
							uint32_t passkey)
{
	unsigned int id;

	if (accept) {
		struct mgmt_cp_user_passkey_reply cp;

		memset(&cp, 0, sizeof(cp));
		bacpy(&cp.addr.bdaddr, bdaddr);
		cp.addr.type = BDADDR_BREDR;
		cp.passkey = htobl(passkey);

		id = mgmt_reply(mgmt_if, MGMT_OP_USER_PASSKEY_REPLY,
						adapter.index, sizeof(cp), &cp,
						NULL, NULL, NULL);
	} else {
		struct mgmt_cp_user_passkey_neg_reply cp;

		memset(&cp, 0, sizeof(cp));
		bacpy(&cp.addr.bdaddr, bdaddr);
		cp.addr.type = BDADDR_BREDR;

		id = mgmt_reply(mgmt_if, MGMT_OP_USER_PASSKEY_NEG_REPLY,
						adapter.index, sizeof(cp), &cp,
						NULL, NULL, NULL);
	}

	if (id == 0)
		return HAL_STATUS_FAILED;

	return HAL_STATUS_SUCCESS;
}

static void handle_ssp_reply_cmd(const void *buf, uint16_t len)
{
	const struct hal_cmd_ssp_reply *cmd = buf;
	bdaddr_t bdaddr;
	uint8_t status;
	char addr[18];

	/* TODO should parameters sanity be verified here? */

	android2bdaddr(cmd->bdaddr, &bdaddr);
	ba2str(&bdaddr, addr);

	DBG("%s variant %u accept %u", addr, cmd->ssp_variant, cmd->accept);

	switch (cmd->ssp_variant) {
	case HAL_SSP_VARIANT_CONFIRM:
	case HAL_SSP_VARIANT_CONSENT:
		status = user_confirm_reply(&bdaddr, cmd->accept);
		break;
	case HAL_SSP_VARIANT_ENTRY:
		status = user_passkey_reply(&bdaddr, cmd->accept,
								cmd->passkey);
		break;
	case HAL_SSP_VARIANT_NOTIF:
		status = HAL_STATUS_SUCCESS;
		break;
	default:
		status = HAL_STATUS_INVALID;
		break;
	}

	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_SSP_REPLY,
									status);
}

static void handle_get_remote_services_cmd(const void *buf, uint16_t len)
{
	const struct hal_cmd_get_remote_services *cmd = buf;
	uint8_t status;
	bdaddr_t addr;

	android2bdaddr(&cmd->bdaddr, &addr);

	status = browse_remote_sdp(&addr);

	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
					HAL_OP_GET_REMOTE_SERVICES, status);
}

static uint8_t get_device_uuids(struct device *dev)
{
	send_device_uuids_notif(dev);

	return HAL_STATUS_SUCCESS;
}

static uint8_t get_device_class(struct device *dev)
{
	send_device_property(dev, HAL_PROP_DEVICE_CLASS,
					sizeof(dev->class), &dev->class);

	return HAL_STATUS_SUCCESS;
}

static uint8_t get_device_type(struct device *dev)
{
	uint8_t type = get_device_android_type(dev);

	send_device_property(dev, HAL_PROP_DEVICE_TYPE, sizeof(type), &type);

	return HAL_STATUS_SUCCESS;
}

static uint8_t get_device_service_rec(struct device *dev)
{
	DBG("Not implemented");

	/* TODO */

	return HAL_STATUS_FAILED;
}

static uint8_t get_device_friendly_name(struct device *dev)
{
	if (!dev->friendly_name)
		return HAL_STATUS_FAILED;

	send_device_property(dev, HAL_PROP_DEVICE_FRIENDLY_NAME,
				strlen(dev->friendly_name), dev->friendly_name);

	return HAL_STATUS_SUCCESS;
}

static uint8_t get_device_rssi(struct device *dev)
{
	if (!dev->rssi)
		return HAL_STATUS_FAILED;

	send_device_property(dev, HAL_PROP_DEVICE_RSSI,
						sizeof(dev->rssi), &dev->rssi);

	return HAL_STATUS_SUCCESS;
}

static uint8_t get_device_version_info(struct device *dev)
{
	DBG("Not implemented");

	/* TODO */

	return HAL_STATUS_FAILED;
}

static uint8_t get_device_timestamp(struct device *dev)
{
	uint32_t timestamp;

	timestamp = device_timestamp(dev);

	send_device_property(dev, HAL_PROP_DEVICE_TIMESTAMP,
						sizeof(timestamp), &timestamp);

	return HAL_STATUS_SUCCESS;
}

static void get_remote_device_props(struct device *dev)
{
	uint8_t buf[IPC_MTU];
	struct hal_ev_remote_device_props *ev = (void *) buf;
	uint128_t uuids[g_slist_length(dev->uuids)];
	uint8_t android_type;
	uint32_t timestamp;
	int size, i;
	GSList *l;

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

	size = sizeof(*ev);

	ev->status = HAL_STATUS_SUCCESS;
	bdaddr2android(&dev->bdaddr, ev->bdaddr);

	android_type = get_device_android_type(dev);
	size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_TYPE,
					sizeof(android_type), &android_type);
	ev->num_props++;

	size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_CLASS,
					sizeof(dev->class), &dev->class);
	ev->num_props++;

	if (dev->rssi) {
		size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_RSSI,
						sizeof(dev->rssi), &dev->rssi);
		ev->num_props++;
	}

	size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_NAME,
						strlen(dev->name), dev->name);
	ev->num_props++;

	if (dev->friendly_name) {
		size += fill_hal_prop(buf + size,
					HAL_PROP_DEVICE_FRIENDLY_NAME,
					strlen(dev->friendly_name),
					dev->friendly_name);
		ev->num_props++;
	}

	for (i = 0, l = dev->uuids; l; l = g_slist_next(l), i++)
		memcpy(&uuids[i], l->data, sizeof(uint128_t));

	size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_UUIDS, sizeof(uuids),
									uuids);
	ev->num_props++;

	timestamp = get_device_timestamp(dev);

	size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_TIMESTAMP,
						sizeof(timestamp), &timestamp);
	ev->num_props++;

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
					HAL_EV_REMOTE_DEVICE_PROPS, size, buf);
}

static void send_bonded_devices_props(void)
{
	GSList *l;

	for (l = bonded_devices; l; l = g_slist_next(l)) {
		struct device *dev = l->data;

		get_remote_device_props(dev);
	}
}

static void handle_enable_cmd(const void *buf, uint16_t len)
{
	uint8_t status;

	/*
	 * Framework expects all properties to be emitted while enabling
	 * adapter
	 */
	get_adapter_properties();

	/* Sent also properties of bonded devices */
	send_bonded_devices_props();

	if (adapter.current_settings & MGMT_SETTING_POWERED) {
		status = HAL_STATUS_SUCCESS;
		goto reply;
	}

	if (!set_mode(MGMT_OP_SET_POWERED, 0x01)) {
		status = HAL_STATUS_FAILED;
		goto reply;
	}

	status = HAL_STATUS_SUCCESS;
reply:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_ENABLE, status);
}

static void handle_disable_cmd(const void *buf, uint16_t len)
{
	uint8_t status;

	if (!(adapter.current_settings & MGMT_SETTING_POWERED)) {
		status = HAL_STATUS_SUCCESS;
		goto reply;
	}

	/* Cancel all pending requests. Need it in case of ongoing paring */
	mgmt_cancel_index(mgmt_if, adapter.index);

	if (!set_mode(MGMT_OP_SET_POWERED, 0x00)) {
		status = HAL_STATUS_FAILED;
		goto reply;
	}

	status = HAL_STATUS_SUCCESS;
reply:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_DISABLE, status);
}

static void handle_get_adapter_props_cmd(const void *buf, uint16_t len)
{
	get_adapter_properties();

	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
				HAL_OP_GET_ADAPTER_PROPS, HAL_STATUS_SUCCESS);
}

static void handle_get_remote_device_props_cmd(const void *buf, uint16_t len)
{
	const struct hal_cmd_get_remote_device_props *cmd = buf;
	struct device *dev;
	uint8_t status;
	bdaddr_t addr;

	android2bdaddr(cmd->bdaddr, &addr);

	dev = find_device(&addr);
	if (!dev) {
		status = HAL_STATUS_INVALID;
		goto failed;
	}

	get_remote_device_props(dev);

	status = HAL_STATUS_SUCCESS;

failed:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
					HAL_OP_GET_REMOTE_DEVICE_PROPS, status);
}

static void handle_get_remote_device_prop_cmd(const void *buf, uint16_t len)
{
	const struct hal_cmd_get_remote_device_prop *cmd = buf;
	struct device *dev;
	uint8_t status;
	bdaddr_t addr;

	android2bdaddr(cmd->bdaddr, &addr);

	dev = find_device(&addr);
	if (!dev) {
		status = HAL_STATUS_INVALID;
		goto failed;
	}

	switch (cmd->type) {
	case HAL_PROP_DEVICE_NAME:
		status = get_device_name(dev);
		break;
	case HAL_PROP_DEVICE_UUIDS:
		status = get_device_uuids(dev);
		break;
	case HAL_PROP_DEVICE_CLASS:
		status = get_device_class(dev);
		break;
	case HAL_PROP_DEVICE_TYPE:
		status = get_device_type(dev);
		break;
	case HAL_PROP_DEVICE_SERVICE_REC:
		status = get_device_service_rec(dev);
		break;
	case HAL_PROP_DEVICE_FRIENDLY_NAME:
		status = get_device_friendly_name(dev);
		break;
	case HAL_PROP_DEVICE_RSSI:
		status = get_device_rssi(dev);
		break;
	case HAL_PROP_DEVICE_VERSION_INFO:
		status = get_device_version_info(dev);
		break;
	case HAL_PROP_DEVICE_TIMESTAMP:
		status = get_device_timestamp(dev);
		break;
	default:
		status = HAL_STATUS_FAILED;
		break;
	}

	if (status != HAL_STATUS_SUCCESS)
		error("Failed to get device property (type %u status %u)",
							cmd->type, status);

failed:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
					HAL_OP_GET_REMOTE_DEVICE_PROP, status);
}

static uint8_t set_device_friendly_name(struct device *dev, const uint8_t *val,
								uint16_t len)
{
	DBG("");

	g_free(dev->friendly_name);
	dev->friendly_name = g_strndup((const char *) val, len);

	if (dev->bredr_paired || dev->le_paired)
		store_device_info(dev, DEVICES_FILE);
	else
		store_device_info(dev, CACHE_FILE);

	return HAL_STATUS_SUCCESS;
}

static uint8_t set_device_version_info(struct device *dev)
{
	DBG("Not implemented");

	/* TODO */

	return HAL_STATUS_FAILED;
}

static void handle_set_remote_device_prop_cmd(const void *buf, uint16_t len)
{
	const struct hal_cmd_set_remote_device_prop *cmd = buf;
	struct device *dev;
	uint8_t status;
	bdaddr_t addr;

	if (len != sizeof(*cmd) + cmd->len) {
		error("Invalid set remote device prop cmd (0x%x), terminating",
								cmd->type);
		raise(SIGTERM);
		return;
	}

	android2bdaddr(cmd->bdaddr, &addr);

	dev = find_device(&addr);
	if (!dev) {
		status = HAL_STATUS_INVALID;
		goto failed;
	}

	switch (cmd->type) {
	case HAL_PROP_DEVICE_FRIENDLY_NAME:
		status = set_device_friendly_name(dev, cmd->val, cmd->len);
		break;
	case HAL_PROP_DEVICE_VERSION_INFO:
		status = set_device_version_info(dev);
		break;
	default:
		status = HAL_STATUS_FAILED;
		break;
	}

	if (status != HAL_STATUS_SUCCESS)
		error("Failed to set device property (type %u status %u)",
							cmd->type, status);

failed:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
					HAL_OP_SET_REMOTE_DEVICE_PROP, status);
}

static void handle_get_remote_service_rec_cmd(const void *buf, uint16_t len)
{
	/* TODO */

	error("get_remote_service_record not supported");

	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
			HAL_OP_GET_REMOTE_SERVICE_REC, HAL_STATUS_FAILED);
}

static void handle_start_discovery_cmd(const void *buf, uint16_t len)
{
	uint8_t status;

	if (!(adapter.current_settings & MGMT_SETTING_POWERED)) {
		status = HAL_STATUS_NOT_READY;
		goto failed;
	}

	switch (adapter.cur_discovery_type) {
	case SCAN_TYPE_DUAL:
	case SCAN_TYPE_BREDR:
		break;
	case SCAN_TYPE_NONE:
		if (!start_discovery(SCAN_TYPE_DUAL)) {
			status = HAL_STATUS_FAILED;
			goto failed;
		}

		break;
	case SCAN_TYPE_LE:
		if (get_supported_discovery_type() == SCAN_TYPE_LE)
			break;

		if (!stop_discovery(SCAN_TYPE_LE)) {
			status = HAL_STATUS_FAILED;
			goto failed;
		}

		adapter.exp_discovery_type = SCAN_TYPE_DUAL;
		break;
	}

	status = HAL_STATUS_SUCCESS;

failed:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_START_DISCOVERY,
									status);
}

static void handle_cancel_discovery_cmd(const void *buf, uint16_t len)
{
	uint8_t status;

	if (!(adapter.current_settings & MGMT_SETTING_POWERED)) {
		status = HAL_STATUS_NOT_READY;
		goto failed;
	}

	switch (adapter.cur_discovery_type) {
	case SCAN_TYPE_NONE:
		break;
	case SCAN_TYPE_LE:
		if (get_supported_discovery_type() != SCAN_TYPE_LE)
			break;

		if (gatt_device_found_cb) {
			status = HAL_STATUS_BUSY;
			goto failed;
		}

		if (!stop_discovery(SCAN_TYPE_LE)) {
			status = HAL_STATUS_FAILED;
			goto failed;
		}

		break;
	case SCAN_TYPE_DUAL:
	case SCAN_TYPE_BREDR:
		if (!stop_discovery(SCAN_TYPE_DUAL)) {
			status = HAL_STATUS_FAILED;
			goto failed;
		}

		adapter.exp_discovery_type = gatt_device_found_cb ?
						SCAN_TYPE_LE : SCAN_TYPE_NONE;
		break;
	}

	status = HAL_STATUS_SUCCESS;

failed:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_CANCEL_DISCOVERY,
									status);
}

static void handle_dut_mode_conf_cmd(const void *buf, uint16_t len)
{
	const struct hal_cmd_dut_mode_conf *cmd = buf;
	char path[FILENAME_MAX];
	uint8_t status;
	int fd, ret;

	DBG("enable %u", cmd->enable);

	snprintf(path, sizeof(path), DUT_MODE_FILE, adapter.index);

	fd = open(path, O_WRONLY);
	if (fd < 0) {
		status = HAL_STATUS_FAILED;
		goto failed;
	}

	if (cmd->enable)
		ret = write(fd, "1", sizeof("1"));
	else
		ret = write(fd, "0", sizeof("0"));

	if (ret < 0)
		status = HAL_STATUS_FAILED;
	else
		status = HAL_STATUS_SUCCESS;

	close(fd);

failed:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_DUT_MODE_CONF,
									status);
}

static void handle_dut_mode_send_cmd(const void *buf, uint16_t len)
{
	const struct hal_cmd_dut_mode_send *cmd = buf;

	if (len != sizeof(*cmd) + cmd->len) {
		error("Invalid dut mode send cmd, terminating");
		raise(SIGTERM);
		return;
	}

	error("dut_mode_send not supported (cmd opcode %u)", cmd->opcode);

	/* TODO */

	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_DUT_MODE_SEND,
							HAL_STATUS_FAILED);
}

static void handle_le_test_mode_cmd(const void *buf, uint16_t len)
{
	const struct hal_cmd_le_test_mode *cmd = buf;

	if (len != sizeof(*cmd) + cmd->len) {
		error("Invalid le test mode cmd, terminating");
		raise(SIGTERM);
		return;
	}

	error("le_test_mode not supported (cmd opcode %u)", cmd->opcode);

	/* TODO */

	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_LE_TEST_MODE,
							HAL_STATUS_FAILED);
}

static const struct ipc_handler cmd_handlers[] = {
	/* HAL_OP_ENABLE */
	{ handle_enable_cmd, false, 0 },
	/* HAL_OP_DISABLE */
	{ handle_disable_cmd, false, 0 },
	/* HAL_OP_GET_ADAPTER_PROPS */
	{ handle_get_adapter_props_cmd, false, 0 },
	/* HAL_OP_GET_ADAPTER_PROP */
	{ handle_get_adapter_prop_cmd, false,
				sizeof(struct hal_cmd_get_adapter_prop) },
	/* HAL_OP_SET_ADAPTER_PROP */
	{ handle_set_adapter_prop_cmd, true,
				sizeof(struct hal_cmd_set_adapter_prop) },
	/* HAL_OP_GET_REMOTE_DEVICE_PROPS */
	{ handle_get_remote_device_props_cmd, false,
			sizeof(struct hal_cmd_get_remote_device_props) },
	/* HAL_OP_GET_REMOTE_DEVICE_PROP */
	{ handle_get_remote_device_prop_cmd, false,
				sizeof(struct hal_cmd_get_remote_device_prop) },
	/* HAL_OP_SET_REMOTE_DEVICE_PROP */
	{ handle_set_remote_device_prop_cmd, true,
				sizeof(struct hal_cmd_set_remote_device_prop) },
	/* HAL_OP_GET_REMOTE_SERVICE_REC */
	{ handle_get_remote_service_rec_cmd, false,
				sizeof(struct hal_cmd_get_remote_service_rec) },
	/* HAL_OP_GET_REMOTE_SERVICES */
	{ handle_get_remote_services_cmd, false,
				sizeof(struct hal_cmd_get_remote_services) },
	/* HAL_OP_START_DISCOVERY */
	{ handle_start_discovery_cmd, false, 0 },
	/* HAL_OP_CANCEL_DISCOVERY */
	{ handle_cancel_discovery_cmd, false, 0 },
	/* HAL_OP_CREATE_BOND */
	{ handle_create_bond_cmd, false, sizeof(struct hal_cmd_create_bond) },
	/* HAL_OP_REMOVE_BOND */
	{ handle_remove_bond_cmd, false, sizeof(struct hal_cmd_remove_bond) },
	/* HAL_OP_CANCEL_BOND */
	{handle_cancel_bond_cmd, false, sizeof(struct hal_cmd_cancel_bond) },
	/* HAL_OP_PIN_REPLY */
	{ handle_pin_reply_cmd, false, sizeof(struct hal_cmd_pin_reply) },
	/* HAL_OP_SSP_REPLY */
	{ handle_ssp_reply_cmd, false, sizeof(struct hal_cmd_ssp_reply) },
	/* HAL_OP_DUT_MODE_CONF */
	{ handle_dut_mode_conf_cmd, false,
					sizeof(struct hal_cmd_dut_mode_conf) },
	/* HAL_OP_DUT_MODE_SEND */
	{ handle_dut_mode_send_cmd, true,
					sizeof(struct hal_cmd_dut_mode_send) },
	/* HAL_OP_LE_TEST_MODE */
	{ handle_le_test_mode_cmd, true, sizeof(struct hal_cmd_le_test_mode) },
};

bool bt_bluetooth_register(struct ipc *ipc, uint8_t mode)
{
	uint32_t missing_settings;

	DBG("mode 0x%x", mode);

	missing_settings = adapter.current_settings ^
					adapter.supported_settings;

	switch (mode) {
	case HAL_MODE_DEFAULT:
		if (missing_settings & MGMT_SETTING_BREDR)
			set_mode(MGMT_OP_SET_BREDR, 0x01);

		if (missing_settings & MGMT_SETTING_LE)
			set_mode(MGMT_OP_SET_LE, 0x01);
		break;
	case HAL_MODE_LE:
		/* Fail if controller does not support LE */
		if (!(adapter.supported_settings & MGMT_SETTING_LE)) {
			error("LE Mode not supported by controller");
			return false;
		}

		/* If LE it is not yet enabled then enable it */
		if (!(adapter.current_settings & MGMT_SETTING_LE))
			set_mode(MGMT_OP_SET_LE, 0x01);

		/* Disable BR/EDR if it is enabled */
		if (adapter.current_settings & MGMT_SETTING_BREDR)
			set_mode(MGMT_OP_SET_BREDR, 0x00);
		break;
	case HAL_MODE_BREDR:
		/* Fail if controller does not support BR/EDR */
		if (!(adapter.supported_settings & MGMT_SETTING_BREDR)) {
			error("BR/EDR Mode not supported");
			return false;
		}

		/* Enable BR/EDR if it is not enabled */
		if (missing_settings & MGMT_SETTING_BREDR)
			set_mode(MGMT_OP_SET_BREDR, 0x01);

		/*
		 * According to Core Spec 4.0 host should not disable LE in
		 * controller if it was enabled (Vol 2. Part E. 7.3.79).
		 * Core Spec 4.1 removed this limitation and chips seem to be
		 * handling this just fine anyway.
		 */
		if (adapter.current_settings & MGMT_SETTING_LE)
			set_mode(MGMT_OP_SET_LE, 0x00);
		break;
	default:
		error("Unknown mode 0x%x", mode);
		return false;
	}

	hal_ipc = ipc;

	ipc_register(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, cmd_handlers,
						G_N_ELEMENTS(cmd_handlers));

	return true;
}

void bt_bluetooth_unregister(void)
{
	DBG("");

	g_slist_free_full(bonded_devices, (GDestroyNotify) free_device);
	bonded_devices = NULL;

	g_slist_free_full(cached_devices, (GDestroyNotify) free_device);
	cached_devices = NULL;

	ipc_unregister(hal_ipc, HAL_SERVICE_ID_CORE);
	hal_ipc = NULL;
}
