/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2010  Nokia Corporation
 *  Copyright (C) 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 <errno.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <glib.h>
#include <sys/stat.h>

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

#include "lib/uuid.h"
#include "btio/btio.h"
#include "log.h"
#include "adapter.h"
#include "device.h"
#include "src/shared/util.h"
#include "attrib/gattrib.h"
#include "attrib/att.h"
#include "attrib/gatt.h"
#include "attrib/att-database.h"
#include "textfile.h"
#include "storage.h"

#include "attrib-server.h"

static GSList *servers = NULL;

struct gatt_server {
	struct btd_adapter *adapter;
	GIOChannel *l2cap_io;
	GIOChannel *le_io;
	uint32_t gatt_sdp_handle;
	uint32_t gap_sdp_handle;
	GList *database;
	GSList *clients;
	uint16_t name_handle;
	uint16_t appearance_handle;
};

struct gatt_channel {
	GAttrib *attrib;
	guint mtu;
	gboolean le;
	guint id;
	gboolean encrypted;
	struct gatt_server *server;
	guint cleanup_id;
	struct btd_device *device;
};

struct group_elem {
	uint16_t handle;
	uint16_t end;
	uint8_t *data;
	uint16_t len;
};

static bt_uuid_t prim_uuid = {
			.type = BT_UUID16,
			.value.u16 = GATT_PRIM_SVC_UUID
};
static bt_uuid_t snd_uuid = {
			.type = BT_UUID16,
			.value.u16 = GATT_SND_SVC_UUID
};
static bt_uuid_t ccc_uuid = {
			.type = BT_UUID16,
			.value.u16 = GATT_CLIENT_CHARAC_CFG_UUID
};

static inline void put_uuid_le(const bt_uuid_t *src, void *dst)
{
	if (src->type == BT_UUID16)
		put_le16(src->value.u16, dst);
	else
		/* Convert from 128-bit BE to LE */
		bswap_128(&src->value.u128, dst);
}

static void attrib_free(void *data)
{
	struct attribute *a = data;

	g_free(a->data);
	g_free(a);
}

static void channel_free(struct gatt_channel *channel)
{

	if (channel->cleanup_id)
		g_source_remove(channel->cleanup_id);

	if (channel->device)
		btd_device_unref(channel->device);

	g_attrib_unref(channel->attrib);
	g_free(channel);
}

static void gatt_server_free(struct gatt_server *server)
{
	g_list_free_full(server->database, attrib_free);

	if (server->l2cap_io != NULL) {
		g_io_channel_shutdown(server->l2cap_io, FALSE, NULL);
		g_io_channel_unref(server->l2cap_io);
	}

	if (server->le_io != NULL) {
		g_io_channel_shutdown(server->le_io, FALSE, NULL);
		g_io_channel_unref(server->le_io);
	}

	g_slist_free_full(server->clients, (GDestroyNotify) channel_free);

	if (server->gatt_sdp_handle > 0)
		adapter_service_remove(server->adapter,
					server->gatt_sdp_handle);

	if (server->gap_sdp_handle > 0)
		adapter_service_remove(server->adapter, server->gap_sdp_handle);

	if (server->adapter != NULL)
		btd_adapter_unref(server->adapter);

	g_free(server);
}

static int adapter_cmp_addr(gconstpointer a, gconstpointer b)
{
	const struct gatt_server *server = a;
	const bdaddr_t *bdaddr = b;

	return bacmp(btd_adapter_get_address(server->adapter), bdaddr);
}

static int adapter_cmp(gconstpointer a, gconstpointer b)
{
	const struct gatt_server *server = a;
	const struct btd_adapter *adapter = b;

	if (server->adapter == adapter)
		return 0;

	return -1;
}

static struct gatt_server *find_gatt_server(const bdaddr_t *bdaddr)
{
	GSList *l;

	l = g_slist_find_custom(servers, bdaddr, adapter_cmp_addr);
	if (l == NULL) {
		char addr[18];

		ba2str(bdaddr, addr);
		error("No GATT server found in %s", addr);
		return NULL;
	}

	return l->data;
}

static sdp_record_t *server_record_new(uuid_t *uuid, uint16_t start, uint16_t end)
{
	sdp_list_t *svclass_id, *apseq, *proto[2], *root, *aproto;
	uuid_t root_uuid, proto_uuid, l2cap;
	sdp_record_t *record;
	sdp_data_t *psm, *sh, *eh;
	uint16_t lp = ATT_PSM;

	if (uuid == NULL)
		return NULL;

	if (start > end)
		return NULL;

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

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

	svclass_id = sdp_list_append(NULL, uuid);
	sdp_set_service_classes(record, svclass_id);
	sdp_list_free(svclass_id, NULL);

	sdp_uuid16_create(&l2cap, L2CAP_UUID);
	proto[0] = sdp_list_append(NULL, &l2cap);
	psm = sdp_data_alloc(SDP_UINT16, &lp);
	proto[0] = sdp_list_append(proto[0], psm);
	apseq = sdp_list_append(NULL, proto[0]);

	sdp_uuid16_create(&proto_uuid, ATT_UUID);
	proto[1] = sdp_list_append(NULL, &proto_uuid);
	sh = sdp_data_alloc(SDP_UINT16, &start);
	proto[1] = sdp_list_append(proto[1], sh);
	eh = sdp_data_alloc(SDP_UINT16, &end);
	proto[1] = sdp_list_append(proto[1], eh);
	apseq = sdp_list_append(apseq, proto[1]);

	aproto = sdp_list_append(NULL, apseq);
	sdp_set_access_protos(record, aproto);

	sdp_data_free(psm);
	sdp_data_free(sh);
	sdp_data_free(eh);
	sdp_list_free(proto[0], NULL);
	sdp_list_free(proto[1], NULL);
	sdp_list_free(apseq, NULL);
	sdp_list_free(aproto, NULL);

	return record;
}

