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

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

#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <sys/file.h>
#include <sys/stat.h>

#include <glib.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/sdp.h>
#include <bluetooth/sdp_lib.h>
#include <bluetooth/uuid.h>

#include "textfile.h"
#include "glib-helper.h"
#include "storage.h"

/* When all services should trust a remote device */
#define GLOBAL_TRUST "[all]"

struct match {
	GSList *keys;
	char *pattern;
};

static inline int create_filename(char *buf, size_t size,
				const bdaddr_t *bdaddr, const char *name)
{
	char addr[18];

	ba2str(bdaddr, addr);

	return create_name(buf, size, STORAGEDIR, addr, name);
}

int read_device_alias(const char *src, const char *dst, uint8_t dst_type,
						char *alias, size_t size)
{
	char filename[PATH_MAX + 1], *tmp;
	char key[20];
	int err;

	create_name(filename, PATH_MAX, STORAGEDIR, src, "aliases");

	snprintf(key, sizeof(key), "%17s#%hhu", dst, dst_type);

	tmp = textfile_get(filename, key);
	if (tmp != NULL)
		goto done;

	/* Try old format (address only) */
	key[17] = '\0';

	tmp = textfile_get(filename, key);
	if (tmp == NULL)
		return -ENXIO;

done:
	err = snprintf(alias, size, "%s", tmp);

	free(tmp);

	return err < 0 ? -EIO : 0;
}

int write_device_alias(const char *src, const char *dst, uint8_t dst_type,
							const char *alias)
{
	char filename[PATH_MAX + 1];
	char key[20];

	create_name(filename, PATH_MAX, STORAGEDIR, src, "aliases");

	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

	snprintf(key, sizeof(key), "%17s#%hhu", dst, dst_type);

	return textfile_put(filename, key, alias);
}

int write_discoverable_timeout(const bdaddr_t *bdaddr, int timeout)
{
	char filename[PATH_MAX + 1], str[32];

	snprintf(str, sizeof(str), "%d", timeout);

	create_filename(filename, PATH_MAX, bdaddr, "config");

	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

	return textfile_put(filename, "discovto", str);
}

int read_discoverable_timeout(const char *src, int *timeout)
{
	char filename[PATH_MAX + 1], *str;

	create_name(filename, PATH_MAX, STORAGEDIR, src, "config");

	str = textfile_get(filename, "discovto");
	if (!str)
		return -ENOENT;

	if (sscanf(str, "%d", timeout) != 1) {
		free(str);
		return -ENOENT;
	}

	free(str);

	return 0;
}

int write_pairable_timeout(const bdaddr_t *bdaddr, int timeout)
{
	char filename[PATH_MAX + 1], str[32];

	snprintf(str, sizeof(str), "%d", timeout);

	create_filename(filename, PATH_MAX, bdaddr, "config");

	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

	return textfile_put(filename, "pairto", str);
}

int read_pairable_timeout(const char *src, int *timeout)
{
	char filename[PATH_MAX + 1], *str;

	create_name(filename, PATH_MAX, STORAGEDIR, src, "config");

	str = textfile_get(filename, "pairto");
	if (!str)
		return -ENOENT;

	if (sscanf(str, "%d", timeout) != 1) {
		free(str);
		return -ENOENT;
	}

	free(str);

	return 0;
}

int write_device_mode(const bdaddr_t *bdaddr, const char *mode)
{
	char filename[PATH_MAX + 1];

	create_filename(filename, PATH_MAX, bdaddr, "config");

	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

	if (strcmp(mode, "off") != 0)
		textfile_put(filename, "onmode", mode);

	return textfile_put(filename, "mode", mode);
}

int read_device_mode(const char *src, char *mode, int length)
{
	char filename[PATH_MAX + 1], *str;

	create_name(filename, PATH_MAX, STORAGEDIR, src, "config");

	str = textfile_get(filename, "mode");
	if (!str)
		return -ENOENT;

	strncpy(mode, str, length);
	mode[length - 1] = '\0';

	free(str);

	return 0;
}

