/* gatt.c - Bluetooth GATT Server Tester */

/*
 * Copyright (c) 2015-2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/types.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>

#include <zephyr/toolchain.h>
#include <zephyr/bluetooth/att.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/l2cap.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/__assert.h>
#include <zephyr/net/buf.h>

#include <zephyr/logging/log.h>
#define LOG_MODULE_NAME bttester_gatt
LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL);

#include "btp/btp.h"

#define MAX_BUFFER_SIZE 2048
#define MAX_UUID_LEN 16

#define MAX_SUBSCRIPTIONS 2

#define UNUSED_SUBSCRIBE_CCC_HANDLE 0x0000

/* This masks Permission bits from GATT API */
#define GATT_PERM_MASK		(BT_GATT_PERM_READ | \
					 BT_GATT_PERM_READ_AUTHEN | \
					 BT_GATT_PERM_READ_ENCRYPT | \
					 BT_GATT_PERM_WRITE | \
					 BT_GATT_PERM_WRITE_AUTHEN | \
					 BT_GATT_PERM_WRITE_ENCRYPT | \
					 BT_GATT_PERM_PREPARE_WRITE)
#define GATT_PERM_ENC_READ_MASK	(BT_GATT_PERM_READ_ENCRYPT | \
					 BT_GATT_PERM_READ_AUTHEN)
#define GATT_PERM_ENC_WRITE_MASK	(BT_GATT_PERM_WRITE_ENCRYPT | \
					 BT_GATT_PERM_WRITE_AUTHEN)
#define GATT_PERM_READ_AUTHORIZATION	0x40
#define GATT_PERM_WRITE_AUTHORIZATION	0x80

/* GATT server context */
#define SERVER_MAX_SERVICES		10
#define SERVER_MAX_ATTRIBUTES		50
#define SERVER_BUF_SIZE			2048
#define MAX_CCC_COUNT			2

/* bt_gatt_attr_next cannot be used on non-registered services */
#define NEXT_DB_ATTR(attr) (attr + 1)
#define LAST_DB_ATTR (server_db + (attr_count - 1))

#define server_buf_push(_len)	net_buf_push(server_buf, ROUND_UP(_len, 4))
#define server_buf_pull(_len)	net_buf_pull(server_buf, ROUND_UP(_len, 4))

static struct bt_gatt_service server_svcs[SERVER_MAX_SERVICES];
static struct bt_gatt_attr server_db[SERVER_MAX_ATTRIBUTES];
static struct net_buf *server_buf;
NET_BUF_POOL_DEFINE(server_pool, 1, SERVER_BUF_SIZE, 0, NULL);

static uint8_t attr_count;
static uint8_t svc_attr_count;
static uint8_t svc_count;
static bool ccc_added;

/*
 * gatt_buf - cache used by a gatt client (to cache data read/discovered)
 * and gatt server (to store attribute user_data).
 * It is not intended to be used by client and server at the same time.
 */
static struct {
	uint16_t len;
	uint8_t buf[MAX_BUFFER_SIZE];
} gatt_buf;

struct get_attr_data {
	struct net_buf_simple *buf;
	struct bt_conn *conn;
};

struct ccc_value {
	struct bt_gatt_attr *attr;
	struct bt_gatt_attr *ccc;
	uint8_t value;
};

static struct ccc_value ccc_values[MAX_CCC_COUNT];

static int ccc_find_by_attr(uint16_t handle)
{
	for (int i = 0; i < MAX_CCC_COUNT; i++) {
		if (handle == ccc_values[i].attr->handle) {
			return i;
		}
	}

	return -ENOENT;
}

static int ccc_find_by_ccc(const struct bt_gatt_attr *attr)
{
	for (int i = 0; i < MAX_CCC_COUNT; i++) {
		if (attr == ccc_values[i].ccc) {
			return i;
		}
	}

	return -ENOENT;
}

static void *gatt_buf_add(const void *data, size_t len)
{
	void *ptr = gatt_buf.buf + gatt_buf.len;

	if ((len + gatt_buf.len) > MAX_BUFFER_SIZE) {
		return NULL;
	}

	if (data) {
		memcpy(ptr, data, len);
	} else {
		(void)memset(ptr, 0, len);
	}

	gatt_buf.len += len;

	LOG_DBG("%d/%d used", gatt_buf.len, MAX_BUFFER_SIZE);

	return ptr;
}

static void *gatt_buf_reserve(size_t len)
{
	return gatt_buf_add(NULL, len);
}

static void gatt_buf_clear(void)
{
	(void)memset(&gatt_buf, 0, sizeof(gatt_buf));
}

union uuid {
	struct bt_uuid uuid;
	struct bt_uuid_16 u16;
	struct bt_uuid_128 u128;
};

static struct bt_gatt_attr *gatt_db_add(const struct bt_gatt_attr *pattern,
					size_t user_data_len)
{
	static struct bt_gatt_attr *attr = server_db;
	const union uuid *u = CONTAINER_OF(pattern->uuid, union uuid, uuid);
	size_t uuid_size = u->uuid.type == BT_UUID_TYPE_16 ? sizeof(u->u16) :
							     sizeof(u->u128);

	/* Return NULL if database is full */
	if (attr == &server_db[SERVER_MAX_ATTRIBUTES - 1]) {
		return NULL;
	}

	/* First attribute in db must be service */
	if (!svc_count) {
		return NULL;
	}

	memcpy(attr, pattern, sizeof(*attr));

	/* Store the UUID. */
	attr->uuid = server_buf_push(uuid_size);
	memcpy((void *) attr->uuid, &u->uuid, uuid_size);

	/* Copy user_data to the buffer. */
	if (user_data_len) {
		attr->user_data = server_buf_push(user_data_len);
		memcpy(attr->user_data, pattern->user_data, user_data_len);
	}

	LOG_DBG("handle 0x%04x", attr->handle);

	attr_count++;
	svc_attr_count++;

	return attr++;
}

/* Convert UUID from BTP command to bt_uuid */
static uint8_t btp2bt_uuid(const uint8_t *uuid, uint8_t len,
			   struct bt_uuid *bt_uuid)
{
	uint16_t le16;

	switch (len) {
	case 0x02: /* UUID 16 */
		bt_uuid->type = BT_UUID_TYPE_16;
		memcpy(&le16, uuid, sizeof(le16));
		BT_UUID_16(bt_uuid)->val = sys_le16_to_cpu(le16);
		break;
	case 0x10: /* UUID 128*/
		bt_uuid->type = BT_UUID_TYPE_128;
		memcpy(BT_UUID_128(bt_uuid)->val, uuid, 16);
		break;
	default:
		return BTP_STATUS_FAILED;
	}

	return BTP_STATUS_SUCCESS;
}

static uint8_t supported_commands(const void *cmd, uint16_t cmd_len,
				  void *rsp, uint16_t *rsp_len)
{
	struct btp_gatt_read_supported_commands_rp *rp = rsp;

	/* octet 0 */
	tester_set_bit(rp->data, BTP_GATT_READ_SUPPORTED_COMMANDS);
	tester_set_bit(rp->data, BTP_GATT_ADD_SERVICE);
	tester_set_bit(rp->data, BTP_GATT_ADD_CHARACTERISTIC);
	tester_set_bit(rp->data, BTP_GATT_ADD_DESCRIPTOR);
	tester_set_bit(rp->data, BTP_GATT_ADD_INCLUDED_SERVICE);
	tester_set_bit(rp->data, BTP_GATT_SET_VALUE);
	tester_set_bit(rp->data, BTP_GATT_START_SERVER);

	/* octet 1 */
	tester_set_bit(rp->data, BTP_GATT_SET_ENC_KEY_SIZE);
	tester_set_bit(rp->data, BTP_GATT_EXCHANGE_MTU);
	tester_set_bit(rp->data, BTP_GATT_DISC_ALL_PRIM);
	tester_set_bit(rp->data, BTP_GATT_DISC_PRIM_UUID);
	tester_set_bit(rp->data, BTP_GATT_FIND_INCLUDED);
	tester_set_bit(rp->data, BTP_GATT_DISC_ALL_CHRC);
	tester_set_bit(rp->data, BTP_GATT_DISC_CHRC_UUID);

	/* octet 2 */
	tester_set_bit(rp->data, BTP_GATT_DISC_ALL_DESC);
	tester_set_bit(rp->data, BTP_GATT_READ);
	tester_set_bit(rp->data, BTP_GATT_READ_LONG);
	tester_set_bit(rp->data, BTP_GATT_READ_MULTIPLE);
	tester_set_bit(rp->data, BTP_GATT_WRITE_WITHOUT_RSP);
	tester_set_bit(rp->data, BTP_GATT_SIGNED_WRITE_WITHOUT_RSP);
	tester_set_bit(rp->data, BTP_GATT_WRITE);

	/* octet 3 */
	tester_set_bit(rp->data, BTP_GATT_WRITE_LONG);
	tester_set_bit(rp->data, BTP_GATT_CFG_NOTIFY);
	tester_set_bit(rp->data, BTP_GATT_CFG_INDICATE);
	tester_set_bit(rp->data, BTP_GATT_GET_ATTRIBUTES);
	tester_set_bit(rp->data, BTP_GATT_GET_ATTRIBUTE_VALUE);
	tester_set_bit(rp->data, BTP_GATT_CHANGE_DB);
	tester_set_bit(rp->data, BTP_GATT_EATT_CONNECT);

	/* octet 4 */
	tester_set_bit(rp->data, BTP_GATT_READ_MULTIPLE_VAR);
	tester_set_bit(rp->data, BTP_GATT_NOTIFY_MULTIPLE);


	*rsp_len = sizeof(*rp) + 5;

	return BTP_STATUS_SUCCESS;
}

static int register_service(void)
{
	int err;

	server_svcs[svc_count].attrs = server_db +
				       (attr_count - svc_attr_count);
	server_svcs[svc_count].attr_count = svc_attr_count;

	err = bt_gatt_service_register(&server_svcs[svc_count]);
	if (!err) {
		/* Service registered, reset the counter */
		svc_attr_count = 0U;
	}

	return err;
}