static int handle_cmp(gconstpointer a, gconstpointer b)
{
	const struct attribute *attrib = a;
	uint16_t handle = GPOINTER_TO_UINT(b);

	return attrib->handle - handle;
}

static int attribute_cmp(gconstpointer a1, gconstpointer a2)
{
	const struct attribute *attrib1 = a1;
	const struct attribute *attrib2 = a2;

	return attrib1->handle - attrib2->handle;
}

static struct attribute *find_svc_range(struct gatt_server *server,
					uint16_t start, uint16_t *end)
{
	struct attribute *attrib;
	guint h = start;
	GList *l;

	if (end == NULL)
		return NULL;

	l = g_list_find_custom(server->database, GUINT_TO_POINTER(h),
								handle_cmp);
	if (!l)
		return NULL;

	attrib = l->data;

	if (bt_uuid_cmp(&attrib->uuid, &prim_uuid) != 0 &&
			bt_uuid_cmp(&attrib->uuid, &snd_uuid) != 0)
		return NULL;

	*end = start;

	for (l = l->next; l; l = l->next) {
		struct attribute *a = l->data;

		if (bt_uuid_cmp(&a->uuid, &prim_uuid) == 0 ||
				bt_uuid_cmp(&a->uuid, &snd_uuid) == 0)
			break;

		*end = a->handle;
	}

	return attrib;
}

static uint32_t attrib_create_sdp_new(struct gatt_server *server,
					uint16_t handle, const char *name)
{
	sdp_record_t *record;
	struct attribute *a;
	uint16_t end = 0;
	uuid_t svc, gap_uuid;

	a = find_svc_range(server, handle, &end);

	if (a == NULL)
		return 0;

	if (a->len == 2)
		sdp_uuid16_create(&svc, get_le16(a->data));
	else if (a->len == 16) {
		uint8_t be128[16];

		/* Converting from LE to BE */
		bswap_128(a->data, be128);
		sdp_uuid128_create(&svc, be128);
	} else
		return 0;

	record = server_record_new(&svc, handle, end);
	if (record == NULL)
		return 0;

	if (name != NULL)
		sdp_set_info_attr(record, name, "BlueZ", NULL);

	sdp_uuid16_create(&gap_uuid, GENERIC_ACCESS_PROFILE_ID);
	if (sdp_uuid_cmp(&svc, &gap_uuid) == 0) {
		sdp_set_url_attr(record, "http://www.bluez.org/",
				"http://www.bluez.org/",
				"http://www.bluez.org/");
	}

	if (adapter_service_add(server->adapter, record) == 0)
		return record->handle;

	sdp_record_free(record);
	return 0;
}

static struct attribute *attrib_db_add_new(struct gatt_server *server,
				uint16_t handle, bt_uuid_t *uuid,
				int read_req, int write_req,
				const uint8_t *value, size_t len)
{
	struct attribute *a;
	guint h = handle;

	DBG("handle=0x%04x", handle);

	if (g_list_find_custom(server->database, GUINT_TO_POINTER(h),
								handle_cmp))
		return NULL;

	a = g_new0(struct attribute, 1);
	a->len = len;
	a->data = g_memdup(value, len);
	a->handle = handle;
	a->uuid = *uuid;
	a->read_req = read_req;
	a->write_req = write_req;

	server->database = g_list_insert_sorted(server->database, a,
								attribute_cmp);

	return a;
}

static uint8_t att_check_reqs(struct gatt_channel *channel, uint8_t opcode,
								int reqs)
{
	/* FIXME: currently, it is assumed an encrypted link is enough for
	 * authentication. This will allow to enable the SMP negotiation once
	 * it is on upstream kernel. High security level should be mapped
	 * to authentication and medium to encryption permission. */
	if (!channel->encrypted)
		channel->encrypted = g_attrib_is_encrypted(channel->attrib);
	if (reqs == ATT_AUTHENTICATION && !channel->encrypted)
		return ATT_ECODE_AUTHENTICATION;
	else if (reqs == ATT_AUTHORIZATION)
		return ATT_ECODE_AUTHORIZATION;

	switch (opcode) {
	case ATT_OP_READ_BY_GROUP_REQ:
	case ATT_OP_READ_BY_TYPE_REQ:
	case ATT_OP_READ_REQ:
	case ATT_OP_READ_BLOB_REQ:
	case ATT_OP_READ_MULTI_REQ:
		if (reqs == ATT_NOT_PERMITTED)
			return ATT_ECODE_READ_NOT_PERM;
		break;
	case ATT_OP_PREP_WRITE_REQ:
	case ATT_OP_WRITE_REQ:
	case ATT_OP_WRITE_CMD:
		if (reqs == ATT_NOT_PERMITTED)
			return ATT_ECODE_WRITE_NOT_PERM;
		break;
	}

	return 0;
}

