/* Bluetooth TBS - Telephone Bearer Service
 *
 * Copyright (c) 2020 Bose Corporation
 * Copyright (c) 2021 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>
#include <zephyr/types.h>

#include <zephyr/init.h>
#include <stdlib.h>

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/gatt.h>

#include "audio_internal.h"
#include "tbs_internal.h"
#include "ccid_internal.h"

#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(bt_tbs, CONFIG_BT_TBS_LOG_LEVEL);

#define BT_TBS_VALID_STATUS_FLAGS(val)         ((val) <= (BIT(0) | BIT(1)))
#define IS_GTBS_CHRC(_attr) \
	IS_ENABLED(CONFIG_BT_GTBS) && BT_AUDIO_CHRC_USER_DATA(_attr) == &gtbs_inst

/* TODO: Have tbs_service_inst include gtbs_service_inst and use CONTAINER_OF
 * to get a specific TBS instance from a GTBS pointer.
 */
struct tbs_service_inst {
	/* Attribute values */
	char provider_name[CONFIG_BT_TBS_MAX_PROVIDER_NAME_LENGTH];
	char uci[BT_TBS_MAX_UCI_SIZE];
	char uri_scheme_list[CONFIG_BT_TBS_MAX_SCHEME_LIST_LENGTH];
	uint8_t technology;
	uint8_t signal_strength;
	uint8_t signal_strength_interval;
	uint8_t ccid;
	uint16_t optional_opcodes;
	uint16_t status_flags;
	struct bt_tbs_in_uri incoming_uri;
	struct bt_tbs_terminate_reason terminate_reason;
	struct bt_tbs_in_uri friendly_name;
	struct bt_tbs_in_uri in_call;

	/* Instance values */
	uint8_t index;
	struct bt_tbs_call calls[CONFIG_BT_TBS_MAX_CALLS];
	bool notify_current_calls;
	bool notify_call_states;
	bool pending_signal_strength_notification;
	struct k_work_delayable reporting_interval_work;

	/* TODO: The TBS (service) and the Telephone Bearers should be separated
	 * into two different instances. This is due to the addition of GTBS,
	 * where we now are in a state where this isn't a 1-to-1 correlation
	 * between TBS and the Telephone Bearers
	 */
	struct bt_gatt_service *service_p;
};

struct gtbs_service_inst {
	/* Attribute values */
	char provider_name[CONFIG_BT_TBS_MAX_PROVIDER_NAME_LENGTH];
	char uci[BT_TBS_MAX_UCI_SIZE];
	uint8_t technology;
	uint8_t signal_strength;
	uint8_t signal_strength_interval;
	uint8_t ccid;
	uint16_t optional_opcodes;
	uint16_t status_flags;
	struct bt_tbs_in_uri incoming_uri;
	struct bt_tbs_in_uri friendly_name;
	struct bt_tbs_in_uri in_call;

	/* Instance values */
	bool notify_current_calls;
	bool notify_call_states;
	bool pending_signal_strength_notification;
	struct k_work_delayable reporting_interval_work;

	/* TODO: The TBS (service) and the Telephone Bearers should be separated
	 * into two different instances. This is due to the addition of GTBS,
	 * where we now are in a state where this isn't a 1-to-1 correlation
	 * between TBS and the Telephone Bearers
	 */
	const struct bt_gatt_service_static *service_p;
};

#if defined(CONFIG_BT_GTBS)
#define READ_BUF_SIZE   (CONFIG_BT_TBS_MAX_CALLS * \
			 sizeof(struct bt_tbs_current_call_item) * \
			 CONFIG_BT_TBS_BEARER_COUNT)
#else
#define READ_BUF_SIZE   (CONFIG_BT_TBS_MAX_CALLS * \
			 sizeof(struct bt_tbs_current_call_item))
#endif /* IS_ENABLED(CONFIG_BT_GTBS) */
NET_BUF_SIMPLE_DEFINE_STATIC(read_buf, READ_BUF_SIZE);

static struct tbs_service_inst svc_insts[CONFIG_BT_TBS_BEARER_COUNT];
static struct gtbs_service_inst gtbs_inst;

/* Used to notify app with held calls in case of join */
static struct bt_tbs_call *held_calls[CONFIG_BT_TBS_MAX_CALLS];
static uint8_t held_calls_cnt;

static struct bt_tbs_cb *tbs_cbs;

static struct bt_tbs_call *lookup_call_in_inst(struct tbs_service_inst *inst,
					       uint8_t call_index)
{
	if (call_index == BT_TBS_FREE_CALL_INDEX) {
		return NULL;
	}

	for (int i = 0; i < ARRAY_SIZE(svc_insts[i].calls); i++) {
		if (inst->calls[i].index == call_index) {
			return &inst->calls[i];
		}
	}

	return NULL;
}

/**
 * @brief Finds and returns a call
 *
 * @param call_index The ID of the call
 * @return struct bt_tbs_call* Pointer to the call. NULL if not found
 */
static struct bt_tbs_call *lookup_call(uint8_t call_index)
{

	if (call_index == BT_TBS_FREE_CALL_INDEX) {
		return NULL;
	}

	for (int i = 0; i < ARRAY_SIZE(svc_insts); i++) {
		struct bt_tbs_call *call = lookup_call_in_inst(&svc_insts[i],
							       call_index);

		if (call != NULL) {
			return call;
		}
	}

	return NULL;
}

static struct tbs_service_inst *lookup_inst_by_ccc(const struct bt_gatt_attr *ccc)
{
	if (ccc == NULL) {
		return NULL;
	}

	for (int i = 0; i < ARRAY_SIZE(svc_insts); i++) {
		struct tbs_service_inst *inst = &svc_insts[i];

		if (inst->service_p == NULL) {
			continue;
		}

		for (size_t j = 0; j < inst->service_p->attr_count; j++) {
			if (inst->service_p->attrs[j].user_data == ccc->user_data) {
				return inst;
			}
		}
	}

	return NULL;
}

static struct tbs_service_inst *lookup_inst_by_call_index(uint8_t call_index)
{
	if (call_index == BT_TBS_FREE_CALL_INDEX) {
		return NULL;
	}

	for (size_t i = 0; i < ARRAY_SIZE(svc_insts); i++) {
		if (lookup_call_in_inst(&svc_insts[i], call_index) != NULL) {
			return &svc_insts[i];
		}
	}

	return NULL;
}

static bool is_authorized(struct bt_conn *conn)
{
	if (IS_ENABLED(CONFIG_BT_TBS_AUTHORIZATION)) {
		if (tbs_cbs != NULL && tbs_cbs->authorize != NULL) {
			return tbs_cbs->authorize(conn);
		} else {
			return false;
		}
	}

	return true;
}

static bool uri_scheme_in_list(const char *uri_scheme,
			       const char *uri_scheme_list)
{
	const size_t scheme_len = strlen(uri_scheme);
	const size_t scheme_list_len = strlen(uri_scheme_list);
	const char *uri_scheme_cand = uri_scheme_list;
	size_t uri_scheme_cand_len;
	size_t start_idx = 0;

	for (size_t i = 0; i < scheme_list_len; i++) {
		if (uri_scheme_list[i] == ',') {
			uri_scheme_cand_len = i - start_idx;
			if (uri_scheme_cand_len != scheme_len) {
				continue;
			}

			if (memcmp(uri_scheme, uri_scheme_cand, scheme_len) == 0) {
				return true;
			}

			if (i + 1 < scheme_list_len) {
				uri_scheme_cand = &uri_scheme_list[i + 1];
			}
		}
	}

	return false;
}

static struct tbs_service_inst *lookup_inst_by_uri_scheme(const char *uri,
							  uint8_t uri_len)
{
	char uri_scheme[CONFIG_BT_TBS_MAX_URI_LENGTH] = { 0 };

	/* Look for ':' between the first and last char */
	for (int i = 1; i < uri_len - 1; i++) {
		if (uri[i] == ':') {
			(void)memcpy(uri_scheme, uri, i);
		}
	}

	if (strlen(uri_scheme) == 0) {
		/* No URI scheme found */
		return NULL;
	}

	for (size_t i = 0; i < ARRAY_SIZE(svc_insts); i++) {
		for (size_t j = 0; j < ARRAY_SIZE(svc_insts[i].calls); j++) {
			if (uri_scheme_in_list(uri_scheme,
					       svc_insts[i].uri_scheme_list)) {
				return &svc_insts[i];
			}
		}
	}

	return NULL;
}

static struct tbs_service_inst *lookup_inst_by_work(const struct k_work *work)
{
	if (work == NULL) {
		return NULL;
	}

	for (size_t i = 0; i < ARRAY_SIZE(svc_insts); i++) {
		if (&svc_insts[i].reporting_interval_work.work == work) {
			return &svc_insts[i];
		}
	}

	return NULL;
}

static void tbs_set_terminate_reason(struct tbs_service_inst *inst,
				     uint8_t call_index, uint8_t reason)
{
	inst->terminate_reason.call_index = call_index;
	inst->terminate_reason.reason = reason;
	LOG_DBG("Index %u: call index 0x%02x, reason %s", inst->index, call_index,
		bt_tbs_term_reason_str(reason));

	bt_gatt_notify_uuid(NULL, BT_UUID_TBS_TERMINATE_REASON,
			    inst->service_p->attrs,
			    (void *)&inst->terminate_reason,
			    sizeof(inst->terminate_reason));

	if (IS_ENABLED(CONFIG_BT_GTBS)) {
		bt_gatt_notify_uuid(NULL, BT_UUID_TBS_TERMINATE_REASON,
				    gtbs_inst.service_p->attrs,
				    (void *)&inst->terminate_reason,
				    sizeof(inst->terminate_reason));
	}
}

/**
 * @brief Gets the next free call_index
 *
 * For each new call, the call index should be incremented and wrap at 255.
 * However, the index = 0 is reserved for outgoing calls
 *
 * @return uint8_t The next free call index
 */
static uint8_t next_free_call_index(void)
{
	for (int i = 0; i < CONFIG_BT_TBS_MAX_CALLS; i++) {
		static uint8_t next_call_index;
		const struct bt_tbs_call *call;

		/* For each new call, the call index should be incremented */
		next_call_index++;

		if (next_call_index == BT_TBS_FREE_CALL_INDEX) {
			/* call_index = 0 reserved for outgoing calls */
			next_call_index = 1;
		}

		call = lookup_call(next_call_index);
		if (call == NULL) {
			return next_call_index;
		}
	}

	LOG_DBG("No more free call spots");

	return BT_TBS_FREE_CALL_INDEX;
}

