/* gatt.c - Generic Attribute Profile handling */

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

#include <zephyr/kernel.h>
#include <string.h>
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
#include <zephyr/sys/atomic.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/iterable_sections.h>
#include <zephyr/sys/util.h>
#include <zephyr/sys/check.h>

#include <zephyr/settings/settings.h>

#if defined(CONFIG_BT_GATT_CACHING)
#include <tinycrypt/constants.h>
#include <tinycrypt/utils.h>
#include <tinycrypt/aes.h>
#include <tinycrypt/cmac_mode.h>
#include <tinycrypt/ccm_mode.h>
#endif /* CONFIG_BT_GATT_CACHING */

#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/drivers/bluetooth/hci_driver.h>

#include "common/bt_str.h"

#include "hci_core.h"
#include "conn_internal.h"
#include "keys.h"
#include "l2cap_internal.h"
#include "att_internal.h"
#include "smp.h"
#include "settings.h"
#include "gatt_internal.h"
#include "long_wq.h"

#define LOG_LEVEL CONFIG_BT_GATT_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(bt_gatt);

#define SC_TIMEOUT	K_MSEC(10)
#define DB_HASH_TIMEOUT	K_MSEC(10)

static uint16_t last_static_handle;

/* Persistent storage format for GATT CCC */
struct ccc_store {
	uint16_t handle;
	uint16_t value;
};

struct gatt_sub {
	uint8_t id;
	bt_addr_le_t peer;
	sys_slist_t list;
};

#if defined(CONFIG_BT_GATT_CLIENT)
#define SUB_MAX (CONFIG_BT_MAX_PAIRED + CONFIG_BT_MAX_CONN)
#else
#define SUB_MAX 0
#endif /* CONFIG_BT_GATT_CLIENT */

/**
 * Entry x is free for reuse whenever (subscriptions[x].peer == BT_ADDR_LE_ANY).
 * Invariant: (sys_slist_is_empty(subscriptions[x].list))
 *              <=> (subscriptions[x].peer == BT_ADDR_LE_ANY).
 */
static struct gatt_sub subscriptions[SUB_MAX];
static sys_slist_t callback_list;

#if defined(CONFIG_BT_GATT_DYNAMIC_DB)
static sys_slist_t db;
#endif /* CONFIG_BT_GATT_DYNAMIC_DB */

enum gatt_global_flags {
	GATT_INITIALIZED,
	GATT_SERVICE_INITIALIZED,

	GATT_NUM_FLAGS,
};

static ATOMIC_DEFINE(gatt_flags, GATT_NUM_FLAGS);

static ssize_t read_name(struct bt_conn *conn, const struct bt_gatt_attr *attr,
			 void *buf, uint16_t len, uint16_t offset)
{
	const char *name = bt_get_name();

	return bt_gatt_attr_read(conn, attr, buf, len, offset, name,
				 strlen(name));
}

#if defined(CONFIG_BT_DEVICE_NAME_GATT_WRITABLE)

static ssize_t write_name(struct bt_conn *conn, const struct bt_gatt_attr *attr,
			 const void *buf, uint16_t len, uint16_t offset,
			 uint8_t flags)
{
	char value[CONFIG_BT_DEVICE_NAME_MAX] = {};

	if (offset >= sizeof(value)) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
	}

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

	memcpy(value, buf, len);

	bt_set_name(value);

	return len;
}

#endif /* CONFIG_BT_DEVICE_NAME_GATT_WRITABLE */

static ssize_t read_appearance(struct bt_conn *conn,
			       const struct bt_gatt_attr *attr, void *buf,
			       uint16_t len, uint16_t offset)
{
	uint16_t appearance = sys_cpu_to_le16(bt_get_appearance());

	return bt_gatt_attr_read(conn, attr, buf, len, offset, &appearance,
				 sizeof(appearance));
}

#if defined(CONFIG_BT_DEVICE_APPEARANCE_GATT_WRITABLE)
static ssize_t write_appearance(struct bt_conn *conn, const struct bt_gatt_attr *attr,
			 const void *buf, uint16_t len, uint16_t offset,
			 uint8_t flags)
{
	uint16_t appearance_le = sys_cpu_to_le16(bt_get_appearance());
	char * const appearance_le_bytes = (char *)&appearance_le;
	uint16_t appearance;
	int err;

	if (offset >= sizeof(appearance_le)) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
	}

	if ((offset + len) > sizeof(appearance_le)) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
	}

	memcpy(&appearance_le_bytes[offset], buf, len);
	appearance = sys_le16_to_cpu(appearance_le);

	err = bt_set_appearance(appearance);

	if (err) {
		return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY);
	}

	return len;
}
#endif /* CONFIG_BT_DEVICE_APPEARANCE_GATT_WRITABLE */

#if CONFIG_BT_DEVICE_APPEARANCE_GATT_WRITABLE
	#define GAP_APPEARANCE_PROPS (BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE)
	#define GAP_APPEARANCE_PERMS (BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_AUTHEN)
	#define GAP_APPEARANCE_WRITE_HANDLER write_appearance
#else
	#define GAP_APPEARANCE_PROPS BT_GATT_CHRC_READ
	#define GAP_APPEARANCE_PERMS BT_GATT_PERM_READ
	#define GAP_APPEARANCE_WRITE_HANDLER NULL
#endif

#if defined (CONFIG_BT_GAP_PERIPHERAL_PREF_PARAMS)
/* This checks if the range entered is valid */
BUILD_ASSERT(!(CONFIG_BT_PERIPHERAL_PREF_MIN_INT > 3200 &&
	     CONFIG_BT_PERIPHERAL_PREF_MIN_INT < 0xffff));
BUILD_ASSERT(!(CONFIG_BT_PERIPHERAL_PREF_MAX_INT > 3200 &&
	     CONFIG_BT_PERIPHERAL_PREF_MAX_INT < 0xffff));
BUILD_ASSERT(!(CONFIG_BT_PERIPHERAL_PREF_TIMEOUT > 3200 &&
	     CONFIG_BT_PERIPHERAL_PREF_TIMEOUT < 0xffff));
BUILD_ASSERT((CONFIG_BT_PERIPHERAL_PREF_MIN_INT == 0xffff) ||
	     (CONFIG_BT_PERIPHERAL_PREF_MIN_INT <=
	     CONFIG_BT_PERIPHERAL_PREF_MAX_INT));
BUILD_ASSERT((CONFIG_BT_PERIPHERAL_PREF_TIMEOUT * 4U) >
	     ((1U + CONFIG_BT_PERIPHERAL_PREF_LATENCY) *
	      CONFIG_BT_PERIPHERAL_PREF_MAX_INT));

static ssize_t read_ppcp(struct bt_conn *conn, const struct bt_gatt_attr *attr,
			 void *buf, uint16_t len, uint16_t offset)
{
	struct __packed {
		uint16_t min_int;
		uint16_t max_int;
		uint16_t latency;
		uint16_t timeout;
	} ppcp;

	ppcp.min_int = sys_cpu_to_le16(CONFIG_BT_PERIPHERAL_PREF_MIN_INT);
	ppcp.max_int = sys_cpu_to_le16(CONFIG_BT_PERIPHERAL_PREF_MAX_INT);
	ppcp.latency = sys_cpu_to_le16(CONFIG_BT_PERIPHERAL_PREF_LATENCY);
	ppcp.timeout = sys_cpu_to_le16(CONFIG_BT_PERIPHERAL_PREF_TIMEOUT);

	return bt_gatt_attr_read(conn, attr, buf, len, offset, &ppcp,
				 sizeof(ppcp));
}
#endif

#if defined(CONFIG_BT_CENTRAL) && defined(CONFIG_BT_PRIVACY)
static ssize_t read_central_addr_res(struct bt_conn *conn,
				     const struct bt_gatt_attr *attr, void *buf,
				     uint16_t len, uint16_t offset)
{
	uint8_t central_addr_res = BT_GATT_CENTRAL_ADDR_RES_SUPP;

	return bt_gatt_attr_read(conn, attr, buf, len, offset,
				 &central_addr_res, sizeof(central_addr_res));
}
#endif /* CONFIG_BT_CENTRAL && CONFIG_BT_PRIVACY */

BT_GATT_SERVICE_DEFINE(_2_gap_svc,
	BT_GATT_PRIMARY_SERVICE(BT_UUID_GAP),
#if defined(CONFIG_BT_DEVICE_NAME_GATT_WRITABLE)
	/* Require pairing for writes to device name */
	BT_GATT_CHARACTERISTIC(BT_UUID_GAP_DEVICE_NAME,
			       BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
			       BT_GATT_PERM_READ |
#if defined(CONFIG_DEVICE_NAME_GATT_WRITABLE_AUTHEN)
			       BT_GATT_PERM_WRITE_AUTHEN,
#elif defined(CONFIG_DEVICE_NAME_GATT_WRITABLE_ENCRYPT)
			       BT_GATT_PERM_WRITE_ENCRYPT,
#else
			       BT_GATT_PERM_WRITE,
#endif
			       read_name, write_name, bt_dev.name),
#else
	BT_GATT_CHARACTERISTIC(BT_UUID_GAP_DEVICE_NAME, BT_GATT_CHRC_READ,
			       BT_GATT_PERM_READ, read_name, NULL, NULL),
#endif /* CONFIG_BT_DEVICE_NAME_GATT_WRITABLE */
	BT_GATT_CHARACTERISTIC(BT_UUID_GAP_APPEARANCE, GAP_APPEARANCE_PROPS,
			       GAP_APPEARANCE_PERMS, read_appearance,
			       GAP_APPEARANCE_WRITE_HANDLER, NULL),
#if defined(CONFIG_BT_CENTRAL) && defined(CONFIG_BT_PRIVACY)
	BT_GATT_CHARACTERISTIC(BT_UUID_CENTRAL_ADDR_RES,
			       BT_GATT_CHRC_READ, BT_GATT_PERM_READ,
			       read_central_addr_res, NULL, NULL),
#endif /* CONFIG_BT_CENTRAL && CONFIG_BT_PRIVACY */
#if defined(CONFIG_BT_GAP_PERIPHERAL_PREF_PARAMS)
	BT_GATT_CHARACTERISTIC(BT_UUID_GAP_PPCP, BT_GATT_CHRC_READ,
			       BT_GATT_PERM_READ, read_ppcp, NULL, NULL),
#endif
);

struct sc_data {
	uint16_t start;
	uint16_t end;
} __packed;

struct gatt_sc_cfg {
	uint8_t		id;
	bt_addr_le_t	peer;
	struct {
		uint16_t		start;
		uint16_t		end;
	} data;
};

#if defined(CONFIG_BT_GATT_SERVICE_CHANGED)
#define SC_CFG_MAX (CONFIG_BT_MAX_PAIRED + CONFIG_BT_MAX_CONN)
#else
#define SC_CFG_MAX 0
#endif
static struct gatt_sc_cfg sc_cfg[SC_CFG_MAX];
BUILD_ASSERT(sizeof(struct sc_data) == sizeof(sc_cfg[0].data));

enum {
	SC_RANGE_CHANGED,    /* SC range changed */
	SC_INDICATE_PENDING, /* SC indicate pending */
	SC_LOAD,	     /* SC has been loaded from settings */

	DB_HASH_VALID,       /* Database hash needs to be calculated */
	DB_HASH_LOAD,        /* Database hash loaded from settings. */
	DB_HASH_LOAD_PROC,   /* DB hash loaded from settings has been processed. */

	/* Total number of flags - must be at the end of the enum */
	SC_NUM_FLAGS,
};

#if defined(CONFIG_BT_GATT_SERVICE_CHANGED)
static struct gatt_sc {
	struct bt_gatt_indicate_params params;
	uint16_t start;
	uint16_t end;
	struct k_work_delayable work;

	ATOMIC_DEFINE(flags, SC_NUM_FLAGS);
} gatt_sc;
#endif /* defined(CONFIG_BT_GATT_SERVICE_CHANGED) */

#if defined(CONFIG_BT_GATT_CACHING)
static struct db_hash {
	uint8_t hash[16];
#if defined(CONFIG_BT_SETTINGS)
	 uint8_t stored_hash[16];
#endif
	struct k_work_delayable work;
	struct k_work_sync sync;
} db_hash;
#endif

static struct gatt_sc_cfg *find_sc_cfg(uint8_t id, const bt_addr_le_t *addr)
{
	LOG_DBG("id: %u, addr: %s", id, bt_addr_le_str(addr));

	for (size_t i = 0; i < ARRAY_SIZE(sc_cfg); i++) {
		if (id == sc_cfg[i].id &&
		    bt_addr_le_eq(&sc_cfg[i].peer, addr)) {
			return &sc_cfg[i];
		}
	}

	return NULL;
}

static void sc_store(struct gatt_sc_cfg *cfg)
{
	char key[BT_SETTINGS_KEY_MAX];
	int err;

	if (cfg->id) {
		char id_str[4];

		u8_to_dec(id_str, sizeof(id_str), cfg->id);
		bt_settings_encode_key(key, sizeof(key), "sc",
				       &cfg->peer, id_str);
	} else {
		bt_settings_encode_key(key, sizeof(key), "sc",
				       &cfg->peer, NULL);
	}

	err = settings_save_one(key, (char *)&cfg->data, sizeof(cfg->data));
	if (err) {
		LOG_ERR("failed to store SC (err %d)", err);
		return;
	}

	LOG_DBG("stored SC for %s (%s, 0x%04x-0x%04x)", bt_addr_le_str(&cfg->peer), key,
		cfg->data.start, cfg->data.end);
}

static void clear_sc_cfg(struct gatt_sc_cfg *cfg)
{
	memset(cfg, 0, sizeof(*cfg));
}

static int bt_gatt_clear_sc(uint8_t id, const bt_addr_le_t *addr)
{

	struct gatt_sc_cfg *cfg;

	cfg = find_sc_cfg(id, (bt_addr_le_t *)addr);
	if (!cfg) {
		return 0;
	}

	if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
		char key[BT_SETTINGS_KEY_MAX];
		int err;

		if (cfg->id) {
			char id_str[4];

			u8_to_dec(id_str, sizeof(id_str), cfg->id);
			bt_settings_encode_key(key, sizeof(key), "sc",
					       &cfg->peer, id_str);
		} else {
			bt_settings_encode_key(key, sizeof(key), "sc",
					       &cfg->peer, NULL);
		}

		err = settings_delete(key);
		if (err) {
			LOG_ERR("failed to delete SC (err %d)", err);
		} else {
			LOG_DBG("deleted SC for %s (%s)", bt_addr_le_str(&cfg->peer), key);
		}
	}

	clear_sc_cfg(cfg);

	return 0;
}

static void sc_clear(struct bt_conn *conn)
{
	if (bt_addr_le_is_bonded(conn->id, &conn->le.dst)) {
		int err;

		err = bt_gatt_clear_sc(conn->id, &conn->le.dst);
		if (err) {
			LOG_ERR("Failed to clear SC %d", err);
		}
	} else {
		struct gatt_sc_cfg *cfg;

		cfg = find_sc_cfg(conn->id, &conn->le.dst);
		if (cfg) {
			clear_sc_cfg(cfg);
		}
	}
}

static void sc_reset(struct gatt_sc_cfg *cfg)
{
	LOG_DBG("peer %s", bt_addr_le_str(&cfg->peer));

	memset(&cfg->data, 0, sizeof(cfg->data));

	if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
		sc_store(cfg);
	}
}

static bool update_range(uint16_t *start, uint16_t *end, uint16_t new_start,
			 uint16_t new_end)
{
	LOG_DBG("start 0x%04x end 0x%04x new_start 0x%04x new_end 0x%04x", *start, *end, new_start,
		new_end);

	/* Check if inside existing range */
	if (new_start >= *start && new_end <= *end) {
		return false;
	}

	/* Update range */
	if (*start > new_start) {
		*start = new_start;
	}

	if (*end < new_end) {
		*end = new_end;
	}

	return true;
}

static void sc_save(uint8_t id, bt_addr_le_t *peer, uint16_t start, uint16_t end)
{
	struct gatt_sc_cfg *cfg;
	bool modified = false;

	LOG_DBG("peer %s start 0x%04x end 0x%04x", bt_addr_le_str(peer), start, end);

	cfg = find_sc_cfg(id, peer);
	if (!cfg) {
		/* Find and initialize a free sc_cfg entry */
		cfg = find_sc_cfg(BT_ID_DEFAULT, BT_ADDR_LE_ANY);
		if (!cfg) {
			LOG_ERR("unable to save SC: no cfg left");
			return;
		}

		cfg->id = id;
		bt_addr_le_copy(&cfg->peer, peer);
	}

	/* Check if there is any change stored */
	if (!(cfg->data.start || cfg->data.end)) {
		cfg->data.start = start;
		cfg->data.end = end;
		modified = true;
		goto done;
	}

	modified = update_range(&cfg->data.start, &cfg->data.end, start, end);

done:
	if (IS_ENABLED(CONFIG_BT_SETTINGS) &&
	    modified && bt_addr_le_is_bonded(cfg->id, &cfg->peer)) {
		sc_store(cfg);
	}
}

static ssize_t sc_ccc_cfg_write(struct bt_conn *conn,
				const struct bt_gatt_attr *attr, uint16_t value)
{
	LOG_DBG("value 0x%04x", value);

	if (value == BT_GATT_CCC_INDICATE) {
		/* Create a new SC configuration entry if subscribed */
		sc_save(conn->id, &conn->le.dst, 0, 0);
	} else {
		sc_clear(conn);
	}

	return sizeof(value);
}

static struct _bt_gatt_ccc sc_ccc = BT_GATT_CCC_INITIALIZER(NULL,
							    sc_ccc_cfg_write,
							    NULL);

/* Do not shuffle the values in this enum, they are used as bit offsets when
 * saving the CF flags to NVS (i.e. NVS persists between FW upgrades).
 */
enum {
	CF_CHANGE_AWARE,	/* Client is changed aware */
	CF_DB_HASH_READ,	/* The client has read the database hash */

	/* Total number of flags - must be at the end of the enum */
	CF_NUM_FLAGS,
};

#define CF_BIT_ROBUST_CACHING	0
#define CF_BIT_EATT		1
#define CF_BIT_NOTIFY_MULTI	2
#define CF_BIT_LAST		CF_BIT_NOTIFY_MULTI

#define CF_NUM_BITS		(CF_BIT_LAST + 1)
#define CF_NUM_BYTES		((CF_BIT_LAST / 8) + 1)
#define CF_FLAGS_STORE_LEN	1

#define CF_ROBUST_CACHING(_cfg) (_cfg->data[0] & BIT(CF_BIT_ROBUST_CACHING))
#define CF_EATT(_cfg) (_cfg->data[0] & BIT(CF_BIT_EATT))
#define CF_NOTIFY_MULTI(_cfg) (_cfg->data[0] & BIT(CF_BIT_NOTIFY_MULTI))

struct gatt_cf_cfg {
	uint8_t			id;
	bt_addr_le_t		peer;
	uint8_t			data[CF_NUM_BYTES];
	ATOMIC_DEFINE(flags, CF_NUM_FLAGS);
};

#if defined(CONFIG_BT_GATT_CACHING)
#define CF_CFG_MAX (CONFIG_BT_MAX_PAIRED + CONFIG_BT_MAX_CONN)
#else
#define CF_CFG_MAX 0
#endif /* CONFIG_BT_GATT_CACHING */

static struct gatt_cf_cfg cf_cfg[CF_CFG_MAX] = {};

static void clear_cf_cfg(struct gatt_cf_cfg *cfg)
{
	bt_addr_le_copy(&cfg->peer, BT_ADDR_LE_ANY);
	memset(cfg->data, 0, sizeof(cfg->data));
	atomic_set(cfg->flags, 0);
}

enum delayed_store_flags {
	DELAYED_STORE_CCC,
	DELAYED_STORE_CF,
	DELAYED_STORE_NUM_FLAGS
};

#if defined(CONFIG_BT_SETTINGS_DELAYED_STORE)
static void gatt_delayed_store_enqueue(uint8_t id, const bt_addr_le_t *peer_addr,
				       enum delayed_store_flags flag);
#endif

#if defined(CONFIG_BT_GATT_CACHING)
static bool set_change_aware_no_store(struct gatt_cf_cfg *cfg, bool aware)
{
	bool changed;

	if (aware) {
		changed = !atomic_test_and_set_bit(cfg->flags, CF_CHANGE_AWARE);
	} else {
		changed = atomic_test_and_clear_bit(cfg->flags, CF_CHANGE_AWARE);
	}

	LOG_DBG("peer is now change-%saware", aware ? "" : "un");

	return changed;
}

static void set_change_aware(struct gatt_cf_cfg *cfg, bool aware)
{
	bool changed = set_change_aware_no_store(cfg, aware);

#if defined(CONFIG_BT_SETTINGS_DELAYED_STORE)
	if (changed) {
		gatt_delayed_store_enqueue(cfg->id, &cfg->peer, DELAYED_STORE_CF);
	}
#else
	(void)changed;
#endif
}

static int bt_gatt_store_cf(uint8_t id, const bt_addr_le_t *peer);

static void set_all_change_unaware(void)
{
#if defined(CONFIG_BT_SETTINGS)
	/* Mark all bonded peers as change-unaware.
	 * - Can be called when not in a connection with said peers
	 * - Doesn't have any effect when no bonds are in memory. This is the
	 *   case when the device has just booted and `settings_load` hasn't yet
	 *   been called.
	 * - Expensive to call, as it will write the new status to settings
	 *   right away.
	 */
	for (size_t i = 0; i < ARRAY_SIZE(cf_cfg); i++) {
		struct gatt_cf_cfg *cfg = &cf_cfg[i];

		if (!bt_addr_le_eq(&cfg->peer, BT_ADDR_LE_ANY)) {
			set_change_aware_no_store(cfg, false);
			bt_gatt_store_cf(cfg->id, &cfg->peer);
		}
	}
#endif	/* CONFIG_BT_SETTINGS */
}

static struct gatt_cf_cfg *find_cf_cfg(struct bt_conn *conn)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(cf_cfg); i++) {
		struct gatt_cf_cfg *cfg = &cf_cfg[i];

		if (!conn) {
			if (bt_addr_le_eq(&cfg->peer, BT_ADDR_LE_ANY)) {
				return cfg;
			}
		} else if (bt_conn_is_peer_addr_le(conn, cfg->id, &cfg->peer)) {
			return cfg;
		}
	}

	return NULL;
}

static ssize_t cf_read(struct bt_conn *conn, const struct bt_gatt_attr *attr,
		       void *buf, uint16_t len, uint16_t offset)
{
	struct gatt_cf_cfg *cfg;
	uint8_t data[1] = {};

	cfg = find_cf_cfg(conn);
	if (cfg) {
		memcpy(data, cfg->data, sizeof(data));
	}

	return bt_gatt_attr_read(conn, attr, buf, len, offset, data,
				 sizeof(data));
}

static bool cf_set_value(struct gatt_cf_cfg *cfg, const uint8_t *value, uint16_t len)
{
	uint16_t i;

	/* Validate the bits */
	for (i = 0U; i <= CF_BIT_LAST && (i / 8) < len; i++) {
		if ((cfg->data[i / 8] & BIT(i % 8)) &&
		    !(value[i / 8] & BIT(i % 8))) {
			/* A client shall never clear a bit it has set */
			return false;
		}
	}

	/* Set the bits for each octect */
	for (i = 0U; i < len && i < CF_NUM_BYTES; i++) {
		if (i == (CF_NUM_BYTES - 1)) {
			cfg->data[i] |= value[i] & BIT_MASK(CF_NUM_BITS % 8);
		} else {
			cfg->data[i] |= value[i];
		}

		LOG_DBG("byte %u: data 0x%02x value 0x%02x", i, cfg->data[i], value[i]);
	}

	return true;
}

static ssize_t cf_write(struct bt_conn *conn, const struct bt_gatt_attr *attr,
			const void *buf, uint16_t len, uint16_t offset, uint8_t flags)
{
	struct gatt_cf_cfg *cfg;
	const uint8_t *value = buf;

	if (offset > sizeof(cfg->data)) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
	}

	if (offset + len > sizeof(cfg->data)) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
	}

	cfg = find_cf_cfg(conn);
	if (!cfg) {
		cfg = find_cf_cfg(NULL);
	}

	if (!cfg) {
		LOG_WRN("No space to store Client Supported Features");
		return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
	}

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

	if (!cf_set_value(cfg, value, len)) {
		return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
	}

	bt_addr_le_copy(&cfg->peer, &conn->le.dst);
	cfg->id = conn->id;
	set_change_aware(cfg, true);

	return len;
}

struct gen_hash_state {
	struct tc_cmac_struct state;
	int err;
};

union hash_attr_value {
	/* Bluetooth Core Specification Version 5.3 | Vol 3, Part G
	 * Table 3.1: Service declaration
	 */
	union {
		uint16_t uuid16;
		uint8_t  uuid128[BT_UUID_SIZE_128];
	} __packed service;
	/* Bluetooth Core Specification Version 5.3 | Vol 3, Part G
	 * Table 3.2: Include declaration
	 */
	struct {
		uint16_t attribute_handle;
		uint16_t end_group_handle;
		uint16_t uuid16;
	} __packed inc;
	/* Bluetooth Core Specification Version 5.3 | Vol 3, Part G
	 * Table 3.3: Characteristic declaration
	 */
	struct {
		uint8_t properties;
		uint16_t value_handle;
		union {
			uint16_t uuid16;
			uint8_t  uuid128[BT_UUID_SIZE_128];
		} __packed;
	} __packed chrc;
	/* Bluetooth Core Specification Version 5.3 | Vol 3, Part G
	 * Table 3.5: Characteristic Properties bit field
	 */
	struct {
		uint16_t properties;
	} __packed cep;
} __packed;