static uint16_t read_by_group(struct gatt_channel *channel, uint16_t start,
						uint16_t end, bt_uuid_t *uuid,
						uint8_t *pdu, size_t len)
{
	struct att_data_list *adl;
	struct attribute *a;
	struct group_elem *cur, *old = NULL;
	GSList *l, *groups;
	GList *dl, *database;
	uint16_t length, last_handle, last_size = 0;
	uint8_t status;
	int i;

	if (start > end || start == 0x0000)
		return enc_error_resp(ATT_OP_READ_BY_GROUP_REQ, start,
					ATT_ECODE_INVALID_HANDLE, pdu, len);

	/*
	 * Only <<Primary Service>> and <<Secondary Service>> grouping
	 * types may be used in the Read By Group Type Request.
	 */

	if (bt_uuid_cmp(uuid, &prim_uuid) != 0 &&
		bt_uuid_cmp(uuid, &snd_uuid) != 0)
		return enc_error_resp(ATT_OP_READ_BY_GROUP_REQ, 0x0000,
					ATT_ECODE_UNSUPP_GRP_TYPE, pdu, len);

	last_handle = end;
	database = channel->server->database;
	for (dl = database, groups = NULL, cur = NULL; dl; dl = dl->next) {

		a = dl->data;

		if (a->handle < start)
			continue;

		if (a->handle >= end)
			break;

		/* The old group ends when a new one starts */
		if (old && (bt_uuid_cmp(&a->uuid, &prim_uuid) == 0 ||
				bt_uuid_cmp(&a->uuid, &snd_uuid) == 0)) {
			old->end = last_handle;
			old = NULL;
		}

		if (bt_uuid_cmp(&a->uuid, uuid) != 0) {
			/* Still inside a service, update its last handle */
			if (old)
				last_handle = a->handle;
			continue;
		}

		if (last_size && (last_size != a->len))
			break;

		status = att_check_reqs(channel, ATT_OP_READ_BY_GROUP_REQ,
								a->read_req);

		if (status == 0x00 && a->read_cb)
			status = a->read_cb(a, channel->device,
							a->cb_user_data);

		if (status) {
			g_slist_free_full(groups, g_free);
			return enc_error_resp(ATT_OP_READ_BY_GROUP_REQ,
						a->handle, status, pdu, len);
		}

		cur = g_new0(struct group_elem, 1);
		cur->handle = a->handle;
		cur->data = a->data;
		cur->len = a->len;

		/* Attribute Grouping Type found */
		groups = g_slist_append(groups, cur);

		last_size = a->len;
		old = cur;
		last_handle = cur->handle;
	}

	if (groups == NULL)
		return enc_error_resp(ATT_OP_READ_BY_GROUP_REQ, start,
					ATT_ECODE_ATTR_NOT_FOUND, pdu, len);

	if (dl == NULL)
		cur->end = a->handle;
	else
		cur->end = last_handle;

	length = g_slist_length(groups);

	adl = att_data_list_alloc(length, last_size + 4);
	if (adl == NULL) {
		g_slist_free_full(groups, g_free);
		return enc_error_resp(ATT_OP_READ_BY_GROUP_REQ, start,
					ATT_ECODE_UNLIKELY, pdu, len);
	}

	for (i = 0, l = groups; l; l = l->next, i++) {
		uint8_t *value;

		cur = l->data;

		value = (void *) adl->data[i];

		put_le16(cur->handle, value);
		put_le16(cur->end, &value[2]);
		/* Attribute Value */
		memcpy(&value[4], cur->data, cur->len);
	}

	length = enc_read_by_grp_resp(adl, pdu, len);

	att_data_list_free(adl);
	g_slist_free_full(groups, g_free);

	return length;
}

static uint16_t read_by_type(struct gatt_channel *channel, uint16_t start,
						uint16_t end, bt_uuid_t *uuid,
						uint8_t *pdu, size_t len)
{
	struct att_data_list *adl;
	GSList *l, *types;
	GList *dl, *database;
	struct attribute *a;
	uint16_t num, length;
	uint8_t status;
	int i;

	if (start > end || start == 0x0000)
		return enc_error_resp(ATT_OP_READ_BY_TYPE_REQ, start,
					ATT_ECODE_INVALID_HANDLE, pdu, len);

	database = channel->server->database;
	for (dl = database, length = 0, types = NULL; dl; dl = dl->next) {

		a = dl->data;

		if (a->handle < start)
			continue;

		if (a->handle > end)
			break;

		if (bt_uuid_cmp(&a->uuid, uuid)  != 0)
			continue;

		status = att_check_reqs(channel, ATT_OP_READ_BY_TYPE_REQ,
								a->read_req);

		if (status == 0x00 && a->read_cb)
			status = a->read_cb(a, channel->device,
							a->cb_user_data);

		if (status) {
			g_slist_free(types);
			return enc_error_resp(ATT_OP_READ_BY_TYPE_REQ,
						a->handle, status, pdu, len);
		}

		/* All elements must have the same length */
		if (length == 0)
			length = a->len;
		else if (a->len != length)
			break;

		types = g_slist_append(types, a);
	}

	if (types == NULL)
		return enc_error_resp(ATT_OP_READ_BY_TYPE_REQ, start,
					ATT_ECODE_ATTR_NOT_FOUND, pdu, len);

	num = g_slist_length(types);

	/* Handle length plus attribute value length */
	length += 2;

	adl = att_data_list_alloc(num, length);
	if (adl == NULL) {
		g_slist_free(types);
		return enc_error_resp(ATT_OP_READ_BY_TYPE_REQ, start,
					ATT_ECODE_UNLIKELY, pdu, len);
	}

	for (i = 0, l = types; l; i++, l = l->next) {
		uint8_t *value;

		a = l->data;

		value = (void *) adl->data[i];

		put_le16(a->handle, value);

		/* Attribute Value */
		memcpy(&value[2], a->data, a->len);
	}

	length = enc_read_by_type_resp(adl, pdu, len);

	att_data_list_free(adl);
	g_slist_free(types);

	return length;
}

static uint16_t find_info(struct gatt_channel *channel, uint16_t start,
				uint16_t end, uint8_t *pdu, size_t len)
{
	struct attribute *a;
	struct att_data_list *adl;
	GSList *l, *info;
	GList *dl, *database;
	uint8_t format, last_type = BT_UUID_UNSPEC;
	uint16_t length, num;
	int i;

	if (start > end || start == 0x0000)
		return enc_error_resp(ATT_OP_FIND_INFO_REQ, start,
					ATT_ECODE_INVALID_HANDLE, pdu, len);

	database = channel->server->database;
	for (dl = database, info = NULL, num = 0; dl; dl = dl->next) {
		a = dl->data;

		if (a->handle < start)
			continue;

		if (a->handle > end)
			break;

		if (last_type == BT_UUID_UNSPEC)
			last_type = a->uuid.type;

		if (a->uuid.type != last_type)
			break;

		info = g_slist_append(info, a);
		num++;

		last_type = a->uuid.type;
	}

	if (info == NULL)
		return enc_error_resp(ATT_OP_FIND_INFO_REQ, start,
					ATT_ECODE_ATTR_NOT_FOUND, pdu, len);

	if (last_type == BT_UUID16) {
		length = 2;
		format = 0x01;
	} else if (last_type == BT_UUID128) {
		length = 16;
		format = 0x02;
	} else {
		g_slist_free(info);
		return 0;
	}

	adl = att_data_list_alloc(num, length + 2);
	if (adl == NULL) {
		g_slist_free(info);
		return enc_error_resp(ATT_OP_FIND_INFO_REQ, start,
					ATT_ECODE_UNLIKELY, pdu, len);
	}

	for (i = 0, l = info; l; i++, l = l->next) {
		uint8_t *value;

		a = l->data;

		value = (void *) adl->data[i];

		put_le16(a->handle, value);

		/* Attribute Value */
		put_uuid_le(&a->uuid, &value[2]);
	}

	length = enc_find_info_resp(format, adl, pdu, len);

	att_data_list_free(adl);
	g_slist_free(info);

	return length;
}