static void net_buf_put_call_state(const void *inst_p)
{
	const struct bt_tbs_call *call;
	const struct bt_tbs_call *calls;
	size_t call_count;

	if (inst_p == NULL) {
		return;
	}

	net_buf_simple_reset(&read_buf);

	if (IS_ENABLED(CONFIG_BT_GTBS) && inst_p == &gtbs_inst) {
		for (size_t i = 0; i < ARRAY_SIZE(svc_insts); i++) {
			calls = svc_insts[i].calls;
			call_count = ARRAY_SIZE(svc_insts[i].calls);

			for (size_t j = 0; j < call_count; j++) {
				call = &calls[j];
				if (call->index == BT_TBS_FREE_CALL_INDEX) {
					continue;
				}

				net_buf_simple_add_u8(&read_buf, call->index);
				net_buf_simple_add_u8(&read_buf, call->state);
				net_buf_simple_add_u8(&read_buf, call->flags);
			}

		}
	} else {
		const struct tbs_service_inst *inst = (struct tbs_service_inst *)inst_p;

		calls = inst->calls;
		call_count = ARRAY_SIZE(inst->calls);

		for (int i = 0; i < call_count; i++) {
			call = &calls[i];
			if (call->index == BT_TBS_FREE_CALL_INDEX) {
				continue;
			}

			net_buf_simple_add_u8(&read_buf, call->index);
			net_buf_simple_add_u8(&read_buf, call->state);
			net_buf_simple_add_u8(&read_buf, call->flags);
		}
	}
}

static void net_buf_put_current_calls(const void *inst_p)
{
	const struct bt_tbs_call *call;
	const struct bt_tbs_call *calls;
	size_t call_count;
	size_t uri_length;
	size_t item_len;

	if (inst_p == NULL) {
		return;
	}

	net_buf_simple_reset(&read_buf);

	if (IS_ENABLED(CONFIG_BT_GTBS) && inst_p == &gtbs_inst) {
		for (size_t i = 0; i < ARRAY_SIZE(svc_insts); i++) {
			calls = svc_insts[i].calls;
			call_count = ARRAY_SIZE(svc_insts[i].calls);

			for (size_t j = 0; j < call_count; j++) {
				call = &calls[j];
				if (call->index == BT_TBS_FREE_CALL_INDEX) {
					continue;
				}
				uri_length = strlen(call->remote_uri);
				item_len = sizeof(call->index) + sizeof(call->state) +
					   sizeof(call->flags) + uri_length;

				net_buf_simple_add_u8(&read_buf, item_len);
				net_buf_simple_add_u8(&read_buf, call->index);
				net_buf_simple_add_u8(&read_buf, call->state);
				net_buf_simple_add_u8(&read_buf, call->flags);
				net_buf_simple_add_mem(&read_buf,
						       call->remote_uri,
						       uri_length);
			}

		}
	} else {
		const struct tbs_service_inst *inst = (struct tbs_service_inst *)inst_p;

		calls = inst->calls;
		call_count = ARRAY_SIZE(inst->calls);

		for (size_t i = 0; i < call_count; i++) {
			call = &calls[i];
			if (call->index == BT_TBS_FREE_CALL_INDEX) {
				continue;
			}

			uri_length = strlen(call->remote_uri);
			item_len = sizeof(call->index) + sizeof(call->state) +
				   sizeof(call->flags) + uri_length;
			net_buf_simple_add_u8(&read_buf, item_len);
			net_buf_simple_add_u8(&read_buf, call->index);
			net_buf_simple_add_u8(&read_buf, call->state);
			net_buf_simple_add_u8(&read_buf, call->flags);
			net_buf_simple_add_mem(&read_buf, call->remote_uri,
					       uri_length);
		}
	}
}

static int notify_calls(const struct tbs_service_inst *inst)
{
	int err = 0;

	if (inst == NULL) {
		return -EINVAL;
	}

	if (IS_ENABLED(CONFIG_BT_GTBS)) {
		if (gtbs_inst.notify_call_states) {
			net_buf_put_call_state(&gtbs_inst);

			err = bt_gatt_notify_uuid(NULL, BT_UUID_TBS_CALL_STATE,
						  gtbs_inst.service_p->attrs,
						  read_buf.data, read_buf.len);
			if (err != 0) {
				return err;
			}
		}

		if (gtbs_inst.notify_current_calls) {
			net_buf_put_current_calls(&gtbs_inst);

			err = bt_gatt_notify_uuid(
				NULL, BT_UUID_TBS_LIST_CURRENT_CALLS,
				gtbs_inst.service_p->attrs,
				read_buf.data, read_buf.len);
			if (err != 0) {
				return err;
			}
		}
	}

	if (inst->notify_call_states) {
		net_buf_put_call_state(inst);

		err = bt_gatt_notify_uuid(NULL, BT_UUID_TBS_CALL_STATE,
					  inst->service_p->attrs,
					  read_buf.data, read_buf.len);
		if (err != 0) {
			return err;
		}
	}
	if (inst->notify_current_calls) {
		net_buf_put_current_calls(inst);

		err = bt_gatt_notify_uuid(NULL, BT_UUID_TBS_LIST_CURRENT_CALLS,
					  inst->service_p->attrs,
					  read_buf.data, read_buf.len);
		if (err != 0) {
			return err;
		}
	}

	return err;
}

static ssize_t read_provider_name(struct bt_conn *conn,
				  const struct bt_gatt_attr *attr,
				  void *buf, uint16_t len, uint16_t offset)
{
	const char *provider_name;

	if (IS_GTBS_CHRC(attr)) {
		provider_name = gtbs_inst.provider_name;
		LOG_DBG("GTBS: Provider name %s", provider_name);
	} else {
		const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);

		provider_name = inst->provider_name;
		LOG_DBG("Index %u, Provider name %s", inst->index, provider_name);
	}

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

static void provider_name_cfg_changed(const struct bt_gatt_attr *attr,
				      uint16_t value)
{
	const struct tbs_service_inst *inst = lookup_inst_by_ccc(attr);

	if (inst != NULL) {
		LOG_DBG("Index %u: value 0x%04x", inst->index, value);
	} else if (IS_ENABLED(CONFIG_BT_GTBS)) {
		LOG_DBG("GTBS: value 0x%04x", value);
	}
}

static ssize_t read_uci(struct bt_conn *conn, const struct bt_gatt_attr *attr,
			void *buf, uint16_t len, uint16_t offset)
{
	const char *uci;

	if (IS_GTBS_CHRC(attr)) {
		uci = gtbs_inst.uci;
		LOG_DBG("GTBS: UCI %s", uci);
	} else {
		const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);

		uci = inst->uci;
		LOG_DBG("Index %u: UCI %s", inst->index, uci);
	}

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

static ssize_t read_technology(struct bt_conn *conn,
			       const struct bt_gatt_attr *attr,
			       void *buf, uint16_t len, uint16_t offset)
{
	uint8_t technology;

	if (IS_GTBS_CHRC(attr)) {
		technology = gtbs_inst.technology;
		LOG_DBG("GTBS: Technology 0x%02X", technology);
	} else {
		const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);

		technology = inst->technology;
		LOG_DBG("Index %u: Technology 0x%02X", inst->index, technology);
	}

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

static void technology_cfg_changed(const struct bt_gatt_attr *attr,
				   uint16_t value)
{
	const struct tbs_service_inst *inst = lookup_inst_by_ccc(attr);

	if (inst != NULL) {
		LOG_DBG("Index %u: value 0x%04x", inst->index, value);
	} else if (IS_ENABLED(CONFIG_BT_GTBS)) {
		LOG_DBG("GTBS: value 0x%04x", value);
	}
}

static ssize_t read_uri_scheme_list(struct bt_conn *conn,
				    const struct bt_gatt_attr *attr,
				    void *buf, uint16_t len, uint16_t offset)
{
	net_buf_simple_reset(&read_buf);

	if (IS_GTBS_CHRC(attr)) {
		/* TODO: Make uri schemes unique */
		for (size_t i = 0; i < ARRAY_SIZE(svc_insts); i++) {
			size_t uri_len = strlen(svc_insts[i].uri_scheme_list);

			if (read_buf.len + uri_len >= read_buf.size) {
				LOG_WRN("Cannot fit all TBS instances in GTBS "
					"URI scheme list");
				break;
			}

			net_buf_simple_add_mem(&read_buf,
					       svc_insts[i].uri_scheme_list,
					       uri_len);
		}

		LOG_DBG("GTBS: URI scheme %.*s", read_buf.len, read_buf.data);
	} else {
		const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);

		net_buf_simple_add_mem(&read_buf, inst->uri_scheme_list,
				       strlen(inst->uri_scheme_list));

		LOG_DBG("Index %u: URI scheme %.*s", inst->index, read_buf.len, read_buf.data);
	}

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

static void uri_scheme_list_cfg_changed(const struct bt_gatt_attr *attr,
				   uint16_t value)
{
	const struct tbs_service_inst *inst = lookup_inst_by_ccc(attr);

	if (inst != NULL) {
		LOG_DBG("Index %u: value 0x%04x", inst->index, value);
	} else if (IS_ENABLED(CONFIG_BT_GTBS)) {
		LOG_DBG("GTBS: value 0x%04x", value);
	}
}

static ssize_t read_signal_strength(struct bt_conn *conn,
				    const struct bt_gatt_attr *attr,
				    void *buf, uint16_t len, uint16_t offset)
{
	uint8_t signal_strength;

	if (IS_GTBS_CHRC(attr)) {
		signal_strength = gtbs_inst.signal_strength;
		LOG_DBG("GTBS: Signal strength 0x%02x", signal_strength);
	} else {
		const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);

		signal_strength = inst->signal_strength;
		LOG_DBG("Index %u: Signal strength 0x%02x", inst->index, signal_strength);
	}

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

static void signal_strength_cfg_changed(const struct bt_gatt_attr *attr,
					uint16_t value)
{
	const struct tbs_service_inst *inst = lookup_inst_by_ccc(attr);

	if (inst != NULL) {
		LOG_DBG("Index %u: value 0x%04x", inst->index, value);
	} else if (IS_ENABLED(CONFIG_BT_GTBS)) {
		LOG_DBG("GTBS: value 0x%04x", value);
	}
}