int read_on_mode(const char *src, char *mode, int length)
{
	char filename[PATH_MAX + 1], *str;

	create_name(filename, PATH_MAX, STORAGEDIR, src, "config");

	str = textfile_get(filename, "onmode");
	if (!str)
		return -ENOENT;

	strncpy(mode, str, length);
	mode[length - 1] = '\0';

	free(str);

	return 0;
}

int write_local_name(const bdaddr_t *bdaddr, const char *name)
{
	char filename[PATH_MAX + 1], str[249];
	int i;

	memset(str, 0, sizeof(str));
	for (i = 0; i < 248 && name[i]; i++)
		if ((unsigned char) name[i] < 32 || name[i] == 127)
			str[i] = '.';
		else
			str[i] = name[i];

	create_filename(filename, PATH_MAX, bdaddr, "config");

	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

	return textfile_put(filename, "name", str);
}

int read_local_name(const bdaddr_t *bdaddr, char *name)
{
	char filename[PATH_MAX + 1], *str;
	int len;

	create_filename(filename, PATH_MAX, bdaddr, "config");

	str = textfile_get(filename, "name");
	if (!str)
		return -ENOENT;

	len = strlen(str);
	if (len > HCI_MAX_NAME_LENGTH)
		str[HCI_MAX_NAME_LENGTH] = '\0';
	strcpy(name, str);

	free(str);

	return 0;
}

int write_local_class(const bdaddr_t *bdaddr, uint8_t *class)
{
	char filename[PATH_MAX + 1], str[9];

	sprintf(str, "0x%2.2x%2.2x%2.2x", class[2], class[1], class[0]);

	create_filename(filename, PATH_MAX, bdaddr, "config");

	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

	return textfile_put(filename, "class", str);
}

int read_local_class(const bdaddr_t *bdaddr, uint8_t *class)
{
	char filename[PATH_MAX + 1], tmp[3], *str;
	int i;

	create_filename(filename, PATH_MAX, bdaddr, "config");

	str = textfile_get(filename, "class");
	if (!str)
		return -ENOENT;

	memset(tmp, 0, sizeof(tmp));
	for (i = 0; i < 3; i++) {
		memcpy(tmp, str + (i * 2) + 2, 2);
		class[2 - i] = (uint8_t) strtol(tmp, NULL, 16);
	}

	free(str);

	return 0;
}

int read_remote_appearance(const bdaddr_t *local, const bdaddr_t *peer,
				uint8_t bdaddr_type, uint16_t *appearance)
{
	char filename[PATH_MAX + 1], key[20], *str;

	create_filename(filename, PATH_MAX, local, "appearances");

	ba2str(peer, key);
	sprintf(&key[17], "#%hhu", bdaddr_type);

	str = textfile_get(filename, key);
	if (!str)
		return -ENOENT;

	if (sscanf(str, "%hx", appearance) != 1) {
		free(str);
		return -ENOENT;
	}

	free(str);

	return 0;
}

int write_remote_appearance(const bdaddr_t *local, const bdaddr_t *peer,
				uint8_t bdaddr_type, uint16_t appearance)
{
	char filename[PATH_MAX + 1], key[20], str[7];

	create_filename(filename, PATH_MAX, local, "appearances");

	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

	ba2str(peer, key);
	sprintf(&key[17], "#%hhu", bdaddr_type);

	sprintf(str, "0x%4.4x", appearance);

	return textfile_put(filename, key, str);
}

int write_remote_class(const bdaddr_t *local, const bdaddr_t *peer,
								uint32_t class)
{
	char filename[PATH_MAX + 1], addr[18], str[9];

	create_filename(filename, PATH_MAX, local, "classes");

	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

	ba2str(peer, addr);
	sprintf(str, "0x%6.6x", class);

	return textfile_put(filename, addr, str);
}

int read_remote_class(const bdaddr_t *local, const bdaddr_t *peer,
							uint32_t *class)
{
	char filename[PATH_MAX + 1], addr[18], *str;

	create_filename(filename, PATH_MAX, local, "classes");

	ba2str(peer, addr);

	str = textfile_get(filename, addr);
	if (!str)
		return -ENOENT;

	if (sscanf(str, "%x", class) != 1) {
		free(str);
		return -ENOENT;
	}

	free(str);

	return 0;
}