static uint16_t find_by_type(struct gatt_channel *channel, uint16_t start,
				uint16_t end, bt_uuid_t *uuid,
				const uint8_t *value, size_t vlen,
				uint8_t *opdu, size_t mtu)
{
	struct attribute *a;
	struct att_range *range;
	GSList *matches;
	GList *dl, *database;
	uint16_t len;

	if (start > end || start == 0x0000)
		return enc_error_resp(ATT_OP_FIND_BY_TYPE_REQ, start,
					ATT_ECODE_INVALID_HANDLE, opdu, mtu);

	/* Searching first requested handle number */
	database = channel->server->database;
	for (dl = database, matches = NULL, range = NULL; dl; dl = dl->next) {
		a = dl->data;

		if (a->handle < start)
			continue;

		if (a->handle > end)
			break;

		/* Primary service? Attribute value matches? */
		if ((bt_uuid_cmp(&a->uuid, uuid) == 0) && (a->len == vlen) &&
					(memcmp(a->data, value, vlen) == 0)) {

			range = g_new0(struct att_range, 1);
			range->start = a->handle;
			/* It is allowed to have end group handle the same as
			 * start handle, for groups with only one attribute. */
			range->end = a->handle;

			matches = g_slist_append(matches, range);
		} else if (range) {
			/* Update the last found handle or reset the pointer
			 * to track that a new group started: Primary or
			 * Secondary service. */
			if (bt_uuid_cmp(&a->uuid, &prim_uuid) == 0 ||
					bt_uuid_cmp(&a->uuid, &snd_uuid) == 0)
				range = NULL;
			else
				range->end = a->handle;
		}
	}

	if (matches == NULL)
		return enc_error_resp(ATT_OP_FIND_BY_TYPE_REQ, start,
				ATT_ECODE_ATTR_NOT_FOUND, opdu, mtu);

	len = enc_find_by_type_resp(matches, opdu, mtu);

	g_slist_free_full(matches, g_free);

	return len;
}

static int read_device_ccc(struct btd_device *device, uint16_t handle,
				uint16_t *value)
{
	char *filename;
	GKeyFile *key_file;
	char group[6];
	char *str;
	unsigned int config;
	int err = 0;

	filename = btd_device_get_storage_path(device, "ccc");
	if (!filename) {
		warn("Unable to get ccc storage path for device");
		return -ENOENT;
	}

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

	sprintf(group, "%hu", handle);

	str = g_key_file_get_string(key_file, group, "Value", NULL);
	if (!str || sscanf(str, "%04X", &config) != 1)
		err = -ENOENT;
	else
		*value = config;

	g_free(str);
	g_free(filename);
	g_key_file_free(key_file);

	return err;
}

static uint16_t read_value(struct gatt_channel *channel, uint16_t handle,
						uint8_t *pdu, size_t len)
{
	struct attribute *a;
	uint8_t status;
	GList *l;
	uint16_t cccval;
	guint h = handle;

	l = g_list_find_custom(channel->server->database,
					GUINT_TO_POINTER(h), handle_cmp);
	if (!l)
		return enc_error_resp(ATT_OP_READ_REQ, handle,
					ATT_ECODE_INVALID_HANDLE, pdu, len);

	a = l->data;

	if (bt_uuid_cmp(&ccc_uuid, &a->uuid) == 0 &&
		read_device_ccc(channel->device, handle, &cccval) == 0) {
		uint8_t config[2];

		put_le16(cccval, config);
		return enc_read_resp(config, sizeof(config), pdu, len);
	}

	status = att_check_reqs(channel, ATT_OP_READ_REQ, a->read_req);

	if (status == 0x00 && a->read_cb)
		status = a->read_cb(a, channel->device, a->cb_user_data);

	if (status)
		return enc_error_resp(ATT_OP_READ_REQ, handle, status, pdu,
									len);

	return enc_read_resp(a->data, a->len, pdu, len);
}

static uint16_t read_blob(struct gatt_channel *channel, uint16_t handle,
				uint16_t offset, uint8_t *pdu, size_t len)
{
	struct attribute *a;
	uint8_t status;
	GList *l;
	uint16_t cccval;
	guint h = handle;

	l = g_list_find_custom(channel->server->database,
					GUINT_TO_POINTER(h), handle_cmp);
	if (!l)
		return enc_error_resp(ATT_OP_READ_BLOB_REQ, handle,
					ATT_ECODE_INVALID_HANDLE, pdu, len);

	a = l->data;

	if (a->len <= offset)
		return enc_error_resp(ATT_OP_READ_BLOB_REQ, handle,
					ATT_ECODE_INVALID_OFFSET, pdu, len);

	if (bt_uuid_cmp(&ccc_uuid, &a->uuid) == 0 &&
		read_device_ccc(channel->device, handle, &cccval) == 0) {
		uint8_t config[2];

		put_le16(cccval, config);
		return enc_read_blob_resp(config, sizeof(config), offset,
								pdu, len);
	}

	status = att_check_reqs(channel, ATT_OP_READ_BLOB_REQ, a->read_req);

	if (status == 0x00 && a->read_cb)
		status = a->read_cb(a, channel->device, a->cb_user_data);

	if (status)
		return enc_error_resp(ATT_OP_READ_BLOB_REQ, handle, status,
								pdu, len);

	return enc_read_blob_resp(a->data, a->len, offset, pdu, len);
}