static ssize_t read_signal_strength_interval(struct bt_conn *conn,
					     const struct bt_gatt_attr *attr,
					     void *buf, uint16_t len,
					     uint16_t offset)
{
	uint8_t signal_strength_interval;

	if (!is_authorized(conn)) {
		return BT_GATT_ERR(BT_ATT_ERR_AUTHORIZATION);
	}

	if (IS_GTBS_CHRC(attr)) {
		signal_strength_interval = gtbs_inst.signal_strength_interval;
		LOG_DBG("GTBS: Signal strength interval 0x%02x", signal_strength_interval);
	} else {
		const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);

		signal_strength_interval = inst->signal_strength_interval;
		LOG_DBG("Index %u: Signal strength interval 0x%02x", inst->index,
			signal_strength_interval);
	}

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

static ssize_t write_signal_strength_interval(struct bt_conn *conn,
					      const struct bt_gatt_attr *attr,
					      const void *buf, uint16_t len,
					      uint16_t offset, uint8_t flags)
{
	struct net_buf_simple net_buf;
	uint8_t signal_strength_interval;

	if (!is_authorized(conn)) {
		return BT_GATT_ERR(BT_ATT_ERR_AUTHORIZATION);
	}

	if (offset != 0) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
	}

	if (len != sizeof(signal_strength_interval)) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
	}

	net_buf_simple_init_with_data(&net_buf, (void *)buf, len);
	signal_strength_interval = net_buf_simple_pull_u8(&net_buf);

	if (IS_GTBS_CHRC(attr)) {
		gtbs_inst.signal_strength_interval = signal_strength_interval;
		LOG_DBG("GTBS: 0x%02x", signal_strength_interval);
	} else {
		struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);

		inst->signal_strength_interval = signal_strength_interval;
		LOG_DBG("Index %u: 0x%02x", inst->index, signal_strength_interval);
	}

	return len;
}

static void current_calls_cfg_changed(const struct bt_gatt_attr *attr,
				      uint16_t value)
{
	struct tbs_service_inst *inst = lookup_inst_by_ccc(attr);

	if (inst != NULL) {
		LOG_DBG("Index %u: value 0x%04x", inst->index, value);
		inst->notify_current_calls = (value == BT_GATT_CCC_NOTIFY);
	} else if (IS_ENABLED(CONFIG_BT_GTBS)) {
		LOG_DBG("GTBS: value 0x%04x", value);
		gtbs_inst.notify_current_calls = (value == BT_GATT_CCC_NOTIFY);
	}
}

static ssize_t read_current_calls(struct bt_conn *conn,
				  const struct bt_gatt_attr *attr,
				  void *buf, uint16_t len, uint16_t offset)
{
	net_buf_put_current_calls(BT_AUDIO_CHRC_USER_DATA(attr));

	if (IS_GTBS_CHRC(attr)) {
		LOG_DBG("GTBS");
	} else {
		const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);

		LOG_DBG("Index %u", inst->index);
	}

	if (offset == 0) {
		LOG_HEXDUMP_DBG(read_buf.data, read_buf.len, "Current calls");
	}

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

static ssize_t read_ccid(struct bt_conn *conn,
			 const struct bt_gatt_attr *attr,
			 void *buf, uint16_t len, uint16_t offset)
{
	uint8_t ccid;

	if (IS_GTBS_CHRC(attr)) {
		ccid = gtbs_inst.ccid;
		LOG_DBG("GTBS: CCID 0x%02X", ccid);
	} else {
		const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);

		ccid = inst->ccid;
		LOG_DBG("Index %u: CCID 0x%02X", inst->index, ccid);
	}

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

static ssize_t read_status_flags(struct bt_conn *conn,
				 const struct bt_gatt_attr *attr,
				 void *buf, uint16_t len, uint16_t offset)
{
	uint16_t status_flags;

	if (IS_GTBS_CHRC(attr)) {
		status_flags = gtbs_inst.status_flags;
		LOG_DBG("GTBS: status_flags 0x%04X", status_flags);
	} else {
		const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);

		status_flags = inst->status_flags;
		LOG_DBG("Index %u: status_flags 0x%04X", inst->index, status_flags);
	}

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

static void status_flags_cfg_changed(const struct bt_gatt_attr *attr,
					   uint16_t value)
{
	const struct tbs_service_inst *inst = lookup_inst_by_ccc(attr);

	if (inst != NULL) {
		LOG_DBG("Index %u: value 0x%04x", inst->index, value);
	} else if (IS_ENABLED(CONFIG_BT_GTBS)) {
		LOG_DBG("GTBS: value 0x%04x", value);
	}
}

static ssize_t read_incoming_uri(struct bt_conn *conn,
					    const struct bt_gatt_attr *attr,
					    void *buf, uint16_t len,
					    uint16_t offset)
{
	const struct bt_tbs_in_uri *inc_call_target;
	size_t val_len;

	if (IS_GTBS_CHRC(attr)) {
		inc_call_target = &gtbs_inst.incoming_uri;
		LOG_DBG("GTBS: call index 0x%02X, URI %s", inc_call_target->call_index,
			inc_call_target->uri);
	} else {
		const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);

		inc_call_target = &inst->incoming_uri;
		LOG_DBG("Index %u: call index 0x%02X, URI %s", inst->index,
			inc_call_target->call_index, inc_call_target->uri);
	}

	if (!inc_call_target->call_index) {
		LOG_DBG("URI not set");

		return bt_gatt_attr_read(conn, attr, buf, len, offset, NULL, 0);
	}

	val_len = sizeof(inc_call_target->call_index) +
			strlen(inc_call_target->uri);

	return bt_gatt_attr_read(conn, attr, buf, len, offset,
				 inc_call_target, val_len);
}

static void incoming_uri_cfg_changed(const struct bt_gatt_attr *attr,
						uint16_t value)
{
	const struct tbs_service_inst *inst = lookup_inst_by_ccc(attr);

	if (inst != NULL) {
		LOG_DBG("Index %u: value 0x%04x", inst->index, value);
	} else if (IS_ENABLED(CONFIG_BT_GTBS)) {
		LOG_DBG("GTBS: value 0x%04x", value);
	}
}

static ssize_t read_call_state(struct bt_conn *conn,
			       const struct bt_gatt_attr *attr,
			       void *buf, uint16_t len, uint16_t offset)
{
	net_buf_put_call_state(BT_AUDIO_CHRC_USER_DATA(attr));

	if (IS_GTBS_CHRC(attr)) {
		LOG_DBG("GTBS");
	} else {
		const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);

		LOG_DBG("Index %u", inst->index);
	}

	if (offset == 0) {
		LOG_HEXDUMP_DBG(read_buf.data, read_buf.len, "Call state");
	}

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

static void call_state_cfg_changed(const struct bt_gatt_attr *attr,
				   uint16_t value)
{
	struct tbs_service_inst *inst = lookup_inst_by_ccc(attr);

	if (inst != NULL) {
		LOG_DBG("Index %u: value 0x%04x", inst->index, value);
		inst->notify_call_states = (value == BT_GATT_CCC_NOTIFY);
	} else if (IS_ENABLED(CONFIG_BT_GTBS)) {
		LOG_DBG("GTBS: value 0x%04x", value);
		gtbs_inst.notify_call_states = (value == BT_GATT_CCC_NOTIFY);
	}
}

static int notify_ccp(struct bt_conn *conn, const struct bt_gatt_attr *attr,
		      uint8_t call_index, uint8_t opcode, uint8_t status)
{
	const struct bt_tbs_call_cp_notify ccp_not = {
		.call_index = call_index,
		.opcode = opcode,
		.status = status
	};

	LOG_DBG("Notifying CCP: Call index %u, %s opcode and status %s", call_index,
		bt_tbs_opcode_str(opcode), bt_tbs_status_str(status));

	return bt_gatt_notify(conn, attr, &ccp_not, sizeof(ccp_not));
}

static void hold_other_calls(struct tbs_service_inst *inst,
			     uint8_t call_index_cnt,
			     const uint8_t *call_indexes)
{
	held_calls_cnt = 0;

	for (int i = 0; i < ARRAY_SIZE(inst->calls); i++) {
		bool hold_call = true;
		uint8_t call_state;

		for (int j = 0; j < call_index_cnt; j++) {
			if (inst->calls[i].index == call_indexes[j]) {
				hold_call = false;
				break;
			}
		}

		if (!hold_call) {
			continue;
		}

		call_state = inst->calls[i].state;
		if (call_state == BT_TBS_CALL_STATE_ACTIVE) {
			inst->calls[i].state = BT_TBS_CALL_STATE_LOCALLY_HELD;
			held_calls[held_calls_cnt++] = &inst->calls[i];
		} else if (call_state == BT_TBS_CALL_STATE_REMOTELY_HELD) {
			inst->calls[i].state =
				BT_TBS_CALL_STATE_LOCALLY_AND_REMOTELY_HELD;
			held_calls[held_calls_cnt++] = &inst->calls[i];
		}
	}
}

static uint8_t accept_call(struct tbs_service_inst *inst,
			   const struct bt_tbs_call_cp_acc *ccp)
{
	struct bt_tbs_call *call = lookup_call_in_inst(inst, ccp->call_index);

	if (call == NULL) {
		return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
	}

	if (call->state == BT_TBS_CALL_STATE_INCOMING) {
		call->state = BT_TBS_CALL_STATE_ACTIVE;

		hold_other_calls(inst, 1, &ccp->call_index);

		return BT_TBS_RESULT_CODE_SUCCESS;
	} else {
		return BT_TBS_RESULT_CODE_STATE_MISMATCH;
	}
}

static uint8_t terminate_call(struct tbs_service_inst *inst,
			      const struct bt_tbs_call_cp_term *ccp,
			      uint8_t reason)
{
	struct bt_tbs_call *call = lookup_call_in_inst(inst, ccp->call_index);

	if (call == NULL) {
		return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
	}

	call->index = BT_TBS_FREE_CALL_INDEX;
	tbs_set_terminate_reason(inst, ccp->call_index, reason);

	return BT_TBS_RESULT_CODE_SUCCESS;
}

static uint8_t tbs_hold_call(struct tbs_service_inst *inst,
			     const struct bt_tbs_call_cp_hold *ccp)
{
	struct bt_tbs_call *call = lookup_call_in_inst(inst, ccp->call_index);

	if ((inst->optional_opcodes & BT_TBS_FEATURE_HOLD) == 0) {
		return BT_TBS_RESULT_CODE_OPCODE_NOT_SUPPORTED;
	}

	if (call == NULL) {
		return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
	}

	if (call->state == BT_TBS_CALL_STATE_ACTIVE) {
		call->state = BT_TBS_CALL_STATE_LOCALLY_HELD;
	} else if (call->state == BT_TBS_CALL_STATE_REMOTELY_HELD) {
		call->state = BT_TBS_CALL_STATE_LOCALLY_AND_REMOTELY_HELD;
	} else if (call->state == BT_TBS_CALL_STATE_INCOMING) {
		call->state = BT_TBS_CALL_STATE_LOCALLY_HELD;
	} else {
		return BT_TBS_RESULT_CODE_STATE_MISMATCH;
	}

	return BT_TBS_RESULT_CODE_SUCCESS;
}