static uint8_t add_service(const void *cmd, uint16_t cmd_len,
			   void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_add_service_cmd *cp = cmd;
	struct btp_gatt_add_service_rp *rp = rsp;
	struct bt_gatt_attr *attr_svc = NULL;
	union uuid uuid;
	size_t uuid_size;

	if ((cmd_len < sizeof(*cp)) ||
	    (cmd_len != sizeof(*cp) + cp->uuid_length)) {
		return BTP_STATUS_FAILED;
	}

	if (btp2bt_uuid(cp->uuid, cp->uuid_length, &uuid.uuid)) {
		return BTP_STATUS_FAILED;
	}

	uuid_size = uuid.uuid.type == BT_UUID_TYPE_16 ? sizeof(uuid.u16) :
							sizeof(uuid.u128);

	/* Register last defined service */
	if (svc_attr_count) {
		if (register_service()) {
			return BTP_STATUS_FAILED;
		}
	}

	svc_count++;

	switch (cp->type) {
	case BTP_GATT_SERVICE_PRIMARY:
		attr_svc = gatt_db_add(&(struct bt_gatt_attr)
				       BT_GATT_PRIMARY_SERVICE(&uuid.uuid),
				       uuid_size);
		break;
	case BTP_GATT_SERVICE_SECONDARY:
		attr_svc = gatt_db_add(&(struct bt_gatt_attr)
				       BT_GATT_SECONDARY_SERVICE(&uuid.uuid),
				       uuid_size);
		break;
	}

	if (!attr_svc) {
		svc_count--;
		return BTP_STATUS_FAILED;
	}

	rp->svc_id = sys_cpu_to_le16(attr_svc->handle);
	*rsp_len = sizeof(*rp);

	return BTP_STATUS_SUCCESS;
}

struct gatt_value {
	uint16_t len;
	uint8_t *data;
	uint8_t enc_key_size;
	uint8_t flags[1];
};

enum {
	GATT_VALUE_CCC_FLAG,
	GATT_VALUE_READ_AUTHOR_FLAG,
	GATT_VALUE_WRITE_AUTHOR_FLAG,
};

static ssize_t read_value(struct bt_conn *conn, const struct bt_gatt_attr *attr,
			  void *buf, uint16_t len, uint16_t offset)
{
	const struct gatt_value *value = attr->user_data;

	if (tester_test_bit(value->flags, GATT_VALUE_READ_AUTHOR_FLAG)) {
		return BT_GATT_ERR(BT_ATT_ERR_AUTHORIZATION);
	}

	if ((attr->perm & GATT_PERM_ENC_READ_MASK) && (conn != NULL) &&
	    (value->enc_key_size > bt_conn_enc_key_size(conn))) {
		return BT_GATT_ERR(BT_ATT_ERR_ENCRYPTION_KEY_SIZE);
	}

	return bt_gatt_attr_read(conn, attr, buf, len, offset, value->data,
				 value->len);
}

static void attr_value_changed_ev(uint16_t handle, const uint8_t *value, uint16_t len)
{
	uint8_t buf[len + sizeof(struct btp_gatt_attr_value_changed_ev)];
	struct btp_gatt_attr_value_changed_ev *ev = (void *) buf;

	ev->handle = sys_cpu_to_le16(handle);
	ev->data_length = sys_cpu_to_le16(len);
	memcpy(ev->data, value, len);

	tester_event(BTP_SERVICE_ID_GATT, BTP_GATT_EV_ATTR_VALUE_CHANGED,
		    buf, sizeof(buf));
}

static ssize_t write_value(struct bt_conn *conn,
			   const struct bt_gatt_attr *attr, const void *buf,
			   uint16_t len, uint16_t offset, uint8_t flags)
{
	struct gatt_value *value = attr->user_data;

	if (tester_test_bit(value->flags, GATT_VALUE_WRITE_AUTHOR_FLAG)) {
		return BT_GATT_ERR(BT_ATT_ERR_AUTHORIZATION);
	}

	if ((attr->perm & GATT_PERM_ENC_WRITE_MASK) &&
	    (value->enc_key_size > bt_conn_enc_key_size(conn))) {
		return BT_GATT_ERR(BT_ATT_ERR_ENCRYPTION_KEY_SIZE);
	}

	/* Don't write anything if prepare flag is set */
	if (flags & BT_GATT_WRITE_FLAG_PREPARE) {
		return 0;
	}

	if (offset > value->len) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
	}

	if (offset + len > value->len) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
	}

	memcpy(value->data + offset, buf, len);
	value->len = len;

	/* Maximum attribute value size is 512 bytes */
	__ASSERT_NO_MSG(value->len < 512);

	attr_value_changed_ev(attr->handle, value->data, value->len);

	return len;
}

struct add_characteristic {
	uint16_t char_id;
	uint8_t properties;
	uint8_t permissions;
	const struct bt_uuid *uuid;
};

static int alloc_characteristic(struct add_characteristic *ch)
{
	struct bt_gatt_attr *attr_chrc, *attr_value;
	struct bt_gatt_chrc *chrc_data;
	struct gatt_value value;

	/* Add Characteristic Declaration */
	attr_chrc = gatt_db_add(&(struct bt_gatt_attr)
				BT_GATT_ATTRIBUTE(BT_UUID_GATT_CHRC,
						  BT_GATT_PERM_READ,
						  bt_gatt_attr_read_chrc, NULL,
						  (&(struct bt_gatt_chrc){})),
				sizeof(*chrc_data));
	if (!attr_chrc) {
		return -EINVAL;
	}

	(void)memset(&value, 0, sizeof(value));

	if (ch->permissions & GATT_PERM_READ_AUTHORIZATION) {
		tester_set_bit(value.flags, GATT_VALUE_READ_AUTHOR_FLAG);

		/* To maintain backward compatibility, set Read Permission */
		if (!(ch->permissions & GATT_PERM_ENC_READ_MASK)) {
			ch->permissions |= BT_GATT_PERM_READ;
		}
	}

	if (ch->permissions & GATT_PERM_WRITE_AUTHORIZATION) {
		tester_set_bit(value.flags, GATT_VALUE_WRITE_AUTHOR_FLAG);

		/* To maintain backward compatibility, set Write Permission */
		if (!(ch->permissions & GATT_PERM_ENC_WRITE_MASK)) {
			ch->permissions |= BT_GATT_PERM_WRITE;
		}
	}

	/* Allow prepare writes */
	ch->permissions |= BT_GATT_PERM_PREPARE_WRITE;

	/* Add Characteristic Value */
	attr_value = gatt_db_add(&(struct bt_gatt_attr)
				 BT_GATT_ATTRIBUTE(ch->uuid,
					ch->permissions & GATT_PERM_MASK,
					read_value, write_value, &value),
					sizeof(value));
	if (!attr_value) {
		server_buf_pull(sizeof(*chrc_data));
		/* Characteristic attribute uuid has constant length */
		server_buf_pull(sizeof(uint16_t));
		return -EINVAL;
	}

	chrc_data = attr_chrc->user_data;
	chrc_data->properties = ch->properties;
	chrc_data->uuid = attr_value->uuid;

	ch->char_id = attr_chrc->handle;
	return 0;
}

static uint8_t add_characteristic(const void *cmd, uint16_t cmd_len,
				  void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_add_characteristic_cmd *cp = cmd;
	struct btp_gatt_add_characteristic_rp *rp = rsp;
	struct add_characteristic cmd_data;
	union uuid uuid;

	if ((cmd_len < sizeof(*cp)) ||
	    (cmd_len != sizeof(*cp) + cp->uuid_length)) {
		return BTP_STATUS_FAILED;
	}

	/* Pre-set char_id */
	cmd_data.char_id = 0U;
	cmd_data.permissions = cp->permissions;
	cmd_data.properties = cp->properties;
	cmd_data.uuid = &uuid.uuid;

	if (btp2bt_uuid(cp->uuid, cp->uuid_length, &uuid.uuid)) {
		return BTP_STATUS_FAILED;
	}

	/* characteristic must be added only sequential */
	if (cp->svc_id) {
		return BTP_STATUS_FAILED;
	}

	if (alloc_characteristic(&cmd_data)) {
		return BTP_STATUS_FAILED;
	}

	ccc_added = false;

	rp->char_id = sys_cpu_to_le16(cmd_data.char_id);
	*rsp_len = sizeof(*rp);

	return BTP_STATUS_SUCCESS;
}

static void ccc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
{
	int i = ccc_find_by_ccc(attr);

	if (i >= 0) {
		ccc_values[i].value = value;
	}
}

static struct bt_gatt_attr ccc = BT_GATT_CCC(ccc_cfg_changed,
					     BT_GATT_PERM_READ |
					     BT_GATT_PERM_WRITE);

static struct bt_gatt_attr *add_ccc(struct bt_gatt_attr *attr)
{
	struct bt_gatt_attr *attr_desc;
	struct bt_gatt_chrc *chrc = attr->user_data;
	struct gatt_value *value = NEXT_DB_ATTR(attr)->user_data;
	int i;

	/* Fail if another CCC already exist for this characteristic */
	if (ccc_added) {
		return NULL;
	}

	/* Check characteristic properties */
	if (!(chrc->properties &
	    (BT_GATT_CHRC_NOTIFY | BT_GATT_CHRC_INDICATE))) {
		return NULL;
	}

	/* Add CCC descriptor to GATT database */
	attr_desc = gatt_db_add(&ccc, 0);
	if (!attr_desc) {
		return NULL;
	}

	i = ccc_find_by_ccc(NULL);
	if (i >= 0) {
		ccc_values[i].attr = attr;
		ccc_values[i].ccc = attr_desc;
		ccc_values[i].value = 0;
	}

	tester_set_bit(value->flags, GATT_VALUE_CCC_FLAG);
	ccc_added = true;

	return attr_desc;
}

static struct bt_gatt_attr *add_cep(const struct bt_gatt_attr *attr_chrc)
{
	struct bt_gatt_chrc *chrc = attr_chrc->user_data;
	struct bt_gatt_cep cep_value;

	/* Extended Properties bit shall be set */
	if (!(chrc->properties & BT_GATT_CHRC_EXT_PROP)) {
		return NULL;
	}

	cep_value.properties = 0x0000;

	/* Add CEP descriptor to GATT database */
	return gatt_db_add(&(struct bt_gatt_attr) BT_GATT_CEP(&cep_value),
			   sizeof(cep_value));
}