static uint16_t write_value(struct gatt_channel *channel, uint16_t handle,
					const uint8_t *value, size_t vlen,
					uint8_t *pdu, size_t len)
{
	struct attribute *a;
	uint8_t status;
	GList *l;
	guint h = handle;

	l = g_list_find_custom(channel->server->database,
					GUINT_TO_POINTER(h), handle_cmp);
	if (!l)
		return enc_error_resp(ATT_OP_WRITE_REQ, handle,
				ATT_ECODE_INVALID_HANDLE, pdu, len);

	a = l->data;

	status = att_check_reqs(channel, ATT_OP_WRITE_REQ, a->write_req);
	if (status)
		return enc_error_resp(ATT_OP_WRITE_REQ, handle, status, pdu,
									len);

	if (bt_uuid_cmp(&ccc_uuid, &a->uuid) != 0) {

		attrib_db_update(channel->server->adapter, handle, NULL,
							value, vlen, NULL);

		if (a->write_cb) {
			status = a->write_cb(a, channel->device,
							a->cb_user_data);
			if (status)
				return enc_error_resp(ATT_OP_WRITE_REQ, handle,
							status, pdu, len);
		}
	} else {
		uint16_t cccval = get_le16(value);
		char *filename;
		GKeyFile *key_file;
		char group[6], value[5];
		char *data;
		gsize length = 0;

		filename = btd_device_get_storage_path(channel->device, "ccc");
		if (!filename) {
			warn("Unable to get ccc storage path for device");
			return enc_error_resp(ATT_OP_WRITE_REQ, handle,
						ATT_ECODE_WRITE_NOT_PERM,
						pdu, len);
		}

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

		sprintf(group, "%hu", handle);
		sprintf(value, "%hX", cccval);
		g_key_file_set_string(key_file, group, "Value", value);

		data = g_key_file_to_data(key_file, &length, NULL);
		if (length > 0) {
			create_file(filename, S_IRUSR | S_IWUSR);
			g_file_set_contents(filename, data, length, NULL);
		}

		g_free(data);
		g_free(filename);
		g_key_file_free(key_file);
	}

	return enc_write_resp(pdu);
}

static uint16_t mtu_exchange(struct gatt_channel *channel, uint16_t mtu,
						uint8_t *pdu, size_t len)
{
	GError *gerr = NULL;
	GIOChannel *io;
	uint16_t imtu;

	if (mtu < ATT_DEFAULT_LE_MTU)
		return enc_error_resp(ATT_OP_MTU_REQ, 0,
					ATT_ECODE_REQ_NOT_SUPP, pdu, len);

	io = g_attrib_get_channel(channel->attrib);

	bt_io_get(io, &gerr, BT_IO_OPT_IMTU, &imtu, BT_IO_OPT_INVALID);
	if (gerr) {
		error("bt_io_get: %s", gerr->message);
		g_error_free(gerr);
		return enc_error_resp(ATT_OP_MTU_REQ, 0, ATT_ECODE_UNLIKELY,
								pdu, len);
	}

	channel->mtu = MIN(mtu, imtu);
	g_attrib_set_mtu(channel->attrib, channel->mtu);

	return enc_mtu_resp(imtu, pdu, len);
}

static void channel_remove(struct gatt_channel *channel)
{
	channel->server->clients = g_slist_remove(channel->server->clients,
								channel);
	channel_free(channel);
}

static gboolean channel_watch_cb(GIOChannel *io, GIOCondition cond,
						gpointer user_data)
{
	channel_remove(user_data);

	return FALSE;
}

static void channel_handler(const uint8_t *ipdu, uint16_t len,
							gpointer user_data)
{
	struct gatt_channel *channel = user_data;
	uint8_t opdu[channel->mtu];
	uint16_t length, start, end, mtu, offset;
	bt_uuid_t uuid;
	uint8_t status = 0;
	size_t vlen;
	uint8_t *value = g_attrib_get_buffer(channel->attrib, &vlen);

	// suppress very common debug message
	// DBG("op 0x%02x", ipdu[0]);

	if (len > vlen) {
		error("Too much data on ATT socket");
		status = ATT_ECODE_INVALID_PDU;
		goto done;
	}

	switch (ipdu[0]) {
	case ATT_OP_READ_BY_GROUP_REQ:
		length = dec_read_by_grp_req(ipdu, len, &start, &end, &uuid);
		if (length == 0) {
			status = ATT_ECODE_INVALID_PDU;
			goto done;
		}

		length = read_by_group(channel, start, end, &uuid, opdu,
								channel->mtu);
		break;
	case ATT_OP_READ_BY_TYPE_REQ:
		length = dec_read_by_type_req(ipdu, len, &start, &end, &uuid);
		if (length == 0) {
			status = ATT_ECODE_INVALID_PDU;
			goto done;
		}

		length = read_by_type(channel, start, end, &uuid, opdu,
								channel->mtu);
		break;
	case ATT_OP_READ_REQ:
		length = dec_read_req(ipdu, len, &start);
		if (length == 0) {
			status = ATT_ECODE_INVALID_PDU;
			goto done;
		}

		length = read_value(channel, start, opdu, channel->mtu);
		break;
	case ATT_OP_READ_BLOB_REQ:
		length = dec_read_blob_req(ipdu, len, &start, &offset);
		if (length == 0) {
			status = ATT_ECODE_INVALID_PDU;
			goto done;
		}

		length = read_blob(channel, start, offset, opdu, channel->mtu);
		break;
	case ATT_OP_MTU_REQ:
		if (!channel->le) {
			status = ATT_ECODE_REQ_NOT_SUPP;
			goto done;
		}

		length = dec_mtu_req(ipdu, len, &mtu);
		if (length == 0) {
			status = ATT_ECODE_INVALID_PDU;
			goto done;
		}

		length = mtu_exchange(channel, mtu, opdu, channel->mtu);
		break;
	case ATT_OP_FIND_INFO_REQ:
		length = dec_find_info_req(ipdu, len, &start, &end);
		if (length == 0) {
			status = ATT_ECODE_INVALID_PDU;
			goto done;
		}

		length = find_info(channel, start, end, opdu, channel->mtu);
		break;
	case ATT_OP_WRITE_REQ:
		length = dec_write_req(ipdu, len, &start, value, &vlen);
		if (length == 0) {
			status = ATT_ECODE_INVALID_PDU;
			goto done;
		}

		length = write_value(channel, start, value, vlen, opdu,
								channel->mtu);
		break;
	case ATT_OP_WRITE_CMD:
		length = dec_write_cmd(ipdu, len, &start, value, &vlen);
		if (length > 0)
			write_value(channel, start, value, vlen, opdu,
								channel->mtu);
		return;
	case ATT_OP_FIND_BY_TYPE_REQ:
		length = dec_find_by_type_req(ipdu, len, &start, &end,
							&uuid, value, &vlen);
		if (length == 0) {
			status = ATT_ECODE_INVALID_PDU;
			goto done;
		}

		length = find_by_type(channel, start, end, &uuid, value, vlen,
							opdu, channel->mtu);
		break;
	case ATT_OP_HANDLE_CNF:
		return;
	case ATT_OP_HANDLE_IND:
	case ATT_OP_HANDLE_NOTIFY:
		/* The attribute client is already handling these */
		return;
	case ATT_OP_READ_MULTI_REQ:
	case ATT_OP_PREP_WRITE_REQ:
	case ATT_OP_EXEC_WRITE_REQ:
	default:
		DBG("Unsupported request 0x%02x", ipdu[0]);
		status = ATT_ECODE_REQ_NOT_SUPP;
		goto done;
	}

	if (length == 0)
		status = ATT_ECODE_IO;

done:
	if (status)
		length = enc_error_resp(ipdu[0], 0x0000, status, opdu,
								channel->mtu);

	g_attrib_send(channel->attrib, 0, opdu, length, NULL, NULL, NULL);
}