static uint8_t retrieve_call(struct tbs_service_inst *inst,
			     const struct bt_tbs_call_cp_retrieve *ccp)
{
	struct bt_tbs_call *call = lookup_call_in_inst(inst, ccp->call_index);

	if ((inst->optional_opcodes & BT_TBS_FEATURE_HOLD) == 0) {
		return BT_TBS_RESULT_CODE_OPCODE_NOT_SUPPORTED;
	}

	if (call == NULL) {
		return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
	}

	if (call->state == BT_TBS_CALL_STATE_LOCALLY_HELD) {
		call->state = BT_TBS_CALL_STATE_ACTIVE;
	} else if (call->state == BT_TBS_CALL_STATE_LOCALLY_AND_REMOTELY_HELD) {
		call->state = BT_TBS_CALL_STATE_REMOTELY_HELD;
	} else {
		return BT_TBS_RESULT_CODE_STATE_MISMATCH;
	}

	hold_other_calls(inst, 1, &ccp->call_index);

	return BT_TBS_RESULT_CODE_SUCCESS;
}

static int originate_call(struct tbs_service_inst *inst,
			  const struct bt_tbs_call_cp_originate *ccp,
			  uint16_t uri_len, uint8_t *call_index)
{
	struct bt_tbs_call *call = NULL;

	/* New call - Look for unused call item */
	for (int i = 0; i < CONFIG_BT_TBS_MAX_CALLS; i++) {
		if (inst->calls[i].index == BT_TBS_FREE_CALL_INDEX) {
			call = &inst->calls[i];
			break;
		}
	}

	/* Only allow one active outgoing call */
	for (int i = 0; i < CONFIG_BT_TBS_MAX_CALLS; i++) {
		if (inst->calls[i].state == BT_TBS_CALL_STATE_ALERTING) {
			return BT_TBS_RESULT_CODE_OPERATION_NOT_POSSIBLE;
		}
	}

	if (call == NULL) {
		return BT_TBS_RESULT_CODE_OUT_OF_RESOURCES;
	}

	call->index = next_free_call_index();

	if (call->index == BT_TBS_FREE_CALL_INDEX) {
		return BT_TBS_RESULT_CODE_OUT_OF_RESOURCES;
	}

	if (uri_len == 0 || uri_len > CONFIG_BT_TBS_MAX_URI_LENGTH) {
		call->index = BT_TBS_FREE_CALL_INDEX;
		return BT_TBS_RESULT_CODE_INVALID_URI;
	}

	(void)memcpy(call->remote_uri, ccp->uri, uri_len);
	call->remote_uri[uri_len] = '\0';
	if (!bt_tbs_valid_uri(call->remote_uri)) {
		LOG_DBG("Invalid URI: %s", call->remote_uri);
		call->index = BT_TBS_FREE_CALL_INDEX;

		return BT_TBS_RESULT_CODE_INVALID_URI;
	}

	/* We need to notify dialing state for test,
	 * even though we don't have an internal dialing state.
	 */
	call->state = BT_TBS_CALL_STATE_DIALING;
	if (call->index != BT_TBS_FREE_CALL_INDEX) {
		*call_index = call->index;
	}
	BT_TBS_CALL_FLAG_SET_OUTGOING(call->flags);

	hold_other_calls(inst, 1, &call->index);

	notify_calls(inst);
	call->state = BT_TBS_CALL_STATE_ALERTING;
	notify_calls(inst);

	LOG_DBG("New call with call index %u", call->index);

	return BT_TBS_RESULT_CODE_SUCCESS;
}

static uint8_t join_calls(struct tbs_service_inst *inst,
			  const struct bt_tbs_call_cp_join *ccp,
			  uint16_t call_index_cnt)
{
	struct bt_tbs_call *joined_calls[CONFIG_BT_TBS_MAX_CALLS];
	uint8_t call_state;

	if ((inst->optional_opcodes & BT_TBS_FEATURE_JOIN) == 0) {
		return BT_TBS_RESULT_CODE_OPCODE_NOT_SUPPORTED;
	}

	/* Check length */
	if (call_index_cnt < 2 || call_index_cnt > CONFIG_BT_TBS_MAX_CALLS) {
		return BT_TBS_RESULT_CODE_OPERATION_NOT_POSSIBLE;
	}

	/* Check for duplicates */
	for (int i = 0; i < call_index_cnt; i++) {
		for (int j = 0; j < i; j++) {
			if (ccp->call_indexes[i] == ccp->call_indexes[j]) {
				return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
			}
		}
	}

	/* Validate that all calls are in a joinable state */
	for (int i = 0; i < call_index_cnt; i++) {
		joined_calls[i] = lookup_call_in_inst(inst,
						      ccp->call_indexes[i]);
		if (joined_calls[i] == NULL) {
			return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
		}

		call_state = joined_calls[i]->state;

		if (call_state == BT_TBS_CALL_STATE_INCOMING) {
			return BT_TBS_RESULT_CODE_OPERATION_NOT_POSSIBLE;
		}

		if (call_state != BT_TBS_CALL_STATE_LOCALLY_HELD &&
		    call_state != BT_TBS_CALL_STATE_LOCALLY_AND_REMOTELY_HELD &&
		    call_state != BT_TBS_CALL_STATE_ACTIVE) {
			return BT_TBS_RESULT_CODE_STATE_MISMATCH;
		}
	}

	/* Join all calls */
	for (int i = 0; i < call_index_cnt; i++) {
		call_state = joined_calls[i]->state;

		if (call_state == BT_TBS_CALL_STATE_LOCALLY_HELD) {
			joined_calls[i]->state = BT_TBS_CALL_STATE_ACTIVE;
		} else if (call_state ==
				BT_TBS_CALL_STATE_LOCALLY_AND_REMOTELY_HELD) {
			joined_calls[i]->state =
				BT_TBS_CALL_STATE_REMOTELY_HELD;
		} else if (call_state == BT_TBS_CALL_STATE_INCOMING) {
			joined_calls[i]->state = BT_TBS_CALL_STATE_ACTIVE;
		}
		/* else active => Do nothing */
	}

	hold_other_calls(inst, call_index_cnt, ccp->call_indexes);

	return BT_TBS_RESULT_CODE_SUCCESS;
}

static void notify_app(struct bt_conn *conn, struct tbs_service_inst *inst, uint16_t len,
		       const union bt_tbs_call_cp_t *ccp, uint8_t status, uint8_t call_index)
{
	if (tbs_cbs == NULL) {
		return;
	}

	switch (ccp->opcode) {
	case BT_TBS_CALL_OPCODE_ACCEPT:
		if (tbs_cbs->accept_call != NULL) {
			tbs_cbs->accept_call(conn, call_index);
		}
		break;
	case BT_TBS_CALL_OPCODE_TERMINATE:
		if (tbs_cbs->terminate_call != NULL) {
			tbs_cbs->terminate_call(conn, call_index,
						inst->terminate_reason.reason);
		}
		break;
	case BT_TBS_CALL_OPCODE_HOLD:
		if (tbs_cbs->hold_call != NULL) {
			tbs_cbs->hold_call(conn, call_index);
		}
		break;
	case BT_TBS_CALL_OPCODE_RETRIEVE:
		if (tbs_cbs->retrieve_call != NULL) {
			tbs_cbs->retrieve_call(conn, call_index);
		}
		break;
	case BT_TBS_CALL_OPCODE_ORIGINATE:
	{
		char uri[CONFIG_BT_TBS_MAX_URI_LENGTH + 1];
		const uint16_t uri_len = len - sizeof(ccp->originate);
		bool remote_party_alerted = false;
		struct bt_tbs_call *call;

		call = lookup_call_in_inst(inst, call_index);

		if (call == NULL) {
			LOG_DBG("Could not find call by call index 0x%02X", call_index);
			break;
		}

		(void)memcpy(uri, ccp->originate.uri, uri_len);
		uri[uri_len] = '\0';
		if (tbs_cbs->originate_call != NULL) {
			remote_party_alerted = tbs_cbs->originate_call(conn,
								       call_index,
								       uri);
		}

		if (remote_party_alerted) {
			call->state = BT_TBS_CALL_STATE_ALERTING;
		} else {
			const struct bt_tbs_call_cp_term term = {
				.call_index = call_index,
				.opcode = BT_TBS_CALL_OPCODE_TERMINATE
			};

			/* Terminate and remove call */
			terminate_call(inst, &term, BT_TBS_REASON_CALL_FAILED);
		}

		notify_calls(inst);

		break;
	}
	case BT_TBS_CALL_OPCODE_JOIN:
	{
		const uint16_t call_index_cnt = len - sizeof(ccp->join);

		/* Let the app know about joined calls */
		if (tbs_cbs->join_calls != NULL) {
			tbs_cbs->join_calls(conn, call_index_cnt,
					    ccp->join.call_indexes);
		}
		break;
	}
	default:
		break;
	}

	/* Let the app know about held calls */
	if (held_calls_cnt != 0 && tbs_cbs->hold_call != NULL) {
		for (int i = 0; i < held_calls_cnt; i++) {
			tbs_cbs->hold_call(conn, held_calls[i]->index);
		}
	}
}