static uint8_t gen_hash_m(const struct bt_gatt_attr *attr, uint16_t handle,
			  void *user_data)
{
	struct gen_hash_state *state = user_data;
	struct bt_uuid_16 *u16;
	uint8_t data[sizeof(union hash_attr_value)];
	ssize_t len;
	uint16_t value;

	if (attr->uuid->type != BT_UUID_TYPE_16)
		return BT_GATT_ITER_CONTINUE;

	u16 = (struct bt_uuid_16 *)attr->uuid;

	switch (u16->val) {
	/* Attributes to hash: handle + UUID + value */
	case BT_UUID_GATT_PRIMARY_VAL:
	case BT_UUID_GATT_SECONDARY_VAL:
	case BT_UUID_GATT_INCLUDE_VAL:
	case BT_UUID_GATT_CHRC_VAL:
	case BT_UUID_GATT_CEP_VAL:
		value = sys_cpu_to_le16(handle);
		if (tc_cmac_update(&state->state, (uint8_t *)&value,
				   sizeof(handle)) == TC_CRYPTO_FAIL) {
			state->err = -EINVAL;
			return BT_GATT_ITER_STOP;
		}

		value = sys_cpu_to_le16(u16->val);
		if (tc_cmac_update(&state->state, (uint8_t *)&value,
				   sizeof(u16->val)) == TC_CRYPTO_FAIL) {
			state->err = -EINVAL;
			return BT_GATT_ITER_STOP;
		}

		len = attr->read(NULL, attr, data, sizeof(data), 0);
		if (len < 0) {
			state->err = len;
			return BT_GATT_ITER_STOP;
		}

		if (tc_cmac_update(&state->state, data, len) ==
		    TC_CRYPTO_FAIL) {
			state->err = -EINVAL;
			return BT_GATT_ITER_STOP;
		}

		break;
	/* Attributes to hash: handle + UUID */
	case BT_UUID_GATT_CUD_VAL:
	case BT_UUID_GATT_CCC_VAL:
	case BT_UUID_GATT_SCC_VAL:
	case BT_UUID_GATT_CPF_VAL:
	case BT_UUID_GATT_CAF_VAL:
		value = sys_cpu_to_le16(handle);
		if (tc_cmac_update(&state->state, (uint8_t *)&value,
				   sizeof(handle)) == TC_CRYPTO_FAIL) {
			state->err = -EINVAL;
			return BT_GATT_ITER_STOP;
		}

		value = sys_cpu_to_le16(u16->val);
		if (tc_cmac_update(&state->state, (uint8_t *)&value,
				   sizeof(u16->val)) == TC_CRYPTO_FAIL) {
			state->err = -EINVAL;
			return BT_GATT_ITER_STOP;
		}
		break;
	default:
		return BT_GATT_ITER_CONTINUE;
	}

	return BT_GATT_ITER_CONTINUE;
}

static void db_hash_store(void)
{
#if defined(CONFIG_BT_SETTINGS)
	int err;

	err = settings_save_one("bt/hash", &db_hash.hash, sizeof(db_hash.hash));
	if (err) {
		LOG_ERR("Failed to save Database Hash (err %d)", err);
	}

	LOG_DBG("Database Hash stored");
#endif	/* CONFIG_BT_SETTINGS */
}

static void db_hash_gen(void)
{
	uint8_t key[16] = {};
	struct tc_aes_key_sched_struct sched;
	struct gen_hash_state state;

	if (tc_cmac_setup(&state.state, key, &sched) == TC_CRYPTO_FAIL) {
		LOG_ERR("Unable to setup AES CMAC");
		return;
	}

	bt_gatt_foreach_attr(0x0001, 0xffff, gen_hash_m, &state);

	if (tc_cmac_final(db_hash.hash, &state.state) == TC_CRYPTO_FAIL) {
		LOG_ERR("Unable to calculate hash");
		return;
	}

	/**
	 * Core 5.1 does not state the endianess of the hash.
	 * However Vol 3, Part F, 3.3.1 says that multi-octet Characteristic
	 * Values shall be LE unless otherwise defined. PTS expects hash to be
	 * in little endianess as well. bt_smp_aes_cmac calculates the hash in
	 * big endianess so we have to swap.
	 */
	sys_mem_swap(db_hash.hash, sizeof(db_hash.hash));

	LOG_HEXDUMP_DBG(db_hash.hash, sizeof(db_hash.hash), "Hash: ");

	atomic_set_bit(gatt_sc.flags, DB_HASH_VALID);
}

#if defined(CONFIG_BT_SETTINGS)
static void sc_indicate(uint16_t start, uint16_t end);
#endif

static void do_db_hash(void)
{
	bool new_hash = !atomic_test_bit(gatt_sc.flags, DB_HASH_VALID);

	if (new_hash) {
		db_hash_gen();
	}

#if defined(CONFIG_BT_SETTINGS)
	bool hash_loaded_from_settings =
		atomic_test_bit(gatt_sc.flags, DB_HASH_LOAD);
	bool already_processed =
		atomic_test_bit(gatt_sc.flags, DB_HASH_LOAD_PROC);

	if (!hash_loaded_from_settings) {
		/* we want to generate the hash, but not overwrite the hash
		 * stored in settings, that we haven't yet loaded.
		 */
		return;
	}

	if (already_processed) {
		/* hash has been loaded from settings and we have already
		 * executed the special case below once. we can now safely save
		 * the calculated hash to settings (if it has changed).
		 */
		if (new_hash) {
			set_all_change_unaware();
			db_hash_store();
		}
	} else {
		/* this is only supposed to run once, on bootup, after the hash
		 * has been loaded from settings.
		 */
		atomic_set_bit(gatt_sc.flags, DB_HASH_LOAD_PROC);

		/* Check if hash matches then skip SC update */
		if (!memcmp(db_hash.stored_hash, db_hash.hash,
			    sizeof(db_hash.stored_hash))) {
			LOG_DBG("Database Hash matches");
			k_work_cancel_delayable(&gatt_sc.work);
			atomic_clear_bit(gatt_sc.flags, SC_RANGE_CHANGED);
			return;
		}

		LOG_HEXDUMP_DBG(db_hash.hash, sizeof(db_hash.hash), "New Hash: ");

		/* GATT database has been modified since last boot, likely due
		 * to a firmware update or a dynamic service that was not
		 * re-registered on boot.
		 * Indicate Service Changed to all bonded devices for the full
		 * database range to invalidate client-side cache and force
		 * discovery on reconnect.
		 */
		sc_indicate(0x0001, 0xffff);

		/* Hash did not match, overwrite with current hash.
		 * Also immediately set all peers (in settings) as
		 * change-unaware.
		 */
		set_all_change_unaware();
		db_hash_store();
	}
#endif /* defined(CONFIG_BT_SETTINGS) */
}

static void db_hash_process(struct k_work *work)
{
	do_db_hash();
}

static ssize_t db_hash_read(struct bt_conn *conn,
			    const struct bt_gatt_attr *attr,
			    void *buf, uint16_t len, uint16_t offset)
{
	struct gatt_cf_cfg *cfg;

	/* Check if db_hash is already pending in which case it shall be
	 * generated immediately instead of waiting for the work to complete.
	 */
	(void)k_work_cancel_delayable_sync(&db_hash.work, &db_hash.sync);
	if (!atomic_test_bit(gatt_sc.flags, DB_HASH_VALID)) {
		db_hash_gen();
		if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
			set_all_change_unaware();
			db_hash_store();
		}
	}

	/* BLUETOOTH CORE SPECIFICATION Version 5.1 | Vol 3, Part G page 2347:
	 * 2.5.2.1 Robust Caching
	 * A connected client becomes change-aware when...
	 * The client reads the Database Hash characteristic and then the server
	 * receives another ATT request from the client.
	 */
	cfg = find_cf_cfg(conn);
	if (cfg &&
	    CF_ROBUST_CACHING(cfg) &&
	    !atomic_test_bit(cfg->flags, CF_CHANGE_AWARE)) {
		atomic_set_bit(cfg->flags, CF_DB_HASH_READ);
	}

	return bt_gatt_attr_read(conn, attr, buf, len, offset, db_hash.hash,
				 sizeof(db_hash.hash));
}

static void remove_cf_cfg(struct bt_conn *conn)
{
	struct gatt_cf_cfg *cfg;

	cfg = find_cf_cfg(conn);
	if (!cfg) {
		return;
	}

	/* BLUETOOTH CORE SPECIFICATION Version 5.1 | Vol 3, Part G page 2405:
	 * For clients with a trusted relationship, the characteristic value
	 * shall be persistent across connections. For clients without a
	 * trusted relationship the characteristic value shall be set to the
	 * default value at each connection.
	 */
	if (!bt_addr_le_is_bonded(conn->id, &conn->le.dst)) {
		clear_cf_cfg(cfg);
	} else {
		/* Update address in case it has changed */
		bt_addr_le_copy(&cfg->peer, &conn->le.dst);
	}
}

#if defined(CONFIG_BT_EATT)
#define SF_BIT_EATT	0
#define SF_BIT_LAST	SF_BIT_EATT

static ssize_t sf_read(struct bt_conn *conn, const struct bt_gatt_attr *attr,
		       void *buf, uint16_t len, uint16_t offset)
{
	uint8_t value = BIT(SF_BIT_EATT);

	return bt_gatt_attr_read(conn, attr, buf, len, offset, &value,
				 sizeof(value));
}
#endif /* CONFIG_BT_EATT */
#endif /* CONFIG_BT_GATT_CACHING */

static struct gatt_cf_cfg *find_cf_cfg_by_addr(uint8_t id,
					       const bt_addr_le_t *addr);

static int bt_gatt_store_cf(uint8_t id, const bt_addr_le_t *peer)
{
#if defined(CONFIG_BT_GATT_CACHING)
	struct gatt_cf_cfg *cfg;
	char key[BT_SETTINGS_KEY_MAX];
	char dst[CF_NUM_BYTES + CF_FLAGS_STORE_LEN];
	char *str;
	size_t len;
	int err;

	cfg = find_cf_cfg_by_addr(id, peer);
	if (!cfg) {
		/* No cfg found, just clear it */
		LOG_DBG("No config for CF");
		str = NULL;
		len = 0;
	} else {
		str = (char *)cfg->data;
		len = sizeof(cfg->data);

		if (id) {
			char id_str[4];

			u8_to_dec(id_str, sizeof(id_str), id);
			bt_settings_encode_key(key, sizeof(key), "cf",
					       peer, id_str);
		}

		/* add the CF data to a temp array */
		memcpy(dst, str, len);

		/* add the change-aware flag */
		bool is_change_aware = atomic_test_bit(cfg->flags, CF_CHANGE_AWARE);

		dst[len] = 0;
		WRITE_BIT(dst[len], CF_CHANGE_AWARE, is_change_aware);
		len += CF_FLAGS_STORE_LEN;

		str = dst;
	}

	if (!cfg || !id) {
		bt_settings_encode_key(key, sizeof(key), "cf",
				       peer, NULL);
	}

	err = settings_save_one(key, str, len);
	if (err) {
		LOG_ERR("Failed to store Client Features (err %d)", err);
		return err;
	}

	LOG_DBG("Stored CF for %s (%s)", bt_addr_le_str(peer), key);
	LOG_HEXDUMP_DBG(str, len, "Saved data");
#endif /* CONFIG_BT_GATT_CACHING */
	return 0;

}

#if defined(CONFIG_BT_SETTINGS) && defined(CONFIG_BT_SMP)
/** Struct used to store both the id and the random address of a device when replacing
 * random addresses in the ccc attribute's cfg array with the device's id address after
 * pairing complete.
 */
struct addr_match {
	const bt_addr_le_t *private_addr;
	const bt_addr_le_t *id_addr;
};

static uint8_t convert_to_id_on_match(const struct bt_gatt_attr *attr,
				      uint16_t handle, void *user_data)
{
	struct _bt_gatt_ccc *ccc;
	struct addr_match *match = user_data;

	/* Check if attribute is a CCC */
	if (attr->write != bt_gatt_attr_write_ccc) {
		return BT_GATT_ITER_CONTINUE;
	}

	ccc = attr->user_data;

	/* Copy the device's id address to the config's address if the config's address is the
	 * same as the device's private address
	 */
	for (size_t i = 0; i < ARRAY_SIZE(ccc->cfg); i++) {
		if (bt_addr_le_eq(&ccc->cfg[i].peer, match->private_addr)) {
			bt_addr_le_copy(&ccc->cfg[i].peer, match->id_addr);
		}
	}

	return BT_GATT_ITER_CONTINUE;
}

static void bt_gatt_identity_resolved(struct bt_conn *conn, const bt_addr_le_t *private_addr,
				      const bt_addr_le_t *id_addr)
{
	/* Update the ccc cfg addresses */
	struct addr_match user_data = {
		.private_addr = private_addr,
		.id_addr      = id_addr
	};
	bool is_bonded = bt_addr_le_is_bonded(conn->id, &conn->le.dst);

	bt_gatt_foreach_attr(0x0001, 0xffff, convert_to_id_on_match, &user_data);

	/* Store the ccc */
	if (is_bonded) {
		bt_gatt_store_ccc(conn->id, &conn->le.dst);
	}

	/* Update the cf addresses and store it if we get a match */
	struct gatt_cf_cfg *cfg = find_cf_cfg_by_addr(conn->id, private_addr);

	if (cfg) {
		bt_addr_le_copy(&cfg->peer, id_addr);
		if (is_bonded) {
			bt_gatt_store_cf(conn->id, &conn->le.dst);
		}
	}
}

static void bt_gatt_pairing_complete(struct bt_conn *conn, bool bonded)
{
	if (bonded) {
		/* Store the ccc and cf data */
		bt_gatt_store_ccc(conn->id, &(conn->le.dst));
		bt_gatt_store_cf(conn->id, &conn->le.dst);
	}
}
#endif /* CONFIG_BT_SETTINGS && CONFIG_BT_SMP */

BT_GATT_SERVICE_DEFINE(_1_gatt_svc,
	BT_GATT_PRIMARY_SERVICE(BT_UUID_GATT),
#if defined(CONFIG_BT_GATT_SERVICE_CHANGED)
	/* Bluetooth 5.0, Vol3 Part G:
	 * The Service Changed characteristic Attribute Handle on the server
	 * shall not change if the server has a trusted relationship with any
	 * client.
	 */
	BT_GATT_CHARACTERISTIC(BT_UUID_GATT_SC, BT_GATT_CHRC_INDICATE,
			       BT_GATT_PERM_NONE, NULL, NULL, NULL),
	BT_GATT_CCC_MANAGED(&sc_ccc, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),
#if defined(CONFIG_BT_GATT_CACHING)
	BT_GATT_CHARACTERISTIC(BT_UUID_GATT_CLIENT_FEATURES,
			       BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
			       BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
			       cf_read, cf_write, NULL),
	BT_GATT_CHARACTERISTIC(BT_UUID_GATT_DB_HASH,
			       BT_GATT_CHRC_READ, BT_GATT_PERM_READ,
			       db_hash_read, NULL, NULL),
#if defined(CONFIG_BT_EATT)
	BT_GATT_CHARACTERISTIC(BT_UUID_GATT_SERVER_FEATURES,
			       BT_GATT_CHRC_READ, BT_GATT_PERM_READ,
			       sf_read, NULL, NULL),
#endif /* CONFIG_BT_EATT */
#endif /* CONFIG_BT_GATT_CACHING */
#endif /* CONFIG_BT_GATT_SERVICE_CHANGED */
);

#if defined(CONFIG_BT_GATT_DYNAMIC_DB)
static uint8_t found_attr(const struct bt_gatt_attr *attr, uint16_t handle,
			  void *user_data)
{
	const struct bt_gatt_attr **found = user_data;

	*found = attr;

	return BT_GATT_ITER_STOP;
}

static const struct bt_gatt_attr *find_attr(uint16_t handle)
{
	const struct bt_gatt_attr *attr = NULL;

	bt_gatt_foreach_attr(handle, handle, found_attr, &attr);

	return attr;
}

static void gatt_insert(struct bt_gatt_service *svc, uint16_t last_handle)
{
	struct bt_gatt_service *tmp, *prev = NULL;

	if (last_handle == 0 || svc->attrs[0].handle > last_handle) {
		sys_slist_append(&db, &svc->node);
		return;
	}

	/* DB shall always have its service in ascending order */
	SYS_SLIST_FOR_EACH_CONTAINER(&db, tmp, node) {
		if (tmp->attrs[0].handle > svc->attrs[0].handle) {
			if (prev) {
				sys_slist_insert(&db, &prev->node, &svc->node);
			} else {
				sys_slist_prepend(&db, &svc->node);
			}
			return;
		}

		prev = tmp;
	}
}

static int gatt_register(struct bt_gatt_service *svc)
{
	struct bt_gatt_service *last;
	uint16_t handle, last_handle;
	struct bt_gatt_attr *attrs = svc->attrs;
	uint16_t count = svc->attr_count;

	if (sys_slist_is_empty(&db)) {
		handle = last_static_handle;
		last_handle = 0;
		goto populate;
	}

	last = SYS_SLIST_PEEK_TAIL_CONTAINER(&db, last, node);
	handle = last->attrs[last->attr_count - 1].handle;
	last_handle = handle;

populate:
	/* Populate the handles and append them to the list */
	for (; attrs && count; attrs++, count--) {
		if (!attrs->handle) {
			/* Allocate handle if not set already */
			attrs->handle = ++handle;
		} else if (attrs->handle > handle) {
			/* Use existing handle if valid */
			handle = attrs->handle;
		} else if (find_attr(attrs->handle)) {
			/* Service has conflicting handles */
			LOG_ERR("Unable to register handle 0x%04x", attrs->handle);
			return -EINVAL;
		}

		LOG_DBG("attr %p handle 0x%04x uuid %s perm 0x%02x", attrs, attrs->handle,
			bt_uuid_str(attrs->uuid), attrs->perm);
	}

	gatt_insert(svc, last_handle);

	return 0;
}
#endif /* CONFIG_BT_GATT_DYNAMIC_DB */

static inline void sc_work_submit(k_timeout_t timeout)
{
#if defined(CONFIG_BT_GATT_SERVICE_CHANGED)
	k_work_reschedule(&gatt_sc.work, timeout);
#endif
}

#if defined(CONFIG_BT_GATT_SERVICE_CHANGED)
static void sc_indicate_rsp(struct bt_conn *conn,
			    struct bt_gatt_indicate_params *params, uint8_t err)
{
#if defined(CONFIG_BT_GATT_CACHING)
	struct gatt_cf_cfg *cfg;
#endif

	LOG_DBG("err 0x%02x", err);

	atomic_clear_bit(gatt_sc.flags, SC_INDICATE_PENDING);

	/* Check if there is new change in the meantime */
	if (atomic_test_bit(gatt_sc.flags, SC_RANGE_CHANGED)) {
		/* Reschedule without any delay since it is waiting already */
		sc_work_submit(K_NO_WAIT);
	}

#if defined(CONFIG_BT_GATT_CACHING)
	/* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 3, Part G page 1476:
	 * 2.5.2.1 Robust Caching
	 * ... a change-unaware connected client using exactly one ATT bearer
	 * becomes change-aware when ...
	 * The client receives and confirms a Handle Value Indication
	 * for the Service Changed characteristic
	 */
	if (bt_att_fixed_chan_only(conn)) {
		cfg = find_cf_cfg(conn);
		if (cfg && CF_ROBUST_CACHING(cfg)) {
			set_change_aware(cfg, true);
		}
	}
#endif /* CONFIG_BT_GATT_CACHING */
}

static void sc_process(struct k_work *work)
{
	struct k_work_delayable *dwork = k_work_delayable_from_work(work);
	struct gatt_sc *sc = CONTAINER_OF(dwork, struct gatt_sc, work);
	uint16_t sc_range[2];

	__ASSERT(!atomic_test_bit(sc->flags, SC_INDICATE_PENDING),
		 "Indicate already pending");

	LOG_DBG("start 0x%04x end 0x%04x", sc->start, sc->end);

	sc_range[0] = sys_cpu_to_le16(sc->start);
	sc_range[1] = sys_cpu_to_le16(sc->end);

	atomic_clear_bit(sc->flags, SC_RANGE_CHANGED);
	sc->start = 0U;
	sc->end = 0U;

	sc->params.attr = &_1_gatt_svc.attrs[2];
	sc->params.func = sc_indicate_rsp;
	sc->params.data = &sc_range[0];
	sc->params.len = sizeof(sc_range);
#if defined(CONFIG_BT_EATT)
	sc->params.chan_opt = BT_ATT_CHAN_OPT_NONE;
#endif /* CONFIG_BT_EATT */

	if (bt_gatt_indicate(NULL, &sc->params)) {
		/* No connections to indicate */
		return;
	}

	atomic_set_bit(sc->flags, SC_INDICATE_PENDING);
}
#endif /* defined(CONFIG_BT_GATT_SERVICE_CHANGED) */

static void clear_ccc_cfg(struct bt_gatt_ccc_cfg *cfg)
{
	bt_addr_le_copy(&cfg->peer, BT_ADDR_LE_ANY);
	cfg->id = 0U;
	cfg->value = 0U;
}

#if defined(CONFIG_BT_SETTINGS_DELAYED_STORE)
struct ds_peer {
	uint8_t id;
	bt_addr_le_t peer;

	ATOMIC_DEFINE(flags, DELAYED_STORE_NUM_FLAGS);
};

static struct gatt_delayed_store {
	struct ds_peer peer_list[CONFIG_BT_MAX_PAIRED + CONFIG_BT_MAX_CONN];
	struct k_work_delayable work;
} gatt_delayed_store;

static struct ds_peer *gatt_delayed_store_find(uint8_t id,
					       const bt_addr_le_t *peer_addr)
{
	struct ds_peer *el;

	for (size_t i = 0; i < ARRAY_SIZE(gatt_delayed_store.peer_list); i++) {
		el = &gatt_delayed_store.peer_list[i];
		if (el->id == id &&
		    bt_addr_le_eq(peer_addr, &el->peer)) {
			return el;
		}
	}

	return NULL;
}

static struct ds_peer *gatt_delayed_store_alloc(uint8_t id,
						const bt_addr_le_t *peer_addr)
{
	struct ds_peer *el;

	for (size_t i = 0; i < ARRAY_SIZE(gatt_delayed_store.peer_list); i++) {
		el = &gatt_delayed_store.peer_list[i];

		/* Checking for the flags is cheaper than a memcmp for the
		 * address, so we use that to signal that a given slot is
		 * free.
		 */
		if (atomic_get(el->flags) == 0) {
			bt_addr_le_copy(&el->peer, peer_addr);
			el->id = id;

			return el;
		}
	}

	return NULL;
}

static void gatt_delayed_store_free(struct ds_peer *el)
{
	if (el) {
		el->id = 0;
		memset(&el->peer, 0, sizeof(el->peer));
		atomic_set(el->flags, 0);
	}
}

static void gatt_delayed_store_enqueue(uint8_t id, const bt_addr_le_t *peer_addr,
				       enum delayed_store_flags flag)
{
	bool bonded = bt_addr_le_is_bonded(id, peer_addr);
	struct ds_peer *el = gatt_delayed_store_find(id, peer_addr);

	if (bonded) {
		if (el == NULL) {
			el = gatt_delayed_store_alloc(id, peer_addr);
			__ASSERT(el != NULL, "Can't save CF / CCC to flash");
		}

		atomic_set_bit(el->flags, flag);

		k_work_reschedule(&gatt_delayed_store.work,
				  K_MSEC(CONFIG_BT_SETTINGS_DELAYED_STORE_MS));
	}
}

static void delayed_store(struct k_work *work)
{
	struct ds_peer *el;
	struct k_work_delayable *dwork = k_work_delayable_from_work(work);
	struct gatt_delayed_store *store =
		CONTAINER_OF(dwork, struct gatt_delayed_store, work);

	for (size_t i = 0; i < ARRAY_SIZE(gatt_delayed_store.peer_list); i++) {
		el = &store->peer_list[i];

		if (bt_addr_le_is_bonded(el->id, &el->peer)) {
			if (IS_ENABLED(CONFIG_BT_SETTINGS_CCC_STORE_ON_WRITE) &&
			    atomic_test_and_clear_bit(el->flags, DELAYED_STORE_CCC)) {
				bt_gatt_store_ccc(el->id, &el->peer);
			}

			if (IS_ENABLED(CONFIG_BT_SETTINGS_CF_STORE_ON_WRITE) &&
			    atomic_test_and_clear_bit(el->flags, DELAYED_STORE_CF)) {
				bt_gatt_store_cf(el->id, &el->peer);
			}

			if (atomic_get(el->flags) == 0) {
				gatt_delayed_store_free(el);
			}
		}
	}
}
#endif	/* CONFIG_BT_SETTINGS_DELAYED_STORE */