GAttrib *attrib_from_device(struct btd_device *device)
{
	struct btd_adapter *adapter = device_get_adapter(device);
	struct gatt_server *server;
	GSList *l;

	l = g_slist_find_custom(servers, adapter, adapter_cmp);
	if (!l)
		return NULL;

	server = l->data;

	for (l = server->clients; l; l = l->next) {
		struct gatt_channel *channel = l->data;

		if (channel->device == device)
			return g_attrib_ref(channel->attrib);
	}

	return NULL;
}

guint attrib_channel_attach(GAttrib *attrib)
{
	struct gatt_server *server;
	struct btd_device *device;
	struct gatt_channel *channel;
	bdaddr_t src, dst;
	GIOChannel *io;
	GError *gerr = NULL;
	uint8_t bdaddr_type;
	uint16_t cid;
	guint mtu = 0;

	io = g_attrib_get_channel(attrib);

	bt_io_get(io, &gerr,
			BT_IO_OPT_SOURCE_BDADDR, &src,
			BT_IO_OPT_DEST_BDADDR, &dst,
			BT_IO_OPT_DEST_TYPE, &bdaddr_type,
			BT_IO_OPT_CID, &cid,
			BT_IO_OPT_IMTU, &mtu,
			BT_IO_OPT_INVALID);
	if (gerr) {
		error("bt_io_get: %s", gerr->message);
		g_error_free(gerr);
		return 0;
	}

	server = find_gatt_server(&src);
	if (server == NULL)
		return 0;

	channel = g_new0(struct gatt_channel, 1);
	channel->server = server;

	device = btd_adapter_find_device(server->adapter, &dst, bdaddr_type);
	if (device == NULL) {
		error("Device object not found for attrib server");
		g_free(channel);
		return 0;
	}

	if (!device_is_bonded(device, bdaddr_type)) {
		char *filename;

		filename = btd_device_get_storage_path(device, "ccc");
		if (filename) {
			unlink(filename);
			g_free(filename);
		}
	}

	if (cid != ATT_CID) {
		channel->le = FALSE;
		channel->mtu = mtu;
	} else {
		channel->le = TRUE;
		channel->mtu = ATT_DEFAULT_LE_MTU;
	}

	channel->attrib = g_attrib_ref(attrib);
	channel->id = g_attrib_register(channel->attrib, GATTRIB_ALL_REQS,
			GATTRIB_ALL_HANDLES, channel_handler, channel, NULL);

	channel->cleanup_id = g_io_add_watch(io, G_IO_HUP, channel_watch_cb,
								channel);

	channel->device = btd_device_ref(device);

	server->clients = g_slist_append(server->clients, channel);

	return channel->id;
}

static int channel_id_cmp(gconstpointer data, gconstpointer user_data)
{
	const struct gatt_channel *channel = data;
	guint id = GPOINTER_TO_UINT(user_data);

	return channel->id - id;
}

gboolean attrib_channel_detach(GAttrib *attrib, guint id)
{
	struct gatt_server *server;
	struct gatt_channel *channel;
	GError *gerr = NULL;
	GIOChannel *io;
	bdaddr_t src;
	GSList *l;

	io = g_attrib_get_channel(attrib);

	bt_io_get(io, &gerr, BT_IO_OPT_SOURCE_BDADDR, &src, BT_IO_OPT_INVALID);

	if (gerr != NULL) {
		error("bt_io_get: %s", gerr->message);
		g_error_free(gerr);
		return FALSE;
	}

	server = find_gatt_server(&src);
	if (server == NULL)
		return FALSE;

	l = g_slist_find_custom(server->clients, GUINT_TO_POINTER(id),
								channel_id_cmp);
	if (!l)
		return FALSE;

	channel = l->data;

	g_attrib_unregister(channel->attrib, channel->id);
	channel_remove(channel);

	return TRUE;
}