int write_device_name(const bdaddr_t *local, const bdaddr_t *peer,
					uint8_t peer_type, const char *name)
{
	char filename[PATH_MAX + 1], key[20], str[HCI_MAX_NAME_LENGTH + 1];
	int i;

	memset(str, 0, sizeof(str));
	for (i = 0; i < HCI_MAX_NAME_LENGTH && name[i]; i++)
		if ((unsigned char) name[i] < 32 || name[i] == 127)
			str[i] = '.';
		else
			str[i] = name[i];

	create_filename(filename, PATH_MAX, local, "names");

	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

	ba2str(peer, key);
	sprintf(&key[17], "#%hhu", peer_type);

	return textfile_put(filename, key, str);
}

int read_device_name(const char *src, const char *dst, uint8_t dst_type,
								char *name)
{
	char filename[PATH_MAX + 1], *str, key[20];
	int len;

	create_name(filename, PATH_MAX, STORAGEDIR, src, "names");

	snprintf(key, sizeof(key), "%17s#%hhu", dst, dst_type);

	str = textfile_get(filename, key);
	if (str != NULL)
		goto done;

	/* Try old format (address only) */
	key[17] = '\0';

	str = textfile_get(filename, key);
	if (str == NULL)
		return -ENOENT;

done:
	len = strlen(str);
	if (len > HCI_MAX_NAME_LENGTH)
		str[HCI_MAX_NAME_LENGTH] = '\0';
	strcpy(name, str);

	free(str);

	return 0;
}

int write_lastseen_info(const bdaddr_t *local, const bdaddr_t *peer,
					uint8_t peer_type, struct tm *tm)
{
	char filename[PATH_MAX + 1], key[20], str[24];

	memset(str, 0, sizeof(str));
	strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S %Z", tm);

	create_filename(filename, PATH_MAX, local, "lastseen");

	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

	ba2str(peer, key);
	sprintf(&key[17], "#%hhu", peer_type);

	return textfile_put(filename, key, str);
}

int write_lastused_info(const bdaddr_t *local, const bdaddr_t *peer,
					uint8_t peer_type, struct tm *tm)
{
	char filename[PATH_MAX + 1], key[20], str[24];

	memset(str, 0, sizeof(str));
	strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S %Z", tm);

	create_filename(filename, PATH_MAX, local, "lastused");

	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

	ba2str(peer, key);
	sprintf(&key[17], "#%hhu", peer_type);

	return textfile_put(filename, key, str);
}

int write_link_key(const bdaddr_t *local, const bdaddr_t *peer,
					uint8_t peer_type, unsigned char *key,
					uint8_t type, int length)
{
	char filename[PATH_MAX + 1], addr[20], str[38];
	int i;

	memset(str, 0, sizeof(str));
	for (i = 0; i < 16; i++)
		sprintf(str + (i * 2), "%2.2X", key[i]);
	sprintf(str + 32, " %d %d", type, length);

	create_filename(filename, PATH_MAX, local, "linkkeys");

	create_file(filename, S_IRUSR | S_IWUSR);

	ba2str(peer, addr);
	sprintf(&addr[17], "#%hhu", peer_type);

	if (length < 0) {
		char *tmp = textfile_get(filename, addr);
		if (tmp) {
			if (strlen(tmp) > 34)
				memcpy(str + 34, tmp + 34, 3);
			free(tmp);
		}
	}

	return textfile_put(filename, addr, str);
}

int read_link_key(const bdaddr_t *local, const bdaddr_t *peer,
					uint8_t peer_type, unsigned char *key,
					uint8_t *type)
{
	char filename[PATH_MAX + 1], addr[20], tmp[3], *str;
	int i;

	create_filename(filename, PATH_MAX, local, "linkkeys");

	ba2str(peer, addr);
	sprintf(&addr[17], "#%hhu", peer_type);

	str = textfile_get(filename, addr);
	if (str != NULL)
		goto done;

	/* Try old format (address only) */
	addr[17] = '\0';

	str = textfile_get(filename, addr);
	if (!str)
		return -ENOENT;

done:
	if (!key) {
		free(str);
		return 0;
	}

	memset(tmp, 0, sizeof(tmp));
	for (i = 0; i < 16; i++) {
		memcpy(tmp, str + (i * 2), 2);
		key[i] = (uint8_t) strtol(tmp, NULL, 16);
	}

	if (type) {
		memcpy(tmp, str + 33, 2);
		*type = (uint8_t) strtol(tmp, NULL, 10);
	}

	free(str);

	return 0;
}