static void bt_gatt_service_init(void)
{
	if (atomic_test_and_set_bit(gatt_flags, GATT_SERVICE_INITIALIZED)) {
		return;
	}

	STRUCT_SECTION_FOREACH(bt_gatt_service_static, svc) {
		last_static_handle += svc->attr_count;
	}
}

void bt_gatt_init(void)
{
	if (atomic_test_and_set_bit(gatt_flags, GATT_INITIALIZED)) {
		return;
	}

	bt_gatt_service_init();

	sys_slist_init(&callback_list);

#if defined(CONFIG_BT_GATT_CACHING)
	k_work_init_delayable(&db_hash.work, db_hash_process);

	/* Submit work to Generate initial hash as there could be static
	 * services already in the database.
	 */
	if (IS_ENABLED(CONFIG_BT_LONG_WQ)) {
		bt_long_wq_schedule(&db_hash.work, DB_HASH_TIMEOUT);
	} else {
		k_work_schedule(&db_hash.work, DB_HASH_TIMEOUT);
	}
#endif /* CONFIG_BT_GATT_CACHING */

#if defined(CONFIG_BT_GATT_SERVICE_CHANGED)
	k_work_init_delayable(&gatt_sc.work, sc_process);
	if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
		/* Make sure to not send SC indications until SC
		 * settings are loaded
		 */
		atomic_set_bit(gatt_sc.flags, SC_INDICATE_PENDING);
	}
#endif /* defined(CONFIG_BT_GATT_SERVICE_CHANGED) */

#if defined(CONFIG_BT_SETTINGS_DELAYED_STORE)
	k_work_init_delayable(&gatt_delayed_store.work, delayed_store);
#endif

#if defined(CONFIG_BT_SETTINGS) && defined(CONFIG_BT_SMP)
	static struct bt_conn_auth_info_cb gatt_conn_auth_info_cb = {
		.pairing_complete = bt_gatt_pairing_complete,
	};

	/* Register the gatt module for authentication info callbacks so it can
	 * be notified when pairing has completed. This is used to enable CCC
	 * and CF storage on pairing complete.
	 */
	bt_conn_auth_info_cb_register(&gatt_conn_auth_info_cb);

	static struct bt_conn_cb gatt_conn_cb = {
		.identity_resolved = bt_gatt_identity_resolved,
	};

	/* Also update the address of CCC or CF writes that happened before the
	 * identity resolution. Note that to increase security in the future, we
	 * might want to explicitly not do this and treat a bonded device as a
	 * brand-new peer.
	 */
	bt_conn_cb_register(&gatt_conn_cb);
#endif /* CONFIG_BT_SETTINGS && CONFIG_BT_SMP */
}

#if defined(CONFIG_BT_GATT_DYNAMIC_DB) || \
    (defined(CONFIG_BT_GATT_CACHING) && defined(CONFIG_BT_SETTINGS))
static void sc_indicate(uint16_t start, uint16_t end)
{
	LOG_DBG("start 0x%04x end 0x%04x", start, end);

	if (!atomic_test_and_set_bit(gatt_sc.flags, SC_RANGE_CHANGED)) {
		gatt_sc.start = start;
		gatt_sc.end = end;
		goto submit;
	}

	if (!update_range(&gatt_sc.start, &gatt_sc.end, start, end)) {
		return;
	}

submit:
	if (atomic_test_bit(gatt_sc.flags, SC_INDICATE_PENDING)) {
		LOG_DBG("indicate pending, waiting until complete...");
		return;
	}

	/* Reschedule since the range has changed */
	sc_work_submit(SC_TIMEOUT);
}
#endif /* BT_GATT_DYNAMIC_DB || (BT_GATT_CACHING && BT_SETTINGS) */

void bt_gatt_cb_register(struct bt_gatt_cb *cb)
{
	sys_slist_append(&callback_list, &cb->node);
}

#if defined(CONFIG_BT_GATT_DYNAMIC_DB)
static void db_changed(void)
{
#if defined(CONFIG_BT_GATT_CACHING)
	struct bt_conn *conn;
	int i;

	atomic_clear_bit(gatt_sc.flags, DB_HASH_VALID);

	if (IS_ENABLED(CONFIG_BT_LONG_WQ)) {
		bt_long_wq_reschedule(&db_hash.work, DB_HASH_TIMEOUT);
	} else {
		k_work_reschedule(&db_hash.work, DB_HASH_TIMEOUT);
	}

	for (i = 0; i < ARRAY_SIZE(cf_cfg); i++) {
		struct gatt_cf_cfg *cfg = &cf_cfg[i];

		if (bt_addr_le_eq(&cfg->peer, BT_ADDR_LE_ANY)) {
			continue;
		}

		if (CF_ROBUST_CACHING(cfg)) {
			/* Core Spec 5.1 | Vol 3, Part G, 2.5.2.1 Robust Caching
			 *... the database changes again before the client
			 * becomes change-aware in which case the error response
			 * shall be sent again.
			 */
			conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cfg->peer);
			if (conn) {
				bt_att_clear_out_of_sync_sent(conn);
				bt_conn_unref(conn);
			}

			atomic_clear_bit(cfg->flags, CF_DB_HASH_READ);
			set_change_aware(cfg, false);
		}
	}
#endif
}

static void gatt_unregister_ccc(struct _bt_gatt_ccc *ccc)
{
	ccc->value = 0;

	for (size_t i = 0; i < ARRAY_SIZE(ccc->cfg); i++) {
		struct bt_gatt_ccc_cfg *cfg = &ccc->cfg[i];

		if (!bt_addr_le_eq(&cfg->peer, BT_ADDR_LE_ANY)) {
			struct bt_conn *conn;
			bool store = true;

			conn = bt_conn_lookup_addr_le(cfg->id, &cfg->peer);
			if (conn) {
				if (conn->state == BT_CONN_CONNECTED) {
#if defined(CONFIG_BT_SETTINGS_CCC_STORE_ON_WRITE)
					gatt_delayed_store_enqueue(conn->id,
								   &conn->le.dst,
								   DELAYED_STORE_CCC);
#endif
					store = false;
				}

				bt_conn_unref(conn);
			}

			if (IS_ENABLED(CONFIG_BT_SETTINGS) && store &&
			    bt_addr_le_is_bonded(cfg->id, &cfg->peer)) {
				bt_gatt_store_ccc(cfg->id, &cfg->peer);
			}

			clear_ccc_cfg(cfg);
		}
	}
}

static int gatt_unregister(struct bt_gatt_service *svc)
{
	if (!sys_slist_find_and_remove(&db, &svc->node)) {
		return -ENOENT;
	}

	for (uint16_t i = 0; i < svc->attr_count; i++) {
		struct bt_gatt_attr *attr = &svc->attrs[i];

		if (attr->write == bt_gatt_attr_write_ccc) {
			gatt_unregister_ccc(attr->user_data);
		}
	}

	return 0;
}

int bt_gatt_service_register(struct bt_gatt_service *svc)
{
	int err;

	__ASSERT(svc, "invalid parameters\n");
	__ASSERT(svc->attrs, "invalid parameters\n");
	__ASSERT(svc->attr_count, "invalid parameters\n");

	if (IS_ENABLED(CONFIG_BT_SETTINGS) &&
	    atomic_test_bit(gatt_flags, GATT_INITIALIZED) &&
	    !atomic_test_bit(gatt_sc.flags, SC_LOAD)) {
		LOG_ERR("Can't register service after init and before settings are loaded.");
		return -EINVAL;
	}

	/* Init GATT core services */
	bt_gatt_service_init();

	/* Do no allow to register mandatory services twice */
	if (!bt_uuid_cmp(svc->attrs[0].uuid, BT_UUID_GAP) ||
	    !bt_uuid_cmp(svc->attrs[0].uuid, BT_UUID_GATT)) {
		return -EALREADY;
	}

	k_sched_lock();

	err = gatt_register(svc);
	if (err < 0) {
		k_sched_unlock();
		return err;
	}

	/* Don't submit any work until the stack is initialized */
	if (!atomic_test_bit(gatt_flags, GATT_INITIALIZED)) {
		k_sched_unlock();
		return 0;
	}

	sc_indicate(svc->attrs[0].handle,
		    svc->attrs[svc->attr_count - 1].handle);

	db_changed();

	k_sched_unlock();

	return 0;
}

int bt_gatt_service_unregister(struct bt_gatt_service *svc)
{
	int err;

	__ASSERT(svc, "invalid parameters\n");

	k_sched_lock();

	err = gatt_unregister(svc);
	if (err) {
		k_sched_unlock();
		return err;
	}

	/* Don't submit any work until the stack is initialized */
	if (!atomic_test_bit(gatt_flags, GATT_INITIALIZED)) {
		k_sched_unlock();
		return 0;
	}

	sc_indicate(svc->attrs[0].handle,
		    svc->attrs[svc->attr_count - 1].handle);

	db_changed();

	k_sched_unlock();

	return 0;
}

bool bt_gatt_service_is_registered(const struct bt_gatt_service *svc)
{
	bool registered = false;
	sys_snode_t *node;

	k_sched_lock();
	SYS_SLIST_FOR_EACH_NODE(&db, node) {
		if (&svc->node == node) {
			registered = true;
			break;
		}
	}

	k_sched_unlock();

	return registered;
}
#endif /* CONFIG_BT_GATT_DYNAMIC_DB */

ssize_t bt_gatt_attr_read(struct bt_conn *conn, const struct bt_gatt_attr *attr,
			  void *buf, uint16_t buf_len, uint16_t offset,
			  const void *value, uint16_t value_len)
{
	uint16_t len;

	if (offset > value_len) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
	}

	len = MIN(buf_len, value_len - offset);

	LOG_DBG("handle 0x%04x offset %u length %u", attr->handle, offset, len);

	memcpy(buf, (uint8_t *)value + offset, len);

	return len;
}

ssize_t bt_gatt_attr_read_service(struct bt_conn *conn,
				  const struct bt_gatt_attr *attr,
				  void *buf, uint16_t len, uint16_t offset)
{
	struct bt_uuid *uuid = attr->user_data;

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

		return bt_gatt_attr_read(conn, attr, buf, len, offset,
					 &uuid16, 2);
	}

	return bt_gatt_attr_read(conn, attr, buf, len, offset,
				 BT_UUID_128(uuid)->val, 16);
}

struct gatt_incl {
	uint16_t start_handle;
	uint16_t end_handle;
	uint16_t uuid16;
} __packed;

static uint8_t get_service_handles(const struct bt_gatt_attr *attr,
				   uint16_t handle, void *user_data)
{
	struct gatt_incl *include = user_data;

	/* Stop if attribute is a service */
	if (!bt_uuid_cmp(attr->uuid, BT_UUID_GATT_PRIMARY) ||
	    !bt_uuid_cmp(attr->uuid, BT_UUID_GATT_SECONDARY)) {
		return BT_GATT_ITER_STOP;
	}

	include->end_handle = sys_cpu_to_le16(handle);

	return BT_GATT_ITER_CONTINUE;
}

uint16_t bt_gatt_attr_get_handle(const struct bt_gatt_attr *attr)
{
	uint16_t handle = 1;

	if (!attr) {
		return 0;
	}

	if (attr->handle) {
		return attr->handle;
	}

	STRUCT_SECTION_FOREACH(bt_gatt_service_static, static_svc) {
		/* Skip ahead if start is not within service attributes array */
		if ((attr < &static_svc->attrs[0]) ||
		    (attr > &static_svc->attrs[static_svc->attr_count - 1])) {
			handle += static_svc->attr_count;
			continue;
		}

		for (size_t i = 0; i < static_svc->attr_count; i++, handle++) {
			if (attr == &static_svc->attrs[i]) {
				return handle;
			}
		}
	}

	return 0;
}

ssize_t bt_gatt_attr_read_included(struct bt_conn *conn,
				   const struct bt_gatt_attr *attr,
				   void *buf, uint16_t len, uint16_t offset)
{
	struct bt_gatt_attr *incl = attr->user_data;
	uint16_t handle = bt_gatt_attr_get_handle(incl);
	struct bt_uuid *uuid = incl->user_data;
	struct gatt_incl pdu;
	uint8_t value_len;

	/* first attr points to the start handle */
	pdu.start_handle = sys_cpu_to_le16(handle);
	value_len = sizeof(pdu.start_handle) + sizeof(pdu.end_handle);

	/*
	 * Core 4.2, Vol 3, Part G, 3.2,
	 * The Service UUID shall only be present when the UUID is a
	 * 16-bit Bluetooth UUID.
	 */
	if (uuid->type == BT_UUID_TYPE_16) {
		pdu.uuid16 = sys_cpu_to_le16(BT_UUID_16(uuid)->val);
		value_len += sizeof(pdu.uuid16);
	}

	/* Lookup for service end handle */
	bt_gatt_foreach_attr(handle + 1, 0xffff, get_service_handles, &pdu);

	return bt_gatt_attr_read(conn, attr, buf, len, offset, &pdu, value_len);
}

struct gatt_chrc {
	uint8_t properties;
	uint16_t value_handle;
	union {
		uint16_t uuid16;
		uint8_t  uuid[16];
	};
} __packed;

uint16_t bt_gatt_attr_value_handle(const struct bt_gatt_attr *attr)
{
	uint16_t handle = 0;

	if (attr != NULL && bt_uuid_cmp(attr->uuid, BT_UUID_GATT_CHRC) == 0) {
		struct bt_gatt_chrc *chrc = attr->user_data;

		handle = chrc->value_handle;
		if (handle == 0) {
			/* Fall back to Zephyr value handle policy */
			handle = bt_gatt_attr_get_handle(attr) + 1U;
		}
	}

	return handle;
}

ssize_t bt_gatt_attr_read_chrc(struct bt_conn *conn,
			       const struct bt_gatt_attr *attr, void *buf,
			       uint16_t len, uint16_t offset)
{
	struct bt_gatt_chrc *chrc = attr->user_data;
	struct gatt_chrc pdu;
	uint8_t value_len;

	pdu.properties = chrc->properties;
	/* BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part G] page 534:
	 * 3.3.2 Characteristic Value Declaration
	 * The Characteristic Value declaration contains the value of the
	 * characteristic. It is the first Attribute after the characteristic
	 * declaration. All characteristic definitions shall have a
	 * Characteristic Value declaration.
	 */
	pdu.value_handle = sys_cpu_to_le16(bt_gatt_attr_value_handle(attr));

	value_len = sizeof(pdu.properties) + sizeof(pdu.value_handle);

	if (chrc->uuid->type == BT_UUID_TYPE_16) {
		pdu.uuid16 = sys_cpu_to_le16(BT_UUID_16(chrc->uuid)->val);
		value_len += 2U;
	} else {
		memcpy(pdu.uuid, BT_UUID_128(chrc->uuid)->val, 16);
		value_len += 16U;
	}

	return bt_gatt_attr_read(conn, attr, buf, len, offset, &pdu, value_len);
}

static uint8_t gatt_foreach_iter(const struct bt_gatt_attr *attr,
				 uint16_t handle, uint16_t start_handle,
				 uint16_t end_handle,
				 const struct bt_uuid *uuid,
				 const void *attr_data, uint16_t *num_matches,
				 bt_gatt_attr_func_t func, void *user_data)
{
	uint8_t result;

	/* Stop if over the requested range */
	if (handle > end_handle) {
		return BT_GATT_ITER_STOP;
	}

	/* Check if attribute handle is within range */
	if (handle < start_handle) {
		return BT_GATT_ITER_CONTINUE;
	}

	/* Match attribute UUID if set */
	if (uuid && bt_uuid_cmp(uuid, attr->uuid)) {
		return BT_GATT_ITER_CONTINUE;
	}

	/* Match attribute user_data if set */
	if (attr_data && attr_data != attr->user_data) {
		return BT_GATT_ITER_CONTINUE;
	}

	*num_matches -= 1;

	result = func(attr, handle, user_data);

	if (!*num_matches) {
		return BT_GATT_ITER_STOP;
	}

	return result;
}

static void foreach_attr_type_dyndb(uint16_t start_handle, uint16_t end_handle,
				    const struct bt_uuid *uuid,
				    const void *attr_data, uint16_t num_matches,
				    bt_gatt_attr_func_t func, void *user_data)
{
#if defined(CONFIG_BT_GATT_DYNAMIC_DB)
	size_t i;
	struct bt_gatt_service *svc;

	SYS_SLIST_FOR_EACH_CONTAINER(&db, svc, node) {
		struct bt_gatt_service *next;

		next = SYS_SLIST_PEEK_NEXT_CONTAINER(svc, node);
		if (next) {
			/* Skip ahead if start is not within service handles */
			if (next->attrs[0].handle <= start_handle) {
				continue;
			}
		}

		for (i = 0; i < svc->attr_count; i++) {
			struct bt_gatt_attr *attr = &svc->attrs[i];

			if (gatt_foreach_iter(attr, attr->handle,
					      start_handle,
					      end_handle,
					      uuid, attr_data,
					      &num_matches,
					      func, user_data) ==
			    BT_GATT_ITER_STOP) {
				return;
			}
		}
	}
#endif /* CONFIG_BT_GATT_DYNAMIC_DB */
}

void bt_gatt_foreach_attr_type(uint16_t start_handle, uint16_t end_handle,
			       const struct bt_uuid *uuid,
			       const void *attr_data, uint16_t num_matches,
			       bt_gatt_attr_func_t func, void *user_data)
{
	size_t i;

	if (!num_matches) {
		num_matches = UINT16_MAX;
	}

	if (start_handle <= last_static_handle) {
		uint16_t handle = 1;

		STRUCT_SECTION_FOREACH(bt_gatt_service_static, static_svc) {
			/* Skip ahead if start is not within service handles */
			if (handle + static_svc->attr_count < start_handle) {
				handle += static_svc->attr_count;
				continue;
			}

			for (i = 0; i < static_svc->attr_count; i++, handle++) {
				if (gatt_foreach_iter(&static_svc->attrs[i],
						      handle, start_handle,
						      end_handle, uuid,
						      attr_data, &num_matches,
						      func, user_data) ==
				    BT_GATT_ITER_STOP) {
					return;
				}
			}
		}
	}

	/* Iterate over dynamic db */
	foreach_attr_type_dyndb(start_handle, end_handle, uuid, attr_data,
				num_matches, func, user_data);
}

static uint8_t find_next(const struct bt_gatt_attr *attr, uint16_t handle,
			 void *user_data)
{
	struct bt_gatt_attr **next = user_data;

	*next = (struct bt_gatt_attr *)attr;

	return BT_GATT_ITER_STOP;
}

struct bt_gatt_attr *bt_gatt_attr_next(const struct bt_gatt_attr *attr)
{
	struct bt_gatt_attr *next = NULL;
	uint16_t handle = bt_gatt_attr_get_handle(attr);

	bt_gatt_foreach_attr(handle + 1, handle + 1, find_next, &next);

	return next;
}

static struct bt_gatt_ccc_cfg *find_ccc_cfg(const struct bt_conn *conn,
					    struct _bt_gatt_ccc *ccc)
{
	for (size_t i = 0; i < ARRAY_SIZE(ccc->cfg); i++) {
		struct bt_gatt_ccc_cfg *cfg = &ccc->cfg[i];

		if (conn) {
			if (bt_conn_is_peer_addr_le(conn, cfg->id,
						    &cfg->peer)) {
				return cfg;
			}
		} else if (bt_addr_le_eq(&cfg->peer, BT_ADDR_LE_ANY)) {
			return cfg;
		}
	}

	return NULL;
}

ssize_t bt_gatt_attr_read_ccc(struct bt_conn *conn,
			      const struct bt_gatt_attr *attr, void *buf,
			      uint16_t len, uint16_t offset)
{
	struct _bt_gatt_ccc *ccc = attr->user_data;
	const struct bt_gatt_ccc_cfg *cfg;
	uint16_t value;

	cfg = find_ccc_cfg(conn, ccc);
	if (cfg) {
		value = sys_cpu_to_le16(cfg->value);
	} else {
		/* Default to disable if there is no cfg for the peer */
		value = 0x0000;
	}

	return bt_gatt_attr_read(conn, attr, buf, len, offset, &value,
				 sizeof(value));
}

static void gatt_ccc_changed(const struct bt_gatt_attr *attr,
			     struct _bt_gatt_ccc *ccc)
{
	int i;
	uint16_t value = 0x0000;

	for (i = 0; i < ARRAY_SIZE(ccc->cfg); i++) {
		if (ccc->cfg[i].value > value) {
			value = ccc->cfg[i].value;
		}
	}

	LOG_DBG("ccc %p value 0x%04x", ccc, value);

	if (value != ccc->value) {
		ccc->value = value;
		if (ccc->cfg_changed) {
			ccc->cfg_changed(attr, value);
		}
	}
}

ssize_t bt_gatt_attr_write_ccc(struct bt_conn *conn,
			       const struct bt_gatt_attr *attr, const void *buf,
			       uint16_t len, uint16_t offset, uint8_t flags)
{
	struct _bt_gatt_ccc *ccc = attr->user_data;
	struct bt_gatt_ccc_cfg *cfg;
	bool value_changed;
	uint16_t value;

	if (offset) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
	}

	if (!len || len > sizeof(uint16_t)) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
	}

	if (len < sizeof(uint16_t)) {
		value = *(uint8_t *)buf;
	} else {
		value = sys_get_le16(buf);
	}

	cfg = find_ccc_cfg(conn, ccc);
	if (!cfg) {
		/* If there's no existing entry, but the new value is zero,
		 * we don't need to do anything, since a disabled CCC is
		 * behaviorally the same as no written CCC.
		 */
		if (!value) {
			return len;
		}

		cfg = find_ccc_cfg(NULL, ccc);
		if (!cfg) {
			LOG_WRN("No space to store CCC cfg");
			return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
		}

		bt_addr_le_copy(&cfg->peer, &conn->le.dst);
		cfg->id = conn->id;
	}

	/* Confirm write if cfg is managed by application */
	if (ccc->cfg_write) {
		ssize_t write = ccc->cfg_write(conn, attr, value);

		if (write < 0) {
			return write;
		}

		/* Accept size=1 for backwards compatibility */
		if (write != sizeof(value) && write != 1) {
			return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY);
		}
	}

	value_changed = cfg->value != value;
	cfg->value = value;

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

	/* Update cfg if don't match */
	if (cfg->value != ccc->value) {
		gatt_ccc_changed(attr, ccc);
	}

	if (value_changed) {
#if defined(CONFIG_BT_SETTINGS_CCC_STORE_ON_WRITE)
		/* Enqueue CCC store if value has changed for the connection */
		gatt_delayed_store_enqueue(conn->id, &conn->le.dst, DELAYED_STORE_CCC);
#endif
	}

	/* Disabled CCC is the same as no configured CCC, so clear the entry */
	if (!value) {
		clear_ccc_cfg(cfg);
	}

	return len;
}

ssize_t bt_gatt_attr_read_cep(struct bt_conn *conn,
			      const struct bt_gatt_attr *attr, void *buf,
			      uint16_t len, uint16_t offset)
{
	const struct bt_gatt_cep *value = attr->user_data;
	uint16_t props = sys_cpu_to_le16(value->properties);

	return bt_gatt_attr_read(conn, attr, buf, len, offset, &props,
				 sizeof(props));
}

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

	return bt_gatt_attr_read(conn, attr, buf, len, offset, value,
				 strlen(value));
}

struct gatt_cpf {
	uint8_t  format;
	int8_t   exponent;
	uint16_t unit;
	uint8_t  name_space;
	uint16_t description;
} __packed;

ssize_t bt_gatt_attr_read_cpf(struct bt_conn *conn,
			      const struct bt_gatt_attr *attr, void *buf,
			      uint16_t len, uint16_t offset)
{
	const struct bt_gatt_cpf *cpf = attr->user_data;
	struct gatt_cpf value;

	value.format = cpf->format;
	value.exponent = cpf->exponent;
	value.unit = sys_cpu_to_le16(cpf->unit);
	value.name_space = cpf->name_space;
	value.description = sys_cpu_to_le16(cpf->description);

	return bt_gatt_attr_read(conn, attr, buf, len, offset, &value,
				 sizeof(value));
}

struct notify_data {
	const struct bt_gatt_attr *attr;
	uint16_t handle;
	int err;
	uint16_t type;
	union {
		struct bt_gatt_notify_params *nfy_params;
		struct bt_gatt_indicate_params *ind_params;
	};
};

#if defined(CONFIG_BT_GATT_NOTIFY_MULTIPLE)

static struct net_buf *nfy_mult[CONFIG_BT_MAX_CONN];