static ssize_t write_call_cp(struct bt_conn *conn,
			     const struct bt_gatt_attr *attr,
			     const void *buf, uint16_t len,
			     uint16_t offset, uint8_t flags)
{
	struct tbs_service_inst *inst = NULL;
	const union bt_tbs_call_cp_t *ccp = (union bt_tbs_call_cp_t *)buf;
	uint8_t status;
	uint8_t call_index = 0;
	const bool is_gtbs = IS_GTBS_CHRC(attr);

	if (!is_authorized(conn)) {
		return BT_GATT_ERR(BT_ATT_ERR_AUTHORIZATION);
	}

	if (offset != 0) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
	}

	if (len < sizeof(ccp->opcode)) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
	}

	if (is_gtbs) {
		LOG_DBG("GTBS: Processing the %s opcode", bt_tbs_opcode_str(ccp->opcode));
	} else {
		inst = BT_AUDIO_CHRC_USER_DATA(attr);

		LOG_DBG("Index %u: Processing the %s opcode", inst->index,
			bt_tbs_opcode_str(ccp->opcode));
	}

	switch (ccp->opcode) {
	case BT_TBS_CALL_OPCODE_ACCEPT:
		if (len != sizeof(ccp->accept)) {
			return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
		}

		call_index = ccp->accept.call_index;

		if (is_gtbs) {
			inst = lookup_inst_by_call_index(call_index);
			if (inst == NULL) {
				status = BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
				break;
			}
		}

		status = accept_call(inst, &ccp->accept);
		break;
	case BT_TBS_CALL_OPCODE_TERMINATE:
		if (len != sizeof(ccp->terminate)) {
			return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
		}

		call_index = ccp->terminate.call_index;

		if (is_gtbs) {
			inst = lookup_inst_by_call_index(call_index);
			if (inst == NULL) {
				status = BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
				break;
			}
		}

		status = terminate_call(inst, &ccp->terminate,
					BT_TBS_REASON_CLIENT_TERMINATED);
		break;
	case BT_TBS_CALL_OPCODE_HOLD:
		if (len != sizeof(ccp->hold)) {
			return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
		}

		call_index = ccp->hold.call_index;

		if (is_gtbs) {
			inst = lookup_inst_by_call_index(call_index);
			if (inst == NULL) {
				status = BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
				break;
			}
		}

		status = tbs_hold_call(inst, &ccp->hold);
		break;
	case BT_TBS_CALL_OPCODE_RETRIEVE:
		if (len != sizeof(ccp->retrieve)) {
			return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
		}

		call_index = ccp->retrieve.call_index;

		if (is_gtbs) {
			inst = lookup_inst_by_call_index(call_index);
			if (inst == NULL) {
				status = BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
				break;
			}
		}

		status = retrieve_call(inst, &ccp->retrieve);
		break;
	case BT_TBS_CALL_OPCODE_ORIGINATE:
	{
		const uint16_t uri_len = len - sizeof(ccp->originate);

		if (len < sizeof(ccp->originate) + BT_TBS_MIN_URI_LEN) {
			return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
		}

		if (is_gtbs) {
			inst = lookup_inst_by_uri_scheme(ccp->originate.uri,
						      uri_len);
			if (inst == NULL) {
				/* TODO: Couldn't find fitting TBS instance;
				 * use the first. If we want to be
				 * restrictive about URIs, return
				 * Invalid Caller ID instead
				 */
				inst = &svc_insts[0];
			}
		}

		status = originate_call(inst, &ccp->originate, uri_len,
					&call_index);
		break;
	}
	case BT_TBS_CALL_OPCODE_JOIN:
	{
		const uint16_t call_index_cnt = len - sizeof(ccp->join);

		if (len < sizeof(ccp->join) + 1) { /* at least 1 call index */
			return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
		}

		call_index = ccp->join.call_indexes[0];

		if (is_gtbs) {
			inst = lookup_inst_by_call_index(call_index);
			if (inst == NULL) {
				status = BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
				break;
			}
		}

		status = join_calls(inst, &ccp->join, call_index_cnt);
		break;
	}
	default:
		status = BT_TBS_RESULT_CODE_OPCODE_NOT_SUPPORTED;
		call_index = 0;
		break;
	}

	if (inst != NULL) {
		if (is_gtbs) {
			LOG_DBG("GTBS: Processed the %s opcode with status %s "
			       "for call index %u",
			       bt_tbs_opcode_str(ccp->opcode),
			       bt_tbs_status_str(status),
			       call_index);
		} else {
			LOG_DBG("Index %u: Processed the %s opcode with status "
			       "%s for call index %u",
			       inst->index,
			       bt_tbs_opcode_str(ccp->opcode),
			       bt_tbs_status_str(status),
			       call_index);
		}

		if (status == BT_TBS_RESULT_CODE_SUCCESS) {
			const struct bt_tbs_call *call = lookup_call(call_index);

			if (call != NULL) {
				LOG_DBG("Call is now in the %s state",
					bt_tbs_state_str(call->state));
			} else {
				LOG_DBG("Call is now terminated");
			}
		}
	}

	if (status != BT_TBS_RESULT_CODE_SUCCESS) {
		call_index = 0;
	}

	if (conn != NULL) {
		notify_ccp(conn, attr, call_index, ccp->opcode, status);
	} /* else local operation; don't notify */

	if (inst != NULL && status == BT_TBS_RESULT_CODE_SUCCESS) {
		notify_calls(inst);
		notify_app(conn, inst, len, ccp, status, call_index);
	}

	return len;
}

static void call_cp_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
{
	const struct tbs_service_inst *inst = lookup_inst_by_ccc(attr);

	if (inst != NULL) {
		LOG_DBG("Index %u: value 0x%04x", inst->index, value);
	} else if (IS_ENABLED(CONFIG_BT_GTBS)) {
		LOG_DBG("GTBS: value 0x%04x", value);
	}
}

static ssize_t read_optional_opcodes(struct bt_conn *conn,
				     const struct bt_gatt_attr *attr,
				     void *buf, uint16_t len, uint16_t offset)
{
	uint16_t optional_opcodes;

	if (IS_GTBS_CHRC(attr)) {
		optional_opcodes = gtbs_inst.optional_opcodes;
		LOG_DBG("GTBS: Supported opcodes 0x%02x", optional_opcodes);
	} else {
		const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);

		optional_opcodes = inst->optional_opcodes;
		LOG_DBG("Index %u: Supported opcodes 0x%02x", inst->index, optional_opcodes);
	}

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

static void terminate_reason_cfg_changed(const struct bt_gatt_attr *attr,
					 uint16_t value)
{
	const struct tbs_service_inst *inst = lookup_inst_by_ccc(attr);

	if (inst != NULL) {
		LOG_DBG("Index %u: value 0x%04x", inst->index, value);
	} else if (IS_ENABLED(CONFIG_BT_GTBS)) {
		LOG_DBG("GTBS: value 0x%04x", value);
	}
}

static ssize_t read_friendly_name(struct bt_conn *conn,
				     const struct bt_gatt_attr *attr,
				     void *buf, uint16_t len, uint16_t offset)
{
	const struct bt_tbs_in_uri *friendly_name;
	size_t val_len;

	if (IS_GTBS_CHRC(attr)) {
		friendly_name = &gtbs_inst.friendly_name;
		LOG_DBG("GTBS: call index 0x%02X, URI %s", friendly_name->call_index,
			friendly_name->uri);
	} else {
		const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);

		friendly_name = &inst->friendly_name;
		LOG_DBG("Index %u: call index 0x%02X, URI %s", inst->index,
			friendly_name->call_index, friendly_name->uri);
	}

	if (friendly_name->call_index == BT_TBS_FREE_CALL_INDEX) {
		LOG_DBG("URI not set");
		return bt_gatt_attr_read(conn, attr, buf, len, offset, NULL, 0);
	}

	val_len = sizeof(friendly_name->call_index) +
			strlen(friendly_name->uri);

	return bt_gatt_attr_read(conn, attr, buf, len, offset,
				 friendly_name, val_len);
}

static void friendly_name_cfg_changed(const struct bt_gatt_attr *attr,
					 uint16_t value)
{
	const struct tbs_service_inst *inst = lookup_inst_by_ccc(attr);

	if (inst != NULL) {
		LOG_DBG("Index %u: value 0x%04x", inst->index, value);
	} else if (IS_ENABLED(CONFIG_BT_GTBS)) {
		LOG_DBG("GTBS: value 0x%04x", value);
	}
}

static ssize_t read_incoming_call(struct bt_conn *conn,
				  const struct bt_gatt_attr *attr,
				  void *buf, uint16_t len, uint16_t offset)
{
	const struct bt_tbs_in_uri *remote_uri;
	size_t val_len;

	if (IS_GTBS_CHRC(attr)) {
		remote_uri = &gtbs_inst.in_call;
		LOG_DBG("GTBS: call index 0x%02X, URI %s", remote_uri->call_index, remote_uri->uri);
	} else {
		const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);

		remote_uri = &inst->in_call;
		LOG_DBG("Index %u: call index 0x%02X, URI %s", inst->index, remote_uri->call_index,
			remote_uri->uri);
	}

	if (remote_uri->call_index == BT_TBS_FREE_CALL_INDEX) {
		LOG_DBG("URI not set");

		return bt_gatt_attr_read(conn, attr, buf, len, offset, NULL, 0);
	}

	val_len = sizeof(remote_uri->call_index) + strlen(remote_uri->uri);

	return bt_gatt_attr_read(conn, attr, buf, len, offset,
				 remote_uri, val_len);
}

static void in_call_cfg_changed(const struct bt_gatt_attr *attr,
				      uint16_t value)
{
	const struct tbs_service_inst *inst = lookup_inst_by_ccc(attr);

	if (inst != NULL) {
		LOG_DBG("Index %u: value 0x%04x", inst->index, value);
	} else if (IS_ENABLED(CONFIG_BT_GTBS)) {
		LOG_DBG("GTBS: value 0x%04x", value);
	}
}

#define BT_TBS_CHR_PROVIDER_NAME(inst) \
	BT_AUDIO_CHRC(BT_UUID_TBS_PROVIDER_NAME, \
		      BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
		      BT_GATT_PERM_READ_ENCRYPT, \
		      read_provider_name, NULL, inst), \
	BT_AUDIO_CCC(provider_name_cfg_changed)

#define BT_TBS_CHR_UCI(inst) \
	BT_AUDIO_CHRC(BT_UUID_TBS_UCI, \
		      BT_GATT_CHRC_READ, \
		      BT_GATT_PERM_READ_ENCRYPT, \
		      read_uci, NULL, inst)

#define BT_TBS_CHR_TECHNOLOGY(inst) \
	BT_AUDIO_CHRC(BT_UUID_TBS_TECHNOLOGY, \
		      BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
		      BT_GATT_PERM_READ_ENCRYPT, \
		      read_technology, NULL, inst), \
	BT_AUDIO_CCC(technology_cfg_changed)

#define BT_TBS_CHR_URI_LIST(inst) \
	BT_AUDIO_CHRC(BT_UUID_TBS_URI_LIST, \
		      BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
		      BT_GATT_PERM_READ_ENCRYPT, \
		      read_uri_scheme_list, NULL, inst), \
	BT_AUDIO_CCC(uri_scheme_list_cfg_changed)

#define BT_TBS_CHR_SIGNAL_STRENGTH(inst) \
	BT_AUDIO_CHRC(BT_UUID_TBS_SIGNAL_STRENGTH, /* Optional */ \
		      BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
		      BT_GATT_PERM_READ_ENCRYPT, \
		      read_signal_strength, NULL, inst), \
	BT_AUDIO_CCC(signal_strength_cfg_changed)