ssize_t read_pin_code(const bdaddr_t *local, const bdaddr_t *peer, char *pin)
{
	char filename[PATH_MAX + 1], addr[18], *str;
	ssize_t len;

	create_filename(filename, PATH_MAX, local, "pincodes");

	ba2str(peer, addr);
	str = textfile_get(filename, addr);
	if (!str)
		return -ENOENT;

	strncpy(pin, str, 16);
	len = strlen(pin);

	free(str);

	return len;
}

int write_trust(const char *src, const char *addr, uint8_t addr_type,
							gboolean trust)
{
	char filename[PATH_MAX + 1], key[20];

	create_name(filename, PATH_MAX, STORAGEDIR, src, "trusts");

	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

	snprintf(key, sizeof(key), "%17s#%hhu", addr, addr_type);

	if (trust == FALSE)
		return textfile_casedel(filename, key);

	return textfile_caseput(filename, key, GLOBAL_TRUST);
}

gboolean read_trust(const bdaddr_t *local, const char *addr, uint8_t addr_type)
{
	char filename[PATH_MAX + 1], key[20], *str;
	gboolean ret;

	create_filename(filename, PATH_MAX, local, "trusts");

	snprintf(key, sizeof(key), "%17s#%hhu", addr, addr_type);

	str = textfile_caseget(filename, key);
	if (str == NULL)
		/* Try old format (address only) */
		str = textfile_caseget(filename, addr);

	if (str == NULL)
		return FALSE;

	if (strcmp(str, GLOBAL_TRUST) == 0)
		ret = TRUE;
	else
		ret = FALSE;

	free(str);
	return ret;
}

int write_device_profiles(const bdaddr_t *src, const bdaddr_t *dst,
					uint8_t dst_type, const char *profiles)
{
	char filename[PATH_MAX + 1], key[20];

	if (!profiles)
		return -EINVAL;

	create_filename(filename, PATH_MAX, src, "profiles");

	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

	ba2str(dst, key);
	sprintf(&key[17], "#%hhu", dst_type);

	return textfile_put(filename, key, profiles);
}

int delete_entry(const bdaddr_t *src, const char *storage, const bdaddr_t *dst,
							uint8_t dst_type)
{
	char filename[PATH_MAX + 1], key[20];
	int err, ret;

	ba2str(dst, key);
	sprintf(&key[17], "#%hhu", dst_type);

	create_filename(filename, PATH_MAX, src, storage);

	err = 0;
	ret = textfile_del(filename, key);
	if (ret)
		err = ret;

	/* Trying without address type */
	key[17] = '\0';
	ret = textfile_del(filename, key);
	if (ret)
		err = ret;

	return err;
}

int store_record(const gchar *src, const gchar *dst, uint8_t dst_type,
							sdp_record_t *rec)
{
	char filename[PATH_MAX + 1], key[30];
	sdp_buf_t buf;
	int err, size, i;
	char *str;

	create_name(filename, PATH_MAX, STORAGEDIR, src, "sdp");

	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

	snprintf(key, sizeof(key), "%17s#%hhu#%08X", dst, dst_type,
								rec->handle);

	if (sdp_gen_record_pdu(rec, &buf) < 0)
		return -1;

	size = buf.data_size;

	str = g_malloc0(size*2+1);

	for (i = 0; i < size; i++)
		sprintf(str + (i * 2), "%02X", buf.data[i]);

	err = textfile_put(filename, key, str);

	free(buf.data);
	g_free(str);

	return err;
}