static int gatt_notify_mult_send(struct bt_conn *conn, struct net_buf *buf)
{
	int ret;
	uint8_t *pdu = buf->data;
	/* PDU structure is [Opcode (1)] [Handle (2)] [Length (2)] [Value (Length)] */
	uint16_t first_attr_len = sys_get_le16(&pdu[3]);

	/* Convert to ATT_HANDLE_VALUE_NTF if containing a single handle. */
	if (buf->len ==
	    (1 + sizeof(struct bt_att_notify_mult) + first_attr_len)) {
		/* Store attr handle */
		uint16_t handle = sys_get_le16(&pdu[1]);

		/* Remove the ATT_MULTIPLE_HANDLE_VALUE_NTF opcode,
		 * attribute handle and length
		 */
		(void)net_buf_pull(buf, 1 + sizeof(struct bt_att_notify_mult));

		/* Add back an ATT_HANDLE_VALUE_NTF opcode and attr handle */
		/* PDU structure is now [Opcode (1)] [Handle (1)] [Value] */
		net_buf_push_le16(buf, handle);
		net_buf_push_u8(buf, BT_ATT_OP_NOTIFY);
		LOG_DBG("Converted BT_ATT_OP_NOTIFY_MULT with single attr to BT_ATT_OP_NOTIFY");
	}

	ret = bt_att_send(conn, buf);
	if (ret < 0) {
		net_buf_unref(buf);
	}

	return ret;
}

static void notify_mult_process(struct k_work *work)
{
	int i;

	/* Send to any connection with an allocated buffer */
	for (i = 0; i < ARRAY_SIZE(nfy_mult); i++) {
		struct net_buf **buf = &nfy_mult[i];

		if (*buf) {
			struct bt_conn *conn = bt_conn_lookup_index(i);

			gatt_notify_mult_send(conn, *buf);
			*buf = NULL;
			bt_conn_unref(conn);
		}
	}
}

K_WORK_DELAYABLE_DEFINE(nfy_mult_work, notify_mult_process);

static bool gatt_cf_notify_multi(struct bt_conn *conn)
{
	struct gatt_cf_cfg *cfg;

	cfg = find_cf_cfg(conn);
	if (!cfg) {
		return false;
	}

	return CF_NOTIFY_MULTI(cfg);
}

static int gatt_notify_flush(struct bt_conn *conn)
{
	int err = 0;
	struct net_buf **buf = &nfy_mult[bt_conn_index(conn)];

	if (*buf) {
		err = gatt_notify_mult_send(conn, *buf);
		*buf = NULL;
	}

	return err;
}

static void cleanup_notify(struct bt_conn *conn)
{
	struct net_buf **buf = &nfy_mult[bt_conn_index(conn)];

	if (*buf) {
		net_buf_unref(*buf);
		*buf = NULL;
	}
}

static void gatt_add_nfy_to_buf(struct net_buf *buf,
				uint16_t handle,
				struct bt_gatt_notify_params *params)
{
	struct bt_att_notify_mult *nfy;

	nfy = net_buf_add(buf, sizeof(*nfy));
	nfy->handle = sys_cpu_to_le16(handle);
	nfy->len = sys_cpu_to_le16(params->len);

	net_buf_add(buf, params->len);
	(void)memcpy(nfy->value, params->data, params->len);
}

#if (CONFIG_BT_GATT_NOTIFY_MULTIPLE_FLUSH_MS != 0)
static int gatt_notify_mult(struct bt_conn *conn, uint16_t handle,
			    struct bt_gatt_notify_params *params)
{
	struct net_buf **buf = &nfy_mult[bt_conn_index(conn)];

	/* Check if we can fit more data into it, in case it doesn't fit send
	 * the existing buffer and proceed to create a new one
	 */
	if (*buf && ((net_buf_tailroom(*buf) < sizeof(struct bt_att_notify_mult) + params->len) ||
	    !bt_att_tx_meta_data_match(*buf, params->func, params->user_data,
				       BT_ATT_CHAN_OPT(params)))) {
		int ret;

		ret = gatt_notify_mult_send(conn, *buf);
		*buf = NULL;
		if (ret < 0) {
			return ret;
		}
	}

	if (!*buf) {
		*buf = bt_att_create_pdu(conn, BT_ATT_OP_NOTIFY_MULT,
					 sizeof(struct bt_att_notify_mult) + params->len);
		if (!*buf) {
			return -ENOMEM;
		}

		bt_att_set_tx_meta_data(*buf, params->func, params->user_data,
					BT_ATT_CHAN_OPT(params));
	} else {
		/* Increment the number of handles, ensuring the notify callback
		 * gets called once for every attribute.
		 */
		bt_att_increment_tx_meta_data_attr_count(*buf, 1);
	}

	LOG_DBG("handle 0x%04x len %u", handle, params->len);
	gatt_add_nfy_to_buf(*buf, handle, params);

	/* Use `k_work_schedule` to keep the original deadline, instead of
	 * re-setting the timeout whenever a new notification is appended.
	 */
	k_work_schedule(&nfy_mult_work,
			K_MSEC(CONFIG_BT_GATT_NOTIFY_MULTIPLE_FLUSH_MS));

	return 0;
}
#endif /* CONFIG_BT_GATT_NOTIFY_MULTIPLE_FLUSH_MS != 0 */
#endif /* CONFIG_BT_GATT_NOTIFY_MULTIPLE */

static int gatt_notify(struct bt_conn *conn, uint16_t handle,
		       struct bt_gatt_notify_params *params)
{
	struct net_buf *buf;
	struct bt_att_notify *nfy;

#if defined(CONFIG_BT_GATT_ENFORCE_CHANGE_UNAWARE)
	/* BLUETOOTH CORE SPECIFICATION Version 5.3
	 * Vol 3, Part G 2.5.3 (page 1479):
	 *
	 * Except for a Handle Value indication for the Service Changed
	 * characteristic, the server shall not send notifications and
	 * indications to such a client until it becomes change-aware.
	 */
	if (!bt_gatt_change_aware(conn, false)) {
		return -EAGAIN;
	}
#endif

	/* Confirm that the connection has the correct level of security */
	if (bt_gatt_check_perm(conn, params->attr, BT_GATT_PERM_READ_ENCRYPT_MASK)) {
		LOG_WRN("Link is not encrypted");
		return -EPERM;
	}

	if (IS_ENABLED(CONFIG_BT_GATT_ENFORCE_SUBSCRIPTION)) {
		/* Check if client has subscribed before sending notifications.
		 * This is not really required in the Bluetooth specification,
		 * but follows its spirit.
		 */
		if (!bt_gatt_is_subscribed(conn, params->attr, BT_GATT_CCC_NOTIFY)) {
			LOG_WRN("Device is not subscribed to characteristic");
			return -EINVAL;
		}
	}

	if (IS_ENABLED(CONFIG_BT_EATT) &&
	    !bt_att_chan_opt_valid(conn, BT_ATT_CHAN_OPT(params))) {
		return -EINVAL;
	}

#if defined(CONFIG_BT_GATT_NOTIFY_MULTIPLE) && (CONFIG_BT_GATT_NOTIFY_MULTIPLE_FLUSH_MS != 0)
	if (gatt_cf_notify_multi(conn)) {
		return gatt_notify_mult(conn, handle, params);
	}
#endif /* CONFIG_BT_GATT_NOTIFY_MULTIPLE */

	buf = bt_att_create_pdu(conn, BT_ATT_OP_NOTIFY,
				sizeof(*nfy) + params->len);
	if (!buf) {
		LOG_WRN("No buffer available to send notification");
		return -ENOMEM;
	}

	LOG_DBG("conn %p handle 0x%04x", conn, handle);

	nfy = net_buf_add(buf, sizeof(*nfy));
	nfy->handle = sys_cpu_to_le16(handle);

	net_buf_add(buf, params->len);
	memcpy(nfy->value, params->data, params->len);

	bt_att_set_tx_meta_data(buf, params->func, params->user_data, BT_ATT_CHAN_OPT(params));
	return bt_att_send(conn, buf);
}

static void gatt_indicate_rsp(struct bt_conn *conn, uint8_t err,
			      const void *pdu, uint16_t length, void *user_data)
{
	struct bt_gatt_indicate_params *params = user_data;

	if (params->func) {
		params->func(conn, params, err);
	}

	params->_ref--;
	if (params->destroy && (params->_ref == 0)) {
		params->destroy(params);
	}
}

static struct bt_att_req *gatt_req_alloc(bt_att_func_t func, void *params,
					 bt_att_encode_t encode,
					 uint8_t op,
					 size_t len)
{
	struct bt_att_req *req;

	/* Allocate new request */
	req = bt_att_req_alloc(BT_ATT_TIMEOUT);
	if (!req) {
		return NULL;
	}

#if defined(CONFIG_BT_SMP)
	req->att_op = op;
	req->len = len;
	req->encode = encode;
#endif
	req->func = func;
	req->user_data = params;

	return req;
}

#ifdef CONFIG_BT_GATT_CLIENT
static int gatt_req_send(struct bt_conn *conn, bt_att_func_t func, void *params,
			 bt_att_encode_t encode, uint8_t op, size_t len,
			 enum bt_att_chan_opt chan_opt)

{
	struct bt_att_req *req;
	struct net_buf *buf;
	int err;

	if (IS_ENABLED(CONFIG_BT_EATT) &&
	    !bt_att_chan_opt_valid(conn, chan_opt)) {
		return -EINVAL;
	}

	req = gatt_req_alloc(func, params, encode, op, len);
	if (!req) {
		return -ENOMEM;
	}

	buf = bt_att_create_pdu(conn, op, len);
	if (!buf) {
		bt_att_req_free(req);
		return -ENOMEM;
	}

	bt_att_set_tx_meta_data(buf, NULL, NULL, chan_opt);

	req->buf = buf;

	err = encode(buf, len, params);
	if (err) {
		bt_att_req_free(req);
		return err;
	}

	err = bt_att_req_send(conn, req);
	if (err) {
		bt_att_req_free(req);
	}

	return err;
}
#endif

static int gatt_indicate(struct bt_conn *conn, uint16_t handle,
			 struct bt_gatt_indicate_params *params)
{
	struct net_buf *buf;
	struct bt_att_indicate *ind;
	struct bt_att_req *req;
	size_t len;
	int err;

#if defined(CONFIG_BT_GATT_ENFORCE_CHANGE_UNAWARE)
	/* BLUETOOTH CORE SPECIFICATION Version 5.1 | Vol 3, Part G page 2350:
	 * Except for the Handle Value indication, the  server shall not send
	 * notifications and indications to such a client until it becomes
	 * change-aware.
	 */
	if (!(params->func && (params->func == sc_indicate_rsp ||
	    params->func == sc_restore_rsp)) &&
	    !bt_gatt_change_aware(conn, false)) {
		return -EAGAIN;
	}
#endif

	/* Confirm that the connection has the correct level of security */
	if (bt_gatt_check_perm(conn, params->attr, BT_GATT_PERM_READ_ENCRYPT_MASK)) {
		LOG_WRN("Link is not encrypted");
		return -EPERM;
	}

	if (IS_ENABLED(CONFIG_BT_GATT_ENFORCE_SUBSCRIPTION)) {
		/* Check if client has subscribed before sending notifications.
		 * This is not really required in the Bluetooth specification,
		 * but follows its spirit.
		 */
		if (!bt_gatt_is_subscribed(conn, params->attr, BT_GATT_CCC_INDICATE)) {
			LOG_WRN("Device is not subscribed to characteristic");
			return -EINVAL;
		}
	}

	if (IS_ENABLED(CONFIG_BT_EATT) &&
	    !bt_att_chan_opt_valid(conn, BT_ATT_CHAN_OPT(params))) {
		return -EINVAL;
	}

	len = sizeof(*ind) + params->len;

	req = gatt_req_alloc(gatt_indicate_rsp, params, NULL,
			     BT_ATT_OP_INDICATE, len);
	if (!req) {
		return -ENOMEM;
	}

	buf = bt_att_create_pdu(conn, BT_ATT_OP_INDICATE, len);
	if (!buf) {
		LOG_WRN("No buffer available to send indication");
		bt_att_req_free(req);
		return -ENOMEM;
	}

	bt_att_set_tx_meta_data(buf, NULL, NULL, BT_ATT_CHAN_OPT(params));

	ind = net_buf_add(buf, sizeof(*ind));
	ind->handle = sys_cpu_to_le16(handle);

	net_buf_add(buf, params->len);
	memcpy(ind->value, params->data, params->len);

	LOG_DBG("conn %p handle 0x%04x", conn, handle);

	req->buf = buf;

	err = bt_att_req_send(conn, req);
	if (err) {
		bt_att_req_free(req);
	}

	return err;
}

static uint8_t notify_cb(const struct bt_gatt_attr *attr, uint16_t handle,
			 void *user_data)
{
	struct notify_data *data = user_data;
	struct _bt_gatt_ccc *ccc;
	size_t i;

	/* Check attribute user_data must be of type struct _bt_gatt_ccc */
	if (attr->write != bt_gatt_attr_write_ccc) {
		return BT_GATT_ITER_CONTINUE;
	}

	ccc = attr->user_data;

	/* Save Service Changed data if peer is not connected */
	if (IS_ENABLED(CONFIG_BT_GATT_SERVICE_CHANGED) && ccc == &sc_ccc) {
		for (i = 0; i < ARRAY_SIZE(sc_cfg); i++) {
			struct gatt_sc_cfg *cfg = &sc_cfg[i];
			struct bt_conn *conn;

			if (bt_addr_le_eq(&cfg->peer, BT_ADDR_LE_ANY)) {
				continue;
			}

			conn = bt_conn_lookup_state_le(cfg->id, &cfg->peer,
						       BT_CONN_CONNECTED);
			if (!conn) {
				struct sc_data *sc;

				sc = (struct sc_data *)data->ind_params->data;
				sc_save(cfg->id, &cfg->peer,
					sys_le16_to_cpu(sc->start),
					sys_le16_to_cpu(sc->end));
				continue;
			}

			bt_conn_unref(conn);
		}
	}

	/* Notify all peers configured */
	for (i = 0; i < ARRAY_SIZE(ccc->cfg); i++) {
		struct bt_gatt_ccc_cfg *cfg = &ccc->cfg[i];
		struct bt_conn *conn;
		int err;

		/* Check if config value matches data type since consolidated
		 * value may be for a different peer.
		 */
		if (cfg->value != data->type) {
			continue;
		}

		conn = bt_conn_lookup_addr_le(cfg->id, &cfg->peer);
		if (!conn) {
			continue;
		}

		if (conn->state != BT_CONN_CONNECTED) {
			bt_conn_unref(conn);
			continue;
		}

		/* Confirm match if cfg is managed by application */
		if (ccc->cfg_match && !ccc->cfg_match(conn, attr)) {
			bt_conn_unref(conn);
			continue;
		}

		/* Confirm that the connection has the correct level of security */
		if (bt_gatt_check_perm(conn, attr, BT_GATT_PERM_READ_ENCRYPT_MASK)) {
			LOG_WRN("Link is not encrypted");
			bt_conn_unref(conn);
			continue;
		}

		/* Use the Characteristic Value handle discovered since the
		 * Client Characteristic Configuration descriptor may occur
		 * in any position within the characteristic definition after
		 * the Characteristic Value.
		 * Only notify or indicate devices which are subscribed.
		 */
		if ((data->type == BT_GATT_CCC_INDICATE) &&
		    (cfg->value & BT_GATT_CCC_INDICATE)) {
			err = gatt_indicate(conn, data->handle, data->ind_params);
			if (err == 0) {
				data->ind_params->_ref++;
			}
		} else if ((data->type == BT_GATT_CCC_NOTIFY) &&
			   (cfg->value & BT_GATT_CCC_NOTIFY)) {
			err = gatt_notify(conn, data->handle, data->nfy_params);
		} else {
			err = 0;
		}

		bt_conn_unref(conn);

		if (err < 0) {
			return BT_GATT_ITER_STOP;
		}

		data->err = 0;
	}

	return BT_GATT_ITER_CONTINUE;
}

static uint8_t match_uuid(const struct bt_gatt_attr *attr, uint16_t handle,
			  void *user_data)
{
	struct notify_data *data = user_data;

	data->attr = attr;
	data->handle = handle;

	return BT_GATT_ITER_STOP;
}

static bool gatt_find_by_uuid(struct notify_data *found,
			      const struct bt_uuid *uuid)
{
	found->attr = NULL;

	bt_gatt_foreach_attr_type(found->handle, 0xffff, uuid, NULL, 1,
				  match_uuid, found);

	return found->attr ? true : false;
}

struct bt_gatt_attr *bt_gatt_find_by_uuid(const struct bt_gatt_attr *attr,
					  uint16_t attr_count,
					  const struct bt_uuid *uuid)
{
	struct bt_gatt_attr *found = NULL;
	uint16_t start_handle = bt_gatt_attr_value_handle(attr);
	uint16_t end_handle = start_handle && attr_count ?
			      start_handle + attr_count : 0xffff;

	bt_gatt_foreach_attr_type(start_handle, end_handle, uuid, NULL, 1,
				  find_next, &found);

	return found;
}

int bt_gatt_notify_cb(struct bt_conn *conn,
		      struct bt_gatt_notify_params *params)
{
	struct notify_data data;

	__ASSERT(params, "invalid parameters\n");
	__ASSERT(params->attr || params->uuid, "invalid parameters\n");

	if (!atomic_test_bit(bt_dev.flags, BT_DEV_READY)) {
		return -EAGAIN;
	}

	if (conn && conn->state != BT_CONN_CONNECTED) {
		return -ENOTCONN;
	}

	data.attr = params->attr;
	data.handle = bt_gatt_attr_get_handle(data.attr);

	/* Lookup UUID if it was given */
	if (params->uuid) {
		if (!gatt_find_by_uuid(&data, params->uuid)) {
			return -ENOENT;
		}

		params->attr = data.attr;
	} else {
		if (!data.handle) {
			return -ENOENT;
		}
	}

	/* Check if attribute is a characteristic then adjust the handle */
	if (!bt_uuid_cmp(data.attr->uuid, BT_UUID_GATT_CHRC)) {
		struct bt_gatt_chrc *chrc = data.attr->user_data;

		if (!(chrc->properties & BT_GATT_CHRC_NOTIFY)) {
			return -EINVAL;
		}

		data.handle = bt_gatt_attr_value_handle(data.attr);
	}

	if (conn) {
		return gatt_notify(conn, data.handle, params);
	}

	data.err = -ENOTCONN;
	data.type = BT_GATT_CCC_NOTIFY;
	data.nfy_params = params;

	bt_gatt_foreach_attr_type(data.handle, 0xffff, BT_UUID_GATT_CCC, NULL,
				  1, notify_cb, &data);

	return data.err;
}

#if defined(CONFIG_BT_GATT_NOTIFY_MULTIPLE)
static int gatt_notify_multiple_verify_args(struct bt_conn *conn,
					    struct bt_gatt_notify_params params[],
					    uint16_t num_params)
{
	__ASSERT(params, "invalid parameters\n");
	__ASSERT(params->attr, "invalid parameters\n");

	CHECKIF(num_params < 2) {
		/* Use the standard notification API when sending only one
		 * notification.
		 */
		return -EINVAL;
	}

	CHECKIF(conn == NULL) {
		/* Use the standard notification API to send to all connected
		 * peers.
		 */
		return -EINVAL;
	}

	if (!atomic_test_bit(bt_dev.flags, BT_DEV_READY)) {
		return -EAGAIN;
	}

	if (conn->state != BT_CONN_CONNECTED) {
		return -ENOTCONN;
	}

#if defined(CONFIG_BT_GATT_ENFORCE_CHANGE_UNAWARE)
	/* BLUETOOTH CORE SPECIFICATION Version 5.3
	 * Vol 3, Part G 2.5.3 (page 1479):
	 *
	 * Except for a Handle Value indication for the Service Changed
	 * characteristic, the server shall not send notifications and
	 * indications to such a client until it becomes change-aware.
	 */
	if (!bt_gatt_change_aware(conn, false)) {
		return -EAGAIN;
	}
#endif

	/* This API guarantees an ATT_MULTIPLE_HANDLE_VALUE_NTF over the air. */
	if (!gatt_cf_notify_multi(conn)) {
		return -EOPNOTSUPP;
	}

	return 0;
}

static int gatt_notify_multiple_verify_params(struct bt_conn *conn,
					     struct bt_gatt_notify_params params[],
					     uint16_t num_params, size_t *total_len)
{
	for (uint16_t i = 0; i < num_params; i++) {
		/* Compute the total data length. */
		*total_len += params[i].len;

		/* Confirm that the connection has the correct level of security. */
		if (bt_gatt_check_perm(conn, params[i].attr,
				       BT_GATT_PERM_READ_ENCRYPT |
				       BT_GATT_PERM_READ_AUTHEN)) {
			LOG_WRN("Link is not encrypted");
			return -EPERM;
		}

		/* The current implementation requires the same callbacks and
		 * user_data.
		 */
		if ((params[0].func != params[i].func) ||
		    (params[0].user_data != params[i].user_data)) {
			return -EINVAL;
		}

		/* This API doesn't support passing UUIDs. */
		if (params[i].uuid) {
			return -EINVAL;
		}

		/* Check if the supplied handle is invalid. */
		if (!bt_gatt_attr_get_handle(params[i].attr)) {
			return -EINVAL;
		}

		/* Check if the characteristic is subscribed. */
		if (IS_ENABLED(CONFIG_BT_GATT_ENFORCE_SUBSCRIPTION) &&
		    !bt_gatt_is_subscribed(conn, params[i].attr,
					   BT_GATT_CCC_NOTIFY)) {
			LOG_WRN("Device is not subscribed to characteristic");
			return -EINVAL;
		}
	}

	/* PDU length is specified with a 16-bit value. */
	if (*total_len > UINT16_MAX) {
		return -ERANGE;
	}

	/* Check there is a bearer with a high enough MTU. */
	if (bt_att_get_mtu(conn) <
	    (sizeof(struct bt_att_notify_mult) + *total_len)) {
		return -ERANGE;
	}

	return 0;
}

int bt_gatt_notify_multiple(struct bt_conn *conn,
			    uint16_t num_params,
			    struct bt_gatt_notify_params params[])
{
	int err;
	size_t total_len = 0;
	struct net_buf *buf;

	/* Validate arguments, connection state and feature support. */
	err = gatt_notify_multiple_verify_args(conn, params, num_params);
	if (err) {
		return err;
	}

	/* Validate all the attributes that we want to notify.
	 * Also gets us the total length of the PDU as a side-effect.
	 */
	err = gatt_notify_multiple_verify_params(conn, params, num_params, &total_len);
	if (err) {
		return err;
	}

	/* Send any outstanding notifications.
	 * Frees up buffer space for our PDU.
	 */
	gatt_notify_flush(conn);

	/* Build the PDU */
	buf = bt_att_create_pdu(conn, BT_ATT_OP_NOTIFY_MULT,
				sizeof(struct bt_att_notify_mult) + total_len);
	if (!buf) {
		return -ENOMEM;
	}

	/* Register the callback. It will be called num_params times. */
	bt_att_set_tx_meta_data(buf, params->func, params->user_data, BT_ATT_CHAN_OPT(params));
	bt_att_increment_tx_meta_data_attr_count(buf, num_params - 1);

	for (uint16_t i = 0; i < num_params; i++) {
		struct notify_data data;

		data.attr = params[i].attr;
		data.handle = bt_gatt_attr_get_handle(data.attr);

		/* Check if attribute is a characteristic then adjust the
		 * handle
		 */
		if (!bt_uuid_cmp(data.attr->uuid, BT_UUID_GATT_CHRC)) {
			data.handle = bt_gatt_attr_value_handle(data.attr);
		}

		/* Add handle and data to the command buffer. */
		gatt_add_nfy_to_buf(buf, data.handle, &params[i]);
	}

	/* Send the buffer. */
	return gatt_notify_mult_send(conn, buf);
}
#endif /* CONFIG_BT_GATT_NOTIFY_MULTIPLE */

int bt_gatt_indicate(struct bt_conn *conn,
		     struct bt_gatt_indicate_params *params)
{
	struct notify_data data;

	__ASSERT(params, "invalid parameters\n");
	__ASSERT(params->attr || params->uuid, "invalid parameters\n");

	if (!atomic_test_bit(bt_dev.flags, BT_DEV_READY)) {
		return -EAGAIN;
	}

	if (conn && conn->state != BT_CONN_CONNECTED) {
		return -ENOTCONN;
	}

	data.attr = params->attr;
	data.handle = bt_gatt_attr_get_handle(data.attr);

	/* Lookup UUID if it was given */
	if (params->uuid) {
		if (!gatt_find_by_uuid(&data, params->uuid)) {
			return -ENOENT;
		}

		params->attr = data.attr;
	} else {
		if (!data.handle) {
			return -ENOENT;
		}
	}

	/* Check if attribute is a characteristic then adjust the handle */
	if (!bt_uuid_cmp(data.attr->uuid, BT_UUID_GATT_CHRC)) {
		struct bt_gatt_chrc *chrc = data.attr->user_data;

		if (!(chrc->properties & BT_GATT_CHRC_INDICATE)) {
			return -EINVAL;
		}

		data.handle = bt_gatt_attr_value_handle(data.attr);
	}

	if (conn) {
		params->_ref = 1;
		return gatt_indicate(conn, data.handle, params);
	}

	data.err = -ENOTCONN;
	data.type = BT_GATT_CCC_INDICATE;
	data.ind_params = params;

	params->_ref = 0;
	bt_gatt_foreach_attr_type(data.handle, 0xffff, BT_UUID_GATT_CCC, NULL,
				  1, notify_cb, &data);

	return data.err;
}

uint16_t bt_gatt_get_mtu(struct bt_conn *conn)
{
	return bt_att_get_mtu(conn);
}