#define BT_TBS_CHR_SIGNAL_INTERVAL(inst) \
	BT_AUDIO_CHRC(BT_UUID_TBS_SIGNAL_INTERVAL, /* Conditional */ \
		      BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | BT_GATT_CHRC_WRITE_WITHOUT_RESP, \
		      BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT, \
		      read_signal_strength_interval, write_signal_strength_interval, inst)

#define BT_TBS_CHR_CURRENT_CALLS(inst) \
	BT_AUDIO_CHRC(BT_UUID_TBS_LIST_CURRENT_CALLS, \
		      BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
		      BT_GATT_PERM_READ_ENCRYPT, \
		      read_current_calls, NULL, inst), \
	BT_AUDIO_CCC(current_calls_cfg_changed)

#define BT_TBS_CHR_CCID(inst) \
	BT_AUDIO_CHRC(BT_UUID_CCID, \
		      BT_GATT_CHRC_READ, \
		      BT_GATT_PERM_READ_ENCRYPT, \
		      read_ccid, NULL, inst)

#define BT_TBS_CHR_STATUS_FLAGS(inst) \
	BT_AUDIO_CHRC(BT_UUID_TBS_STATUS_FLAGS, \
		      BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
		      BT_GATT_PERM_READ_ENCRYPT, \
		      read_status_flags, NULL, inst), \
	BT_AUDIO_CCC(status_flags_cfg_changed)

#define BT_TBS_CHR_INCOMING_URI(inst) \
	BT_AUDIO_CHRC(BT_UUID_TBS_INCOMING_URI, /* Optional */ \
		      BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
		      BT_GATT_PERM_READ_ENCRYPT, \
		      read_incoming_uri, NULL, inst), \
	BT_AUDIO_CCC(incoming_uri_cfg_changed)

#define BT_TBS_CHR_CALL_STATE(inst) \
	BT_AUDIO_CHRC(BT_UUID_TBS_CALL_STATE, \
		      BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
		      BT_GATT_PERM_READ_ENCRYPT, \
		      read_call_state, NULL, inst), \
	BT_AUDIO_CCC(call_state_cfg_changed)

#define BT_TBS_CHR_CONTROL_POINT(inst) \
	BT_AUDIO_CHRC(BT_UUID_TBS_CALL_CONTROL_POINT, \
		      BT_GATT_CHRC_WRITE | BT_GATT_CHRC_NOTIFY | BT_GATT_CHRC_WRITE_WITHOUT_RESP, \
		      BT_GATT_PERM_WRITE_ENCRYPT, \
		      NULL, write_call_cp, inst), \
	BT_AUDIO_CCC(call_cp_cfg_changed)

#define BT_TBS_CHR_OPTIONAL_OPCODES(inst) \
	BT_AUDIO_CHRC(BT_UUID_TBS_OPTIONAL_OPCODES, \
		      BT_GATT_CHRC_READ, \
		      BT_GATT_PERM_READ_ENCRYPT, \
		      read_optional_opcodes, NULL, inst) \

#define BT_TBS_CHR_TERMINATE_REASON(inst) \
	BT_AUDIO_CHRC(BT_UUID_TBS_TERMINATE_REASON, \
		      BT_GATT_CHRC_NOTIFY, \
		      BT_GATT_PERM_READ_ENCRYPT, \
		      NULL, NULL, inst), \
	BT_AUDIO_CCC(terminate_reason_cfg_changed)

#define BT_TBS_CHR_INCOMING_CALL(inst) \
	BT_AUDIO_CHRC(BT_UUID_TBS_INCOMING_CALL, \
		      BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
		      BT_GATT_PERM_READ_ENCRYPT, \
		      read_incoming_call, NULL, inst), \
	BT_AUDIO_CCC(in_call_cfg_changed)

#define BT_TBS_CHR_FRIENDLY_NAME(inst) \
	BT_AUDIO_CHRC(BT_UUID_TBS_FRIENDLY_NAME, /* Optional */ \
		      BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
		      BT_GATT_PERM_READ_ENCRYPT, \
		      read_friendly_name, NULL, inst), \
	BT_AUDIO_CCC(friendly_name_cfg_changed)

#define BT_TBS_SERVICE_DEFINE(_uuid, _inst)                                                        \
	BT_GATT_PRIMARY_SERVICE(_uuid),                                                            \
	BT_TBS_CHR_PROVIDER_NAME(_inst),                                                           \
	BT_TBS_CHR_UCI(_inst),                                                                     \
	BT_TBS_CHR_TECHNOLOGY(_inst),                                                              \
	BT_TBS_CHR_URI_LIST(_inst),                                                                \
	BT_TBS_CHR_SIGNAL_STRENGTH(_inst),                                                         \
	BT_TBS_CHR_SIGNAL_INTERVAL(_inst),                                                         \
	BT_TBS_CHR_CURRENT_CALLS(_inst),                                                           \
	BT_TBS_CHR_CCID(_inst),                                                                    \
	BT_TBS_CHR_STATUS_FLAGS(_inst),                                                            \
	BT_TBS_CHR_INCOMING_URI(_inst),                                                            \
	BT_TBS_CHR_CALL_STATE(_inst),                                                              \
	BT_TBS_CHR_CONTROL_POINT(_inst),                                                           \
	BT_TBS_CHR_OPTIONAL_OPCODES(_inst),                                                        \
	BT_TBS_CHR_TERMINATE_REASON(_inst),                                                        \
	BT_TBS_CHR_INCOMING_CALL(_inst),                                                           \
	BT_TBS_CHR_FRIENDLY_NAME(_inst)

#define BT_TBS_SERVICE_DEFINITION(_inst) { BT_TBS_SERVICE_DEFINE(BT_UUID_TBS, &(_inst)) }

/*
 * Defining this as extern make it possible to link code that otherwise would
 * give "unknown identifier" linking errors.
 */
extern const struct bt_gatt_service_static gtbs_svc;

/* TODO: Can we make the multiple service instance more generic? */
#if CONFIG_BT_GTBS
BT_GATT_SERVICE_DEFINE(gtbs_svc, BT_TBS_SERVICE_DEFINE(BT_UUID_GTBS, &gtbs_inst));
#endif /* CONFIG_BT_GTBS */

BT_GATT_SERVICE_INSTANCE_DEFINE(tbs_service_list, svc_insts, CONFIG_BT_TBS_BEARER_COUNT,
				BT_TBS_SERVICE_DEFINITION);

static void signal_interval_timeout(struct k_work *work)
{
	struct tbs_service_inst *inst = lookup_inst_by_work(work);

	if (inst && inst->pending_signal_strength_notification) {
		bt_gatt_notify_uuid(NULL, BT_UUID_TBS_SIGNAL_STRENGTH,
				    inst->service_p->attrs,
				    &inst->signal_strength,
				    sizeof(inst->signal_strength));

		if (inst->signal_strength_interval) {
			k_work_reschedule(
				&inst->reporting_interval_work,
				K_SECONDS(inst->signal_strength_interval));
		}

		inst->pending_signal_strength_notification = false;
	} else if (IS_ENABLED(CONFIG_BT_GTBS) &&
		   gtbs_inst.pending_signal_strength_notification) {

		bt_gatt_notify_uuid(NULL, BT_UUID_TBS_SIGNAL_STRENGTH,
				    gtbs_inst.service_p->attrs,
				    &gtbs_inst.signal_strength,
				    sizeof(gtbs_inst.signal_strength));

		if (gtbs_inst.signal_strength_interval) {
			k_work_reschedule(
				&gtbs_inst.reporting_interval_work,
				K_SECONDS(gtbs_inst.signal_strength_interval));
		}

		gtbs_inst.pending_signal_strength_notification = false;
	}
}

static int bt_tbs_init(void)
{
	for (size_t i = 0; i < ARRAY_SIZE(svc_insts); i++) {
		int err;

		svc_insts[i].service_p = &tbs_service_list[i];

		err = bt_gatt_service_register(svc_insts[i].service_p);
		if (err != 0) {
			LOG_ERR("Could not register TBS[%d]: %d", i, err);
		}
	}

	if (IS_ENABLED(CONFIG_BT_GTBS)) {
		gtbs_inst.service_p = &gtbs_svc;
		(void)strcpy(gtbs_inst.provider_name, "Generic TBS");
		gtbs_inst.optional_opcodes = CONFIG_BT_TBS_SUPPORTED_FEATURES;
		gtbs_inst.ccid = bt_ccid_get_value();
		(void)strcpy(gtbs_inst.uci, "un000");

		k_work_init_delayable(&gtbs_inst.reporting_interval_work,
				      signal_interval_timeout);
	}

	for (int i = 0; i < ARRAY_SIZE(svc_insts); i++) {
		/* Init default values */
		svc_insts[i].index = i;
		svc_insts[i].ccid = bt_ccid_get_value();
		(void)strcpy(svc_insts[i].provider_name,
			     CONFIG_BT_TBS_PROVIDER_NAME);
		(void)strcpy(svc_insts[i].uci, CONFIG_BT_TBS_UCI);
		(void)strcpy(svc_insts[i].uri_scheme_list,
			     CONFIG_BT_TBS_URI_SCHEMES_LIST);
		svc_insts[i].optional_opcodes = CONFIG_BT_TBS_SUPPORTED_FEATURES;
		svc_insts[i].technology = CONFIG_BT_TBS_TECHNOLOGY;
		svc_insts[i].signal_strength_interval = CONFIG_BT_TBS_SIGNAL_STRENGTH_INTERVAL;
		svc_insts[i].status_flags = CONFIG_BT_TBS_STATUS_FLAGS;

		k_work_init_delayable(&svc_insts[i].reporting_interval_work,
				      signal_interval_timeout);
	}

	return 0;
}

SYS_INIT(bt_tbs_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);

/***************************** Profile API *****************************/
int bt_tbs_accept(uint8_t call_index)
{
	struct tbs_service_inst *inst = lookup_inst_by_call_index(call_index);
	int status = -EINVAL;
	const struct bt_tbs_call_cp_acc ccp = {
		.call_index = call_index,
		.opcode = BT_TBS_CALL_OPCODE_ACCEPT
	};

	if (inst != NULL) {
		status = accept_call(inst, &ccp);
	}

	if (status == BT_TBS_RESULT_CODE_SUCCESS) {
		notify_calls(inst);
	}

	return status;
}