sdp_record_t *record_from_string(const gchar *str)
{
	sdp_record_t *rec;
	int size, i, len;
	uint8_t *pdata;
	char tmp[3];

	size = strlen(str)/2;
	pdata = g_malloc0(size);

	tmp[2] = 0;
	for (i = 0; i < size; i++) {
		memcpy(tmp, str + (i * 2), 2);
		pdata[i] = (uint8_t) strtol(tmp, NULL, 16);
	}

	rec = sdp_extract_pdu(pdata, size, &len);
	g_free(pdata);

	return rec;
}


sdp_record_t *fetch_record(const gchar *src, const gchar *dst,
			   uint8_t dst_type, const uint32_t handle)
{
	char filename[PATH_MAX + 1], old_key[28], key[30], *str;
	sdp_record_t *rec;

	create_name(filename, PATH_MAX, STORAGEDIR, src, "sdp");

	snprintf(key, sizeof(key), "%17s#%hhu#%08X", dst, dst_type, handle);
	snprintf(old_key, sizeof(old_key), "%17s#%08X", dst, handle);

	str = textfile_get(filename, key);
	if (str != NULL)
		goto done;

	/* Try old format (address#handle) */
	str = textfile_get(filename, old_key);
	if (str == NULL)
		return NULL;

done:
	rec = record_from_string(str);
	free(str);

	return rec;
}

int delete_record(const gchar *src, const gchar *dst, uint8_t dst_type,
							const uint32_t handle)
{
	char filename[PATH_MAX + 1], old_key[28], key[30];
	int err, ret;

	create_name(filename, PATH_MAX, STORAGEDIR, src, "sdp");

	snprintf(key, sizeof(key), "%17s#%hhu#%08X", dst, dst_type, handle);
	snprintf(old_key, sizeof(old_key), "%17s#%08X", dst, handle);

	err = 0;
	ret = textfile_del(filename, key);
	if (ret)
		err = ret;

	/* Try old format (address#handle) */
	ret = textfile_del(filename, old_key);
	if (ret)
		err = ret;

	return err;
}

struct record_list {
	sdp_list_t *recs;
	const gchar *addr;
};

static void create_stored_records_from_keys(char *key, char *value,
							void *user_data)
{
	struct record_list *rec_list = user_data;
	const gchar *addr = rec_list->addr;
	sdp_record_t *rec;

	if (strncmp(key, addr, 17))
		return;

	rec = record_from_string(value);

	rec_list->recs = sdp_list_append(rec_list->recs, rec);
}

void delete_all_records(const bdaddr_t *src, const bdaddr_t *dst,
							uint8_t dst_type)
{
	sdp_list_t *records, *seq;
	char srcaddr[18], dstaddr[18];

	ba2str(src, srcaddr);
	ba2str(dst, dstaddr);

	records = read_records(src, dst);

	for (seq = records; seq; seq = seq->next) {
		sdp_record_t *rec = seq->data;
		delete_record(srcaddr, dstaddr, dst_type, rec->handle);
	}

	if (records)
		sdp_list_free(records, (sdp_free_func_t) sdp_record_free);
}

sdp_list_t *read_records(const bdaddr_t *src, const bdaddr_t *dst)
{
	char filename[PATH_MAX + 1];
	struct record_list rec_list;
	char srcaddr[18], dstaddr[18];

	ba2str(src, srcaddr);
	ba2str(dst, dstaddr);

	rec_list.addr = dstaddr;
	rec_list.recs = NULL;

	create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, "sdp");
	textfile_foreach(filename, create_stored_records_from_keys, &rec_list);

	return rec_list.recs;
}

sdp_record_t *find_record_in_list(sdp_list_t *recs, const char *uuid)
{
	sdp_list_t *seq;

	for (seq = recs; seq; seq = seq->next) {
		sdp_record_t *rec = (sdp_record_t *) seq->data;
		sdp_list_t *svcclass = NULL;
		char *uuid_str;

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

		/* Extract the uuid */
		uuid_str = bt_uuid2string(svcclass->data);
		if (!uuid_str)
			continue;

		if (!strcasecmp(uuid_str, uuid)) {
			sdp_list_free(svcclass, free);
			free(uuid_str);
			return rec;
		}

		sdp_list_free(svcclass, free);
		free(uuid_str);
	}
	return NULL;
}