uint8_t bt_gatt_check_perm(struct bt_conn *conn, const struct bt_gatt_attr *attr,
			uint16_t mask)
{
	if ((mask & BT_GATT_PERM_READ) &&
	    (!(attr->perm & BT_GATT_PERM_READ_MASK) || !attr->read)) {
		return BT_ATT_ERR_READ_NOT_PERMITTED;
	}

	if ((mask & BT_GATT_PERM_WRITE) &&
	    (!(attr->perm & BT_GATT_PERM_WRITE_MASK) || !attr->write)) {
		return BT_ATT_ERR_WRITE_NOT_PERMITTED;
	}

	if (IS_ENABLED(CONFIG_BT_CONN_DISABLE_SECURITY)) {
		return 0;
	}

	mask &= attr->perm;

	/*
	 * Core Specification 5.4 Vol. 3 Part C 10.3.1
	 *
	 * If neither an LTK nor an STK is available, the service
	 * request shall be rejected with the error code
	 * “Insufficient Authentication”.
	 * Note: When the link is not encrypted, the error code
	 * “Insufficient Authentication” does not indicate that
	 *  MITM protection is required.
	 *
	 * If an LTK or an STK is available and encryption is
	 * required (LE security mode 1) but encryption is not
	 * enabled, the service request shall be rejected with
	 * the error code “Insufficient Encryption”.
	 */

	if (mask & (BT_GATT_PERM_ENCRYPT_MASK | BT_GATT_PERM_AUTHEN_MASK)) {
#if defined(CONFIG_BT_SMP)
		if (!conn->encrypt) {
			if (bt_conn_ltk_present(conn)) {
				return BT_ATT_ERR_INSUFFICIENT_ENCRYPTION;
			} else {
				return BT_ATT_ERR_AUTHENTICATION;
			}
		}

		if (mask & BT_GATT_PERM_AUTHEN_MASK) {
			if (bt_conn_get_security(conn) < BT_SECURITY_L3) {
				return BT_ATT_ERR_AUTHENTICATION;
			}
		}

		if (mask & BT_GATT_PERM_LESC_MASK) {
			const struct bt_keys *keys = conn->le.keys;

			if (!keys || (keys->flags & BT_KEYS_SC) == 0) {
				return BT_ATT_ERR_AUTHENTICATION;
			}
		}
#else
		return BT_ATT_ERR_AUTHENTICATION;
#endif /* CONFIG_BT_SMP */
	}

	return 0;
}

static void sc_restore_rsp(struct bt_conn *conn,
			   struct bt_gatt_indicate_params *params, uint8_t err)
{
#if defined(CONFIG_BT_GATT_CACHING)
	struct gatt_cf_cfg *cfg;
#endif

	LOG_DBG("err 0x%02x", err);

#if defined(CONFIG_BT_GATT_CACHING)
	/* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 3, Part G page 1476:
	 * 2.5.2.1 Robust Caching
	 * ... a change-unaware connected client using exactly one ATT bearer
	 * becomes change-aware when ...
	 * The client receives and confirms a Handle Value Indication
	 * for the Service Changed characteristic
	 */

	if (bt_att_fixed_chan_only(conn)) {
		cfg = find_cf_cfg(conn);
		if (cfg && CF_ROBUST_CACHING(cfg)) {
			set_change_aware(cfg, true);
		}
	}
#endif /* CONFIG_BT_GATT_CACHING */

	if (!err && IS_ENABLED(CONFIG_BT_GATT_SERVICE_CHANGED)) {
		struct gatt_sc_cfg *sc_cfg = find_sc_cfg(conn->id, &conn->le.dst);

		if (sc_cfg) {
			sc_reset(sc_cfg);
		}
	}
}

static struct bt_gatt_indicate_params sc_restore_params[CONFIG_BT_MAX_CONN];
static uint16_t sc_range[CONFIG_BT_MAX_CONN][2];

static void sc_restore(struct bt_conn *conn)
{
	struct gatt_sc_cfg *cfg;
	uint8_t index;

	cfg = find_sc_cfg(conn->id, &conn->le.dst);
	if (!cfg) {
		LOG_DBG("no SC data found");
		return;
	}

	if (!(cfg->data.start || cfg->data.end)) {
		return;
	}

	LOG_DBG("peer %s start 0x%04x end 0x%04x", bt_addr_le_str(&cfg->peer), cfg->data.start,
		cfg->data.end);

	index = bt_conn_index(conn);

	sc_range[index][0] = sys_cpu_to_le16(cfg->data.start);
	sc_range[index][1] = sys_cpu_to_le16(cfg->data.end);

	sc_restore_params[index].attr = &_1_gatt_svc.attrs[2];
	sc_restore_params[index].func = sc_restore_rsp;
	sc_restore_params[index].data = &sc_range[index][0];
	sc_restore_params[index].len = sizeof(sc_range[index]);

	if (bt_gatt_indicate(conn, &sc_restore_params[index])) {
		LOG_ERR("SC restore indication failed");
	}
}

struct conn_data {
	struct bt_conn *conn;
	bt_security_t sec;
};

static uint8_t update_ccc(const struct bt_gatt_attr *attr, uint16_t handle,
			  void *user_data)
{
	struct conn_data *data = user_data;
	struct bt_conn *conn = data->conn;
	struct _bt_gatt_ccc *ccc;
	size_t i;
	uint8_t err;

	/* Check attribute user_data must be of type struct _bt_gatt_ccc */
	if (attr->write != bt_gatt_attr_write_ccc) {
		return BT_GATT_ITER_CONTINUE;
	}

	ccc = attr->user_data;

	for (i = 0; i < ARRAY_SIZE(ccc->cfg); i++) {
		struct bt_gatt_ccc_cfg *cfg = &ccc->cfg[i];

		/* Ignore configuration for different peer or not active */
		if (!cfg->value ||
		    !bt_conn_is_peer_addr_le(conn, cfg->id, &cfg->peer)) {
			continue;
		}

		/* Check if attribute requires encryption/authentication */
		err = bt_gatt_check_perm(conn, attr, BT_GATT_PERM_WRITE_MASK);
		if (err) {
			bt_security_t sec;

			if (err == BT_ATT_ERR_WRITE_NOT_PERMITTED) {
				LOG_WRN("CCC %p not writable", attr);
				continue;
			}

			sec = BT_SECURITY_L2;

			if (err == BT_ATT_ERR_AUTHENTICATION) {
				sec = BT_SECURITY_L3;
			}

			/* Check if current security is enough */
			if (IS_ENABLED(CONFIG_BT_SMP) &&
			    bt_conn_get_security(conn) < sec) {
				if (data->sec < sec) {
					data->sec = sec;
				}
				continue;
			}
		}

		gatt_ccc_changed(attr, ccc);

		if (IS_ENABLED(CONFIG_BT_GATT_SERVICE_CHANGED) &&
		    ccc == &sc_ccc) {
			sc_restore(conn);
		}

		return BT_GATT_ITER_CONTINUE;
	}

	return BT_GATT_ITER_CONTINUE;
}

static uint8_t disconnected_cb(const struct bt_gatt_attr *attr, uint16_t handle,
			       void *user_data)
{
	struct bt_conn *conn = user_data;
	struct _bt_gatt_ccc *ccc;
	bool value_used;
	size_t i;

	/* Check attribute user_data must be of type struct _bt_gatt_ccc */
	if (attr->write != bt_gatt_attr_write_ccc) {
		return BT_GATT_ITER_CONTINUE;
	}

	ccc = attr->user_data;

	/* If already disabled skip */
	if (!ccc->value) {
		return BT_GATT_ITER_CONTINUE;
	}

	/* Checking if all values are disabled */
	value_used = false;

	for (i = 0; i < ARRAY_SIZE(ccc->cfg); i++) {
		struct bt_gatt_ccc_cfg *cfg = &ccc->cfg[i];

		/* Ignore configurations with disabled value */
		if (!cfg->value) {
			continue;
		}

		if (!bt_conn_is_peer_addr_le(conn, cfg->id, &cfg->peer)) {
			struct bt_conn *tmp;

			/* Skip if there is another peer connected */
			tmp = bt_conn_lookup_addr_le(cfg->id, &cfg->peer);
			if (tmp) {
				if (tmp->state == BT_CONN_CONNECTED) {
					value_used = true;
				}

				bt_conn_unref(tmp);
			}
		} else {
			/* Clear value if not paired */
			if (!bt_addr_le_is_bonded(conn->id, &conn->le.dst)) {
				if (ccc == &sc_ccc) {
					sc_clear(conn);
				}

				clear_ccc_cfg(cfg);
			} else {
				/* Update address in case it has changed */
				bt_addr_le_copy(&cfg->peer, &conn->le.dst);
			}
		}
	}

	/* If all values are now disabled, reset value while disconnected */
	if (!value_used) {
		ccc->value = 0U;
		if (ccc->cfg_changed) {
			ccc->cfg_changed(attr, ccc->value);
		}

		LOG_DBG("ccc %p reseted", ccc);
	}

	return BT_GATT_ITER_CONTINUE;
}

bool bt_gatt_is_subscribed(struct bt_conn *conn,
			   const struct bt_gatt_attr *attr, uint16_t ccc_type)
{
	const struct _bt_gatt_ccc *ccc;

	__ASSERT(conn, "invalid parameter\n");
	__ASSERT(attr, "invalid parameter\n");

	if (conn->state != BT_CONN_CONNECTED) {
		return false;
	}

	/* Check if attribute is a characteristic declaration */
	if (!bt_uuid_cmp(attr->uuid, BT_UUID_GATT_CHRC)) {
		struct bt_gatt_chrc *chrc = attr->user_data;

		if (!(chrc->properties &
			(BT_GATT_CHRC_NOTIFY | BT_GATT_CHRC_INDICATE))) {
			/* Characteristic doesn't support subscription */
			return false;
		}

		attr = bt_gatt_attr_next(attr);
		__ASSERT(attr, "No more attributes\n");
	}

	/* Check if attribute is a characteristic value */
	if (bt_uuid_cmp(attr->uuid, BT_UUID_GATT_CCC) != 0) {
		attr = bt_gatt_attr_next(attr);
		__ASSERT(attr, "No more attributes\n");
	}

	/* Find the CCC Descriptor */
	while (bt_uuid_cmp(attr->uuid, BT_UUID_GATT_CCC) &&
	       /* Also stop if we leave the current characteristic definition */
	       bt_uuid_cmp(attr->uuid, BT_UUID_GATT_CHRC) &&
	       bt_uuid_cmp(attr->uuid, BT_UUID_GATT_PRIMARY) &&
	       bt_uuid_cmp(attr->uuid, BT_UUID_GATT_SECONDARY)) {
		attr = bt_gatt_attr_next(attr);
		if (!attr) {
			return false;
		}
	}

	if (bt_uuid_cmp(attr->uuid, BT_UUID_GATT_CCC) != 0) {
		return false;
	}

	ccc = attr->user_data;

	/* Check if the connection is subscribed */
	for (size_t i = 0; i < BT_GATT_CCC_MAX; i++) {
		const struct bt_gatt_ccc_cfg *cfg = &ccc->cfg[i];

		if (bt_conn_is_peer_addr_le(conn, cfg->id, &cfg->peer) &&
		    (ccc_type & ccc->cfg[i].value)) {
			return true;
		}
	}

	return false;
}

static bool gatt_sub_is_empty(struct gatt_sub *sub)
{
	return sys_slist_is_empty(&sub->list);
}

/** @brief Free sub for reuse.
 */
static void gatt_sub_free(struct gatt_sub *sub)
{
	__ASSERT_NO_MSG(gatt_sub_is_empty(sub));
	bt_addr_le_copy(&sub->peer, BT_ADDR_LE_ANY);
}

static void gatt_sub_remove(struct bt_conn *conn, struct gatt_sub *sub,
			    sys_snode_t *prev,
			    struct bt_gatt_subscribe_params *params)
{
	if (params) {
		/* Remove subscription from the list*/
		sys_slist_remove(&sub->list, prev, &params->node);
		/* Notify removal */
		params->notify(conn, params, NULL, 0);
	}

	if (gatt_sub_is_empty(sub)) {
		gatt_sub_free(sub);
	}
}

#if defined(CONFIG_BT_GATT_CLIENT)
static struct gatt_sub *gatt_sub_find(struct bt_conn *conn)
{
	for (int i = 0; i < ARRAY_SIZE(subscriptions); i++) {
		struct gatt_sub *sub = &subscriptions[i];

		if (!conn) {
			if (bt_addr_le_eq(&sub->peer, BT_ADDR_LE_ANY)) {
				return sub;
			}
		} else if (bt_conn_is_peer_addr_le(conn, sub->id, &sub->peer)) {
			return sub;
		}
	}

	return NULL;
}

static struct gatt_sub *gatt_sub_add(struct bt_conn *conn)
{
	struct gatt_sub *sub;

	sub = gatt_sub_find(conn);
	if (!sub) {
		sub = gatt_sub_find(NULL);
		if (sub) {
			bt_addr_le_copy(&sub->peer, &conn->le.dst);
			sub->id = conn->id;
		}
	}

	return sub;
}

static struct gatt_sub *gatt_sub_find_by_addr(uint8_t id,
					      const bt_addr_le_t *addr)
{
	for (int i = 0; i < ARRAY_SIZE(subscriptions); i++) {
		struct gatt_sub *sub = &subscriptions[i];

		if (id == sub->id && bt_addr_le_eq(&sub->peer, addr)) {
			return sub;
		}
	}

	return NULL;
}

static struct gatt_sub *gatt_sub_add_by_addr(uint8_t id,
					     const bt_addr_le_t *addr)
{
	struct gatt_sub *sub;

	sub = gatt_sub_find_by_addr(id, addr);
	if (!sub) {
		sub = gatt_sub_find(NULL);
		if (sub) {
			bt_addr_le_copy(&sub->peer, addr);
			sub->id = id;
		}
	}

	return sub;
}

static bool check_subscribe_security_level(struct bt_conn *conn,
					   const struct bt_gatt_subscribe_params *params)
{
#if defined(CONFIG_BT_SMP)
	return conn->sec_level >= params->min_security;
#endif
	return true;
}

void bt_gatt_notification(struct bt_conn *conn, uint16_t handle,
			  const void *data, uint16_t length)
{
	struct bt_gatt_subscribe_params *params, *tmp;
	struct gatt_sub *sub;

	LOG_DBG("handle 0x%04x length %u", handle, length);

	sub = gatt_sub_find(conn);
	if (!sub) {
		return;
	}

	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&sub->list, params, tmp, node) {
		if (handle != params->value_handle) {
			continue;
		}

		if (check_subscribe_security_level(conn, params)) {
			if (params->notify(conn, params, data, length) ==
			    BT_GATT_ITER_STOP) {
				bt_gatt_unsubscribe(conn, params);
			}
		}
	}
}

void bt_gatt_mult_notification(struct bt_conn *conn, const void *data,
			       uint16_t length)
{
	struct bt_gatt_subscribe_params *params, *tmp;
	const struct bt_att_notify_mult *nfy;
	struct net_buf_simple buf;
	struct gatt_sub *sub;

	LOG_DBG("length %u", length);

	sub = gatt_sub_find(conn);
	if (!sub) {
		return;
	}

	/* This is fine since there no write operation to the buffer.  */
	net_buf_simple_init_with_data(&buf, (void *)data, length);

	while (buf.len > sizeof(*nfy)) {
		uint16_t handle;
		uint16_t len;

		nfy = net_buf_simple_pull_mem(&buf, sizeof(*nfy));
		handle = sys_cpu_to_le16(nfy->handle);
		len = sys_cpu_to_le16(nfy->len);

		LOG_DBG("handle 0x%02x len %u", handle, len);

		if (len > buf.len) {
			LOG_ERR("Invalid data len %u > %u", len, length);
			return;
		}

		SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&sub->list, params, tmp,
						  node) {
			if (handle != params->value_handle) {
				continue;
			}

			if (check_subscribe_security_level(conn, params)) {
				if (params->notify(conn, params, nfy->value, len) ==
					BT_GATT_ITER_STOP) {
					bt_gatt_unsubscribe(conn, params);
				}
			}
		}

		net_buf_simple_pull_mem(&buf, len);
	}
}

static void gatt_sub_update(struct bt_conn *conn, struct gatt_sub *sub)
{
	if (sub->peer.type == BT_ADDR_LE_PUBLIC) {
		return;
	}

	/* Update address */
	bt_addr_le_copy(&sub->peer, &conn->le.dst);
}

static void remove_subscriptions(struct bt_conn *conn)
{
	struct gatt_sub *sub;
	struct bt_gatt_subscribe_params *params, *tmp;
	sys_snode_t *prev = NULL;

	sub = gatt_sub_find(conn);
	if (!sub) {
		return;
	}

	/* Lookup existing subscriptions */
	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&sub->list, params, tmp, node) {
		atomic_clear_bit(params->flags, BT_GATT_SUBSCRIBE_FLAG_SENT);

		if (!bt_addr_le_is_bonded(conn->id, &conn->le.dst) ||
		    (atomic_test_bit(params->flags,
				     BT_GATT_SUBSCRIBE_FLAG_VOLATILE))) {
			/* Remove subscription */
			params->value = 0U;
			gatt_sub_remove(conn, sub, prev, params);
		} else {
			gatt_sub_update(conn, sub);
			prev = &params->node;
		}
	}
}

static void gatt_mtu_rsp(struct bt_conn *conn, uint8_t err, const void *pdu,
			 uint16_t length, void *user_data)
{
	struct bt_gatt_exchange_params *params = user_data;

	params->func(conn, err, params);
}

static int gatt_exchange_mtu_encode(struct net_buf *buf, size_t len,
				    void *user_data)
{
	struct bt_att_exchange_mtu_req *req;
	uint16_t mtu;

	mtu = BT_LOCAL_ATT_MTU_UATT;

	LOG_DBG("Client MTU %u", mtu);

	req = net_buf_add(buf, sizeof(*req));
	req->mtu = sys_cpu_to_le16(mtu);

	return 0;
}

int bt_gatt_exchange_mtu(struct bt_conn *conn,
			 struct bt_gatt_exchange_params *params)
{
	int err;

	__ASSERT(conn, "invalid parameter\n");
	__ASSERT(params && params->func, "invalid parameters\n");

	if (conn->state != BT_CONN_CONNECTED) {
		return -ENOTCONN;
	}

	/* This request shall only be sent once during a connection by the client. */
	if (atomic_test_and_set_bit(conn->flags, BT_CONN_ATT_MTU_EXCHANGED)) {
		return -EALREADY;
	}

	err = gatt_req_send(conn, gatt_mtu_rsp, params,
			    gatt_exchange_mtu_encode, BT_ATT_OP_MTU_REQ,
			    sizeof(struct bt_att_exchange_mtu_req),
			    BT_ATT_CHAN_OPT_UNENHANCED_ONLY);
	if (err) {
		atomic_clear_bit(conn->flags, BT_CONN_ATT_MTU_EXCHANGED);
	}

	return err;
}

static void gatt_discover_next(struct bt_conn *conn, uint16_t last_handle,
			       struct bt_gatt_discover_params *params)
{
	/* Skip if last_handle is not set */
	if (!last_handle)
		goto discover;

	/* Continue from the last found handle */
	params->start_handle = last_handle;
	if (params->start_handle < UINT16_MAX) {
		params->start_handle++;
	} else {
		goto done;
	}

	/* Stop if over the range or the requests */
	if (params->start_handle > params->end_handle) {
		goto done;
	}

discover:
	/* Discover next range */
	if (!bt_gatt_discover(conn, params)) {
		return;
	}

done:
	params->func(conn, NULL, params);
}

static void gatt_find_type_rsp(struct bt_conn *conn, uint8_t err,
			       const void *pdu, uint16_t length,
			       void *user_data)
{
	const struct bt_att_handle_group *rsp = pdu;
	struct bt_gatt_discover_params *params = user_data;
	uint8_t count;
	uint16_t end_handle = 0U, start_handle;

	LOG_DBG("err 0x%02x", err);

	if (err || (length % sizeof(struct bt_att_handle_group) != 0)) {
		goto done;
	}

	count = length / sizeof(struct bt_att_handle_group);

	/* Parse attributes found */
	for (uint8_t i = 0U; i < count; i++) {
		struct bt_uuid_16 uuid_svc;
		struct bt_gatt_attr attr;
		struct bt_gatt_service_val value;

		start_handle = sys_le16_to_cpu(rsp[i].start_handle);
		end_handle = sys_le16_to_cpu(rsp[i].end_handle);

		LOG_DBG("start_handle 0x%04x end_handle 0x%04x", start_handle, end_handle);

		uuid_svc.uuid.type = BT_UUID_TYPE_16;
		if (params->type == BT_GATT_DISCOVER_PRIMARY) {
			uuid_svc.val = BT_UUID_GATT_PRIMARY_VAL;
		} else {
			uuid_svc.val = BT_UUID_GATT_SECONDARY_VAL;
		}

		value.end_handle = end_handle;
		value.uuid = params->uuid;

		attr = (struct bt_gatt_attr) {
			.uuid = &uuid_svc.uuid,
			.user_data = &value,
			.handle = start_handle,
		};

		if (params->func(conn, &attr, params) == BT_GATT_ITER_STOP) {
			return;
		}
	}

	gatt_discover_next(conn, end_handle, params);

	return;
done:
	params->func(conn, NULL, params);
}

static int gatt_find_type_encode(struct net_buf *buf, size_t len,
				 void *user_data)
{
	struct bt_gatt_discover_params *params = user_data;
	struct bt_att_find_type_req *req;
	uint16_t uuid_val;

	req = net_buf_add(buf, sizeof(*req));
	req->start_handle = sys_cpu_to_le16(params->start_handle);
	req->end_handle = sys_cpu_to_le16(params->end_handle);

	if (params->type == BT_GATT_DISCOVER_PRIMARY) {
		uuid_val = BT_UUID_GATT_PRIMARY_VAL;
	} else {
		uuid_val = BT_UUID_GATT_SECONDARY_VAL;
	}

	req->type = sys_cpu_to_le16(uuid_val);

	LOG_DBG("uuid %s start_handle 0x%04x end_handle 0x%04x", bt_uuid_str(params->uuid),
		params->start_handle, params->end_handle);

	switch (params->uuid->type) {
	case BT_UUID_TYPE_16:
		net_buf_add_le16(buf, BT_UUID_16(params->uuid)->val);
		break;
	case BT_UUID_TYPE_128:
		net_buf_add_mem(buf, BT_UUID_128(params->uuid)->val, 16);
		break;
	}

	return 0;
}

static int gatt_find_type(struct bt_conn *conn,
			  struct bt_gatt_discover_params *params)
{
	size_t len;

	len = sizeof(struct bt_att_find_type_req);

	switch (params->uuid->type) {
	case BT_UUID_TYPE_16:
		len += BT_UUID_SIZE_16;
		break;
	case BT_UUID_TYPE_128:
		len += BT_UUID_SIZE_128;
		break;
	default:
		LOG_ERR("Unknown UUID type %u", params->uuid->type);
		return -EINVAL;
	}

	return gatt_req_send(conn, gatt_find_type_rsp, params,
			     gatt_find_type_encode, BT_ATT_OP_FIND_TYPE_REQ,
			     len, BT_ATT_CHAN_OPT(params));
}

static void read_included_uuid_cb(struct bt_conn *conn, uint8_t err,
				  const void *pdu, uint16_t length,
				  void *user_data)
{
	struct bt_gatt_discover_params *params = user_data;
	struct bt_gatt_include value;
	struct bt_gatt_attr attr;
	uint16_t handle;
	union {
		struct bt_uuid uuid;
		struct bt_uuid_128 u128;
	} u;

	if (length != 16U) {
		LOG_ERR("Invalid data len %u", length);
		params->func(conn, NULL, params);
		return;
	}

	handle = params->_included.attr_handle;
	value.start_handle = params->_included.start_handle;
	value.end_handle = params->_included.end_handle;
	value.uuid = &u.uuid;
	u.uuid.type = BT_UUID_TYPE_128;
	memcpy(u.u128.val, pdu, length);

	LOG_DBG("handle 0x%04x uuid %s start_handle 0x%04x "
	       "end_handle 0x%04x\n", params->_included.attr_handle,
	       bt_uuid_str(&u.uuid), value.start_handle, value.end_handle);

	/* Skip if UUID is set but doesn't match */
	if (params->uuid && bt_uuid_cmp(&u.uuid, params->uuid)) {
		goto next;
	}

	attr = (struct bt_gatt_attr) {
		.uuid = BT_UUID_GATT_INCLUDE,
		.user_data = &value,
		.handle = handle,
	};

	if (params->func(conn, &attr, params) == BT_GATT_ITER_STOP) {
		return;
	}
next:
	gatt_discover_next(conn, params->start_handle, params);

	return;
}

static int read_included_uuid_encode(struct net_buf *buf, size_t len,
				     void *user_data)
{
	struct bt_gatt_discover_params *params = user_data;
	struct bt_att_read_req *req;

	req = net_buf_add(buf, sizeof(*req));
	req->handle = sys_cpu_to_le16(params->_included.start_handle);

	return 0;
}

static int read_included_uuid(struct bt_conn *conn,
			      struct bt_gatt_discover_params *params)
{
	LOG_DBG("handle 0x%04x", params->_included.start_handle);