struct add_descriptor {
	uint16_t desc_id;
	uint8_t permissions;
	const struct bt_uuid *uuid;
};

static int alloc_descriptor(struct bt_gatt_attr *attr,
			    struct add_descriptor *d)
{
	struct bt_gatt_attr *attr_desc;
	struct gatt_value value;

	if (!bt_uuid_cmp(d->uuid, BT_UUID_GATT_CEP)) {
		attr_desc = add_cep(attr);
	} else if (!bt_uuid_cmp(d->uuid, BT_UUID_GATT_CCC)) {
		attr_desc = add_ccc(attr);
	} else {
		(void)memset(&value, 0, sizeof(value));

		if (d->permissions & GATT_PERM_READ_AUTHORIZATION) {
			tester_set_bit(value.flags,
				       GATT_VALUE_READ_AUTHOR_FLAG);

			/*
			 * To maintain backward compatibility,
			 * set Read Permission
			 */
			if (!(d->permissions & GATT_PERM_ENC_READ_MASK)) {
				d->permissions |= BT_GATT_PERM_READ;
			}
		}

		if (d->permissions & GATT_PERM_WRITE_AUTHORIZATION) {
			tester_set_bit(value.flags,
				       GATT_VALUE_WRITE_AUTHOR_FLAG);

			/*
			 * To maintain backward compatibility,
			 * set Write Permission
			 */
			if (!(d->permissions & GATT_PERM_ENC_WRITE_MASK)) {
				d->permissions |= BT_GATT_PERM_WRITE;
			}
		}

		/* Allow prepare writes */
		d->permissions |= BT_GATT_PERM_PREPARE_WRITE;

		attr_desc = gatt_db_add(&(struct bt_gatt_attr)
					BT_GATT_DESCRIPTOR(d->uuid,
						d->permissions & GATT_PERM_MASK,
						read_value, write_value,
						&value), sizeof(value));
	}

	if (!attr_desc) {
		return -EINVAL;
	}

	d->desc_id = attr_desc->handle;
	return 0;
}

static struct bt_gatt_attr *get_base_chrc(struct bt_gatt_attr *attr)
{
	struct bt_gatt_attr *tmp;

	for (tmp = attr; tmp > server_db; tmp--) {
		/* Service Declaration cannot precede Descriptor declaration */
		if (!bt_uuid_cmp(tmp->uuid, BT_UUID_GATT_PRIMARY) ||
		    !bt_uuid_cmp(tmp->uuid, BT_UUID_GATT_SECONDARY)) {
			break;
		}

		if (!bt_uuid_cmp(tmp->uuid, BT_UUID_GATT_CHRC)) {
			return tmp;
		}
	}

	return NULL;
}

static uint8_t add_descriptor(const void *cmd, uint16_t cmd_len,
			      void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_add_descriptor_cmd *cp = cmd;
	struct btp_gatt_add_descriptor_rp *rp = rsp;
	struct add_descriptor cmd_data;
	struct bt_gatt_attr *chrc;
	union uuid uuid;

	if ((cmd_len < sizeof(*cp)) ||
	    (cmd_len != sizeof(*cp) + cp->uuid_length)) {
		return BTP_STATUS_FAILED;
	}

	/* Must be declared first svc or at least 3 attrs (svc+char+char val) */
	if (!svc_count || attr_count < 3) {
		return BTP_STATUS_FAILED;
	}

	/* Pre-set desc_id */
	cmd_data.desc_id = 0U;
	cmd_data.permissions = cp->permissions;
	cmd_data.uuid = &uuid.uuid;

	if (btp2bt_uuid(cp->uuid, cp->uuid_length, &uuid.uuid)) {
		return BTP_STATUS_FAILED;
	}

	/* descriptor can be added only sequential */
	if (cp->char_id) {
		return BTP_STATUS_FAILED;
	}

	/* Lookup preceding Characteristic Declaration here */
	chrc = get_base_chrc(LAST_DB_ATTR);
	if (!chrc) {
		return BTP_STATUS_FAILED;
	}

	if (alloc_descriptor(chrc, &cmd_data)) {
		return BTP_STATUS_FAILED;
	}

	rp->desc_id = sys_cpu_to_le16(cmd_data.desc_id);
	*rsp_len = sizeof(*rp);

	return BTP_STATUS_SUCCESS;
}

static int alloc_included(struct bt_gatt_attr *attr,
			  uint16_t *included_service_id, uint16_t svc_handle)
{
	struct bt_gatt_attr *attr_incl;

	/*
	 * user_data_len is set to 0 to NOT allocate memory in server_buf for
	 * user_data, just to assign to it attr pointer.
	 */
	attr_incl = gatt_db_add(&(struct bt_gatt_attr)
				BT_GATT_INCLUDE_SERVICE(attr), 0);

	if (!attr_incl) {
		return -EINVAL;
	}

	attr_incl->user_data = attr;

	*included_service_id = attr_incl->handle;
	return 0;
}

static uint8_t add_included(const void *cmd, uint16_t cmd_len,
			    void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_add_included_service_cmd *cp = cmd;
	struct btp_gatt_add_included_service_rp *rp = rsp;
	struct bt_gatt_attr *svc;
	uint16_t svc_id;
	uint16_t included_service_id = 0U;

	if (!svc_count) {
		return BTP_STATUS_FAILED;
	}

	svc_id = sys_le16_to_cpu(cp->svc_id);

	if (svc_id == 0 || svc_id > SERVER_MAX_ATTRIBUTES) {
		return BTP_STATUS_FAILED;
	}

	svc = &server_db[svc_id - 1];

	/* Fail if attribute stored under requested handle is not a service */
	if (bt_uuid_cmp(svc->uuid, BT_UUID_GATT_PRIMARY) &&
	    bt_uuid_cmp(svc->uuid, BT_UUID_GATT_SECONDARY)) {
		return BTP_STATUS_FAILED;
	}

	if (alloc_included(svc, &included_service_id, svc_id)) {
		return BTP_STATUS_FAILED;
	}

	rp->included_service_id = sys_cpu_to_le16(included_service_id);
	*rsp_len = sizeof(*rp);

	return BTP_STATUS_SUCCESS;
}

static uint8_t set_cep_value(struct bt_gatt_attr *attr, const void *value,
			     const uint16_t len)
{
	struct bt_gatt_cep *cep_value = attr->user_data;
	uint16_t properties;

	if (len != sizeof(properties)) {
		return BTP_STATUS_FAILED;
	}

	memcpy(&properties, value, len);
	cep_value->properties = sys_le16_to_cpu(properties);

	return BTP_STATUS_SUCCESS;
}

struct set_value {
	const uint8_t *value;
	uint16_t len;
};

struct bt_gatt_indicate_params indicate_params;

static void indicate_cb(struct bt_conn *conn,
			struct bt_gatt_indicate_params *params, uint8_t err)
{
	if (err != 0U) {
		LOG_ERR("Indication fail");
	} else {
		LOG_DBG("Indication success");
	}
}

static uint8_t alloc_value(struct bt_gatt_attr *attr, struct set_value *data)
{
	struct gatt_value *value;
	uint8_t ccc_value;
	int i;

	/* Value has been already set while adding CCC to the gatt_db */
	if (!bt_uuid_cmp(attr->uuid, BT_UUID_GATT_CCC)) {
		return BTP_STATUS_SUCCESS;
	}

	/* Set CEP value */
	if (!bt_uuid_cmp(attr->uuid, BT_UUID_GATT_CEP)) {
		return set_cep_value(attr, data->value, data->len);
	}

	value = attr->user_data;

	/* Check if attribute value has been already set */
	if (!value->len) {
		value->data = server_buf_push(data->len);
		value->len = data->len;
	}

	/* Fail if value length doesn't match  */
	if (value->len != data->len) {
		return BTP_STATUS_FAILED;
	}

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

	/** Handle of attribute is 1 less that handle to its value */
	i = ccc_find_by_attr(attr->handle - 1);

	if (i < 0) {
		ccc_value = 0;
	} else {
		ccc_value = ccc_values[i].value;
	}

	if (tester_test_bit(value->flags, GATT_VALUE_CCC_FLAG) && ccc_value) {
		if (ccc_value == BT_GATT_CCC_NOTIFY) {
			bt_gatt_notify(NULL, attr, value->data, value->len);
		} else {
			indicate_params.attr = attr;
			indicate_params.data = value->data;
			indicate_params.len = value->len;
			indicate_params.func = indicate_cb;
			indicate_params.destroy = NULL;
			indicate_params.chan_opt = BT_ATT_CHAN_OPT_NONE;

			bt_gatt_indicate(NULL, &indicate_params);
		}
	}

	return BTP_STATUS_SUCCESS;
}

static uint8_t set_value(const void *cmd, uint16_t cmd_len,
			 void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_set_value_cmd *cp = cmd;
	struct set_value cmd_data;
	uint16_t attr_id;
	uint8_t status;

	if ((cmd_len < sizeof(*cp)) ||
	    (cmd_len != sizeof(*cp) + sys_le16_to_cpu(cp->len))) {
		return BTP_STATUS_FAILED;
	}

	attr_id = sys_le16_to_cpu(cp->attr_id);
	if (attr_id > SERVER_MAX_ATTRIBUTES) {
		return BTP_STATUS_FAILED;
	}

	/* Pre-set btp_status */
	cmd_data.value = cp->value;
	cmd_data.len = sys_le16_to_cpu(cp->len);

	if (attr_id == 0) {
		status = alloc_value(LAST_DB_ATTR, &cmd_data);
	} else {
		/* set value of local attr, corrected by pre set attr handles */
		status = alloc_value(&server_db[attr_id - server_db[0].handle],
				     &cmd_data);
	}

	return BTP_STATUS_SUCCESS;
}

static uint8_t start_server(const void *cmd, uint16_t cmd_len,
			    void *rsp, uint16_t *rsp_len)
{
	struct btp_gatt_start_server_rp *rp = rsp;

	/* Register last defined service */
	if (svc_attr_count) {
		if (register_service()) {
			return BTP_STATUS_FAILED;
		}
	}

	rp->db_attr_off = sys_cpu_to_le16(0); /* TODO*/
	rp->db_attr_cnt = svc_attr_count;
	*rsp_len = sizeof(*rp);

	return BTP_STATUS_SUCCESS;
}