int store_device_id(const gchar *src, const gchar *dst, uint8_t dst_type,
				const uint16_t source, const uint16_t vendor,
				const uint16_t product, const uint16_t version)
{
	char filename[PATH_MAX + 1], key[20], str[20];

	create_name(filename, PATH_MAX, STORAGEDIR, src, "did");

	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

	snprintf(key, sizeof(key), "%17s#%hhu", dst, dst_type);

	snprintf(str, sizeof(str), "%04X %04X %04X %04X", source,
						vendor, product, version);

	return textfile_put(filename, key, str);
}

static int read_device_id_from_did(const gchar *src, const gchar *dst,
				   uint8_t dst_type, uint16_t *source,
				   uint16_t *vendor, uint16_t *product,
							uint16_t *version)
{
	char filename[PATH_MAX + 1];
	char key[20], *str, *vendor_str, *product_str, *version_str;

	create_name(filename, PATH_MAX, STORAGEDIR, src, "did");

	snprintf(key, sizeof(key), "%17s#%hhu", dst, dst_type);

	str = textfile_get(filename, key);
	if (str != NULL)
		goto done;

	/* Try old format (address only) */
	str = textfile_get(filename, dst);
	if (!str)
		return -ENOENT;

done:
	vendor_str = strchr(str, ' ');
	if (!vendor_str) {
		free(str);
		return -ENOENT;
	}
	*(vendor_str++) = 0;

	product_str = strchr(vendor_str, ' ');
	if (!product_str) {
		free(str);
		return -ENOENT;
	}
	*(product_str++) = 0;

	version_str = strchr(product_str, ' ');
	if (!version_str) {
		free(str);
		return -ENOENT;
	}
	*(version_str++) = 0;

	if (source)
		*source = (uint16_t) strtol(str, NULL, 16);
	if (vendor)
		*vendor = (uint16_t) strtol(vendor_str, NULL, 16);
	if (product)
		*product = (uint16_t) strtol(product_str, NULL, 16);
	if (version)
		*version = (uint16_t) strtol(version_str, NULL, 16);

	free(str);

	return 0;
}

int read_device_id(const gchar *srcaddr, const gchar *dstaddr,
		   uint8_t dst_type, uint16_t *source, uint16_t *vendor,
					uint16_t *product, uint16_t *version)
{
	uint16_t lsource, lvendor, lproduct, lversion;
	sdp_list_t *recs;
	sdp_record_t *rec;
	bdaddr_t src, dst;
	int err;

	err = read_device_id_from_did(srcaddr, dstaddr, dst_type, &lsource,
								vendor, product,
								version);
	if (!err) {
		if (lsource == 0xffff)
			err = -ENOENT;

		return err;
	}

	str2ba(srcaddr, &src);
	str2ba(dstaddr, &dst);

	recs = read_records(&src, &dst);
	rec = find_record_in_list(recs, PNP_UUID);

	if (rec) {
		sdp_data_t *pdlist;

		pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID_SOURCE);
		lsource = pdlist ? pdlist->val.uint16 : 0x0000;

		pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID);
		lvendor = pdlist ? pdlist->val.uint16 : 0x0000;

		pdlist = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID);
		lproduct = pdlist ? pdlist->val.uint16 : 0x0000;

		pdlist = sdp_data_get(rec, SDP_ATTR_VERSION);
		lversion = pdlist ? pdlist->val.uint16 : 0x0000;

		err = 0;
	}

	sdp_list_free(recs, (sdp_free_func_t)sdp_record_free);

	if (err) {
		/* FIXME: We should try EIR data if we have it, too */

		/* If we don't have the data, we don't want to go through the
		 * above search every time. */
		lsource = 0xffff;
		lvendor = 0x0000;
		lproduct = 0x0000;
		lversion = 0x0000;
	}

	store_device_id(srcaddr, dstaddr, dst_type, lsource, lvendor,
							lproduct, lversion);

	if (err)
		return err;

	if (source)
		*source = lsource;
	if (vendor)
		*vendor = lvendor;
	if (product)
		*product = lproduct;
	if (version)
		*version = lversion;

	return 0;
}