	return gatt_req_send(conn, read_included_uuid_cb, params,
			     read_included_uuid_encode, BT_ATT_OP_READ_REQ,
			     sizeof(struct bt_att_read_req), BT_ATT_CHAN_OPT(params));
}

static uint16_t parse_include(struct bt_conn *conn, const void *pdu,
			   struct bt_gatt_discover_params *params,
			   uint16_t length)
{
	const struct bt_att_read_type_rsp *rsp = pdu;
	uint16_t handle = 0U;
	struct bt_gatt_include value;
	union {
		struct bt_uuid uuid;
		struct bt_uuid_16 u16;
		struct bt_uuid_128 u128;
	} u;

	/* Data can be either in UUID16 or UUID128 */
	switch (rsp->len) {
	case 8: /* UUID16 */
		u.uuid.type = BT_UUID_TYPE_16;
		break;
	case 6: /* UUID128 */
		/* BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part G] page 550
		 * To get the included service UUID when the included service
		 * uses a 128-bit UUID, the Read Request is used.
		 */
		u.uuid.type = BT_UUID_TYPE_128;
		break;
	default:
		LOG_ERR("Invalid data len %u", rsp->len);
		goto done;
	}

	/* Parse include found */
	for (length--, pdu = rsp->data; length >= rsp->len;
	     length -= rsp->len, pdu = (const uint8_t *)pdu + rsp->len) {
		struct bt_gatt_attr attr;
		const struct bt_att_data *data = pdu;
		struct gatt_incl *incl = (void *)data->value;

		handle = sys_le16_to_cpu(data->handle);
		/* Handle 0 is invalid */
		if (!handle) {
			goto done;
		}

		/* Convert include data, bt_gatt_incl and gatt_incl
		 * have different formats so the conversion have to be done
		 * field by field.
		 */
		value.start_handle = sys_le16_to_cpu(incl->start_handle);
		value.end_handle = sys_le16_to_cpu(incl->end_handle);

		switch (u.uuid.type) {
		case BT_UUID_TYPE_16:
			value.uuid = &u.uuid;
			u.u16.val = sys_le16_to_cpu(incl->uuid16);
			break;
		case BT_UUID_TYPE_128:
			params->_included.attr_handle = handle;
			params->_included.start_handle = value.start_handle;
			params->_included.end_handle = value.end_handle;

			return read_included_uuid(conn, params);
		}

		LOG_DBG("handle 0x%04x uuid %s start_handle 0x%04x "
		       "end_handle 0x%04x\n", handle, bt_uuid_str(&u.uuid),
		       value.start_handle, value.end_handle);

		/* Skip if UUID is set but doesn't match */
		if (params->uuid && bt_uuid_cmp(&u.uuid, params->uuid)) {
			continue;
		}

		attr = (struct bt_gatt_attr) {
			.uuid = BT_UUID_GATT_INCLUDE,
			.user_data = &value,
			.handle = handle,
		};

		if (params->func(conn, &attr, params) == BT_GATT_ITER_STOP) {
			return 0;
		}
	}

	/* Whole PDU read without error */
	if (length == 0U && handle) {
		return handle;
	}

done:
	params->func(conn, NULL, params);
	return 0;
}

static uint16_t parse_characteristic(struct bt_conn *conn, const void *pdu,
				  struct bt_gatt_discover_params *params,
				  uint16_t length)
{
	const struct bt_att_read_type_rsp *rsp = pdu;
	uint16_t handle = 0U;
	union {
		struct bt_uuid uuid;
		struct bt_uuid_16 u16;
		struct bt_uuid_128 u128;
	} u;

	/* Data can be either in UUID16 or UUID128 */
	switch (rsp->len) {
	case 7: /* UUID16 */
		u.uuid.type = BT_UUID_TYPE_16;
		break;
	case 21: /* UUID128 */
		u.uuid.type = BT_UUID_TYPE_128;
		break;
	default:
		LOG_ERR("Invalid data len %u", rsp->len);
		goto done;
	}

	/* Parse characteristics found */
	for (length--, pdu = rsp->data; length >= rsp->len;
	     length -= rsp->len, pdu = (const uint8_t *)pdu + rsp->len) {
		struct bt_gatt_attr attr;
		struct bt_gatt_chrc value;
		const struct bt_att_data *data = pdu;
		struct gatt_chrc *chrc = (void *)data->value;

		handle = sys_le16_to_cpu(data->handle);
		/* Handle 0 is invalid */
		if (!handle) {
			goto done;
		}

		switch (u.uuid.type) {
		case BT_UUID_TYPE_16:
			u.u16.val = sys_le16_to_cpu(chrc->uuid16);
			break;
		case BT_UUID_TYPE_128:
			memcpy(u.u128.val, chrc->uuid, sizeof(chrc->uuid));
			break;
		}

		LOG_DBG("handle 0x%04x uuid %s properties 0x%02x", handle, bt_uuid_str(&u.uuid),
			chrc->properties);

		/* Skip if UUID is set but doesn't match */
		if (params->uuid && bt_uuid_cmp(&u.uuid, params->uuid)) {
			continue;
		}

		value = (struct bt_gatt_chrc)BT_GATT_CHRC_INIT(
			&u.uuid, sys_le16_to_cpu(chrc->value_handle),
			chrc->properties);

		attr = (struct bt_gatt_attr) {
			.uuid = BT_UUID_GATT_CHRC,
			.user_data = &value,
			.handle = handle,
		};

		if (params->func(conn, &attr, params) == BT_GATT_ITER_STOP) {
			return 0;
		}
	}

	/* Whole PDU read without error */
	if (length == 0U && handle) {
		return handle;
	}

done:
	params->func(conn, NULL, params);
	return 0;
}

static uint16_t parse_read_std_char_desc(struct bt_conn *conn, const void *pdu,
					 struct bt_gatt_discover_params *params,
					 uint16_t length)
{
	const struct bt_att_read_type_rsp *rsp = pdu;
	uint16_t handle = 0U;
	uint16_t uuid_val;

	if (params->uuid->type != BT_UUID_TYPE_16) {
		goto done;
	}

	uuid_val = BT_UUID_16(params->uuid)->val;

	/* Parse characteristics found */
	for (length--, pdu = rsp->data; length >= rsp->len;
	     length -= rsp->len, pdu = (const uint8_t *)pdu + rsp->len) {
		union {
			struct bt_gatt_ccc ccc;
			struct bt_gatt_cpf cpf;
			struct bt_gatt_cep cep;
			struct bt_gatt_scc scc;
		} value;
		const struct bt_att_data *data = pdu;
		struct bt_gatt_attr attr;

		handle = sys_le16_to_cpu(data->handle);
		/* Handle 0 is invalid */
		if (!handle) {
			goto done;
		}

		switch (uuid_val) {
		case BT_UUID_GATT_CEP_VAL:
			value.cep.properties = sys_get_le16(data->value);
			break;
		case BT_UUID_GATT_CCC_VAL:
			value.ccc.flags = sys_get_le16(data->value);
			break;
		case BT_UUID_GATT_SCC_VAL:
			value.scc.flags = sys_get_le16(data->value);
			break;
		case BT_UUID_GATT_CPF_VAL:
		{
			struct gatt_cpf *cpf = (struct gatt_cpf *)data->value;

			value.cpf.format = cpf->format;
			value.cpf.exponent = cpf->exponent;
			value.cpf.unit = sys_le16_to_cpu(cpf->unit);
			value.cpf.name_space = cpf->name_space;
			value.cpf.description = sys_le16_to_cpu(cpf->description);
			break;
		}
		default:
			goto done;
		}

		attr = (struct bt_gatt_attr) {
			.uuid = params->uuid,
			.user_data = &value,
			.handle = handle,
		};

		if (params->func(conn, &attr, params) == BT_GATT_ITER_STOP) {
			return 0;
		}
	}

	/* Whole PDU read without error */
	if (length == 0U && handle) {
		return handle;
	}

done:
	params->func(conn, NULL, params);
	return 0;
}

static void gatt_read_type_rsp(struct bt_conn *conn, uint8_t err,
			       const void *pdu, uint16_t length,
			       void *user_data)
{
	struct bt_gatt_discover_params *params = user_data;
	uint16_t handle;

	LOG_DBG("err 0x%02x", err);

	if (err) {
		params->func(conn, NULL, params);
		return;
	}

	if (params->type == BT_GATT_DISCOVER_INCLUDE) {
		handle = parse_include(conn, pdu, params, length);
	} else if (params->type == BT_GATT_DISCOVER_CHARACTERISTIC) {
		handle = parse_characteristic(conn, pdu, params, length);
	} else {
		handle = parse_read_std_char_desc(conn, pdu, params, length);
	}

	if (!handle) {
		return;
	}

	gatt_discover_next(conn, handle, params);
}

static int gatt_read_type_encode(struct net_buf *buf, size_t len,
				 void *user_data)
{
	struct bt_gatt_discover_params *params = user_data;
	struct bt_att_read_type_req *req;

	req = net_buf_add(buf, sizeof(*req));
	req->start_handle = sys_cpu_to_le16(params->start_handle);
	req->end_handle = sys_cpu_to_le16(params->end_handle);

	switch (params->type) {
	case BT_GATT_DISCOVER_INCLUDE:
		net_buf_add_le16(buf, BT_UUID_GATT_INCLUDE_VAL);
		break;
	case BT_GATT_DISCOVER_CHARACTERISTIC:
		net_buf_add_le16(buf, BT_UUID_GATT_CHRC_VAL);
		break;
	default:
		/* Only 16-bit UUIDs supported */
		net_buf_add_le16(buf, BT_UUID_16(params->uuid)->val);
		break;
	}

	return 0;
}

static int gatt_read_type(struct bt_conn *conn,
			  struct bt_gatt_discover_params *params)
{
	LOG_DBG("start_handle 0x%04x end_handle 0x%04x", params->start_handle, params->end_handle);

	return gatt_req_send(conn, gatt_read_type_rsp, params,
			     gatt_read_type_encode, BT_ATT_OP_READ_TYPE_REQ,
			     sizeof(struct bt_att_read_type_req), BT_ATT_CHAN_OPT(params));
}

static uint16_t parse_service(struct bt_conn *conn, const void *pdu,
				  struct bt_gatt_discover_params *params,
				  uint16_t length)
{
	const struct bt_att_read_group_rsp *rsp = pdu;
	uint16_t start_handle, end_handle = 0U;
	union {
		struct bt_uuid uuid;
		struct bt_uuid_16 u16;
		struct bt_uuid_128 u128;
	} u;

	/* Data can be either in UUID16 or UUID128 */
	switch (rsp->len) {
	case 6: /* UUID16 */
		u.uuid.type = BT_UUID_TYPE_16;
		break;
	case 20: /* UUID128 */
		u.uuid.type = BT_UUID_TYPE_128;
		break;
	default:
		LOG_ERR("Invalid data len %u", rsp->len);
		goto done;
	}

	/* Parse services found */
	for (length--, pdu = rsp->data; length >= rsp->len;
	     length -= rsp->len, pdu = (const uint8_t *)pdu + rsp->len) {
		struct bt_uuid_16 uuid_svc;
		struct bt_gatt_attr attr = {};
		struct bt_gatt_service_val value;
		const struct bt_att_group_data *data = pdu;

		start_handle = sys_le16_to_cpu(data->start_handle);
		if (!start_handle) {
			goto done;
		}

		end_handle = sys_le16_to_cpu(data->end_handle);
		if (!end_handle || end_handle < start_handle) {
			goto done;
		}

		switch (u.uuid.type) {
		case BT_UUID_TYPE_16:
			memcpy(&u.u16.val, data->value, sizeof(u.u16.val));
			u.u16.val = sys_le16_to_cpu(u.u16.val);
			break;
		case BT_UUID_TYPE_128:
			memcpy(u.u128.val, data->value, sizeof(u.u128.val));
			break;
		}

		LOG_DBG("start_handle 0x%04x end_handle 0x%04x uuid %s", start_handle, end_handle,
			bt_uuid_str(&u.uuid));

		uuid_svc.uuid.type = BT_UUID_TYPE_16;
		if (params->type == BT_GATT_DISCOVER_PRIMARY) {
			uuid_svc.val = BT_UUID_GATT_PRIMARY_VAL;
		} else {
			uuid_svc.val = BT_UUID_GATT_SECONDARY_VAL;
		}

		value.end_handle = end_handle;
		value.uuid = &u.uuid;

		attr.uuid = &uuid_svc.uuid;
		attr.handle = start_handle;
		attr.user_data = &value;

		if (params->func(conn, &attr, params) == BT_GATT_ITER_STOP) {
			return 0;
		}
	}

	/* Whole PDU read without error */
	if (length == 0U && end_handle) {
		return end_handle;
	}

done:
	params->func(conn, NULL, params);
	return 0;
}

static void gatt_read_group_rsp(struct bt_conn *conn, uint8_t err,
				const void *pdu, uint16_t length,
				void *user_data)
{
	struct bt_gatt_discover_params *params = user_data;
	uint16_t handle;

	LOG_DBG("err 0x%02x", err);

	if (err) {
		params->func(conn, NULL, params);
		return;
	}

	handle = parse_service(conn, pdu, params, length);
	if (!handle) {
		return;
	}

	gatt_discover_next(conn, handle, params);
}

static int gatt_read_group_encode(struct net_buf *buf, size_t len,
				  void *user_data)
{
	struct bt_gatt_discover_params *params = user_data;
	struct bt_att_read_group_req *req;

	req = net_buf_add(buf, sizeof(*req));
	req->start_handle = sys_cpu_to_le16(params->start_handle);
	req->end_handle = sys_cpu_to_le16(params->end_handle);

	if (params->type == BT_GATT_DISCOVER_PRIMARY) {
		net_buf_add_le16(buf, BT_UUID_GATT_PRIMARY_VAL);
	} else {
		net_buf_add_le16(buf, BT_UUID_GATT_SECONDARY_VAL);
	}

	return 0;
}

static int gatt_read_group(struct bt_conn *conn,
			   struct bt_gatt_discover_params *params)
{
	LOG_DBG("start_handle 0x%04x end_handle 0x%04x", params->start_handle, params->end_handle);

	return gatt_req_send(conn, gatt_read_group_rsp, params,
			     gatt_read_group_encode,
			     BT_ATT_OP_READ_GROUP_REQ,
			     sizeof(struct bt_att_read_group_req),
			     BT_ATT_CHAN_OPT(params));
}

static void gatt_find_info_rsp(struct bt_conn *conn, uint8_t err,
			       const void *pdu, uint16_t length,
			       void *user_data)
{
	const struct bt_att_find_info_rsp *rsp = pdu;
	struct bt_gatt_discover_params *params = user_data;
	uint16_t handle = 0U;
	uint16_t len;
	union {
		const struct bt_att_info_16 *i16;
		const struct bt_att_info_128 *i128;
	} info;
	union {
		struct bt_uuid uuid;
		struct bt_uuid_16 u16;
		struct bt_uuid_128 u128;
	} u;
	int i;
	bool skip = false;

	LOG_DBG("err 0x%02x", err);

	if (err) {
		goto done;
	}

	/* Data can be either in UUID16 or UUID128 */
	switch (rsp->format) {
	case BT_ATT_INFO_16:
		u.uuid.type = BT_UUID_TYPE_16;
		len = sizeof(*info.i16);
		break;
	case BT_ATT_INFO_128:
		u.uuid.type = BT_UUID_TYPE_128;
		len = sizeof(*info.i128);
		break;
	default:
		LOG_ERR("Invalid format %u", rsp->format);
		goto done;
	}

	length--;

	/* Check if there is a least one descriptor in the response */
	if (length < len) {
		goto done;
	}

	/* Parse descriptors found */
	for (i = length / len, pdu = rsp->info; i != 0;
	     i--, pdu = (const uint8_t *)pdu + len) {
		struct bt_gatt_attr attr;

		info.i16 = pdu;
		handle = sys_le16_to_cpu(info.i16->handle);

		if (skip) {
			skip = false;
			continue;
		}

		switch (u.uuid.type) {
		case BT_UUID_TYPE_16:
			u.u16.val = sys_le16_to_cpu(info.i16->uuid);
			break;
		case BT_UUID_TYPE_128:
			memcpy(u.u128.val, info.i128->uuid, 16);
			break;
		}

		LOG_DBG("handle 0x%04x uuid %s", handle, bt_uuid_str(&u.uuid));

		/* Skip if UUID is set but doesn't match */
		if (params->uuid && bt_uuid_cmp(&u.uuid, params->uuid)) {
			continue;
		}

		if (params->type == BT_GATT_DISCOVER_DESCRIPTOR) {
			/* Skip attributes that are not considered
			 * descriptors.
			 */
			if (!bt_uuid_cmp(&u.uuid, BT_UUID_GATT_PRIMARY) ||
			    !bt_uuid_cmp(&u.uuid, BT_UUID_GATT_SECONDARY) ||
			    !bt_uuid_cmp(&u.uuid, BT_UUID_GATT_INCLUDE)) {
				continue;
			}

			/* If Characteristic Declaration skip ahead as the next
			 * entry must be its value.
			 */
			if (!bt_uuid_cmp(&u.uuid, BT_UUID_GATT_CHRC)) {
				skip = true;
				continue;
			}
		}

		/* No user_data in this case */
		attr = (struct bt_gatt_attr) {
			.uuid = &u.uuid,
			.handle = handle,
		};

		if (params->func(conn, &attr, params) == BT_GATT_ITER_STOP) {
			return;
		}
	}

	gatt_discover_next(conn, handle, params);

	return;

done:
	params->func(conn, NULL, params);
}

static int gatt_find_info_encode(struct net_buf *buf, size_t len,
				 void *user_data)
{
	struct bt_gatt_discover_params *params = user_data;
	struct bt_att_find_info_req *req;

	req = net_buf_add(buf, sizeof(*req));
	req->start_handle = sys_cpu_to_le16(params->start_handle);
	req->end_handle = sys_cpu_to_le16(params->end_handle);

	return 0;
}

static int gatt_find_info(struct bt_conn *conn,
			  struct bt_gatt_discover_params *params)
{
	LOG_DBG("start_handle 0x%04x end_handle 0x%04x", params->start_handle, params->end_handle);

	return gatt_req_send(conn, gatt_find_info_rsp, params,
			     gatt_find_info_encode, BT_ATT_OP_FIND_INFO_REQ,
			     sizeof(struct bt_att_find_info_req),
			     BT_ATT_CHAN_OPT(params));
}

int bt_gatt_discover(struct bt_conn *conn,
		     struct bt_gatt_discover_params *params)
{
	__ASSERT(conn, "invalid parameters\n");
	__ASSERT(params && params->func, "invalid parameters\n");
	__ASSERT((params->start_handle && params->end_handle),
		 "invalid parameters\n");
	__ASSERT((params->start_handle <= params->end_handle),
		 "invalid parameters\n");

	if (conn->state != BT_CONN_CONNECTED) {
		return -ENOTCONN;
	}

	switch (params->type) {
	case BT_GATT_DISCOVER_PRIMARY:
	case BT_GATT_DISCOVER_SECONDARY:
		if (params->uuid) {
			return gatt_find_type(conn, params);
		}
		return gatt_read_group(conn, params);

	case BT_GATT_DISCOVER_STD_CHAR_DESC:
		if (!(params->uuid && params->uuid->type == BT_UUID_TYPE_16 &&
		      (!bt_uuid_cmp(params->uuid, BT_UUID_GATT_CEP) ||
		       !bt_uuid_cmp(params->uuid, BT_UUID_GATT_CCC) ||
		       !bt_uuid_cmp(params->uuid, BT_UUID_GATT_SCC) ||
		       !bt_uuid_cmp(params->uuid, BT_UUID_GATT_CPF)))) {
			return -EINVAL;
		}
		__fallthrough;
	case BT_GATT_DISCOVER_INCLUDE:
	case BT_GATT_DISCOVER_CHARACTERISTIC:
		return gatt_read_type(conn, params);
	case BT_GATT_DISCOVER_DESCRIPTOR:
		/* Only descriptors can be filtered */
		if (params->uuid &&
		    (!bt_uuid_cmp(params->uuid, BT_UUID_GATT_PRIMARY) ||
		     !bt_uuid_cmp(params->uuid, BT_UUID_GATT_SECONDARY) ||
		     !bt_uuid_cmp(params->uuid, BT_UUID_GATT_INCLUDE) ||
		     !bt_uuid_cmp(params->uuid, BT_UUID_GATT_CHRC))) {
			return -EINVAL;
		}
		__fallthrough;
	case BT_GATT_DISCOVER_ATTRIBUTE:
		return gatt_find_info(conn, params);
	default:
		LOG_ERR("Invalid discovery type: %u", params->type);
	}

	return -EINVAL;
}

static void parse_read_by_uuid(struct bt_conn *conn,
			       struct bt_gatt_read_params *params,
			       const void *pdu, uint16_t length)
{
	const struct bt_att_read_type_rsp *rsp = pdu;

	/* Parse values found */
	for (length--, pdu = rsp->data; length;
	     length -= rsp->len, pdu = (const uint8_t *)pdu + rsp->len) {
		const struct bt_att_data *data = pdu;
		uint16_t handle;
		uint16_t len;

		handle = sys_le16_to_cpu(data->handle);

		/* Handle 0 is invalid */
		if (!handle) {
			LOG_ERR("Invalid handle");
			return;
		}

		len = rsp->len > length ? length - 2 : rsp->len - 2;

		LOG_DBG("handle 0x%04x len %u value %u", handle, rsp->len, len);

		/* Update start_handle */
		params->by_uuid.start_handle = handle;

		if (params->func(conn, 0, params, data->value, len) ==
		    BT_GATT_ITER_STOP) {
			return;
		}

		/* Check if long attribute */
		if (rsp->len > length) {
			break;
		}

		/* Stop if it's the last handle to be read */
		if (params->by_uuid.start_handle == params->by_uuid.end_handle) {
			params->func(conn, 0, params, NULL, 0);
			return;
		}

		params->by_uuid.start_handle++;
	}

	/* Continue reading the attributes */
	if (bt_gatt_read(conn, params) < 0) {
		params->func(conn, BT_ATT_ERR_UNLIKELY, params, NULL, 0);
	}
}

static void gatt_read_rsp(struct bt_conn *conn, uint8_t err, const void *pdu,
			  uint16_t length, void *user_data)
{
	struct bt_gatt_read_params *params = user_data;

	LOG_DBG("err 0x%02x", err);

	if (err || !length) {
		params->func(conn, err, params, NULL, 0);
		return;
	}

	if (!params->handle_count) {
		parse_read_by_uuid(conn, params, pdu, length);
		return;
	}

	if (params->func(conn, 0, params, pdu, length) == BT_GATT_ITER_STOP) {
		return;
	}

	/*
	 * Core Spec 4.2, Vol. 3, Part G, 4.8.1
	 * If the Characteristic Value is greater than (ATT_MTU - 1) octets
	 * in length, the Read Long Characteristic Value procedure may be used
	 * if the rest of the Characteristic Value is required.
	 */
	if (length < (bt_att_get_mtu(conn) - 1)) {
		params->func(conn, 0, params, NULL, 0);
		return;
	}

	params->single.offset += length;

	/* Continue reading the attribute */
	if (bt_gatt_read(conn, params) < 0) {
		params->func(conn, BT_ATT_ERR_UNLIKELY, params, NULL, 0);
	}
}

static int gatt_read_blob_encode(struct net_buf *buf, size_t len,
				 void *user_data)
{
	struct bt_gatt_read_params *params = user_data;
	struct bt_att_read_blob_req *req;

	req = net_buf_add(buf, sizeof(*req));
	req->handle = sys_cpu_to_le16(params->single.handle);
	req->offset = sys_cpu_to_le16(params->single.offset);

	return 0;
}

static int gatt_read_blob(struct bt_conn *conn,
			  struct bt_gatt_read_params *params)
{
	LOG_DBG("handle 0x%04x offset 0x%04x", params->single.handle, params->single.offset);

	return gatt_req_send(conn, gatt_read_rsp, params,
			     gatt_read_blob_encode, BT_ATT_OP_READ_BLOB_REQ,
			     sizeof(struct bt_att_read_blob_req),
			     BT_ATT_CHAN_OPT(params));
}

static int gatt_read_uuid_encode(struct net_buf *buf, size_t len,
				 void *user_data)
{
	struct bt_gatt_read_params *params = user_data;
	struct bt_att_read_type_req *req;

	req = net_buf_add(buf, sizeof(*req));
	req->start_handle = sys_cpu_to_le16(params->by_uuid.start_handle);
	req->end_handle = sys_cpu_to_le16(params->by_uuid.end_handle);

	if (params->by_uuid.uuid->type == BT_UUID_TYPE_16) {
		net_buf_add_le16(buf, BT_UUID_16(params->by_uuid.uuid)->val);
	} else {
		net_buf_add_mem(buf, BT_UUID_128(params->by_uuid.uuid)->val, 16);
	}

	return 0;
}

static int gatt_read_uuid(struct bt_conn *conn,
			  struct bt_gatt_read_params *params)
{
	LOG_DBG("start_handle 0x%04x end_handle 0x%04x uuid %s", params->by_uuid.start_handle,
		params->by_uuid.end_handle, bt_uuid_str(params->by_uuid.uuid));