int bt_tbs_hold(uint8_t call_index)
{
	struct tbs_service_inst *inst = lookup_inst_by_call_index(call_index);
	int status = -EINVAL;
	const struct bt_tbs_call_cp_hold ccp = {
		.call_index = call_index,
		.opcode = BT_TBS_CALL_OPCODE_HOLD
	};

	if (inst != NULL) {
		status = tbs_hold_call(inst, &ccp);
	}

	notify_calls(inst);

	return status;
}

int bt_tbs_retrieve(uint8_t call_index)
{
	struct tbs_service_inst *inst = lookup_inst_by_call_index(call_index);
	int status = -EINVAL;
	const struct bt_tbs_call_cp_retrieve ccp = {
		.call_index = call_index,
		.opcode = BT_TBS_CALL_OPCODE_RETRIEVE
	};

	if (inst != NULL) {
		status = retrieve_call(inst, &ccp);
	}

	notify_calls(inst);

	return status;
}

int bt_tbs_terminate(uint8_t call_index)
{
	struct tbs_service_inst *inst = lookup_inst_by_call_index(call_index);
	int status = -EINVAL;
	const struct bt_tbs_call_cp_term ccp = {
		.call_index = call_index,
		.opcode = BT_TBS_CALL_OPCODE_TERMINATE
	};

	if (inst != NULL) {
		status = terminate_call(inst, &ccp,
					BT_TBS_REASON_SERVER_ENDED_CALL);
	}

	notify_calls(inst);

	return status;
}

int bt_tbs_originate(uint8_t bearer_index, char *remote_uri,
		     uint8_t *call_index)
{
	struct tbs_service_inst *inst;
	uint8_t buf[CONFIG_BT_TBS_MAX_URI_LENGTH +
		    sizeof(struct bt_tbs_call_cp_originate)];
	struct bt_tbs_call_cp_originate *ccp =
		(struct bt_tbs_call_cp_originate *)buf;
	size_t uri_len;

	if (bearer_index >= CONFIG_BT_TBS_BEARER_COUNT) {
		return -EINVAL;
	} else if (!bt_tbs_valid_uri(remote_uri)) {
		LOG_DBG("Invalid URI %s", remote_uri);
		return -EINVAL;
	}

	uri_len = strlen(remote_uri);

	inst = &svc_insts[bearer_index];

	ccp->opcode = BT_TBS_CALL_OPCODE_ORIGINATE;
	(void)memcpy(ccp->uri, remote_uri, uri_len);

	return originate_call(inst, ccp, uri_len, call_index);
}

int bt_tbs_join(uint8_t call_index_cnt, uint8_t *call_indexes)
{
	struct tbs_service_inst *inst;
	uint8_t buf[CONFIG_BT_TBS_MAX_CALLS +
		 sizeof(struct bt_tbs_call_cp_join)];
	struct bt_tbs_call_cp_join *ccp = (struct bt_tbs_call_cp_join *)buf;
	int status = -EINVAL;

	if (call_index_cnt != 0 && call_indexes != 0) {
		inst = lookup_inst_by_call_index(call_indexes[0]);
	} else {
		return status;
	}

	if (inst != NULL) {
		ccp->opcode = BT_TBS_CALL_OPCODE_JOIN;
		(void)memcpy(ccp->call_indexes, call_indexes,
		MIN(call_index_cnt, CONFIG_BT_TBS_MAX_CALLS));

		status = join_calls(inst, ccp, call_index_cnt);
	}

	return status;
}

int bt_tbs_remote_answer(uint8_t call_index)
{
	struct tbs_service_inst *inst = lookup_inst_by_call_index(call_index);
	struct bt_tbs_call *call;

	if (inst == NULL) {
		return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
	}

	call = lookup_call_in_inst(inst, call_index);

	if (call == NULL) {
		return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
	}

	if (call->state == BT_TBS_CALL_STATE_ALERTING) {
		call->state = BT_TBS_CALL_STATE_ACTIVE;
		notify_calls(inst);
		return BT_TBS_RESULT_CODE_SUCCESS;
	} else {
		return BT_TBS_RESULT_CODE_STATE_MISMATCH;
	}
}

int bt_tbs_remote_hold(uint8_t call_index)
{
	struct tbs_service_inst *inst = lookup_inst_by_call_index(call_index);
	struct bt_tbs_call *call;
	uint8_t status;

	if (inst == NULL) {
		return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
	}

	call = lookup_call_in_inst(inst, call_index);

	if (call == NULL) {
		return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
	}

	if (call->state == BT_TBS_CALL_STATE_ACTIVE) {
		call->state = BT_TBS_CALL_STATE_REMOTELY_HELD;
		status = BT_TBS_RESULT_CODE_SUCCESS;
	} else if (call->state == BT_TBS_CALL_STATE_LOCALLY_HELD) {
		call->state = BT_TBS_CALL_STATE_LOCALLY_AND_REMOTELY_HELD;
		status = BT_TBS_RESULT_CODE_SUCCESS;
	} else {
		status = BT_TBS_RESULT_CODE_STATE_MISMATCH;
	}

	if (status == BT_TBS_RESULT_CODE_SUCCESS) {
		notify_calls(inst);
	}

	return status;
}

int bt_tbs_remote_retrieve(uint8_t call_index)
{
	struct tbs_service_inst *inst = lookup_inst_by_call_index(call_index);
	struct bt_tbs_call *call;
	int status;

	if (inst == NULL) {
		return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
	}

	call = lookup_call_in_inst(inst, call_index);

	if (call == NULL) {
		return BT_TBS_RESULT_CODE_INVALID_CALL_INDEX;
	}

	if (call->state == BT_TBS_CALL_STATE_REMOTELY_HELD) {
		call->state = BT_TBS_CALL_STATE_ACTIVE;
		status = BT_TBS_RESULT_CODE_SUCCESS;
	} else if (call->state == BT_TBS_CALL_STATE_LOCALLY_AND_REMOTELY_HELD) {
		call->state = BT_TBS_CALL_STATE_LOCALLY_HELD;
		status = BT_TBS_RESULT_CODE_SUCCESS;
	} else {
		status = BT_TBS_RESULT_CODE_STATE_MISMATCH;
	}

	if (status == BT_TBS_RESULT_CODE_SUCCESS) {
		notify_calls(inst);
	}

	return status;
}

int bt_tbs_remote_terminate(uint8_t call_index)
{
	struct tbs_service_inst *inst = lookup_inst_by_call_index(call_index);
	int status = -EINVAL;
	const struct bt_tbs_call_cp_term ccp = {
		.call_index = call_index,
		.opcode = BT_TBS_CALL_OPCODE_TERMINATE
	};

	if (inst != NULL) {
		status = terminate_call(inst, &ccp,
					BT_TBS_REASON_REMOTE_ENDED_CALL);
	}

	notify_calls(inst);

	return status;
}

int bt_tbs_remote_incoming(uint8_t bearer_index, const char *to,
			   const char *from, const char *friendly_name)
{
	struct tbs_service_inst *inst;
	struct bt_tbs_call *call = NULL;
	size_t local_uri_ind_len;
	size_t remote_uri_ind_len;
	size_t friend_name_ind_len;

	if (bearer_index >= CONFIG_BT_TBS_BEARER_COUNT) {
		return -EINVAL;
	} else if (!bt_tbs_valid_uri(to)) {
		LOG_DBG("Invalid \"to\" URI: %s", to);
		return -EINVAL;
	} else if (!bt_tbs_valid_uri(from)) {
		LOG_DBG("Invalid \"from\" URI: %s", from);
		return -EINVAL;
	}

	local_uri_ind_len = strlen(to) + 1;
	remote_uri_ind_len = strlen(from) + 1;

	inst = &svc_insts[bearer_index];

	/* New call - Look for unused call item */
	for (int i = 0; i < CONFIG_BT_TBS_MAX_CALLS; i++) {
		if (inst->calls[i].index == BT_TBS_FREE_CALL_INDEX) {
			call = &inst->calls[i];
			break;
		}
	}

	if (call == NULL) {
		return -BT_TBS_RESULT_CODE_OUT_OF_RESOURCES;
	}

	call->index = next_free_call_index();

	if (call->index == BT_TBS_FREE_CALL_INDEX) {
		return -BT_TBS_RESULT_CODE_OUT_OF_RESOURCES;
	}

	BT_TBS_CALL_FLAG_SET_INCOMING(call->flags);

	(void)strcpy(call->remote_uri, from);
	call->state = BT_TBS_CALL_STATE_INCOMING;

	inst->in_call.call_index = call->index;
	(void)strcpy(inst->in_call.uri, from);

	inst->incoming_uri.call_index = call->index;
	(void)strcpy(inst->incoming_uri.uri, to);

	bt_gatt_notify_uuid(NULL, BT_UUID_TBS_INCOMING_URI,
			    inst->service_p->attrs,
			    &inst->incoming_uri, local_uri_ind_len);

	bt_gatt_notify_uuid(NULL, BT_UUID_TBS_INCOMING_CALL,
			    inst->service_p->attrs,
			    &inst->in_call, remote_uri_ind_len);

	if (friendly_name) {
		inst->friendly_name.call_index = call->index;
		utf8_lcpy(inst->friendly_name.uri, friendly_name, sizeof(inst->friendly_name.uri));
		friend_name_ind_len = strlen(from) + 1;

		bt_gatt_notify_uuid(NULL, BT_UUID_TBS_FRIENDLY_NAME,
				    inst->service_p->attrs,
				    &inst->friendly_name,
				    friend_name_ind_len);
	} else {
		inst->friendly_name.call_index = BT_TBS_FREE_CALL_INDEX;
		bt_gatt_notify_uuid(NULL, BT_UUID_TBS_FRIENDLY_NAME,
				    inst->service_p->attrs, NULL, 0);
	}

	if (IS_ENABLED(CONFIG_BT_GTBS)) {
		gtbs_inst.in_call.call_index = call->index;
		(void)strcpy(gtbs_inst.in_call.uri, from);

		gtbs_inst.incoming_uri.call_index = call->index;
		(void)strcpy(gtbs_inst.incoming_uri.uri, to);

		bt_gatt_notify_uuid(NULL, BT_UUID_TBS_INCOMING_URI,
				    gtbs_inst.service_p->attrs,
				    &gtbs_inst.incoming_uri, local_uri_ind_len);

		bt_gatt_notify_uuid(NULL, BT_UUID_TBS_INCOMING_CALL,
				    gtbs_inst.service_p->attrs,
				    &gtbs_inst.in_call, remote_uri_ind_len);

		if (friendly_name) {
			gtbs_inst.friendly_name.call_index = call->index;
			utf8_lcpy(inst->friendly_name.uri, friendly_name,
				  sizeof(inst->friendly_name.uri));
			friend_name_ind_len = strlen(from) + 1;

			bt_gatt_notify_uuid(NULL, BT_UUID_TBS_FRIENDLY_NAME,
					    gtbs_inst.service_p->attrs,
					    &gtbs_inst.friendly_name,
					    friend_name_ind_len);
		} else {
			gtbs_inst.friendly_name.call_index = 0;
			bt_gatt_notify_uuid(NULL, BT_UUID_TBS_FRIENDLY_NAME,
					    gtbs_inst.service_p->attrs,
					    NULL, 0);
		}
	}

	notify_calls(inst);

	LOG_DBG("New call with call index %u", call->index);

	return call->index;
}

