/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2006-2007  Nokia Corporation
 *  Copyright (C) 2004-2009  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 <sys/param.h>
#include <sys/socket.h>

#include <glib.h>

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

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

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, char *alias, size_t size)
{
	char filename[PATH_MAX + 1], *tmp;
	int err;

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

	tmp = textfile_get(filename, dst);
	if (!tmp)
		return -ENXIO;

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

	free(tmp);

	return err;
}

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

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

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

	return textfile_put(filename, dst, alias);
}

int write_discoverable_timeout(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(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(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(bdaddr_t *bdaddr, 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(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 > 248)
		str[248] = '\0';
	strcpy(name, str);

	free(str);

	return 0;
}

int write_local_class(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(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 write_remote_class(bdaddr_t *local, 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(bdaddr_t *local, 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(bdaddr_t *local, bdaddr_t *peer, char *name)
{
	char filename[PATH_MAX + 1], addr[18], 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, local, "names");

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

	ba2str(peer, addr);
	return textfile_put(filename, addr, str);
}

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

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

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

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

	free(str);

	return 0;
}

int write_remote_eir(bdaddr_t *local, bdaddr_t *peer, uint8_t *data)
{
	char filename[PATH_MAX + 1], addr[18], str[481];
	int i;

	memset(str, 0, sizeof(str));
	for (i = 0; i < 240; i++)
		sprintf(str + (i * 2), "%2.2X", data[i]);

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

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

	ba2str(peer, addr);
	return textfile_put(filename, addr, str);
}

int read_remote_eir(bdaddr_t *local, bdaddr_t *peer, uint8_t *data)
{
	char filename[PATH_MAX + 1], addr[18], *str;
	int i;

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

	ba2str(peer, addr);

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

	if (!data) {
		free(str);
		return 0;
	}

	if (strlen(str) < 480) {
		free(str);
		return -EIO;
	}

	for (i = 0; i < 240; i++)
		sscanf(str + (i * 2), "%02hhX", &data[i]);

	free(str);

	return 0;
}

int write_l2cap_info(bdaddr_t *local, bdaddr_t *peer,
			uint16_t mtu_result, uint16_t mtu,
			uint16_t mask_result, uint32_t mask)
{
	char filename[PATH_MAX + 1], addr[18], str[18];

	if (mask_result)
		snprintf(str, sizeof(str), "%d -1", mtu_result ? -1 : mtu);
	else
		snprintf(str, sizeof(str), "%d 0x%08x", mtu_result ? -1 : mtu, mask);

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

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

	ba2str(peer, addr);
	return textfile_put(filename, addr, str);
}

int read_l2cap_info(bdaddr_t *local, bdaddr_t *peer,
			uint16_t *mtu_result, uint16_t *mtu,
			uint16_t *mask_result, uint32_t *mask)
{
	char filename[PATH_MAX + 1], addr[18], *str, *space, *msk;

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

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

	space = strchr(str, ' ');
	if (!space) {
		free(str);
		return -ENOENT;
	}

	msk = space + 1;
	*space = '\0';

	if (mtu_result && mtu) {
		if (str[0] == '-')
			*mtu_result = 0x0001;
		else {
			*mtu_result = 0;
			*mtu = (uint16_t) strtol(str, NULL, 0);
		}
	}

	if (mask_result && mask) {
		if (msk[0] == '-')
			*mask_result = 0x0001;
		else {
			*mask_result = 0;
			*mask = (uint32_t) strtol(msk, NULL, 16);
		}
	}

	free(str);

	return 0;
}

int write_version_info(bdaddr_t *local, bdaddr_t *peer, uint16_t manufacturer,
					uint8_t lmp_ver, uint16_t lmp_subver)
{
	char filename[PATH_MAX + 1], addr[18], str[16];

	memset(str, 0, sizeof(str));
	sprintf(str, "%d %d %d", manufacturer, lmp_ver, lmp_subver);

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

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

	ba2str(peer, addr);
	return textfile_put(filename, addr, str);
}

int write_features_info(bdaddr_t *local, bdaddr_t *peer, unsigned char *features)
{
	char filename[PATH_MAX + 1], addr[18], str[17];
	int i;

	memset(str, 0, sizeof(str));
	for (i = 0; i < 8; i++)
		sprintf(str + (i * 2), "%2.2X", features[i]);

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

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

	ba2str(peer, addr);
	return textfile_put(filename, addr, str);
}

int write_lastseen_info(bdaddr_t *local, bdaddr_t *peer, struct tm *tm)
{
	char filename[PATH_MAX + 1], addr[18], 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, addr);
	return textfile_put(filename, addr, str);
}

int write_lastused_info(bdaddr_t *local, bdaddr_t *peer, struct tm *tm)
{
	char filename[PATH_MAX + 1], addr[18], 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, addr);
	return textfile_put(filename, addr, str);
}

int write_link_key(bdaddr_t *local, bdaddr_t *peer, unsigned char *key, uint8_t type, int length)
{
	char filename[PATH_MAX + 1], addr[18], 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);

	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(bdaddr_t *local, bdaddr_t *peer, unsigned char *key, uint8_t *type)
{
	char filename[PATH_MAX + 1], addr[18], tmp[3], *str;
	int i;

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

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

	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;
}

int read_pin_length(bdaddr_t *local, bdaddr_t *peer)
{
	char filename[PATH_MAX + 1], addr[18], *str;
	int len;

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

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

	if (strlen(str) < 36) {
		free(str);
		return -ENOENT;
	}

	len = atoi(str + 35);

	free(str);

	return len;
}

int read_pin_code(bdaddr_t *local, bdaddr_t *peer, char *pin)
{
	char filename[PATH_MAX + 1], addr[18], *str;
	int 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;
}

static GSList *service_string_to_list(char *services)
{
	GSList *l = NULL;
	char *start = services;
	int i, finished = 0;

	for (i = 0; !finished; i++) {
		if (services[i] == '\0')
			finished = 1;

		if (services[i] == ' ' || services[i] == '\0') {
			services[i] = '\0';
			l = g_slist_append(l, start);
			start = services + i + 1;
		}
	}

	return l;
}

static char *service_list_to_string(GSList *services)
{
	char str[1024];
	int len = 0;

	if (!services)
		return g_strdup("");

	memset(str, 0, sizeof(str));

	while (services) {
		int ret;
		char *ident = services->data;

		ret = snprintf(str + len, sizeof(str) - len - 1, "%s%s",
				ident, services->next ? " " : "");

		if (ret > 0)
			len += ret;

		services = services->next;
	}

	return g_strdup(str);
}

int write_trust(const char *src, const char *addr, const char *service,
		gboolean trust)
{
	char filename[PATH_MAX + 1], *str;
	GSList *services = NULL, *match;
	gboolean trusted;
	int ret;

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

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

	str = textfile_caseget(filename, addr);
	if (str)
		services = service_string_to_list(str);

	match = g_slist_find_custom(services, service, (GCompareFunc) strcmp);
	trusted = match ? TRUE : FALSE;

	/* If the old setting is the same as the requested one, we're done */
	if (trusted == trust) {
		g_slist_free(services);
		if (str)
			free(str);
		return 0;
	}

	if (trust)
		services = g_slist_append(services, (void *) service);
	else
		services = g_slist_remove(services, match->data);

	/* Remove the entry if the last trusted service was removed */
	if (!trust && !services)
		ret = textfile_casedel(filename, addr);
	else {
		char *new_str = service_list_to_string(services);
		ret = textfile_caseput(filename, addr, new_str);
		free(new_str);
	}

	g_slist_free(services);

	if (str)
		free(str);

	return ret;
}

gboolean read_trust(const bdaddr_t *local, const char *addr, const char *service)
{
	char filename[PATH_MAX + 1], *str;
	GSList *services;
	gboolean ret;

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

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

	services = service_string_to_list(str);

	if (g_slist_find_custom(services, service, (GCompareFunc) strcmp))
		ret = TRUE;
	else
		ret = FALSE;

	g_slist_free(services);
	free(str);

	return ret;
}

struct trust_list {
	GSList *trusts;
	const char *service;
};

static void append_trust(char *key, char *value, void *data)
{
	struct trust_list *list = data;

	if (strstr(value, list->service))
		list->trusts = g_slist_append(list->trusts, g_strdup(key));
}

GSList *list_trusts(bdaddr_t *local, const char *service)
{
	char filename[PATH_MAX + 1];
	struct trust_list list;

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

	list.trusts = NULL;
	list.service = service;

	if (textfile_foreach(filename, append_trust, &list) < 0)
		return NULL;

	return list.trusts;
}

int write_device_profiles(bdaddr_t *src, bdaddr_t *dst, const char *profiles)
{
	char filename[PATH_MAX + 1], addr[18];

	if (!profiles)
		return -EINVAL;

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

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

	ba2str(dst, addr);
	return textfile_put(filename, addr, profiles);
}

int delete_entry(bdaddr_t *src, const char *storage, const char *key)
{
	char filename[PATH_MAX + 1];

	create_filename(filename, PATH_MAX, src, storage);

	return textfile_del(filename, key);
}

int store_record(const gchar *src, const gchar *dst, sdp_record_t *rec)
{
	char filename[PATH_MAX + 1], key[28];
	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#%08X", dst, 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);
	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);
	free(pdata);

	return rec;
}


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

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

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

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

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

	return rec;
}

int delete_record(const gchar *src, const gchar *dst, const uint32_t handle)
{
	char filename[PATH_MAX + 1], key[28];

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

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

	return textfile_del(filename, key);
}

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);
}

sdp_list_t *read_records(bdaddr_t *src, 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,
				const uint16_t source, const uint16_t vendor,
				const uint16_t product, const uint16_t version)
{
	char filename[PATH_MAX + 1], str[20];

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

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

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

	return textfile_put(filename, dst, str);
}

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

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

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

	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,
					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, &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, 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(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(bdaddr_t *bdaddr, gboolean *mode)
{
	char filename[PATH_MAX + 1], *str;

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

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

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

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

	free(str);

	return 0;
}