	return gatt_req_send(conn, gatt_read_rsp, params,
			     gatt_read_uuid_encode, BT_ATT_OP_READ_TYPE_REQ,
			     sizeof(struct bt_att_read_type_req),
			     BT_ATT_CHAN_OPT(params));
}

#if defined(CONFIG_BT_GATT_READ_MULTIPLE)
static void gatt_read_mult_rsp(struct bt_conn *conn, uint8_t err, const void *pdu,
			       uint16_t length, void *user_data)
{
	struct bt_gatt_read_params *params = user_data;

	LOG_DBG("err 0x%02x", err);

	if (err || !length) {
		params->func(conn, err, params, NULL, 0);
		return;
	}

	params->func(conn, 0, params, pdu, length);

	/* mark read as complete since read multiple is single response */
	params->func(conn, 0, params, NULL, 0);
}

static int gatt_read_mult_encode(struct net_buf *buf, size_t len,
				 void *user_data)
{
	struct bt_gatt_read_params *params = user_data;
	uint8_t i;

	for (i = 0U; i < params->handle_count; i++) {
		net_buf_add_le16(buf, params->multiple.handles[i]);
	}

	return 0;
}

static int gatt_read_mult(struct bt_conn *conn,
			  struct bt_gatt_read_params *params)
{
	LOG_DBG("handle_count %zu", params->handle_count);

	return gatt_req_send(conn, gatt_read_mult_rsp, params,
			     gatt_read_mult_encode, BT_ATT_OP_READ_MULT_REQ,
			     params->handle_count * sizeof(uint16_t),
			     BT_ATT_CHAN_OPT(params));
}

#else
static int gatt_read_mult(struct bt_conn *conn,
			      struct bt_gatt_read_params *params)
{
	return -ENOTSUP;
}
#endif /* CONFIG_BT_GATT_READ_MULTIPLE */

#if defined(CONFIG_BT_GATT_READ_MULT_VAR_LEN)
static void gatt_read_mult_vl_rsp(struct bt_conn *conn, uint8_t err,
				  const void *pdu, uint16_t length,
				  void *user_data)
{
	struct bt_gatt_read_params *params = user_data;
	const struct bt_att_read_mult_vl_rsp *rsp;
	struct net_buf_simple buf;

	LOG_DBG("err 0x%02x", err);

	if (err || !length) {
		params->func(conn, err, params, NULL, 0);
		return;
	}

	net_buf_simple_init_with_data(&buf, (void *)pdu, length);

	while (buf.len >= sizeof(*rsp)) {
		uint16_t len;

		rsp = net_buf_simple_pull_mem(&buf, sizeof(*rsp));
		len = sys_le16_to_cpu(rsp->len);

		/* If a Length Value Tuple is truncated, then the amount of
		 * Attribute Value will be less than the value of the Value
		 * Length field.
		 */
		if (len > buf.len) {
			len = buf.len;
		}

		params->func(conn, 0, params, rsp->value, len);

		net_buf_simple_pull_mem(&buf, len);
	}

	/* mark read as complete since read multiple is single response */
	params->func(conn, 0, params, NULL, 0);
}

static int gatt_read_mult_vl_encode(struct net_buf *buf, size_t len,
				    void *user_data)
{
	struct bt_gatt_read_params *params = user_data;
	uint8_t i;

	for (i = 0U; i < params->handle_count; i++) {
		net_buf_add_le16(buf, params->multiple.handles[i]);
	}

	return 0;
}

static int gatt_read_mult_vl(struct bt_conn *conn,
			     struct bt_gatt_read_params *params)
{
	LOG_DBG("handle_count %zu", params->handle_count);

	return gatt_req_send(conn, gatt_read_mult_vl_rsp, params,
			     gatt_read_mult_vl_encode,
			     BT_ATT_OP_READ_MULT_VL_REQ,
			     params->handle_count * sizeof(uint16_t),
			     BT_ATT_CHAN_OPT(params));
}

#else
static int gatt_read_mult_vl(struct bt_conn *conn,
			     struct bt_gatt_read_params *params)
{
	return -ENOTSUP;
}
#endif /* CONFIG_BT_GATT_READ_MULT_VAR_LEN */

static int gatt_read_encode(struct net_buf *buf, size_t len, void *user_data)
{
	struct bt_gatt_read_params *params = user_data;
	struct bt_att_read_req *req;

	req = net_buf_add(buf, sizeof(*req));
	req->handle = sys_cpu_to_le16(params->single.handle);

	return 0;
}

int bt_gatt_read(struct bt_conn *conn, struct bt_gatt_read_params *params)
{
	__ASSERT(conn, "invalid parameters\n");
	__ASSERT(params && params->func, "invalid parameters\n");

	if (conn->state != BT_CONN_CONNECTED) {
		return -ENOTCONN;
	}

	if (params->handle_count == 0) {
		return gatt_read_uuid(conn, params);
	}

	if (params->handle_count > 1) {
		if (params->multiple.variable) {
			return gatt_read_mult_vl(conn, params);
		} else {
			return gatt_read_mult(conn, params);
		}
	}

	if (params->single.offset) {
		return gatt_read_blob(conn, params);
	}

	LOG_DBG("handle 0x%04x", params->single.handle);

	return gatt_req_send(conn, gatt_read_rsp, params, gatt_read_encode,
			     BT_ATT_OP_READ_REQ, sizeof(struct bt_att_read_req),
			     BT_ATT_CHAN_OPT(params));
}

static void gatt_write_rsp(struct bt_conn *conn, uint8_t err, const void *pdu,
			   uint16_t length, void *user_data)
{
	struct bt_gatt_write_params *params = user_data;

	LOG_DBG("err 0x%02x", err);

	params->func(conn, err, params);
}

int bt_gatt_write_without_response_cb(struct bt_conn *conn, uint16_t handle,
				      const void *data, uint16_t length, bool sign,
				      bt_gatt_complete_func_t func,
				      void *user_data)
{
	struct net_buf *buf;
	struct bt_att_write_cmd *cmd;
	size_t write;

	__ASSERT(conn, "invalid parameters\n");
	__ASSERT(handle, "invalid parameters\n");

	if (conn->state != BT_CONN_CONNECTED) {
		return -ENOTCONN;
	}

#if defined(CONFIG_BT_SMP)
	if (conn->encrypt) {
		/* Don't need to sign if already encrypted */
		sign = false;
	}
#endif

	if (sign) {
		buf = bt_att_create_pdu(conn, BT_ATT_OP_SIGNED_WRITE_CMD,
					sizeof(*cmd) + length + 12);
	} else {
		buf = bt_att_create_pdu(conn, BT_ATT_OP_WRITE_CMD,
					sizeof(*cmd) + length);
	}
	if (!buf) {
		return -ENOMEM;
	}

	cmd = net_buf_add(buf, sizeof(*cmd));
	cmd->handle = sys_cpu_to_le16(handle);

	write = net_buf_append_bytes(buf, length, data, K_NO_WAIT, NULL, NULL);
	if (write != length) {
		LOG_WRN("Unable to allocate length %u: only %zu written", length, write);
		net_buf_unref(buf);
		return -ENOMEM;
	}

	LOG_DBG("handle 0x%04x length %u", handle, length);

	bt_att_set_tx_meta_data(buf, func, user_data, BT_ATT_CHAN_OPT_NONE);

	return bt_att_send(conn, buf);
}

static int gatt_exec_encode(struct net_buf *buf, size_t len, void *user_data)
{
	struct bt_att_exec_write_req *req;

	req = net_buf_add(buf, sizeof(*req));
	req->flags = BT_ATT_FLAG_EXEC;

	return 0;
}

static int gatt_exec_write(struct bt_conn *conn,
			   struct bt_gatt_write_params *params)
{
	LOG_DBG("");

	return gatt_req_send(conn, gatt_write_rsp, params, gatt_exec_encode,
			     BT_ATT_OP_EXEC_WRITE_REQ,
			     sizeof(struct bt_att_exec_write_req),
			     BT_ATT_CHAN_OPT(params));
}

static int gatt_cancel_encode(struct net_buf *buf, size_t len, void *user_data)
{
	struct bt_att_exec_write_req *req;

	req = net_buf_add(buf, sizeof(*req));
	req->flags = BT_ATT_FLAG_CANCEL;

	return 0;
}

static int gatt_cancel_all_writes(struct bt_conn *conn,
			   struct bt_gatt_write_params *params)
{
	LOG_DBG("");

	return gatt_req_send(conn, gatt_write_rsp, params, gatt_cancel_encode,
			     BT_ATT_OP_EXEC_WRITE_REQ,
			     sizeof(struct bt_att_exec_write_req),
			     BT_ATT_CHAN_OPT(params));
}

static void gatt_prepare_write_rsp(struct bt_conn *conn, uint8_t err,
				   const void *pdu, uint16_t length,
				   void *user_data)
{
	struct bt_gatt_write_params *params = user_data;
	const struct bt_att_prepare_write_rsp *rsp = pdu;
	size_t len;
	bool data_valid;

	LOG_DBG("err 0x%02x", err);

	/* Don't continue in case of error */
	if (err) {
		params->func(conn, err, params);
		return;
	}

	len = length - sizeof(*rsp);
	if (len > params->length) {
		LOG_ERR("Incorrect length, canceling write");
		if (gatt_cancel_all_writes(conn, params)) {
			goto fail;
		}

		return;
	}

	data_valid = memcmp(params->data, rsp->value, len) == 0;
	if (params->offset != rsp->offset || !data_valid) {
		LOG_ERR("Incorrect offset or data in response, canceling write");
		if (gatt_cancel_all_writes(conn, params)) {
			goto fail;
		}

		return;
	}

	/* Update params */
	params->offset += len;
	params->data = (const uint8_t *)params->data + len;
	params->length -= len;

	/* If there is no more data execute */
	if (!params->length) {
		if (gatt_exec_write(conn, params)) {
			goto fail;
		}

		return;
	}

	/* Write next chunk */
	if (!bt_gatt_write(conn, params)) {
		/* Success */
		return;
	}

fail:
	/* Notify application that the write operation has failed */
	params->func(conn, BT_ATT_ERR_UNLIKELY, params);
}

static int gatt_prepare_write_encode(struct net_buf *buf, size_t len,
				     void *user_data)
{
	struct bt_gatt_write_params *params = user_data;
	struct bt_att_prepare_write_req *req;
	size_t write;

	req = net_buf_add(buf, sizeof(*req));
	req->handle = sys_cpu_to_le16(params->handle);
	req->offset = sys_cpu_to_le16(params->offset);

	write = net_buf_append_bytes(buf, len - sizeof(*req),
				     (uint8_t *)params->data, K_NO_WAIT, NULL,
				     NULL);
	if (write != (len - sizeof(*req))) {
		return -ENOMEM;
	}

	return 0;
}

static int gatt_prepare_write(struct bt_conn *conn,
			      struct bt_gatt_write_params *params)
{
	uint16_t len, req_len;

	req_len = sizeof(struct bt_att_prepare_write_req);

	len = bt_att_get_mtu(conn) - req_len - 1;
	len = MIN(params->length, len);
	len += req_len;

	return gatt_req_send(conn, gatt_prepare_write_rsp, params,
			     gatt_prepare_write_encode,
			     BT_ATT_OP_PREPARE_WRITE_REQ, len,
			     BT_ATT_CHAN_OPT(params));
}

static int gatt_write_encode(struct net_buf *buf, size_t len, void *user_data)
{
	struct bt_gatt_write_params *params = user_data;
	struct bt_att_write_req *req;
	size_t write;

	req = net_buf_add(buf, sizeof(*req));
	req->handle = sys_cpu_to_le16(params->handle);

	write = net_buf_append_bytes(buf, params->length, params->data,
				     K_NO_WAIT, NULL, NULL);
	if (write != params->length) {
		return -ENOMEM;
	}

	return 0;
}

int bt_gatt_write(struct bt_conn *conn, struct bt_gatt_write_params *params)
{
	size_t len;

	__ASSERT(conn, "invalid parameters\n");
	__ASSERT(params && params->func, "invalid parameters\n");
	__ASSERT(params->handle, "invalid parameters\n");

	if (conn->state != BT_CONN_CONNECTED) {
		return -ENOTCONN;
	}

	len = sizeof(struct bt_att_write_req) + params->length;

	/* Use Prepare Write if offset is set or Long Write is required */
	if (params->offset || len > (bt_att_get_mtu(conn) - 1)) {
		return gatt_prepare_write(conn, params);
	}

	LOG_DBG("handle 0x%04x length %u", params->handle, params->length);

	return gatt_req_send(conn, gatt_write_rsp, params, gatt_write_encode,
			     BT_ATT_OP_WRITE_REQ, len, BT_ATT_CHAN_OPT(params));
}

static void gatt_write_ccc_rsp(struct bt_conn *conn, uint8_t err,
			       const void *pdu, uint16_t length,
			       void *user_data)
{
	struct bt_gatt_subscribe_params *params = user_data;

	LOG_DBG("err 0x%02x", err);

	atomic_clear_bit(params->flags, BT_GATT_SUBSCRIBE_FLAG_WRITE_PENDING);

	/* if write to CCC failed we remove subscription and notify app */
	if (err) {
		struct gatt_sub *sub;
		sys_snode_t *node, *tmp;

		sub = gatt_sub_find(conn);
		if (!sub) {
			return;
		}

		SYS_SLIST_FOR_EACH_NODE_SAFE(&sub->list, node, tmp) {
			if (node == &params->node) {
				gatt_sub_remove(conn, sub, tmp, params);
				break;
			}
		}
	} else if (!params->value) {
		/* Notify with NULL data to complete unsubscribe */
		params->notify(conn, params, NULL, 0);
	}

	if (params->subscribe) {
		params->subscribe(conn, err, params);
	} else if (params->write) {
		/* TODO: Remove after deprecation */
		LOG_WRN("write callback is deprecated, use subscribe cb instead");
		params->write(conn, err, NULL);
	}
}


static int gatt_write_ccc_buf(struct net_buf *buf, size_t len, void *user_data)
{
	struct bt_gatt_subscribe_params *params = user_data;
	struct bt_att_write_req *write_req;

	write_req = net_buf_add(buf, sizeof(*write_req));
	write_req->handle = sys_cpu_to_le16(params->ccc_handle);
	net_buf_add_le16(buf, params->value);

	atomic_set_bit(params->flags, BT_GATT_SUBSCRIBE_FLAG_WRITE_PENDING);

	return 0;
}

static int gatt_write_ccc(struct bt_conn *conn,
			  struct bt_gatt_subscribe_params *params)
{
	size_t len = sizeof(struct bt_att_write_req) + sizeof(uint16_t);

	LOG_DBG("handle 0x%04x value 0x%04x", params->ccc_handle, params->value);

	/* The value of the params doesn't matter, this is just so we don't
	 * repeat CCC writes when the AUTO_RESUBSCRIBE quirk is enabled.
	 */
	atomic_set_bit(params->flags, BT_GATT_SUBSCRIBE_FLAG_SENT);

	return gatt_req_send(conn, gatt_write_ccc_rsp, params,
			     gatt_write_ccc_buf, BT_ATT_OP_WRITE_REQ, len,
			     BT_ATT_CHAN_OPT(params));
}

#if defined(CONFIG_BT_GATT_AUTO_DISCOVER_CCC)
static uint8_t gatt_ccc_discover_cb(struct bt_conn *conn,
				    const struct bt_gatt_attr *attr,
				    struct bt_gatt_discover_params *params)
{
	struct bt_gatt_subscribe_params *sub_params = params->sub_params;

	if (!attr) {
		memset(params, 0, sizeof(*params));
		sub_params->notify(conn, sub_params, NULL, 0);
		return BT_GATT_ITER_STOP;
	}

	if (params->type == BT_GATT_DISCOVER_DESCRIPTOR) {
		memset(params, 0, sizeof(*params));
		sub_params->ccc_handle = attr->handle;

		if (bt_gatt_subscribe(conn, sub_params)) {
			sub_params->notify(conn, sub_params, NULL, 0);
		}
		/* else if no error occurred, then `bt_gatt_subscribe` will
		 * call the notify function once subscribed.
		 */

		return BT_GATT_ITER_STOP;
	}

	return BT_GATT_ITER_CONTINUE;
}

static int gatt_ccc_discover(struct bt_conn *conn,
			     struct bt_gatt_subscribe_params *params)
{
	int err;
	static struct bt_uuid_16 ccc_uuid = BT_UUID_INIT_16(0);

	memcpy(&ccc_uuid, BT_UUID_GATT_CCC, sizeof(ccc_uuid));
	memset(params->disc_params, 0, sizeof(*params->disc_params));

	params->disc_params->sub_params = params;
	params->disc_params->uuid = &ccc_uuid.uuid;
	params->disc_params->type = BT_GATT_DISCOVER_DESCRIPTOR;
	params->disc_params->start_handle = params->value_handle;
	params->disc_params->end_handle = params->end_handle;
	params->disc_params->func = gatt_ccc_discover_cb;
#if defined(CONFIG_BT_EATT)
	params->disc_params->chan_opt = params->chan_opt;
#endif /* CONFIG_BT_EATT */

	err = bt_gatt_discover(conn, params->disc_params);
	if (err) {
		LOG_DBG("CCC Discovery failed (err %d)", err);
		return err;
	}
	return 0;

}
#endif /* CONFIG_BT_GATT_AUTO_DISCOVER_CCC */

int bt_gatt_subscribe(struct bt_conn *conn,
		      struct bt_gatt_subscribe_params *params)
{
	struct gatt_sub *sub;
	struct bt_gatt_subscribe_params *tmp;
	bool has_subscription = false;

	__ASSERT(conn, "invalid parameters\n");
	__ASSERT(params && params->notify,  "invalid parameters\n");
	__ASSERT(params->value, "invalid parameters\n");
#if defined(CONFIG_BT_GATT_AUTO_DISCOVER_CCC)
	__ASSERT(params->ccc_handle ||
		 (params->end_handle && params->disc_params),
		 "invalid parameters\n");
#else
	__ASSERT(params->ccc_handle, "invalid parameters\n");
#endif

	if (conn->state != BT_CONN_CONNECTED) {
		return -ENOTCONN;
	}

	sub = gatt_sub_add(conn);
	if (!sub) {
		return -ENOMEM;
	}

	/* Lookup existing subscriptions */
	SYS_SLIST_FOR_EACH_CONTAINER(&sub->list, tmp, node) {
		/* Fail if entry already exists */
		if (tmp == params) {
			gatt_sub_remove(conn, sub, NULL, NULL);
			return -EALREADY;
		}

		/* Check if another subscription exists */
		if (tmp->value_handle == params->value_handle &&
		    tmp->value >= params->value) {
			has_subscription = true;
		}
	}

	/* Skip write if already subscribed */
	if (!has_subscription) {
		int err;

#if defined(CONFIG_BT_GATT_AUTO_DISCOVER_CCC)
		if (!params->ccc_handle) {
			return gatt_ccc_discover(conn, params);
		}
#endif
		err = gatt_write_ccc(conn, params);
		if (err) {
			gatt_sub_remove(conn, sub, NULL, NULL);
			return err;
		}
	}

	/*
	 * Add subscription before write complete as some implementation were
	 * reported to send notification before reply to CCC write.
	 */
	sys_slist_prepend(&sub->list, &params->node);

	return 0;
}

int bt_gatt_resubscribe(uint8_t id, const bt_addr_le_t *peer,
			     struct bt_gatt_subscribe_params *params)
{
	struct gatt_sub *sub;
	struct bt_gatt_subscribe_params *tmp;

	__ASSERT(params && params->notify,  "invalid parameters\n");
	__ASSERT(params->value, "invalid parameters\n");
	__ASSERT(params->ccc_handle, "invalid parameters\n");

	sub = gatt_sub_add_by_addr(id, peer);
	if (!sub) {
		return -ENOMEM;
	}

	/* Lookup existing subscriptions */
	SYS_SLIST_FOR_EACH_CONTAINER(&sub->list, tmp, node) {
		/* Fail if entry already exists */
		if (tmp == params) {
			gatt_sub_remove(NULL, sub, NULL, NULL);
			return -EALREADY;
		}
	}

	sys_slist_prepend(&sub->list, &params->node);
	return 0;
}

int bt_gatt_unsubscribe(struct bt_conn *conn,
			struct bt_gatt_subscribe_params *params)
{
	struct gatt_sub *sub;
	struct bt_gatt_subscribe_params *tmp;
	bool has_subscription = false, found = false;

	__ASSERT(conn, "invalid parameters\n");
	__ASSERT(params, "invalid parameters\n");

	if (conn->state != BT_CONN_CONNECTED) {
		return -ENOTCONN;
	}

	sub = gatt_sub_find(conn);
	if (!sub) {
		return -EINVAL;
	}

	/* Lookup existing subscriptions */
	SYS_SLIST_FOR_EACH_CONTAINER(&sub->list, tmp, node) {
		if (params == tmp) {
			found = true;
			continue;
		}

		/* Check if there still remains any other subscription */
		if (tmp->value_handle == params->value_handle) {
			has_subscription = true;
		}
	}

	if (!found) {
		return -EINVAL;
	}

	/* Attempt to cancel if write is pending */
	if (atomic_test_bit(params->flags, BT_GATT_SUBSCRIBE_FLAG_WRITE_PENDING)) {
		bt_gatt_cancel(conn, params);
	}

	if (!has_subscription) {
		int err;

		params->value = 0x0000;
		err = gatt_write_ccc(conn, params);
		if (err) {
			return err;
		}
	}

	sys_slist_find_and_remove(&sub->list, &params->node);

	if (gatt_sub_is_empty(sub)) {
		gatt_sub_free(sub);
	}

	if (has_subscription) {
		/* Notify with NULL data to complete unsubscribe */
		params->notify(conn, params, NULL, 0);
	}

	return 0;
}

void bt_gatt_cancel(struct bt_conn *conn, void *params)
{
	struct bt_att_req *req;
	bt_att_func_t func = NULL;

	k_sched_lock();

	req = bt_att_find_req_by_user_data(conn, params);
	if (req) {
		func = req->func;
		bt_att_req_cancel(conn, req);
	}

	k_sched_unlock();

	if (func) {
		func(conn, BT_ATT_ERR_UNLIKELY, NULL, 0, params);
	}
}

#if defined(CONFIG_BT_GATT_AUTO_RESUBSCRIBE)
static void add_subscriptions(struct bt_conn *conn)
{
	struct gatt_sub *sub;
	struct bt_gatt_subscribe_params *params;

	if (!bt_addr_le_is_bonded(conn->id, &conn->le.dst)) {
		return;
	}

	sub = gatt_sub_find(conn);
	if (!sub) {
		return;
	}

	/* Lookup existing subscriptions */
	SYS_SLIST_FOR_EACH_CONTAINER(&sub->list, params, node) {
		if (!atomic_test_bit(params->flags,
				     BT_GATT_SUBSCRIBE_FLAG_SENT) &&
		    !atomic_test_bit(params->flags,
				     BT_GATT_SUBSCRIBE_FLAG_NO_RESUB)) {
			/* Force write to CCC to workaround devices that don't
			 * track it properly.
			 */
			gatt_write_ccc(conn, params);
		}
	}
}
#endif	/* CONFIG_BT_GATT_AUTO_RESUBSCRIBE */

#if defined(CONFIG_BT_GATT_AUTO_UPDATE_MTU)
static void gatt_exchange_mtu_func(struct bt_conn *conn, uint8_t err,
				   struct bt_gatt_exchange_params *params)
{
	if (err) {
		LOG_WRN("conn %p err 0x%02x", conn, err);
	}
}

static struct bt_gatt_exchange_params gatt_exchange_params = {
	.func = gatt_exchange_mtu_func,
};
#endif /* CONFIG_BT_GATT_AUTO_UPDATE_MTU */
#endif /* CONFIG_BT_GATT_CLIENT */

#define CCC_STORE_MAX 48

static struct bt_gatt_ccc_cfg *ccc_find_cfg(struct _bt_gatt_ccc *ccc,
					    const bt_addr_le_t *addr,
					    uint8_t id)
{
	for (size_t i = 0; i < ARRAY_SIZE(ccc->cfg); i++) {
		if (id == ccc->cfg[i].id &&
		    bt_addr_le_eq(&ccc->cfg[i].peer, addr)) {
			return &ccc->cfg[i];
		}
	}

	return NULL;
}

struct addr_with_id {
	const bt_addr_le_t *addr;
	uint8_t id;
};

struct ccc_load {
	struct addr_with_id addr_with_id;
	struct ccc_store *entry;
	size_t count;
};

static void ccc_clear(struct _bt_gatt_ccc *ccc,
		      const bt_addr_le_t *addr,
		      uint8_t id)
{
	struct bt_gatt_ccc_cfg *cfg;

	cfg = ccc_find_cfg(ccc, addr, id);
	if (!cfg) {
		LOG_DBG("Unable to clear CCC: cfg not found");
		return;
	}

	clear_ccc_cfg(cfg);
}