int bt_tbs_set_bearer_provider_name(uint8_t bearer_index, const char *name)
{
	const size_t len = strlen(name);
	const struct bt_gatt_attr *attr;

	if (len >= CONFIG_BT_TBS_MAX_PROVIDER_NAME_LENGTH || len == 0) {
		return -EINVAL;
	} else if (bearer_index >= CONFIG_BT_TBS_BEARER_COUNT) {
		if (!(IS_ENABLED(CONFIG_BT_GTBS) &&
		    bearer_index == BT_TBS_GTBS_INDEX)) {
			return -EINVAL;
		}
	}

	if (bearer_index == BT_TBS_GTBS_INDEX) {
		if (strcmp(gtbs_inst.provider_name, name) == 0) {
			return 0;
		}

		(void)strcpy(gtbs_inst.provider_name, name);
		attr = gtbs_inst.service_p->attrs;
	} else {
		if (strcmp(svc_insts[bearer_index].provider_name, name) == 0) {
			return 0;
		}

		(void)strcpy(svc_insts[bearer_index].provider_name, name);
		attr = svc_insts[bearer_index].service_p->attrs;
	}

	bt_gatt_notify_uuid(NULL, BT_UUID_TBS_PROVIDER_NAME,
			    attr, name, strlen(name));
	return 0;
}

int bt_tbs_set_bearer_technology(uint8_t bearer_index, uint8_t new_technology)
{
	const struct bt_gatt_attr *attr;

	if (new_technology < BT_TBS_TECHNOLOGY_3G ||
	    new_technology > BT_TBS_TECHNOLOGY_IP) {
		return -EINVAL;
	} else if (bearer_index >= CONFIG_BT_TBS_BEARER_COUNT) {
		if (!(IS_ENABLED(CONFIG_BT_GTBS) &&
		    bearer_index == BT_TBS_GTBS_INDEX)) {
			return -EINVAL;
		}
	}

	if (bearer_index == BT_TBS_GTBS_INDEX) {
		if (gtbs_inst.technology == new_technology) {
			return 0;
		}

		gtbs_inst.technology = new_technology;
		attr = gtbs_inst.service_p->attrs;
	} else {
		if (svc_insts[bearer_index].technology == new_technology) {
			return 0;
		}

		svc_insts[bearer_index].technology = new_technology;
		attr = svc_insts[bearer_index].service_p->attrs;
	}

	bt_gatt_notify_uuid(NULL, BT_UUID_TBS_TECHNOLOGY,
			   attr, &new_technology, sizeof(new_technology));

	return 0;
}

int bt_tbs_set_signal_strength(uint8_t bearer_index,
			       uint8_t new_signal_strength)
{
	const struct bt_gatt_attr *attr;
	uint32_t timer_status;
	uint8_t interval;
	struct k_work_delayable *reporting_interval_work;
	struct tbs_service_inst *inst;

	if (new_signal_strength > BT_TBS_SIGNAL_STRENGTH_MAX &&
	    new_signal_strength != BT_TBS_SIGNAL_STRENGTH_UNKNOWN) {
		return -EINVAL;
	} else if (bearer_index >= CONFIG_BT_TBS_BEARER_COUNT) {
		if (!(IS_ENABLED(CONFIG_BT_GTBS) &&
		    bearer_index == BT_TBS_GTBS_INDEX)) {
			return -EINVAL;
		}
	}

	if (bearer_index == BT_TBS_GTBS_INDEX) {
		if (gtbs_inst.signal_strength == new_signal_strength) {
			return 0;
		}

		gtbs_inst.signal_strength = new_signal_strength;
		attr = gtbs_inst.service_p->attrs;
		timer_status = k_work_delayable_remaining_get(
					&gtbs_inst.reporting_interval_work);
		interval = gtbs_inst.signal_strength_interval;
		reporting_interval_work = &gtbs_inst.reporting_interval_work;
	} else {
		inst = &svc_insts[bearer_index];
		if (inst->signal_strength == new_signal_strength) {
			return 0;
		}

		inst->signal_strength = new_signal_strength;
		attr = inst->service_p->attrs;
		timer_status = k_work_delayable_remaining_get(
					&inst->reporting_interval_work);
		interval = inst->signal_strength_interval;
		reporting_interval_work = &inst->reporting_interval_work;
	}

	if (timer_status == 0) {
		const k_timeout_t delay = K_SECONDS(interval);

		bt_gatt_notify_uuid(NULL, BT_UUID_TBS_SIGNAL_STRENGTH,
				    attr, &new_signal_strength,
				    sizeof(new_signal_strength));
		if (interval) {
			k_work_reschedule(reporting_interval_work, delay);
		}
	} else {
		if (bearer_index == BT_TBS_GTBS_INDEX) {
			LOG_DBG("GTBS: Reporting signal strength in %d ms", timer_status);
			gtbs_inst.pending_signal_strength_notification = true;

		} else {
			LOG_DBG("Index %u: Reporting signal strength in %d ms", bearer_index,
				timer_status);
			inst->pending_signal_strength_notification = true;
		}
	}

	return 0;
}

int bt_tbs_set_status_flags(uint8_t bearer_index, uint16_t status_flags)
{
	const struct bt_gatt_attr *attr;

	if (!BT_TBS_VALID_STATUS_FLAGS(status_flags)) {
		return -EINVAL;
	} else if (bearer_index >= CONFIG_BT_TBS_BEARER_COUNT) {
		if (!(IS_ENABLED(CONFIG_BT_GTBS) &&
		    bearer_index == BT_TBS_GTBS_INDEX)) {
			return -EINVAL;
		}
	}

	if (bearer_index == BT_TBS_GTBS_INDEX) {
		if (gtbs_inst.status_flags == status_flags) {
			return 0;
		}

		gtbs_inst.status_flags = status_flags;
		attr = gtbs_inst.service_p->attrs;
	} else {
		if (svc_insts[bearer_index].status_flags == status_flags) {
			return 0;
		}

		svc_insts[bearer_index].status_flags = status_flags;
		attr = svc_insts[bearer_index].service_p->attrs;
	}

	bt_gatt_notify_uuid(NULL, BT_UUID_TBS_STATUS_FLAGS,
			   attr, &status_flags, sizeof(status_flags));
	return 0;
}

int bt_tbs_set_uri_scheme_list(uint8_t bearer_index, const char **uri_list,
			       uint8_t uri_count)
{
	char uri_scheme_list[CONFIG_BT_TBS_MAX_SCHEME_LIST_LENGTH];
	size_t len = 0;
	struct tbs_service_inst *inst;

	if (bearer_index >= CONFIG_BT_TBS_BEARER_COUNT) {
		return -EINVAL;
	}

	inst = &svc_insts[bearer_index];
	(void)memset(uri_scheme_list, 0, sizeof(uri_scheme_list));

	for (int i = 0; i < uri_count; i++) {
		if (len) {
			len++;
			if (len > sizeof(uri_scheme_list) - 1)  {
				return -ENOMEM;
			}

			strcat(uri_scheme_list, ",");
		}

		len += strlen(uri_list[i]);
		if (len > sizeof(uri_scheme_list) - 1)  {
			return -ENOMEM;
		}

		/* Store list in temp list in case something goes wrong */
		strcat(uri_scheme_list, uri_list[i]);
	}

	if (strcmp(inst->uri_scheme_list, uri_scheme_list) == 0) {
		/* identical; don't update or notify */
		return 0;
	}

	/* Store final result */
	(void)strcpy(inst->uri_scheme_list, uri_scheme_list);

	LOG_DBG("TBS instance %u uri prefix list is now %s", bearer_index, inst->uri_scheme_list);

	bt_gatt_notify_uuid(NULL, BT_UUID_TBS_URI_LIST,
			    inst->service_p->attrs, &inst->uri_scheme_list,
			    strlen(inst->uri_scheme_list));

	if (IS_ENABLED(CONFIG_BT_GTBS)) {
		NET_BUF_SIMPLE_DEFINE(uri_scheme_buf, READ_BUF_SIZE);

		/* TODO: Make uri schemes unique */
		for (int i = 0; i < ARRAY_SIZE(svc_insts); i++) {
			const size_t uri_len = strlen(svc_insts[i].uri_scheme_list);

			if (uri_scheme_buf.len + uri_len >= uri_scheme_buf.size) {
				LOG_WRN("Cannot fit all TBS instances in GTBS "
					"URI scheme list");
				break;
			}

			net_buf_simple_add_mem(&uri_scheme_buf,
					       svc_insts[i].uri_scheme_list,
					       uri_len);
		}

		LOG_DBG("GTBS: URI scheme %.*s", uri_scheme_buf.len, uri_scheme_buf.data);

		bt_gatt_notify_uuid(NULL, BT_UUID_TBS_URI_LIST,
				    gtbs_inst.service_p->attrs,
				    uri_scheme_buf.data, uri_scheme_buf.len);
	}

	return 0;
}

void bt_tbs_register_cb(struct bt_tbs_cb *cbs)
{
	tbs_cbs = cbs;
}

#if defined(CONFIG_BT_TBS_LOG_LEVEL_DBG)
void bt_tbs_dbg_print_calls(void)
{
	for (int i = 0; i < CONFIG_BT_TBS_BEARER_COUNT; i++) {
		LOG_DBG("Bearer #%u", i);
		for (int j = 0; j < ARRAY_SIZE(svc_insts[i].calls); j++) {
			struct bt_tbs_call *call = &svc_insts[i].calls[j];

			if (call->index == BT_TBS_FREE_CALL_INDEX) {
				continue;
			}

			LOG_DBG("  Call #%u", call->index);
			LOG_DBG("    State: %s", bt_tbs_state_str(call->state));
			LOG_DBG("    Flags: 0x%02X", call->flags);
			LOG_DBG("    URI  : %s", call->remote_uri);
		}
	}
}
#endif /* defined(CONFIG_BT_TBS_LOG_LEVEL_DBG) */