static void connect_event(GIOChannel *io, GError *gerr, void *user_data)
{
	struct btd_adapter *adapter;
	struct btd_device *device;
	uint8_t dst_type;
	bdaddr_t src, dst;

	DBG("");

	if (gerr) {
		error("%s", gerr->message);
		return;
	}

	bt_io_get(io, &gerr,
			BT_IO_OPT_SOURCE_BDADDR, &src,
			BT_IO_OPT_DEST_BDADDR, &dst,
			BT_IO_OPT_DEST_TYPE, &dst_type,
			BT_IO_OPT_INVALID);
	if (gerr) {
		error("bt_io_get: %s", gerr->message);
		g_error_free(gerr);
		return;
	}

	adapter = adapter_find(&src);
	if (!adapter)
		return;

	device = btd_adapter_get_device(adapter, &dst, dst_type);
	if (!device)
		return;

	device_attach_attrib(device, io);
}

static gboolean register_core_services(struct gatt_server *server)
{
	uint8_t atval[256];
	bt_uuid_t uuid;
	uint16_t appearance = 0x0000;

	/* GAP service: primary service definition */
	bt_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
	put_le16(GENERIC_ACCESS_PROFILE_ID, &atval[0]);
	attrib_db_add_new(server, 0x0001, &uuid, ATT_NONE, ATT_NOT_PERMITTED,
								atval, 2);

	/* GAP service: device name characteristic */
	server->name_handle = 0x0006;
	bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
	atval[0] = GATT_CHR_PROP_READ;
	put_le16(server->name_handle, &atval[1]);
	put_le16(GATT_CHARAC_DEVICE_NAME, &atval[3]);
	attrib_db_add_new(server, 0x0004, &uuid, ATT_NONE, ATT_NOT_PERMITTED,
								atval, 5);

	/* GAP service: device name attribute */
	bt_uuid16_create(&uuid, GATT_CHARAC_DEVICE_NAME);
	attrib_db_add_new(server, server->name_handle, &uuid, ATT_NONE,
						ATT_NOT_PERMITTED, NULL, 0);

	/* GAP service: device appearance characteristic */
	server->appearance_handle = 0x0008;
	bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
	atval[0] = GATT_CHR_PROP_READ;
	put_le16(server->appearance_handle, &atval[1]);
	put_le16(GATT_CHARAC_APPEARANCE, &atval[3]);
	attrib_db_add_new(server, 0x0007, &uuid, ATT_NONE, ATT_NOT_PERMITTED,
								atval, 5);

	/* GAP service: device appearance attribute */
	bt_uuid16_create(&uuid, GATT_CHARAC_APPEARANCE);
	put_le16(appearance, &atval[0]);
	attrib_db_add_new(server, server->appearance_handle, &uuid, ATT_NONE,
						ATT_NOT_PERMITTED, atval, 2);
	server->gap_sdp_handle = attrib_create_sdp_new(server, 0x0001,
						"Generic Access Profile");
	if (server->gap_sdp_handle == 0) {
		error("Failed to register GAP service record");
		return FALSE;
	}

	/* GATT service: primary service definition */
	bt_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
	put_le16(GENERIC_ATTRIB_PROFILE_ID, &atval[0]);
	attrib_db_add_new(server, 0x0010, &uuid, ATT_NONE, ATT_NOT_PERMITTED,
								atval, 2);

	server->gatt_sdp_handle = attrib_create_sdp_new(server, 0x0010,
						"Generic Attribute Profile");
	if (server->gatt_sdp_handle == 0) {
		error("Failed to register GATT service record");
		return FALSE;
	}

	return TRUE;
}

int btd_adapter_gatt_server_start(struct btd_adapter *adapter)
{
	struct gatt_server *server;
	GError *gerr = NULL;
	const bdaddr_t *addr;

	DBG("Start GATT server in hci%d", btd_adapter_get_index(adapter));

	server = g_new0(struct gatt_server, 1);
	server->adapter = btd_adapter_ref(adapter);

	addr = btd_adapter_get_address(server->adapter);

	/* BR/EDR socket */
	server->l2cap_io = bt_io_listen(connect_event, NULL, NULL, NULL, &gerr,
					BT_IO_OPT_SOURCE_BDADDR, addr,
					BT_IO_OPT_PSM, ATT_PSM,
					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
					BT_IO_OPT_INVALID);

	if (server->l2cap_io == NULL) {
		error("%s", gerr->message);
		g_error_free(gerr);
		gatt_server_free(server);
		return -1;
	}

	if (!register_core_services(server)) {
		gatt_server_free(server);
		return -1;
	}

	/* LE socket */
	server->le_io = bt_io_listen(connect_event, NULL,
					&server->le_io, NULL, &gerr,
					BT_IO_OPT_SOURCE_BDADDR, addr,
					BT_IO_OPT_SOURCE_TYPE, BDADDR_LE_PUBLIC,
					BT_IO_OPT_CID, ATT_CID,
					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
					BT_IO_OPT_INVALID);

	if (server->le_io == NULL) {
		error("%s", gerr->message);
		g_error_free(gerr);
		/* Doesn't have LE support, continue */
	}

	servers = g_slist_prepend(servers, server);
	return 0;
}

void btd_adapter_gatt_server_stop(struct btd_adapter *adapter)
{
	struct gatt_server *server;
	GSList *l;

	l = g_slist_find_custom(servers, adapter, adapter_cmp);
	if (l == NULL)
		return;

	DBG("Stop GATT server in hci%d", btd_adapter_get_index(adapter));

	server = l->data;
	servers = g_slist_remove(servers, server);
	gatt_server_free(server);
}

uint32_t attrib_create_sdp(struct btd_adapter *adapter, uint16_t handle,
							const char *name)
{
	GSList *l;

	l = g_slist_find_custom(servers, adapter, adapter_cmp);
	if (l == NULL)
		return 0;

	return attrib_create_sdp_new(l->data, handle, name);
}