int write_device_pairable(const bdaddr_t *bdaddr, gboolean mode)
{
	char filename[PATH_MAX + 1];

	create_filename(filename, PATH_MAX, bdaddr, "config");

	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

	return textfile_put(filename, "pairable", mode ? "yes" : "no");
}

int read_device_pairable(const bdaddr_t *bdaddr, gboolean *mode)
{
	char filename[PATH_MAX + 1], *str;

	create_filename(filename, PATH_MAX, bdaddr, "config");

	str = textfile_get(filename, "pairable");
	if (!str)
		return -ENOENT;

	*mode = strcmp(str, "yes") == 0 ? TRUE : FALSE;

	free(str);

	return 0;
}

gboolean read_blocked(const bdaddr_t *local, const bdaddr_t *remote,
							uint8_t remote_type)
{
	char filename[PATH_MAX + 1], *str, key[20];

	create_filename(filename, PATH_MAX, local, "blocked");

	ba2str(remote, key);
	sprintf(&key[17], "#%hhu", remote_type);

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

	/* Try old format (address only) */
	key[17] = '\0';

	str = textfile_caseget(filename, key);
	if (str == NULL)
		return FALSE;

done:
	free(str);

	return TRUE;
}

int write_blocked(const bdaddr_t *local, const bdaddr_t *remote,
				uint8_t remote_type, gboolean blocked)
{
	char filename[PATH_MAX + 1], key[20];

	create_filename(filename, PATH_MAX, local, "blocked");

	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

	ba2str(remote, key);
	sprintf(&key[17], "#%hhu", remote_type);

	if (blocked == FALSE)
		return textfile_casedel(filename, key);

	return textfile_caseput(filename, key, "");
}

int write_device_services(const bdaddr_t *sba, const bdaddr_t *dba,
			  uint8_t bdaddr_type, const char *services)
{
	char filename[PATH_MAX + 1], key[20];

	create_filename(filename, PATH_MAX, sba, "primaries");

	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

	ba2str(dba, key);
	sprintf(&key[17], "#%hhu", bdaddr_type);

	return textfile_put(filename, key, services);
}

static void filter_keys(char *key, char *value, void *data)
{
	struct match *match = data;

	if (strncasecmp(key, match->pattern, strlen(match->pattern)) == 0)
		match->keys = g_slist_append(match->keys, g_strdup(key));
}

static void delete_by_pattern(const char *filename, char *pattern)
{
	struct match match;
	GSList *l;
	int err;

	memset(&match, 0, sizeof(match));
	match.pattern = pattern;

	err = textfile_foreach(filename, filter_keys, &match);
	if (err < 0)
		goto done;

	for (l = match.keys; l; l = l->next) {
		const char *key = l->data;
		textfile_del(filename, key);
	}

done:
	g_slist_free_full(match.keys, g_free);
}

int delete_device_service(const bdaddr_t *sba, const bdaddr_t *dba,
						uint8_t bdaddr_type)
{
	char filename[PATH_MAX + 1], key[20];

	memset(key, 0, sizeof(key));

	ba2str(dba, key);
	sprintf(&key[17], "#%hhu", bdaddr_type);

	/* Deleting all characteristics of a given key */
	create_filename(filename, PATH_MAX, sba, "characteristics");
	delete_by_pattern(filename, key);

	/* Deleting all attributes values of a given key */
	create_filename(filename, PATH_MAX, sba, "attributes");
	delete_by_pattern(filename, key);

	/* Deleting all CCC values of a given key */
	create_filename(filename, PATH_MAX, sba, "ccc");
	delete_by_pattern(filename, key);

	create_filename(filename, PATH_MAX, sba, "primaries");

	return textfile_del(filename, key);
}

char *read_device_services(const bdaddr_t *sba, const bdaddr_t *dba,
							uint8_t bdaddr_type)
{
	char filename[PATH_MAX + 1], key[20];

	create_filename(filename, PATH_MAX, sba, "primaries");

	ba2str(dba, key);
	sprintf(&key[17], "#%hhu", bdaddr_type);

	return textfile_caseget(filename, key);
}