static int set_attr_enc_key_size(const struct bt_gatt_attr *attr,
				 uint8_t key_size)
{
	struct gatt_value *value;

	/* Fail if requested attribute is a service */
	if (!bt_uuid_cmp(attr->uuid, BT_UUID_GATT_PRIMARY) ||
	    !bt_uuid_cmp(attr->uuid, BT_UUID_GATT_SECONDARY) ||
	    !bt_uuid_cmp(attr->uuid, BT_UUID_GATT_INCLUDE)) {
		return -EINVAL;
	}

	/* Fail if permissions are not set */
	if (!(attr->perm & (GATT_PERM_ENC_READ_MASK |
			    GATT_PERM_ENC_WRITE_MASK))) {
		return -EINVAL;
	}

	value = attr->user_data;
	value->enc_key_size = key_size;

	return 0;
}

static uint8_t set_enc_key_size(const void *cmd, uint16_t cmd_len,
				void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_set_enc_key_size_cmd *cp = cmd;
	uint16_t attr_id;
	int ret;

	/* Fail if requested key size is invalid */
	if (cp->key_size < 0x07 || cp->key_size > 0x0f) {
		return BTP_STATUS_FAILED;
	}

	attr_id = sys_le16_to_cpu(cp->attr_id);

	if (!attr_id) {
		ret = set_attr_enc_key_size(LAST_DB_ATTR, cp->key_size);
	} else {
		/* set value of local attr, corrected by pre set attr handles */
		ret = set_attr_enc_key_size(&server_db[attr_id -
					    server_db[0].handle], cp->key_size);
	}

	if (ret) {
		return BTP_STATUS_FAILED;
	}

	return BTP_STATUS_SUCCESS;
}

static void exchange_func(struct bt_conn *conn, uint8_t err,
			  struct bt_gatt_exchange_params *params)
{
	if (err != 0U) {
		LOG_ERR("MTU exchange failed");
	} else {
		LOG_DBG("MTU exchange succeed");
	}
}

static struct bt_gatt_exchange_params exchange_params;