void attrib_free_sdp(struct btd_adapter *adapter, uint32_t sdp_handle)
{
	adapter_service_remove(adapter, sdp_handle);
}

static uint16_t find_uuid16_avail(struct btd_adapter *adapter, uint16_t nitems)
{
	struct gatt_server *server;
	uint16_t handle;
	GSList *l;
	GList *dl;

	l = g_slist_find_custom(servers, adapter, adapter_cmp);
	if (l == NULL)
		return 0;

	server = l->data;
	if (server->database == NULL)
		return 0x0001;

	for (dl = server->database, handle = 0x0001; dl; dl = dl->next) {
		struct attribute *a = dl->data;

		if ((bt_uuid_cmp(&a->uuid, &prim_uuid) == 0 ||
				bt_uuid_cmp(&a->uuid, &snd_uuid) == 0) &&
				a->handle - handle >= nitems)
			/* Note: the range above excludes the current handle */
			return handle;

		if (a->len == 16 && (bt_uuid_cmp(&a->uuid, &prim_uuid) == 0 ||
				bt_uuid_cmp(&a->uuid, &snd_uuid) == 0)) {
			/* 128 bit UUID service definition */
			return 0;
		}

		if (a->handle == 0xffff)
			return 0;

		handle = a->handle + 1;
	}

	if (0xffff - handle + 1 >= nitems)
		return handle;

	return 0;
}

static uint16_t find_uuid128_avail(struct btd_adapter *adapter, uint16_t nitems)
{
	uint16_t handle = 0, end = 0xffff;
	struct gatt_server *server;
	GList *dl;
	GSList *l;

	l = g_slist_find_custom(servers, adapter, adapter_cmp);
	if (l == NULL)
		return 0;

	server = l->data;
	if (server->database == NULL)
		return 0xffff - nitems + 1;

	for (dl = g_list_last(server->database); dl; dl = dl->prev) {
		struct attribute *a = dl->data;

		if (handle == 0)
			handle = a->handle;

		if (bt_uuid_cmp(&a->uuid, &prim_uuid) != 0 &&
				bt_uuid_cmp(&a->uuid, &snd_uuid) != 0)
			continue;

		if (end - handle >= nitems)
			return end - nitems + 1;

		if (a->len == 2) {
			/* 16 bit UUID service definition */
			return 0;
		}

		if (a->handle == 0x0001)
			return 0;

		end = a->handle - 1;
		handle = 0;
	}

	if (end - 0x0001 >= nitems)
		return end - nitems + 1;

	return 0;
}

uint16_t attrib_db_find_avail(struct btd_adapter *adapter, bt_uuid_t *svc_uuid,
								uint16_t nitems)
{
	g_assert(nitems > 0);

	if (svc_uuid->type == BT_UUID16)
		return find_uuid16_avail(adapter, nitems);
	else if (svc_uuid->type == BT_UUID128)
		return find_uuid128_avail(adapter, nitems);
	else {
		char uuidstr[MAX_LEN_UUID_STR];

		bt_uuid_to_string(svc_uuid, uuidstr, MAX_LEN_UUID_STR);
		error("Service uuid: %s is neither a 16-bit nor a 128-bit uuid",
								uuidstr);
		return 0;
	}
}

struct attribute *attrib_db_add(struct btd_adapter *adapter, uint16_t handle,
					bt_uuid_t *uuid, int read_req,
					int write_req, const uint8_t *value,
					size_t len)
{
	GSList *l;

	l = g_slist_find_custom(servers, adapter, adapter_cmp);
	if (l == NULL)
		return NULL;

	return attrib_db_add_new(l->data, handle, uuid, read_req, write_req,
								value, len);
}

int attrib_db_update(struct btd_adapter *adapter, uint16_t handle,
					bt_uuid_t *uuid, const uint8_t *value,
					size_t len, struct attribute **attr)
{
	struct gatt_server *server;
	struct attribute *a;
	GSList *l;
	GList *dl;
	guint h = handle;

	l = g_slist_find_custom(servers, adapter, adapter_cmp);
	if (l == NULL)
		return -ENOENT;

	server = l->data;

	DBG("handle=0x%04x", handle);

	dl = g_list_find_custom(server->database, GUINT_TO_POINTER(h),
								handle_cmp);
	if (dl == NULL)
		return -ENOENT;

	a = dl->data;

	a->data = g_try_realloc(a->data, len);
	if (len && a->data == NULL)
		return -ENOMEM;

	a->len = len;
	memcpy(a->data, value, len);

	if (uuid != NULL)
		a->uuid = *uuid;

	if (attr)
		*attr = a;

	return 0;
}

int attrib_db_del(struct btd_adapter *adapter, uint16_t handle)
{
	struct gatt_server *server;
	struct attribute *a;
	GSList *l;
	GList *dl;
	guint h = handle;

	l = g_slist_find_custom(servers, adapter, adapter_cmp);
	if (l == NULL)
		return -ENOENT;

	server = l->data;

	DBG("handle=0x%04x", handle);

	dl = g_list_find_custom(server->database, GUINT_TO_POINTER(h),
								handle_cmp);
	if (dl == NULL)
		return -ENOENT;

	a = dl->data;
	server->database = g_list_remove(server->database, a);
	g_free(a->data);
	g_free(a);

	return 0;
}

int attrib_gap_set(struct btd_adapter *adapter, uint16_t uuid,
					const uint8_t *value, size_t len)
{
	struct gatt_server *server;
	uint16_t handle;
	GSList *l;

	l = g_slist_find_custom(servers, adapter, adapter_cmp);
	if (l == NULL)
		return -ENOENT;

	server = l->data;

	/* FIXME: Missing Privacy and Reconnection Address */

	switch (uuid) {
	case GATT_CHARAC_DEVICE_NAME:
		handle = server->name_handle;
		break;
	case GATT_CHARAC_APPEARANCE:
		handle = server->appearance_handle;
		break;
	default:
		return -ENOSYS;
	}

	return attrib_db_update(adapter, handle, NULL, value, len, NULL);
}
