/* 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/device.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"

#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_TBS)
#define LOG_MODULE_NAME bt_tbs
#include "common/log.h"

#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 IS_ENABLED(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;
	BT_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 = 1;
		const struct bt_tbs_call *call = lookup_call(next_call_index);

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

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

	BT_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 != BT_TBS_FREE_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;
		BT_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;
		BT_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) {
		BT_DBG("Index %u: value 0x%04x", inst->index, value);
	} else if (IS_ENABLED(CONFIG_BT_GTBS)) {
		BT_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;
		BT_DBG("GTBS: UCI %s", uci);
	} else {
		const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);

		uci = inst->uci;
		BT_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;
		BT_DBG("GTBS: Technology 0x%02X", technology);
	} else {
		const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);

		technology = inst->technology;
		BT_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) {
		BT_DBG("Index %u: value 0x%04x", inst->index, value);
	} else if (IS_ENABLED(CONFIG_BT_GTBS)) {
		BT_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) {
				BT_WARN("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);
		}
		/* Add null terminator for printing */
		read_buf.data[read_buf.len] = '\0';
		BT_DBG("GTBS: URI scheme %s", 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));
		/* Add null terminator for printing */
		read_buf.data[read_buf.len] = '\0';
		BT_DBG("Index %u: URI scheme %s", inst->index,
		       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) {
		BT_DBG("Index %u: value 0x%04x", inst->index, value);
	} else if (IS_ENABLED(CONFIG_BT_GTBS)) {
		BT_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;
		BT_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;
		BT_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) {
		BT_DBG("Index %u: value 0x%04x", inst->index, value);
	} else if (IS_ENABLED(CONFIG_BT_GTBS)) {
		BT_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;
		BT_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;
		BT_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;
		BT_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;
		BT_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) {
		BT_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)) {
		BT_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)) {
		BT_DBG("GTBS");
	} else {
		const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);

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

	if (offset == 0) {
		BT_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;
		BT_DBG("GTBS: CCID 0x%02X", ccid);
	} else {
		const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);

		ccid = inst->ccid;
		BT_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;
		BT_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;
		BT_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) {
		BT_DBG("Index %u: value 0x%04x", inst->index, value);
	} else if (IS_ENABLED(CONFIG_BT_GTBS)) {
		BT_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;
		BT_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;
		BT_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) {
		BT_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) {
		BT_DBG("Index %u: value 0x%04x", inst->index, value);
	} else if (IS_ENABLED(CONFIG_BT_GTBS)) {
		BT_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)) {
		BT_DBG("GTBS");
	} else {
		const struct tbs_service_inst *inst = BT_AUDIO_CHRC_USER_DATA(attr);

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

	if (offset == 0) {
		BT_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) {
		BT_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)) {
		BT_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
	};

	BT_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)) {
		BT_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);

	BT_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, 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) {
			const struct tbs_service_inst *inst =
				lookup_inst_by_call_index(ccp->terminate.call_index);

			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;
		struct tbs_service_inst *inst;

		inst = lookup_inst_by_call_index(call_index);

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

		call = lookup_call_in_inst(inst, call_index);

		if (call == NULL) {
			BT_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) {
		BT_DBG("GTBS: Processing the %s opcode",
		       bt_tbs_opcode_str(ccp->opcode));
	} else {
		inst = BT_AUDIO_CHRC_USER_DATA(attr);

		BT_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) {
			BT_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 {
			BT_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) {
				BT_DBG("Call is now in the %s state",
				       bt_tbs_state_str(call->state));
			} else {
				BT_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 (status == BT_TBS_RESULT_CODE_SUCCESS) {
		notify_calls(inst);
		notify_app(conn, 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) {
		BT_DBG("Index %u: value 0x%04x", inst->index, value);
	} else if (IS_ENABLED(CONFIG_BT_GTBS)) {
		BT_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;
		BT_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;
		BT_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) {
		BT_DBG("Index %u: value 0x%04x", inst->index, value);
	} else if (IS_ENABLED(CONFIG_BT_GTBS)) {
		BT_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;
		BT_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;
		BT_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) {
		BT_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) {
		BT_DBG("Index %u: value 0x%04x", inst->index, value);
	} else if (IS_ENABLED(CONFIG_BT_GTBS)) {
		BT_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;
		BT_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;
		BT_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) {
		BT_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) {
		BT_DBG("Index %u: value 0x%04x", inst->index, value);
	} else if (IS_ENABLED(CONFIG_BT_GTBS)) {
		BT_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_DEFINITION(inst) {\
	BT_GATT_PRIMARY_SERVICE(BT_UUID_TBS), \
	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_GTBS_SERVICE_DEFINITION(inst) \
	BT_GATT_PRIMARY_SERVICE(BT_UUID_GTBS), \
	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)

/*
 * 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_GTBS_SERVICE_DEFINITION(&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(const struct device *unused)
{
	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) {
			BT_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;
}

DEVICE_DEFINE(bt_tbs, "bt_tbs", &bt_tbs_init, NULL, NULL, NULL,
	      APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, NULL);

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

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

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

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

	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)) {
		BT_DBG("Invalid \"to\" URI: %s", to);
		return -EINVAL;
	} else if (!bt_tbs_valid_uri(from)) {
		BT_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;
		(void)strcpy(inst->friendly_name.uri, friendly_name);
		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;
			(void)strcpy(gtbs_inst.friendly_name.uri, friendly_name);
			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);

	BT_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) {
			BT_DBG("GTBS: Reporting signal strength in %d ms",
			       timer_status);
			gtbs_inst.pending_signal_strength_notification = true;

		} else {
			BT_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);

	BT_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) {
				BT_WARN("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);
		}

		/* Add null terminator for printing */
		uri_scheme_buf.data[uri_scheme_buf.len] = '\0';
		BT_DBG("GTBS: URI scheme %s", 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_DEBUG_TBS)
void bt_tbs_dbg_print_calls(void)
{
	for (int i = 0; i < CONFIG_BT_TBS_BEARER_COUNT; i++) {
		BT_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;
			}

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