int write_device_characteristics(const bdaddr_t *sba, const bdaddr_t *dba,
					uint8_t bdaddr_type, uint16_t handle,
							      const char *chars)
{
	char filename[PATH_MAX + 1], addr[18], key[25];

	create_filename(filename, PATH_MAX, sba, "characteristics");

	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

	ba2str(dba, addr);
	snprintf(key, sizeof(key), "%17s#%hhu#%04X", addr, bdaddr_type, handle);

	return textfile_put(filename, key, chars);
}

char *read_device_characteristics(const bdaddr_t *sba, const bdaddr_t *dba,
					uint8_t bdaddr_type, uint16_t handle)
{
	char filename[PATH_MAX + 1], addr[18], key[25];

	create_filename(filename, PATH_MAX, sba, "characteristics");

	ba2str(dba, addr);
	snprintf(key, sizeof(key), "%17s#%hhu#%04X", addr, bdaddr_type, handle);

	return textfile_caseget(filename, key);
}

int write_device_attribute(const bdaddr_t *sba, const bdaddr_t *dba,
				uint8_t bdaddr_type, uint16_t handle,
							const char *chars)
{
	char filename[PATH_MAX + 1], addr[18], key[25];

	create_filename(filename, PATH_MAX, sba, "attributes");

	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

	ba2str(dba, addr);
	snprintf(key, sizeof(key), "%17s#%hhu#%04X", addr, bdaddr_type, handle);

	return textfile_put(filename, key, chars);
}

int read_device_attributes(const bdaddr_t *sba, textfile_cb func, void *data)
{
	char filename[PATH_MAX + 1];

	create_filename(filename, PATH_MAX, sba, "attributes");

	return textfile_foreach(filename, func, data);
}

int read_device_ccc(const bdaddr_t *local, const bdaddr_t *peer,
					uint8_t bdaddr_type, uint16_t handle,
					uint16_t *value)
{
	char filename[PATH_MAX + 1], addr[18], key[25];
	char *str;
	unsigned int config;
	int err = 0;

	create_filename(filename, PATH_MAX, local, "ccc");

	ba2str(peer, addr);
	snprintf(key, sizeof(key), "%17s#%hhu#%04X", addr, bdaddr_type, handle);

	str = textfile_caseget(filename, key);
	if (str == NULL)
		return -ENOENT;

	if (sscanf(str, "%04X", &config) != 1)
		err = -ENOENT;
	else
		*value = config;

	free(str);

	return err;
}

int write_device_ccc(const bdaddr_t *local, const bdaddr_t *peer,
					uint8_t bdaddr_type, uint16_t handle,
					uint16_t value)
{
	char filename[PATH_MAX + 1], addr[18], key[25], config[5];

	create_filename(filename, PATH_MAX, local, "ccc");

	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

	ba2str(peer, addr);
	snprintf(key, sizeof(key), "%17s#%hhu#%04X", addr, bdaddr_type, handle);

	snprintf(config, sizeof(config), "%04X", value);

	return textfile_put(filename, key, config);
}

void delete_device_ccc(const bdaddr_t *local, const bdaddr_t *peer)
{
	char filename[PATH_MAX + 1], addr[18];

	ba2str(peer, addr);

	/* Deleting all CCC values of a given address */
	create_filename(filename, PATH_MAX, local, "ccc");
	delete_by_pattern(filename, addr);
}

int write_longtermkeys(const bdaddr_t *local, const bdaddr_t *peer,
					uint8_t bdaddr_type, const char *key)
{
	char filename[PATH_MAX + 1], addr[20];

	if (!key)
		return -EINVAL;

	create_filename(filename, PATH_MAX, local, "longtermkeys");

	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

	ba2str(peer, addr);
	sprintf(&addr[17], "#%hhu", bdaddr_type);

	return textfile_put(filename, addr, key);
}

gboolean has_longtermkeys(const bdaddr_t *local, const bdaddr_t *peer,
							uint8_t bdaddr_type)
{
	char filename[PATH_MAX + 1], key[20], *str;

	create_filename(filename, PATH_MAX, local, "longtermkeys");

	ba2str(peer, key);
	sprintf(&key[17], "#%hhu", bdaddr_type);

	str = textfile_caseget(filename, key);
	if (str) {
		free(str);
		return TRUE;
	}

	return FALSE;
}