static uint8_t ccc_load(const struct bt_gatt_attr *attr, uint16_t handle,
			void *user_data)
{
	struct ccc_load *load = user_data;
	struct _bt_gatt_ccc *ccc;
	struct bt_gatt_ccc_cfg *cfg;

	/* Check if attribute is a CCC */
	if (attr->write != bt_gatt_attr_write_ccc) {
		return BT_GATT_ITER_CONTINUE;
	}

	ccc = attr->user_data;

	/* Clear if value was invalidated */
	if (!load->entry) {
		ccc_clear(ccc, load->addr_with_id.addr, load->addr_with_id.id);
		return BT_GATT_ITER_CONTINUE;
	} else if (!load->count) {
		return BT_GATT_ITER_STOP;
	}

	/* Skip if value is not for the given attribute */
	if (load->entry->handle != handle) {
		/* If attribute handle is bigger then it means
		 * the attribute no longer exists and cannot
		 * be restored.
		 */
		if (load->entry->handle < handle) {
			LOG_DBG("Unable to restore CCC: handle 0x%04x cannot be"
			       " found",  load->entry->handle);
			goto next;
		}
		return BT_GATT_ITER_CONTINUE;
	}

	LOG_DBG("Restoring CCC: handle 0x%04x value 0x%04x", load->entry->handle,
		load->entry->value);

	cfg = ccc_find_cfg(ccc, load->addr_with_id.addr, load->addr_with_id.id);
	if (!cfg) {
		cfg = ccc_find_cfg(ccc, BT_ADDR_LE_ANY, 0);
		if (!cfg) {
			LOG_DBG("Unable to restore CCC: no cfg left");
			goto next;
		}
		bt_addr_le_copy(&cfg->peer, load->addr_with_id.addr);
		cfg->id = load->addr_with_id.id;
	}

	cfg->value = load->entry->value;

next:
	load->entry++;
	load->count--;

	return load->count ? BT_GATT_ITER_CONTINUE : BT_GATT_ITER_STOP;
}

static int ccc_set(const char *name, size_t len_rd, settings_read_cb read_cb,
		   void *cb_arg)
{
	if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
		struct ccc_store ccc_store[CCC_STORE_MAX];
		struct ccc_load load;
		bt_addr_le_t addr;
		ssize_t len;
		int err;
		const char *next;

		settings_name_next(name, &next);

		if (!name) {
			LOG_ERR("Insufficient number of arguments");
			return -EINVAL;
		} else if (!next) {
			load.addr_with_id.id = BT_ID_DEFAULT;
		} else {
			unsigned long next_id = strtoul(next, NULL, 10);

			if (next_id >= CONFIG_BT_ID_MAX) {
				LOG_ERR("Invalid local identity %lu", next_id);
				return -EINVAL;
			}

			load.addr_with_id.id = (uint8_t)next_id;
		}

		err = bt_settings_decode_key(name, &addr);
		if (err) {
			LOG_ERR("Unable to decode address %s", name);
			return -EINVAL;
		}

		load.addr_with_id.addr = &addr;

		if (len_rd) {
			len = read_cb(cb_arg, ccc_store, sizeof(ccc_store));

			if (len < 0) {
				LOG_ERR("Failed to decode value (err %zd)", len);
				return len;
			}

			load.entry = ccc_store;
			load.count = len / sizeof(*ccc_store);

			for (size_t i = 0; i < load.count; i++) {
				LOG_DBG("Read CCC: handle 0x%04x value 0x%04x", ccc_store[i].handle,
					ccc_store[i].value);
			}
		} else {
			load.entry = NULL;
			load.count = 0;
		}

		bt_gatt_foreach_attr(0x0001, 0xffff, ccc_load, &load);

		LOG_DBG("Restored CCC for id:%" PRIu8 " addr:%s", load.addr_with_id.id,
			bt_addr_le_str(load.addr_with_id.addr));
	}

	return 0;
}

static int ccc_set_cb(const char *name, size_t len_rd, settings_read_cb read_cb,
		      void *cb_arg)
{
	if (IS_ENABLED(CONFIG_BT_SETTINGS_CCC_LAZY_LOADING)) {
		/* Only load CCCs on demand */
		return 0;
	}

	return ccc_set(name, len_rd, read_cb, cb_arg);
}

SETTINGS_STATIC_HANDLER_DEFINE(bt_ccc, "bt/ccc", NULL, ccc_set_cb, NULL, NULL);

static int ccc_set_direct(const char *key, size_t len, settings_read_cb read_cb,
			  void *cb_arg, void *param)
{
	if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
		const char *name;

		LOG_DBG("key: %s", (const char *)param);

		/* Only "bt/ccc" settings should ever come here */
		if (!settings_name_steq((const char *)param, "bt/ccc", &name)) {
			LOG_ERR("Invalid key");
			return -EINVAL;
		}

		return ccc_set(name, len, read_cb, cb_arg);
	}
	return 0;
}

void bt_gatt_connected(struct bt_conn *conn)
{
	struct conn_data data;

	LOG_DBG("conn %p", conn);

	data.conn = conn;
	data.sec = BT_SECURITY_L1;

	/* Load CCC settings from backend if bonded */
	if (IS_ENABLED(CONFIG_BT_SETTINGS_CCC_LAZY_LOADING) &&
	    bt_addr_le_is_bonded(conn->id, &conn->le.dst)) {
		char key[BT_SETTINGS_KEY_MAX];

		if (conn->id) {
			char id_str[4];

			u8_to_dec(id_str, sizeof(id_str), conn->id);
			bt_settings_encode_key(key, sizeof(key), "ccc",
					       &conn->le.dst, id_str);
		} else {
			bt_settings_encode_key(key, sizeof(key), "ccc",
					       &conn->le.dst, NULL);
		}

		settings_load_subtree_direct(key, ccc_set_direct, (void *)key);
	}

	bt_gatt_foreach_attr(0x0001, 0xffff, update_ccc, &data);

	/* BLUETOOTH CORE SPECIFICATION Version 5.1 | Vol 3, Part C page 2192:
	 *
	 * 10.3.1.1 Handling of GATT indications and notifications
	 *
	 * A client “requests” a server to send indications and notifications
	 * by appropriately configuring the server via a Client Characteristic
	 * Configuration Descriptor. Since the configuration is persistent
	 * across a disconnection and reconnection, security requirements must
	 * be checked against the configuration upon a reconnection before
	 * sending indications or notifications. When a server reconnects to a
	 * client to send an indication or notification for which security is
	 * required, the server shall initiate or request encryption with the
	 * client prior to sending an indication or notification. If the client
	 * does not have an LTK indicating that the client has lost the bond,
	 * enabling encryption will fail.
	 */
	if (IS_ENABLED(CONFIG_BT_SMP) &&
	    (conn->role == BT_HCI_ROLE_CENTRAL ||
	     IS_ENABLED(CONFIG_BT_GATT_AUTO_SEC_REQ)) &&
	    bt_conn_get_security(conn) < data.sec) {
		int err = bt_conn_set_security(conn, data.sec);

		if (err) {
			LOG_WRN("Failed to set security for bonded peer (%d)", err);
		}
	}

#if defined(CONFIG_BT_GATT_AUTO_UPDATE_MTU)
	int err;

	err = bt_gatt_exchange_mtu(conn, &gatt_exchange_params);
	if (err) {
		LOG_WRN("MTU Exchange failed (err %d)", err);
	}
#endif /* CONFIG_BT_GATT_AUTO_UPDATE_MTU */
}

void bt_gatt_att_max_mtu_changed(struct bt_conn *conn, uint16_t tx, uint16_t rx)
{
	struct bt_gatt_cb *cb;

	SYS_SLIST_FOR_EACH_CONTAINER(&callback_list, cb, node) {
		if (cb->att_mtu_updated) {
			cb->att_mtu_updated(conn, tx, rx);
		}
	}
}

void bt_gatt_encrypt_change(struct bt_conn *conn)
{
	struct conn_data data;

	LOG_DBG("conn %p", conn);

	data.conn = conn;
	data.sec = BT_SECURITY_L1;

#if defined(CONFIG_BT_GATT_AUTO_RESUBSCRIBE)
	add_subscriptions(conn);
#endif	/* CONFIG_BT_GATT_AUTO_RESUBSCRIBE */

	bt_gatt_foreach_attr(0x0001, 0xffff, update_ccc, &data);

#if defined(CONFIG_BT_SETTINGS) && defined(CONFIG_BT_GATT_SERVICE_CHANGED)
	if (!bt_gatt_change_aware(conn, false)) {
		/* Send a Service Changed indication if the current peer is
		 * marked as change-unaware.
		 */
		sc_indicate(0x0001, 0xffff);
	}
#endif	/* CONFIG_BT_SETTINGS && CONFIG_BT_GATT_SERVICE_CHANGED */
}

bool bt_gatt_change_aware(struct bt_conn *conn, bool req)
{
#if defined(CONFIG_BT_GATT_CACHING)
	struct gatt_cf_cfg *cfg;

	cfg = find_cf_cfg(conn);
	if (!cfg || !CF_ROBUST_CACHING(cfg)) {
		return true;
	}

	if (atomic_test_bit(cfg->flags, CF_CHANGE_AWARE)) {
		return true;
	}

	/* BLUETOOTH CORE SPECIFICATION Version 5.1 | Vol 3, Part G page 2350:
	 * If a change-unaware client sends an ATT command, the server shall
	 * ignore it.
	 */
	if (!req) {
		return false;
	}

	/* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 3, Part G page 1475:
	 * 2.5.2.1 Robust Caching
	 * A change-unaware connected client becomes change-aware when it reads
	 * the Database Hash characteristic and then the server receives another
	 * ATT request from the client.
	 */
	if (atomic_test_and_clear_bit(cfg->flags, CF_DB_HASH_READ)) {
		bt_att_clear_out_of_sync_sent(conn);
		set_change_aware(cfg, true);
		return true;
	}

	/* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 3, Part G page 1476:
	 * 2.5.2.1 Robust Caching
	 * ... a change-unaware connected client using exactly one ATT bearer
	 * becomes change-aware when ...
	 * The server sends the client a response with the Error Code parameter
	 * set to Database Out Of Sync (0x12) and then the server receives
	 * another ATT request from the client.
	 */
	if (bt_att_fixed_chan_only(conn) && bt_att_out_of_sync_sent_on_fixed(conn)) {
		atomic_clear_bit(cfg->flags, CF_DB_HASH_READ);
		bt_att_clear_out_of_sync_sent(conn);
		set_change_aware(cfg, true);
		return true;
	}

	return false;
#else
	return true;
#endif
}

static struct gatt_cf_cfg *find_cf_cfg_by_addr(uint8_t id,
					       const bt_addr_le_t *addr)
{
	if (IS_ENABLED(CONFIG_BT_GATT_CACHING)) {
		int i;

		for (i = 0; i < ARRAY_SIZE(cf_cfg); i++) {
			if (id == cf_cfg[i].id &&
			    bt_addr_le_eq(addr, &cf_cfg[i].peer)) {
				return &cf_cfg[i];
			}
		}
	}

	return NULL;
}

#if defined(CONFIG_BT_SETTINGS)

struct ccc_save {
	struct addr_with_id addr_with_id;
	struct ccc_store store[CCC_STORE_MAX];
	size_t count;
};

static uint8_t ccc_save(const struct bt_gatt_attr *attr, uint16_t handle,
			void *user_data)
{
	struct ccc_save *save = user_data;
	struct _bt_gatt_ccc *ccc;
	struct bt_gatt_ccc_cfg *cfg;

	/* Check if attribute is a CCC */
	if (attr->write != bt_gatt_attr_write_ccc) {
		return BT_GATT_ITER_CONTINUE;
	}

	ccc = attr->user_data;

	/* Check if there is a cfg for the peer */
	cfg = ccc_find_cfg(ccc, save->addr_with_id.addr, save->addr_with_id.id);
	if (!cfg) {
		return BT_GATT_ITER_CONTINUE;
	}

	LOG_DBG("Storing CCCs handle 0x%04x value 0x%04x", handle, cfg->value);

	save->store[save->count].handle = handle;
	save->store[save->count].value = cfg->value;
	save->count++;

	return BT_GATT_ITER_CONTINUE;
}

int bt_gatt_store_ccc(uint8_t id, const bt_addr_le_t *addr)
{
	struct ccc_save save;
	char key[BT_SETTINGS_KEY_MAX];
	size_t len;
	char *str;
	int err;

	save.addr_with_id.addr = addr;
	save.addr_with_id.id = id;
	save.count = 0;

	bt_gatt_foreach_attr(0x0001, 0xffff, ccc_save, &save);

	if (id) {
		char id_str[4];

		u8_to_dec(id_str, sizeof(id_str), id);
		bt_settings_encode_key(key, sizeof(key), "ccc", addr, id_str);
	} else {
		bt_settings_encode_key(key, sizeof(key), "ccc", addr, NULL);
	}

	if (save.count) {
		str = (char *)save.store;
		len = save.count * sizeof(*save.store);
	} else {
		/* No entries to encode, just clear */
		str = NULL;
		len = 0;
	}

	err = settings_save_one(key, str, len);
	if (err) {
		LOG_ERR("Failed to store CCCs (err %d)", err);
		return err;
	}

	LOG_DBG("Stored CCCs for %s (%s)", bt_addr_le_str(addr), key);
	if (len) {
		for (size_t i = 0; i < save.count; i++) {
			LOG_DBG("  CCC: handle 0x%04x value 0x%04x", save.store[i].handle,
				save.store[i].value);
		}
	} else {
		LOG_DBG("  CCC: NULL");
	}

	return 0;
}

#if defined(CONFIG_BT_GATT_SERVICE_CHANGED)
static int sc_set(const char *name, size_t len_rd, settings_read_cb read_cb,
		  void *cb_arg)
{
	struct gatt_sc_cfg *cfg;
	uint8_t id;
	bt_addr_le_t addr;
	ssize_t len;
	int err;
	const char *next;

	if (!name) {
		LOG_ERR("Insufficient number of arguments");
		return -EINVAL;
	}

	err = bt_settings_decode_key(name, &addr);
	if (err) {
		LOG_ERR("Unable to decode address %s", name);
		return -EINVAL;
	}

	settings_name_next(name, &next);

	if (!next) {
		id = BT_ID_DEFAULT;
	} else {
		unsigned long next_id = strtoul(next, NULL, 10);

		if (next_id >= CONFIG_BT_ID_MAX) {
			LOG_ERR("Invalid local identity %lu", next_id);
			return -EINVAL;
		}

		id = (uint8_t)next_id;
	}

	cfg = find_sc_cfg(id, &addr);
	if (!cfg && len_rd) {
		/* Find and initialize a free sc_cfg entry */
		cfg = find_sc_cfg(BT_ID_DEFAULT, BT_ADDR_LE_ANY);
		if (!cfg) {
			LOG_ERR("Unable to restore SC: no cfg left");
			return -ENOMEM;
		}

		cfg->id = id;
		bt_addr_le_copy(&cfg->peer, &addr);
	}

	if (len_rd) {
		len = read_cb(cb_arg, &cfg->data, sizeof(cfg->data));
		if (len < 0) {
			LOG_ERR("Failed to decode value (err %zd)", len);
			return len;
		}

		LOG_DBG("Read SC: len %zd", len);

		LOG_DBG("Restored SC for %s", bt_addr_le_str(&addr));
	} else if (cfg) {
		/* Clear configuration */
		memset(cfg, 0, sizeof(*cfg));

		LOG_DBG("Removed SC for %s", bt_addr_le_str(&addr));
	}

	return 0;
}

static int sc_commit(void)
{
	atomic_set_bit(gatt_sc.flags, SC_LOAD);
	atomic_clear_bit(gatt_sc.flags, SC_INDICATE_PENDING);

	if (atomic_test_bit(gatt_sc.flags, SC_RANGE_CHANGED)) {
		/* Schedule SC indication since the range has changed */
		sc_work_submit(SC_TIMEOUT);
	}

	return 0;
}

SETTINGS_STATIC_HANDLER_DEFINE(bt_sc, "bt/sc", NULL, sc_set, sc_commit, NULL);
#endif /* CONFIG_BT_GATT_SERVICE_CHANGED */

#if defined(CONFIG_BT_GATT_CACHING)
static int cf_set(const char *name, size_t len_rd, settings_read_cb read_cb,
		  void *cb_arg)
{
	struct gatt_cf_cfg *cfg;
	bt_addr_le_t addr;
	const char *next;
	ssize_t len;
	int err;
	uint8_t id;

	if (!name) {
		LOG_ERR("Insufficient number of arguments");
		return -EINVAL;
	}

	err = bt_settings_decode_key(name, &addr);
	if (err) {
		LOG_ERR("Unable to decode address %s", name);
		return -EINVAL;
	}

	settings_name_next(name, &next);

	if (!next) {
		id = BT_ID_DEFAULT;
	} else {
		unsigned long next_id = strtoul(next, NULL, 10);

		if (next_id >= CONFIG_BT_ID_MAX) {
			LOG_ERR("Invalid local identity %lu", next_id);
			return -EINVAL;
		}

		id = (uint8_t)next_id;
	}

	cfg = find_cf_cfg_by_addr(id, &addr);
	if (!cfg) {
		cfg = find_cf_cfg(NULL);
		if (!cfg) {
			LOG_ERR("Unable to restore CF: no cfg left");
			return -ENOMEM;
		}

		cfg->id = id;
		bt_addr_le_copy(&cfg->peer, &addr);
	}

	if (len_rd) {
		char dst[CF_NUM_BYTES + CF_FLAGS_STORE_LEN];

		len = read_cb(cb_arg, dst, sizeof(dst));
		if (len < 0) {
			LOG_ERR("Failed to decode value (err %zd)", len);
			return len;
		}

		memcpy(cfg->data, dst, sizeof(cfg->data));
		LOG_DBG("Read CF: len %zd", len);

		if (len != sizeof(dst)) {
			LOG_WRN("Change-aware status not found in settings, "
				"defaulting peer status to change-unaware");
			set_change_aware(cfg, false);
		} else {
			/* change-aware byte is present in NVS */
			uint8_t change_aware = dst[sizeof(cfg->data)];

			if (change_aware & ~BIT(CF_CHANGE_AWARE)) {
				LOG_WRN("Read back bad change-aware value: 0x%x, "
					"defaulting peer status to change-unaware",
					change_aware);
				set_change_aware(cfg, false);
			} else {
				set_change_aware_no_store(cfg, change_aware);
			}
		}
	} else {
		clear_cf_cfg(cfg);
	}

	LOG_DBG("Restored CF for %s", bt_addr_le_str(&addr));

	return 0;
}

SETTINGS_STATIC_HANDLER_DEFINE(bt_cf, "bt/cf", NULL, cf_set, NULL, NULL);

static int db_hash_set(const char *name, size_t len_rd,
		       settings_read_cb read_cb, void *cb_arg)
{
	ssize_t len;

	len = read_cb(cb_arg, db_hash.stored_hash, sizeof(db_hash.stored_hash));
	if (len < 0) {
		LOG_ERR("Failed to decode value (err %zd)", len);
		return len;
	}

	LOG_HEXDUMP_DBG(db_hash.stored_hash, sizeof(db_hash.stored_hash), "Stored Hash: ");

	return 0;
}

static int db_hash_commit(void)
{
	atomic_set_bit(gatt_sc.flags, DB_HASH_LOAD);

	/* Calculate the hash and compare it against the value loaded from
	 * flash. Do it from the current context to avoid any potential race
	 * conditions.
	 */
	do_db_hash();

	return 0;
}

SETTINGS_STATIC_HANDLER_DEFINE(bt_hash, "bt/hash", NULL, db_hash_set,
			       db_hash_commit, NULL);
#endif /*CONFIG_BT_GATT_CACHING */
#endif /* CONFIG_BT_SETTINGS */

static uint8_t remove_peer_from_attr(const struct bt_gatt_attr *attr,
				     uint16_t handle, void *user_data)
{
	const struct addr_with_id *addr_with_id = user_data;
	struct _bt_gatt_ccc *ccc;
	struct bt_gatt_ccc_cfg *cfg;

	/* Check if attribute is a CCC */
	if (attr->write != bt_gatt_attr_write_ccc) {
		return BT_GATT_ITER_CONTINUE;
	}

	ccc = attr->user_data;

	/* Check if there is a cfg for the peer */
	cfg = ccc_find_cfg(ccc, addr_with_id->addr, addr_with_id->id);
	if (cfg) {
		memset(cfg, 0, sizeof(*cfg));
	}

	return BT_GATT_ITER_CONTINUE;
}

static int bt_gatt_clear_ccc(uint8_t id, const bt_addr_le_t *addr)
{
	struct addr_with_id addr_with_id = {
		.addr = addr,
		.id = id,
	};

	bt_gatt_foreach_attr(0x0001, 0xffff, remove_peer_from_attr,
			     &addr_with_id);

	if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
		char key[BT_SETTINGS_KEY_MAX];

		if (id) {
			char id_str[4];

			u8_to_dec(id_str, sizeof(id_str), id);
			bt_settings_encode_key(key, sizeof(key), "ccc",
					       addr, id_str);
		} else {
			bt_settings_encode_key(key, sizeof(key), "ccc",
					       addr, NULL);
		}

		return settings_delete(key);
	}

	return 0;
}

static int bt_gatt_clear_cf(uint8_t id, const bt_addr_le_t *addr)
{
	struct gatt_cf_cfg *cfg;

	cfg = find_cf_cfg_by_addr(id, addr);
	if (cfg) {
		clear_cf_cfg(cfg);
	}

	if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
		char key[BT_SETTINGS_KEY_MAX];

		if (id) {
			char id_str[4];

			u8_to_dec(id_str, sizeof(id_str), id);
			bt_settings_encode_key(key, sizeof(key), "cf",
					       addr, id_str);
		} else {
			bt_settings_encode_key(key, sizeof(key), "cf",
					       addr, NULL);
		}

		return settings_delete(key);
	}

	return 0;

}


static struct gatt_sub *find_gatt_sub(uint8_t id, const bt_addr_le_t *addr)
{
	for (int i = 0; i < ARRAY_SIZE(subscriptions); i++) {
		struct gatt_sub *sub = &subscriptions[i];

		if (id == sub->id &&
		    bt_addr_le_eq(addr, &sub->peer)) {
			return sub;
		}
	}

	return NULL;
}

static void bt_gatt_clear_subscriptions(uint8_t id, const bt_addr_le_t *addr)
{
	struct gatt_sub *sub;
	struct bt_gatt_subscribe_params *params, *tmp;
	sys_snode_t *prev = NULL;

	sub = find_gatt_sub(id, addr);
	if (!sub) {
		return;
	}

	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&sub->list, params, tmp,
					  node) {
		params->value = 0U;
		gatt_sub_remove(NULL, sub, prev, params);
	}
}

int bt_gatt_clear(uint8_t id, const bt_addr_le_t *addr)
{
	int err;

	err = bt_gatt_clear_ccc(id, addr);
	if (err < 0) {
		return err;
	}

	if (IS_ENABLED(CONFIG_BT_GATT_SERVICE_CHANGED)) {
		err = bt_gatt_clear_sc(id, addr);
		if (err < 0) {
			return err;
		}
	}

	if (IS_ENABLED(CONFIG_BT_GATT_CACHING)) {
		err = bt_gatt_clear_cf(id, addr);
		if (err < 0) {
			return err;
		}
	}

	if (IS_ENABLED(CONFIG_BT_GATT_CLIENT)) {
		bt_gatt_clear_subscriptions(id, addr);
	}

	return 0;
}

void bt_gatt_disconnected(struct bt_conn *conn)
{
	LOG_DBG("conn %p", conn);
	bt_gatt_foreach_attr(0x0001, 0xffff, disconnected_cb, conn);

#if defined(CONFIG_BT_GATT_NOTIFY_MULTIPLE)
	/* Clear pending notifications */
	cleanup_notify(conn);
#endif /* CONFIG_BT_GATT_NOTIFY_MULTIPLE */

#if defined(CONFIG_BT_SETTINGS_DELAYED_STORE)
	if (gatt_delayed_store_find(conn->id, &conn->le.dst)) {
		int err = k_work_reschedule(&gatt_delayed_store.work, K_NO_WAIT);

		if (err < 0) {
			LOG_ERR("Unable to reschedule settings storage (err %d)",
				err);
		}
	}
#else
	if (IS_ENABLED(CONFIG_BT_SETTINGS) &&
	    bt_addr_le_is_bonded(conn->id, &conn->le.dst)) {
		bt_gatt_store_ccc(conn->id, &conn->le.dst);
		bt_gatt_store_cf(conn->id, &conn->le.dst);
	}
#endif	/* CONFIG_BT_SETTINGS_DELAYED_STORE */

	/* Make sure to clear the CCC entry when using lazy loading */
	if (IS_ENABLED(CONFIG_BT_SETTINGS_CCC_LAZY_LOADING) &&
	    bt_addr_le_is_bonded(conn->id, &conn->le.dst)) {
		struct addr_with_id addr_with_id = {
			.addr = &conn->le.dst,
			.id = conn->id,
		};
		bt_gatt_foreach_attr(0x0001, 0xffff,
				     remove_peer_from_attr,
				     &addr_with_id);
	}

#if defined(CONFIG_BT_GATT_CLIENT)
	remove_subscriptions(conn);
#endif /* CONFIG_BT_GATT_CLIENT */

#if defined(CONFIG_BT_GATT_CACHING)
	remove_cf_cfg(conn);
#endif
}