static uint8_t exchange_mtu(const void *cmd, uint16_t cmd_len,
			    void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_exchange_mtu_cmd *cp = cmd;
	struct bt_conn *conn;

	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
	if (!conn) {
		return BTP_STATUS_FAILED;
	}

	exchange_params.func = exchange_func;

	if (bt_gatt_exchange_mtu(conn, &exchange_params) < 0) {
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	bt_conn_unref(conn);

	/* this BTP command is about initiating MTU exchange, no need to wait
	 * for procedure to complete.
	 */
	return BTP_STATUS_SUCCESS;
}

static struct bt_gatt_discover_params discover_params;
static union uuid uuid;
static uint8_t btp_opcode;

static void discover_destroy(struct bt_gatt_discover_params *params)
{
	(void)memset(params, 0, sizeof(*params));
	gatt_buf_clear();
}

static uint8_t disc_prim_cb(struct bt_conn *conn,
			 const struct bt_gatt_attr *attr,
			 struct bt_gatt_discover_params *params)
{
	struct bt_gatt_service_val *data;
	struct btp_gatt_disc_prim_rp *rp = (void *) gatt_buf.buf;
	struct btp_gatt_service *service;
	uint8_t uuid_length;

	if (!attr) {
		tester_rsp_full(BTP_SERVICE_ID_GATT, btp_opcode,
				gatt_buf.buf, gatt_buf.len);
		discover_destroy(params);
		return BT_GATT_ITER_STOP;
	}

	data = attr->user_data;

	uuid_length = data->uuid->type == BT_UUID_TYPE_16 ? 2 : 16;

	service = gatt_buf_reserve(sizeof(*service) + uuid_length);
	if (!service) {
		tester_rsp(BTP_SERVICE_ID_GATT, btp_opcode, BTP_STATUS_FAILED);
		discover_destroy(params);
		return BT_GATT_ITER_STOP;
	}

	service->start_handle = sys_cpu_to_le16(attr->handle);
	service->end_handle = sys_cpu_to_le16(data->end_handle);
	service->uuid_length = uuid_length;

	if (data->uuid->type == BT_UUID_TYPE_16) {
		uint16_t u16 = sys_cpu_to_le16(BT_UUID_16(data->uuid)->val);

		memcpy(service->uuid, &u16, uuid_length);
	} else {
		memcpy(service->uuid, BT_UUID_128(data->uuid)->val,
		       uuid_length);
	}

	rp->services_count++;

	return BT_GATT_ITER_CONTINUE;
}

static uint8_t disc_all_prim(const void *cmd, uint16_t cmd_len,
			     void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_disc_all_prim_cmd *cp = cmd;
	struct bt_conn *conn;

	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
	if (!conn) {
		return BTP_STATUS_FAILED;
	}

	if (!gatt_buf_reserve(sizeof(struct btp_gatt_disc_prim_rp))) {
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	discover_params.uuid = NULL;
	discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
	discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
	discover_params.type = BT_GATT_DISCOVER_PRIMARY;
	discover_params.func = disc_prim_cb;
	discover_params.chan_opt = BT_ATT_CHAN_OPT_NONE;

	btp_opcode = BTP_GATT_DISC_ALL_PRIM;

	if (bt_gatt_discover(conn, &discover_params) < 0) {
		discover_destroy(&discover_params);
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	bt_conn_unref(conn);

	return BTP_STATUS_DELAY_REPLY;
}

static uint8_t disc_prim_uuid(const void *cmd, uint16_t cmd_len,
			      void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_disc_prim_uuid_cmd *cp = cmd;
	struct bt_conn *conn;

	if ((cmd_len < sizeof(*cp)) ||
	    (cmd_len != sizeof(*cp) + cp->uuid_length)) {
		return BTP_STATUS_FAILED;
	}

	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
	if (!conn) {
		return BTP_STATUS_FAILED;
	}

	if (btp2bt_uuid(cp->uuid, cp->uuid_length, &uuid.uuid)) {
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	if (!gatt_buf_reserve(sizeof(struct btp_gatt_disc_prim_rp))) {
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	discover_params.uuid = &uuid.uuid;
	discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
	discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
	discover_params.type = BT_GATT_DISCOVER_PRIMARY;
	discover_params.func = disc_prim_cb;
	discover_params.chan_opt = BT_ATT_CHAN_OPT_NONE;

	btp_opcode = BTP_GATT_DISC_PRIM_UUID;

	if (bt_gatt_discover(conn, &discover_params) < 0) {
		discover_destroy(&discover_params);
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	bt_conn_unref(conn);

	return BTP_STATUS_DELAY_REPLY;
}

static uint8_t find_included_cb(struct bt_conn *conn,
				const struct bt_gatt_attr *attr,
				struct bt_gatt_discover_params *params)
{
	struct bt_gatt_include *data;
	struct btp_gatt_find_included_rp *rp = (void *) gatt_buf.buf;
	struct btp_gatt_included *included;
	uint8_t uuid_length;

	if (!attr) {
		tester_rsp_full(BTP_SERVICE_ID_GATT, BTP_GATT_FIND_INCLUDED,
				gatt_buf.buf, gatt_buf.len);
		discover_destroy(params);
		return BT_GATT_ITER_STOP;
	}

	data = attr->user_data;

	uuid_length = data->uuid->type == BT_UUID_TYPE_16 ? 2 : 16;

	included = gatt_buf_reserve(sizeof(*included) + uuid_length);
	if (!included) {
		tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_FIND_INCLUDED, BTP_STATUS_FAILED);
		discover_destroy(params);
		return BT_GATT_ITER_STOP;
	}

	included->included_handle = attr->handle;
	included->service.start_handle = sys_cpu_to_le16(data->start_handle);
	included->service.end_handle = sys_cpu_to_le16(data->end_handle);
	included->service.uuid_length = uuid_length;

	if (data->uuid->type == BT_UUID_TYPE_16) {
		uint16_t u16 = sys_cpu_to_le16(BT_UUID_16(data->uuid)->val);

		memcpy(included->service.uuid, &u16, uuid_length);
	} else {
		memcpy(included->service.uuid, BT_UUID_128(data->uuid)->val,
		       uuid_length);
	}

	rp->services_count++;

	return BT_GATT_ITER_CONTINUE;
}

static uint8_t find_included(const void *cmd, uint16_t cmd_len,
			     void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_find_included_cmd *cp = cmd;
	struct bt_conn *conn;

	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
	if (!conn) {
		return BTP_STATUS_FAILED;
	}

	if (!gatt_buf_reserve(sizeof(struct btp_gatt_find_included_rp))) {
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	discover_params.start_handle = sys_le16_to_cpu(cp->start_handle);
	discover_params.end_handle = sys_le16_to_cpu(cp->end_handle);
	discover_params.type = BT_GATT_DISCOVER_INCLUDE;
	discover_params.func = find_included_cb;
	discover_params.chan_opt = BT_ATT_CHAN_OPT_NONE;

	if (bt_gatt_discover(conn, &discover_params) < 0) {
		discover_destroy(&discover_params);
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	bt_conn_unref(conn);

	return BTP_STATUS_DELAY_REPLY;
}

static uint8_t disc_chrc_cb(struct bt_conn *conn,
			    const struct bt_gatt_attr *attr,
			    struct bt_gatt_discover_params *params)
{
	struct bt_gatt_chrc *data;
	struct btp_gatt_disc_chrc_rp *rp = (void *) gatt_buf.buf;
	struct btp_gatt_characteristic *chrc;
	uint8_t uuid_length;

	if (!attr) {
		tester_rsp_full(BTP_SERVICE_ID_GATT, btp_opcode,
				gatt_buf.buf, gatt_buf.len);
		discover_destroy(params);
		return BT_GATT_ITER_STOP;
	}

	data = attr->user_data;

	uuid_length = data->uuid->type == BT_UUID_TYPE_16 ? 2 : 16;

	chrc = gatt_buf_reserve(sizeof(*chrc) + uuid_length);
	if (!chrc) {
		tester_rsp(BTP_SERVICE_ID_GATT, btp_opcode, BTP_STATUS_FAILED);
		discover_destroy(params);
		return BT_GATT_ITER_STOP;
	}

	chrc->characteristic_handle = sys_cpu_to_le16(attr->handle);
	chrc->properties = data->properties;
	chrc->value_handle = sys_cpu_to_le16(attr->handle + 1);
	chrc->uuid_length = uuid_length;

	if (data->uuid->type == BT_UUID_TYPE_16) {
		uint16_t u16 = sys_cpu_to_le16(BT_UUID_16(data->uuid)->val);

		memcpy(chrc->uuid, &u16, uuid_length);
	} else {
		memcpy(chrc->uuid, BT_UUID_128(data->uuid)->val, uuid_length);
	}

	rp->characteristics_count++;

	return BT_GATT_ITER_CONTINUE;
}

static uint8_t disc_all_chrc(const void *cmd, uint16_t cmd_len,
			     void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_disc_all_chrc_cmd *cp = cmd;
	struct bt_conn *conn;

	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
	if (!conn) {
		return BTP_STATUS_FAILED;
	}

	if (!gatt_buf_reserve(sizeof(struct btp_gatt_disc_chrc_rp))) {
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	discover_params.start_handle = sys_le16_to_cpu(cp->start_handle);
	discover_params.end_handle = sys_le16_to_cpu(cp->end_handle);
	discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
	discover_params.func = disc_chrc_cb;
	discover_params.chan_opt = BT_ATT_CHAN_OPT_NONE;

	/* TODO should be handled as user_data via CONTAINER_OF macro */
	btp_opcode = BTP_GATT_DISC_ALL_CHRC;

	if (bt_gatt_discover(conn, &discover_params) < 0) {
		discover_destroy(&discover_params);
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	bt_conn_unref(conn);

	return BTP_STATUS_DELAY_REPLY;
}

static uint8_t disc_chrc_uuid(const void *cmd, uint16_t cmd_len,
			      void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_disc_chrc_uuid_cmd *cp = cmd;
	struct bt_conn *conn;

	if ((cmd_len < sizeof(*cp)) ||
	    (cmd_len != sizeof(*cp) + cp->uuid_length)) {
		return BTP_STATUS_FAILED;
	}

	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
	if (!conn) {
		return BTP_STATUS_FAILED;
	}

	if (btp2bt_uuid(cp->uuid, cp->uuid_length, &uuid.uuid)) {
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	if (!gatt_buf_reserve(sizeof(struct btp_gatt_disc_chrc_rp))) {
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	discover_params.uuid = &uuid.uuid;
	discover_params.start_handle = sys_le16_to_cpu(cp->start_handle);
	discover_params.end_handle = sys_le16_to_cpu(cp->end_handle);
	discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
	discover_params.func = disc_chrc_cb;
	discover_params.chan_opt = BT_ATT_CHAN_OPT_NONE;

	/* TODO should be handled as user_data via CONTAINER_OF macro */
	btp_opcode = BTP_GATT_DISC_CHRC_UUID;

	if (bt_gatt_discover(conn, &discover_params) < 0) {
		discover_destroy(&discover_params);
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	bt_conn_unref(conn);

	return BTP_STATUS_DELAY_REPLY;
}

static uint8_t disc_all_desc_cb(struct bt_conn *conn,
				const struct bt_gatt_attr *attr,
				struct bt_gatt_discover_params *params)
{
	struct btp_gatt_disc_all_desc_rp *rp = (void *) gatt_buf.buf;
	struct btp_gatt_descriptor *descriptor;
	uint8_t uuid_length;

	if (!attr) {
		tester_rsp_full(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_ALL_DESC,
				gatt_buf.buf, gatt_buf.len);
		discover_destroy(params);
		return BT_GATT_ITER_STOP;
	}

	uuid_length = attr->uuid->type == BT_UUID_TYPE_16 ? 2 : 16;

	descriptor = gatt_buf_reserve(sizeof(*descriptor) + uuid_length);
	if (!descriptor) {
		tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_ALL_DESC, BTP_STATUS_FAILED);
		discover_destroy(params);
		return BT_GATT_ITER_STOP;
	}

	descriptor->descriptor_handle = sys_cpu_to_le16(attr->handle);
	descriptor->uuid_length = uuid_length;

	if (attr->uuid->type == BT_UUID_TYPE_16) {
		uint16_t u16 = sys_cpu_to_le16(BT_UUID_16(attr->uuid)->val);

		memcpy(descriptor->uuid, &u16, uuid_length);
	} else {
		memcpy(descriptor->uuid, BT_UUID_128(attr->uuid)->val,
		       uuid_length);
	}

	rp->descriptors_count++;

	return BT_GATT_ITER_CONTINUE;
}

static uint8_t disc_all_desc(const void *cmd, uint16_t cmd_len,
			     void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_disc_all_desc_cmd *cp = cmd;
	struct bt_conn *conn;

	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
	if (!conn) {
		return BTP_STATUS_FAILED;
	}

	if (!gatt_buf_reserve(sizeof(struct btp_gatt_disc_all_desc_rp))) {
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	discover_params.start_handle = sys_le16_to_cpu(cp->start_handle);
	discover_params.end_handle = sys_le16_to_cpu(cp->end_handle);
	discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR;
	discover_params.func = disc_all_desc_cb;
	discover_params.chan_opt = BT_ATT_CHAN_OPT_NONE;

	if (bt_gatt_discover(conn, &discover_params) < 0) {
		discover_destroy(&discover_params);
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	bt_conn_unref(conn);

	return BTP_STATUS_DELAY_REPLY;
}

static struct bt_gatt_read_params read_params;

static void read_destroy(struct bt_gatt_read_params *params)
{
	(void)memset(params, 0, sizeof(*params));
	gatt_buf_clear();
}

static uint8_t read_cb(struct bt_conn *conn, uint8_t err,
		       struct bt_gatt_read_params *params, const void *data,
		       uint16_t length)
{
	struct btp_gatt_read_rp *rp = (void *) gatt_buf.buf;

	/* Respond to the Lower Tester with ATT Error received */
	if (err) {
		rp->att_response = err;
	}

	/* read complete */
	if (!data) {
		tester_rsp_full(BTP_SERVICE_ID_GATT, btp_opcode,
				gatt_buf.buf, gatt_buf.len);
		read_destroy(params);
		return BT_GATT_ITER_STOP;
	}

	if (!gatt_buf_add(data, length)) {
		tester_rsp(BTP_SERVICE_ID_GATT, btp_opcode, BTP_STATUS_FAILED);
		read_destroy(params);
		return BT_GATT_ITER_STOP;
	}

	rp->data_length += length;

	return BT_GATT_ITER_CONTINUE;
}

static uint8_t read_uuid_cb(struct bt_conn *conn, uint8_t err,
		       struct bt_gatt_read_params *params, const void *data,
		       uint16_t length)
{
	struct btp_gatt_read_uuid_rp *rp = (void *)gatt_buf.buf;
	struct btp_gatt_char_value value;

	/* Respond to the Lower Tester with ATT Error received */
	if (err) {
		rp->att_response = err;
	}

	/* read complete */
	if (!data) {
		tester_rsp_full(BTP_SERVICE_ID_GATT, btp_opcode,
				gatt_buf.buf, gatt_buf.len);
		read_destroy(params);

		return BT_GATT_ITER_STOP;
	}

	value.handle = params->by_uuid.start_handle;
	value.data_len = length;

	if (!gatt_buf_add(&value, sizeof(struct btp_gatt_char_value))) {
		tester_rsp(BTP_SERVICE_ID_GATT, btp_opcode, BTP_STATUS_FAILED);
		read_destroy(params);

		return BT_GATT_ITER_STOP;
	}

	if (!gatt_buf_add(data, length)) {
		tester_rsp(BTP_SERVICE_ID_GATT, btp_opcode, BTP_STATUS_FAILED);
		read_destroy(params);

		return BT_GATT_ITER_STOP;
	}

	rp->values_count++;

	return BT_GATT_ITER_CONTINUE;
}

static uint8_t read_data(const void *cmd, uint16_t cmd_len,
			 void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_read_cmd *cp = cmd;
	struct bt_conn *conn;

	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
	if (!conn) {
		return BTP_STATUS_FAILED;
	}

	if (!gatt_buf_reserve(sizeof(struct btp_gatt_read_rp))) {
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	read_params.handle_count = 1;
	read_params.single.handle = sys_le16_to_cpu(cp->handle);
	read_params.single.offset = 0x0000;
	read_params.func = read_cb;
	read_params.chan_opt = BT_ATT_CHAN_OPT_NONE;

	/* TODO should be handled as user_data via CONTAINER_OF macro */
	btp_opcode = BTP_GATT_READ;

	if (bt_gatt_read(conn, &read_params) < 0) {
		read_destroy(&read_params);
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	bt_conn_unref(conn);

	return BTP_STATUS_DELAY_REPLY;
}

static uint8_t read_uuid(const void *cmd, uint16_t cmd_len,
			 void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_read_uuid_cmd *cp = cmd;
	struct bt_conn *conn;

	if ((cmd_len < sizeof(*cp)) ||
	    (cmd_len != sizeof(*cp) + cp->uuid_length)) {
		return BTP_STATUS_FAILED;
	}

	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
	if (!conn) {
		return BTP_STATUS_FAILED;
	}

	if (btp2bt_uuid(cp->uuid, cp->uuid_length, &uuid.uuid)) {
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	if (!gatt_buf_reserve(sizeof(struct btp_gatt_read_uuid_rp))) {
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	read_params.by_uuid.uuid = &uuid.uuid;
	read_params.handle_count = 0;
	read_params.by_uuid.start_handle = sys_le16_to_cpu(cp->start_handle);
	read_params.by_uuid.end_handle = sys_le16_to_cpu(cp->end_handle);
	read_params.func = read_uuid_cb;
	read_params.chan_opt = BT_ATT_CHAN_OPT_NONE;

	btp_opcode = BTP_GATT_READ_UUID;

	if (bt_gatt_read(conn, &read_params) < 0) {
		read_destroy(&read_params);
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	bt_conn_unref(conn);

	return BTP_STATUS_DELAY_REPLY;
}

static uint8_t read_long(const void *cmd, uint16_t cmd_len,
			 void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_read_long_cmd *cp = cmd;
	struct bt_conn *conn;

	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
	if (!conn) {
		return BTP_STATUS_FAILED;
	}

	if (!gatt_buf_reserve(sizeof(struct btp_gatt_read_rp))) {
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	read_params.handle_count = 1;
	read_params.single.handle = sys_le16_to_cpu(cp->handle);
	read_params.single.offset = sys_le16_to_cpu(cp->offset);
	read_params.func = read_cb;
	read_params.chan_opt = BT_ATT_CHAN_OPT_NONE;

	/* TODO should be handled as user_data via CONTAINER_OF macro */
	btp_opcode = BTP_GATT_READ_LONG;

	if (bt_gatt_read(conn, &read_params) < 0) {
		read_destroy(&read_params);
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	bt_conn_unref(conn);

	return BTP_STATUS_DELAY_REPLY;
}

static uint8_t read_multiple(const void *cmd, uint16_t cmd_len,
			     void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_read_multiple_cmd *cp = cmd;
	uint16_t handles[5];
	struct bt_conn *conn;
	int i;

	if ((cmd_len < sizeof(*cp)) ||
	    (cmd_len != sizeof(*cp) + (cp->handles_count * sizeof(cp->handles[0])))) {
		return BTP_STATUS_FAILED;
	}

	if (cp->handles_count > ARRAY_SIZE(handles)) {
		return BTP_STATUS_FAILED;
	}

	for (i = 0; i < ARRAY_SIZE(handles); i++) {
		handles[i] = sys_le16_to_cpu(cp->handles[i]);
	}

	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
	if (!conn) {
		return BTP_STATUS_FAILED;
	}

	if (!gatt_buf_reserve(sizeof(struct btp_gatt_read_rp))) {
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	read_params.func = read_cb;
	read_params.handle_count = i;
	read_params.multiple.handles = handles; /* not used in read func */
	read_params.multiple.variable = false;
	read_params.chan_opt = BT_ATT_CHAN_OPT_NONE;

	/* TODO should be handled as user_data via CONTAINER_OF macro */
	btp_opcode = BTP_GATT_READ_MULTIPLE;

	if (bt_gatt_read(conn, &read_params) < 0) {
		gatt_buf_clear();
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	bt_conn_unref(conn);

	return BTP_STATUS_DELAY_REPLY;
}

static uint8_t read_multiple_var(const void *cmd, uint16_t cmd_len,
				 void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_read_multiple_var_cmd *cp = cmd;
	uint16_t handles[5];
	struct bt_conn *conn;
	int i;

	if ((cmd_len < sizeof(*cp)) ||
	    (cmd_len != sizeof(*cp) + (cp->handles_count * sizeof(cp->handles[0])))) {
		return BTP_STATUS_FAILED;
	}

	if (cp->handles_count > ARRAY_SIZE(handles)) {
		return BTP_STATUS_FAILED;
	}

	for (i = 0; i < ARRAY_SIZE(handles); i++) {
		handles[i] = sys_le16_to_cpu(cp->handles[i]);
	}

	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
	if (!conn) {
		return BTP_STATUS_FAILED;
	}

	if (!gatt_buf_reserve(sizeof(struct btp_gatt_read_rp))) {
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	read_params.func = read_cb;
	read_params.handle_count = i;
	read_params.multiple.handles = handles; /* not used in read func */
	read_params.multiple.variable = true;
	read_params.chan_opt = BT_ATT_CHAN_OPT_NONE;

	/* TODO should be handled as user_data via CONTAINER_OF macro */
	btp_opcode = BTP_GATT_READ_MULTIPLE_VAR;

	if (bt_gatt_read(conn, &read_params) < 0) {
		gatt_buf_clear();
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	bt_conn_unref(conn);

	return BTP_STATUS_DELAY_REPLY;
}

static uint8_t write_without_rsp(const void *cmd, uint16_t cmd_len,
				 void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_write_without_rsp_cmd *cp = cmd;
	struct bt_conn *conn;

	if (cmd_len < sizeof(*cp) ||
	    cmd_len != sizeof(*cp) + sys_le16_to_cpu(cp->data_length)) {
		return BTP_STATUS_FAILED;
	}

	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
	if (!conn) {
		return BTP_STATUS_FAILED;
	}

	if (bt_gatt_write_without_response(conn, sys_le16_to_cpu(cp->handle),
					   cp->data,
					   sys_le16_to_cpu(cp->data_length),
					   false) < 0) {
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	bt_conn_unref(conn);
	return BTP_STATUS_SUCCESS;
}

static uint8_t write_signed_without_rsp(const void *cmd, uint16_t cmd_len,
					void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_signed_write_without_rsp_cmd *cp = cmd;
	struct bt_conn *conn;

	if (cmd_len < sizeof(*cp) ||
	    cmd_len != sizeof(*cp) + sys_le16_to_cpu(cp->data_length)) {
		return BTP_STATUS_FAILED;
	}

	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
	if (!conn) {
		return BTP_STATUS_FAILED;
	}

	if (bt_gatt_write_without_response(conn, sys_le16_to_cpu(cp->handle),
					   cp->data,
					   sys_le16_to_cpu(cp->data_length),
					   true) < 0) {
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	bt_conn_unref(conn);
	return BTP_STATUS_SUCCESS;
}

static void write_rsp(struct bt_conn *conn, uint8_t err,
		      struct bt_gatt_write_params *params)
{
	tester_rsp_full(BTP_SERVICE_ID_GATT, BTP_GATT_WRITE, &err, sizeof(err));
}

static struct bt_gatt_write_params write_params;

static uint8_t write_data(const void *cmd, uint16_t cmd_len,
			  void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_write_cmd *cp = cmd;
	struct bt_conn *conn;

	if (cmd_len < sizeof(*cp) ||
	    cmd_len != sizeof(*cp) + sys_le16_to_cpu(cp->data_length)) {
		return BTP_STATUS_FAILED;
	}

	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
	if (!conn) {
		return BTP_STATUS_FAILED;
	}

	write_params.handle = sys_le16_to_cpu(cp->handle);
	write_params.func = write_rsp;
	write_params.offset = 0U;
	write_params.data = cp->data;
	write_params.length = sys_le16_to_cpu(cp->data_length);
	write_params.chan_opt = BT_ATT_CHAN_OPT_NONE;

	if (bt_gatt_write(conn, &write_params) < 0) {
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	bt_conn_unref(conn);
	return BTP_STATUS_DELAY_REPLY;
}

static void write_long_rsp(struct bt_conn *conn, uint8_t err,
			   struct bt_gatt_write_params *params)
{
	tester_rsp_full(BTP_SERVICE_ID_GATT, BTP_GATT_WRITE_LONG, &err, sizeof(err));
}

static uint8_t write_long(const void *cmd, uint16_t cmd_len,
			  void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_write_long_cmd *cp = cmd;
	struct bt_conn *conn;

	if (cmd_len < sizeof(*cp) ||
	    cmd_len != sizeof(*cp) + sys_le16_to_cpu(cp->data_length)) {
		return BTP_STATUS_FAILED;
	}

	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
	if (!conn) {
		return BTP_STATUS_FAILED;
	}

	write_params.handle = sys_le16_to_cpu(cp->handle);
	write_params.func = write_long_rsp;
	write_params.offset = sys_le16_to_cpu(cp->offset);
	write_params.data = cp->data;
	write_params.length = sys_le16_to_cpu(cp->data_length);
	write_params.chan_opt = BT_ATT_CHAN_OPT_NONE;

	if (bt_gatt_write(conn, &write_params) < 0) {
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	bt_conn_unref(conn);
	return BTP_STATUS_DELAY_REPLY;
}

static struct bt_gatt_subscribe_params subscriptions[MAX_SUBSCRIPTIONS];

static struct bt_gatt_subscribe_params *find_subscription(uint16_t ccc_handle)
{
	for (int i = 0; i < MAX_SUBSCRIPTIONS; i++) {
		if (subscriptions[i].ccc_handle == ccc_handle) {
			return &subscriptions[i];
		}
	}

	return NULL;
}

/* TODO there should be better way of determining max supported MTU */
#define MAX_NOTIF_DATA (MIN(BT_L2CAP_RX_MTU, BT_L2CAP_TX_MTU) - 3)

static uint8_t ev_buf[sizeof(struct btp_gatt_notification_ev) + MAX_NOTIF_DATA];

static uint8_t notify_func(struct bt_conn *conn,
			   struct bt_gatt_subscribe_params *params,
			   const void *data, uint16_t length)
{
	struct btp_gatt_notification_ev *ev = (void *) ev_buf;

	if (!conn || !data) {
		LOG_DBG("Unsubscribed");
		(void)memset(params, 0, sizeof(*params));
		return BT_GATT_ITER_STOP;
	}
	ev->type = (uint8_t)params->value;
	ev->handle = sys_cpu_to_le16(params->value_handle);

	length = MIN(length, MAX_NOTIF_DATA);

	ev->data_length = sys_cpu_to_le16(length);
	memcpy(ev->data, data, length);
	bt_addr_le_copy(&ev->address, bt_conn_get_dst(conn));

	tester_event(BTP_SERVICE_ID_GATT, BTP_GATT_EV_NOTIFICATION,
		     ev, sizeof(*ev) + length);

	return BT_GATT_ITER_CONTINUE;
}

static void discover_complete(struct bt_conn *conn,
			      struct bt_gatt_discover_params *params)
{
	struct bt_gatt_subscribe_params *subscription;
	uint8_t op, status;

	subscription = find_subscription(discover_params.end_handle);
	__ASSERT_NO_MSG(subscription);

	/* If no value handle it means that chrc has not been found */
	if (!subscription->value_handle) {
		status = BTP_STATUS_FAILED;
		goto fail;
	}

	subscription->chan_opt = BT_ATT_CHAN_OPT_NONE;
	if (bt_gatt_subscribe(conn, subscription) < 0) {
		status = BTP_STATUS_FAILED;
		goto fail;
	}

	status = BTP_STATUS_SUCCESS;
fail:
	op = subscription->value == BT_GATT_CCC_NOTIFY ? BTP_GATT_CFG_NOTIFY :
							 BTP_GATT_CFG_INDICATE;

	if (status == BTP_STATUS_FAILED) {
		(void)memset(subscription, 0, sizeof(*subscription));
	}

	tester_rsp(BTP_SERVICE_ID_GATT, op, status);

	(void)memset(params, 0, sizeof(*params));
}

static uint8_t discover_func(struct bt_conn *conn,
			     const struct bt_gatt_attr *attr,
			     struct bt_gatt_discover_params *params)
{
	struct bt_gatt_subscribe_params *subscription;

	if (!attr) {
		discover_complete(conn, params);
		return BT_GATT_ITER_STOP;
	}

	subscription = find_subscription(discover_params.end_handle);
	__ASSERT_NO_MSG(subscription);

	/* Characteristic Value Handle is the next handle beyond declaration */
	subscription->value_handle = attr->handle + 1;

	/*
	 * Continue characteristic discovery to get last characteristic
	 * preceding this CCC descriptor
	 */
	return BT_GATT_ITER_CONTINUE;
}

static int enable_subscription(struct bt_conn *conn, uint16_t ccc_handle,
			       uint16_t value)
{
	struct bt_gatt_subscribe_params *subscription;

	/* find unused subscription */
	subscription = find_subscription(UNUSED_SUBSCRIBE_CCC_HANDLE);
	if (!subscription) {
		return -ENOMEM;
	}

	/* if discovery is busy fail */
	if (discover_params.start_handle) {
		return -EBUSY;
	}

	/* Discover Characteristic Value this CCC Descriptor refers to */
	discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
	discover_params.end_handle = ccc_handle;
	discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
	discover_params.func = discover_func;
	discover_params.chan_opt = BT_ATT_CHAN_OPT_NONE;

	subscription->ccc_handle = ccc_handle;
	subscription->value = value;
	subscription->notify = notify_func;

	/* require security level from time of subscription */
	subscription->min_security = bt_conn_get_security(conn);

	return bt_gatt_discover(conn, &discover_params);
}

static int disable_subscription(struct bt_conn *conn, uint16_t ccc_handle)
{
	struct bt_gatt_subscribe_params *subscription;

	/* Fail if CCC handle doesn't match */
	subscription = find_subscription(ccc_handle);
	if (!subscription) {
		LOG_ERR("CCC handle doesn't match");
		return -EINVAL;
	}

	if (bt_gatt_unsubscribe(conn, subscription) < 0) {
		return -EBUSY;
	}

	(void)memset(subscription, 0, sizeof(*subscription));

	return 0;
}

static uint8_t config_subscription_notif(const void *cmd, uint16_t cmd_len,
					 void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_cfg_notify_cmd *cp = cmd;
	struct bt_conn *conn;
	uint16_t ccc_handle = sys_le16_to_cpu(cp->ccc_handle);
	uint8_t status;

	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
	if (!conn) {
		return BTP_STATUS_FAILED;
	}

	if (cp->enable) {
		/* on success response will be sent from callback */
		if (enable_subscription(conn, ccc_handle, BT_GATT_CCC_NOTIFY) == 0) {
			bt_conn_unref(conn);
			return BTP_STATUS_DELAY_REPLY;
		}

		status = BTP_STATUS_FAILED;
	} else {
		if (disable_subscription(conn, ccc_handle) < 0) {
			status = BTP_STATUS_FAILED;
		} else {
			status = BTP_STATUS_SUCCESS;
		}
	}

	LOG_DBG("Config notification subscription status %u", status);

	bt_conn_unref(conn);
	return status;
}

static uint8_t config_subscription_ind(const void *cmd, uint16_t cmd_len,
				       void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_cfg_notify_cmd *cp = cmd;
	struct bt_conn *conn;
	uint16_t ccc_handle = sys_le16_to_cpu(cp->ccc_handle);
	uint8_t status;

	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
	if (!conn) {
		return BTP_STATUS_FAILED;
	}

	if (cp->enable) {
		/* on success response will be sent from callback */
		if (enable_subscription(conn, ccc_handle, BT_GATT_CCC_INDICATE) == 0) {
			bt_conn_unref(conn);
			return BTP_STATUS_DELAY_REPLY;
		}

		status = BTP_STATUS_FAILED;
	} else {
		if (disable_subscription(conn, ccc_handle) < 0) {
			status = BTP_STATUS_FAILED;
		} else {
			status = BTP_STATUS_SUCCESS;
		}
	}

	LOG_DBG("Config indication subscription status %u", status);

	bt_conn_unref(conn);
	return status;
}

#if defined(CONFIG_BT_GATT_NOTIFY_MULTIPLE)
static void notify_cb(struct bt_conn *conn, void *user_data)
{
	LOG_DBG("Nofication sent");
}

static uint8_t notify_mult(const void *cmd, uint16_t cmd_len,
			   void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_cfg_notify_mult_cmd *cp = cmd;
	const size_t max_cnt = CONFIG_BT_L2CAP_TX_BUF_COUNT;
	struct bt_gatt_notify_params params[max_cnt];
	struct bt_conn *conn;
	const size_t min_cnt = 1U;
	int err = 0;
	uint16_t attr_data_len = 0;

	if ((cmd_len < sizeof(*cp)) ||
	    (cmd_len != sizeof(*cp) + (cp->cnt * sizeof(cp->attr_id[0])))) {
		return BTP_STATUS_FAILED;
	}

	if (!IN_RANGE(cp->cnt, min_cnt, max_cnt)) {
		LOG_ERR("Invalid count value %d (range %zu to %zu)",
			    cp->cnt, min_cnt, max_cnt);

		return BTP_STATUS_FAILED;
	}

	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
	if (!conn) {
		return BTP_STATUS_FAILED;
	}

	(void)memset(params, 0, sizeof(params));

	for (uint16_t i = 0U; i < cp->cnt; i++) {
		struct bt_gatt_attr attr = server_db[cp->attr_id[i] -
			server_db[0].handle];

		attr_data_len = strtoul(attr.user_data, NULL, 16);
		params[i].uuid = 0;
		params[i].attr = &attr;
		params[i].data = &attr.user_data;
		params[i].len = attr_data_len;
		params[i].func = notify_cb;
		params[i].user_data = NULL;
	}

	err = bt_gatt_notify_multiple(conn, cp->cnt, params);
	if (err != 0) {
		LOG_ERR("bt_gatt_notify_multiple failed: %d", err);
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	LOG_DBG("Send %u notifications", cp->cnt);
	bt_conn_unref(conn);
	return BTP_STATUS_SUCCESS;
}
#endif /* CONFIG_BT_GATT_NOTIFY_MULTIPLE */

struct get_attrs_foreach_data {
	struct net_buf_simple *buf;
	struct bt_uuid *uuid;
	uint8_t count;
};

static uint8_t get_attrs_rp(const struct bt_gatt_attr *attr, uint16_t handle,
			    void *user_data)
{
	struct get_attrs_foreach_data *foreach = user_data;
	struct btp_gatt_attr *gatt_attr;

	if (foreach->uuid && bt_uuid_cmp(foreach->uuid, attr->uuid)) {

		return BT_GATT_ITER_CONTINUE;
	}

	gatt_attr = net_buf_simple_add(foreach->buf, sizeof(*gatt_attr));
	gatt_attr->handle = sys_cpu_to_le16(handle);
	gatt_attr->permission = attr->perm;

	if (attr->uuid->type == BT_UUID_TYPE_16) {
		gatt_attr->type_length = 2U;
		net_buf_simple_add_le16(foreach->buf,
					BT_UUID_16(attr->uuid)->val);
	} else {
		gatt_attr->type_length = 16U;
		net_buf_simple_add_mem(foreach->buf,
				       BT_UUID_128(attr->uuid)->val,
				       gatt_attr->type_length);
	}

	foreach->count++;

	return BT_GATT_ITER_CONTINUE;
}

static uint8_t get_attrs(const void *cmd, uint16_t cmd_len,
			 void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_get_attributes_cmd *cp = cmd;
	struct btp_gatt_get_attributes_rp *rp = rsp;
	struct net_buf_simple *buf = NET_BUF_SIMPLE(BTP_DATA_MAX_SIZE - sizeof(*rp));
	struct get_attrs_foreach_data foreach;
	uint16_t start_handle, end_handle;
	union uuid uuid;

	if ((cmd_len < sizeof(*cp)) ||
	    (cmd_len != sizeof(*cp) + cp->type_length)) {
		return BTP_STATUS_FAILED;
	}

	start_handle = sys_le16_to_cpu(cp->start_handle);
	end_handle = sys_le16_to_cpu(cp->end_handle);

	if (cp->type_length) {
		char uuid_str[BT_UUID_STR_LEN];

		if (btp2bt_uuid(cp->type, cp->type_length, &uuid.uuid)) {
			return BTP_STATUS_FAILED;
		}

		bt_uuid_to_str(&uuid.uuid, uuid_str, sizeof(uuid_str));
		LOG_DBG("start 0x%04x end 0x%04x, uuid %s", start_handle,
			end_handle, uuid_str);

		foreach.uuid = &uuid.uuid;
	} else {
		LOG_DBG("start 0x%04x end 0x%04x", start_handle, end_handle);

		foreach.uuid = NULL;
	}

	net_buf_simple_init(buf, 0);

	foreach.buf = buf;
	foreach.count = 0U;

	bt_gatt_foreach_attr(start_handle, end_handle, get_attrs_rp, &foreach);

	(void)memcpy(rp->attrs, buf->data, buf->len);
	rp->attrs_count = foreach.count;

	*rsp_len = sizeof(*rp) + buf->len;

	return BTP_STATUS_SUCCESS;
}

static uint8_t err_to_att(int err)
{
	if (err < 0 && err >= -0xff) {
		return -err;
	}

	return BT_ATT_ERR_UNLIKELY;
}

static uint8_t get_attr_val_rp(const struct bt_gatt_attr *attr, uint16_t handle,
			       void *user_data)
{
	struct get_attr_data *u_data = user_data;
	struct net_buf_simple *buf = u_data->buf;
	struct bt_conn *conn = u_data->conn;
	struct btp_gatt_get_attribute_value_rp *rp;
	ssize_t read, to_read;

	rp = net_buf_simple_add(buf, sizeof(*rp));
	rp->value_length = 0x0000;
	rp->att_response = BT_ATT_ERR_SUCCESS;

	do {
		to_read = net_buf_simple_tailroom(buf);

		if (!attr->read) {
			rp->att_response = BT_ATT_ERR_READ_NOT_PERMITTED;
			break;
		}

		read = attr->read(conn, attr, buf->data + buf->len, to_read,
				  rp->value_length);
		if (read < 0) {
			rp->att_response = err_to_att(read);
			break;
		}

		rp->value_length += read;

		net_buf_simple_add(buf, read);
	} while (read == to_read);

	/* use userdata only for tester own attributes */
	if (IS_ARRAY_ELEMENT(server_db, attr)) {
		const struct gatt_value *value = attr->user_data;

		if ((rp->att_response == BT_ATT_ERR_SUCCESS) && (value->enc_key_size > 0)) {
			/*
			 * If attribute has enc_key_size set to non-zero value
			 * it means that it is used for testing encryption key size
			 * error on GATT database access and we need to report it
			 * when local database is read.
			 *
			 * It is min key size and is used to trigger error on GATT operation
			 * when PTS pairs with small key size (typically it is set it to 16
			 * for specified test characteristics, while PTS pairs with keysize
			 * set to <16, but is can be of any 7-16 value)
			 *
			 * Depending on test, PTS may ask about handle during connection or
			 * prior to connection. If former we validate keysize against
			 * current connection, if latter we just report error status.
			 *
			 * Note that we report expected error and data as this is used for
			 * PTS validation and not actual GATT operation.
			 */
			if (conn) {
				if (value->enc_key_size > bt_conn_enc_key_size(conn)) {
					rp->att_response = BT_ATT_ERR_ENCRYPTION_KEY_SIZE;
				}
			} else {
				rp->att_response = BT_ATT_ERR_ENCRYPTION_KEY_SIZE;
			}
		}
	}

	return BT_GATT_ITER_STOP;
}

static uint8_t get_attr_val(const void *cmd, uint16_t cmd_len,
			    void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_get_attribute_value_cmd *cp = cmd;
	struct net_buf_simple *buf = NET_BUF_SIMPLE(BTP_DATA_MAX_SIZE);
	uint16_t handle = sys_le16_to_cpu(cp->handle);
	struct bt_conn *conn;

	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);

	net_buf_simple_init(buf, 0);

	struct get_attr_data cb_data = { .buf = buf, .conn = conn };

	bt_gatt_foreach_attr(handle, handle, get_attr_val_rp, &cb_data);

	if (buf->len) {
		(void)memcpy(rsp, buf->data,  buf->len);
		*rsp_len = buf->len;
		return BTP_STATUS_SUCCESS;
	}

	return BTP_STATUS_FAILED;
}

static struct bt_uuid_128 test_uuid = BT_UUID_INIT_128(
	0x94, 0x99, 0xb6, 0xa9, 0xcd, 0x1c, 0x42, 0x95,
	0xb2, 0x07, 0x2f, 0x7f, 0xec, 0xc0, 0xc7, 0x5b);

static struct bt_gatt_attr test_attrs[] = {
	BT_GATT_PRIMARY_SERVICE(&test_uuid),
};

static struct bt_gatt_service test_service = BT_GATT_SERVICE(test_attrs);

static uint8_t change_database(const void *cmd, uint16_t cmd_len,
			       void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_change_db_cmd *cp = cmd;
	static bool test_service_registered;
	int err;

	/* currently support only "any" handles */
	if (cp->start_handle > 0 || cp->end_handle > 0) {
		return BTP_STATUS_FAILED;
	}

	switch (cp->operation) {
	case BTP_GATT_CHANGE_DB_ADD:
		if (test_service_registered) {
			return BTP_STATUS_FAILED;
		}

		err = bt_gatt_service_register(&test_service);
		break;
	case BTP_GATT_CHANGE_DB_REMOVE:
		if (!test_service_registered) {
			return BTP_STATUS_FAILED;
		}

		err = bt_gatt_service_unregister(&test_service);
		break;
	case BTP_GATT_CHANGE_DB_ANY:
		if (test_service_registered) {
			err = bt_gatt_service_unregister(&test_service);
		} else {
			err = bt_gatt_service_register(&test_service);
		}
		break;
	default:
		return BTP_STATUS_FAILED;
	}

	if (err) {
		return BTP_STATUS_FAILED;
	}

	test_service_registered = !test_service_registered;

	return BTP_STATUS_SUCCESS;
}

static uint8_t eatt_connect(const void *cmd, uint16_t cmd_len,
			    void *rsp, uint16_t *rsp_len)
{
	const struct btp_gatt_eatt_connect_cmd *cp = cmd;
	struct bt_conn *conn;
	int err;

	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
	if (!conn) {
		return BTP_STATUS_FAILED;
	}

	err = bt_eatt_connect(conn, cp->num_channels);
	if (err) {
		bt_conn_unref(conn);
		return BTP_STATUS_FAILED;
	}

	bt_conn_unref(conn);
	return BTP_STATUS_SUCCESS;
}

static const struct btp_handler handlers[] = {
	{
		.opcode = BTP_GATT_READ_SUPPORTED_COMMANDS,
		.index = BTP_INDEX_NONE,
		.expect_len = 0,
		.func = supported_commands,
	},
	{
		.opcode = BTP_GATT_ADD_SERVICE,
		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
		.func = add_service,
	},
	{
		.opcode = BTP_GATT_ADD_CHARACTERISTIC,
		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
		.func = add_characteristic,
	},
	{
		.opcode = BTP_GATT_ADD_DESCRIPTOR,
		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
		.func = add_descriptor,
	},
	{
		.opcode = BTP_GATT_ADD_INCLUDED_SERVICE,
		.expect_len = sizeof(struct btp_gatt_add_included_service_cmd),
		.func = add_included,
	},
	{
		.opcode = BTP_GATT_SET_VALUE,
		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
		.func = set_value,
	},
	{
		.opcode = BTP_GATT_START_SERVER,
		.expect_len = 0,
		.func = start_server,
	},
	{
		.opcode = BTP_GATT_SET_ENC_KEY_SIZE,
		.expect_len = sizeof(struct btp_gatt_set_enc_key_size_cmd),
		.func = set_enc_key_size,
	},
	{
		.opcode = BTP_GATT_EXCHANGE_MTU,
		.expect_len = sizeof(struct btp_gatt_exchange_mtu_cmd),
		.func = exchange_mtu,
	},
	{
		.opcode = BTP_GATT_DISC_ALL_PRIM,
		.expect_len = sizeof(struct btp_gatt_disc_all_prim_cmd),
		.func = disc_all_prim,
	},
	{
		.opcode = BTP_GATT_DISC_PRIM_UUID,
		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
		.func = disc_prim_uuid,
	},
	{
		.opcode = BTP_GATT_FIND_INCLUDED,
		.expect_len = sizeof(struct btp_gatt_find_included_cmd),
		.func = find_included,
	},
	{
		.opcode = BTP_GATT_DISC_ALL_CHRC,
		.expect_len = sizeof(struct btp_gatt_disc_all_chrc_cmd),
		.func = disc_all_chrc,
	},
	{
		.opcode = BTP_GATT_DISC_CHRC_UUID,
		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
		.func = disc_chrc_uuid,
	},
	{
		.opcode = BTP_GATT_DISC_ALL_DESC,
		.expect_len = sizeof(struct btp_gatt_disc_all_desc_cmd),
		.func = disc_all_desc,
	},
	{
		.opcode = BTP_GATT_READ,
		.expect_len = sizeof(struct btp_gatt_read_cmd),
		.func = read_data,
	},
	{
		.opcode = BTP_GATT_READ_UUID,
		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
		.func = read_uuid,
	},
	{
		.opcode = BTP_GATT_READ_LONG,
		.expect_len = sizeof(struct btp_gatt_read_long_cmd),
		.func = read_long,
	},
	{
		.opcode = BTP_GATT_READ_MULTIPLE,
		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
		.func = read_multiple,
	},
	{
		.opcode = BTP_GATT_WRITE_WITHOUT_RSP,
		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
		.func = write_without_rsp,
	},
	{
		.opcode = BTP_GATT_SIGNED_WRITE_WITHOUT_RSP,
		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
		.func = write_signed_without_rsp,
	},
	{
		.opcode = BTP_GATT_WRITE,
		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
		.func = write_data,
	},
	{
		.opcode = BTP_GATT_WRITE_LONG,
		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
		.func = write_long,
	},
	{
		.opcode = BTP_GATT_CFG_NOTIFY,
		.expect_len = sizeof(struct btp_gatt_cfg_notify_cmd),
		.func = config_subscription_notif,
	},
	{
		.opcode = BTP_GATT_CFG_INDICATE,
		.expect_len = sizeof(struct btp_gatt_cfg_notify_cmd),
		.func = config_subscription_ind,
	},
	{
		.opcode = BTP_GATT_GET_ATTRIBUTES,
		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
		.func = get_attrs,
	},
	{
		.opcode = BTP_GATT_GET_ATTRIBUTE_VALUE,
		.expect_len = sizeof(struct btp_gatt_get_attribute_value_cmd),
		.func = get_attr_val,
	},
	{
		.opcode = BTP_GATT_CHANGE_DB,
		.expect_len = sizeof(struct btp_gatt_change_db_cmd),
		.func = change_database,
	},
	{
		.opcode = BTP_GATT_EATT_CONNECT,
		.expect_len = sizeof(struct btp_gatt_eatt_connect_cmd),
		.func = eatt_connect,
	},
	{
		.opcode = BTP_GATT_READ_MULTIPLE_VAR,
		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
		.func = read_multiple_var,
	},
	{
		.opcode = BTP_GATT_NOTIFY_MULTIPLE,
		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
		.func = notify_mult,
	},
};

uint8_t tester_init_gatt(void)
{
	server_buf = net_buf_alloc(&server_pool, K_NO_WAIT);
	if (!server_buf) {
		return BTP_STATUS_FAILED;
	}

	net_buf_reserve(server_buf, SERVER_BUF_SIZE);

	tester_register_command_handlers(BTP_SERVICE_ID_GATT, handlers,
					 ARRAY_SIZE(handlers));

	return BTP_STATUS_SUCCESS;
}

uint8_t tester_unregister_gatt(void)
{
	return BTP_STATUS_SUCCESS;
}
