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

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

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

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/buf.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/bluetooth/audio/tbs.h>

#include "tbs_internal.h"

#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_TBS_CLIENT)
#define LOG_MODULE_NAME bt_tbs_client
#include "common/log.h"

#define MAX_URI_SCHEME_LIST_SIZE   64
#if IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS)
#define BT_TBS_INSTANCE_MAX_CNT    (CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES + 1)
#else
#define BT_TBS_INSTANCE_MAX_CNT    CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES
#endif /* IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) */
#define GTBS_INDEX                 CONFIG_BT_TBS_CLIENT_MAX_TBS_INSTANCES

struct bt_tbs_instance {
	struct bt_tbs_client_call_state calls[CONFIG_BT_TBS_CLIENT_MAX_CALLS];

	uint16_t start_handle;
	uint16_t end_handle;
	uint16_t provider_name_handle;
	uint16_t bearer_uci_handle;
	uint16_t technology_handle;
	uint16_t uri_list_handle;
	uint16_t signal_strength_handle;
	uint16_t signal_interval_handle;
	uint16_t current_calls_handle;
	uint16_t ccid_handle;
	uint16_t status_flags_handle;
	uint16_t in_uri_handle;
	uint16_t call_state_handle;
	uint16_t call_cp_handle;
	uint16_t optional_opcodes_handle;
	uint16_t termination_reason_handle;
	uint16_t friendly_name_handle;
	uint16_t in_call_handle;

	bool busy;
	uint8_t subscribe_cnt;
	uint8_t index;
	bool gtbs;

	struct bt_gatt_subscribe_params name_sub_params;
	struct bt_gatt_discover_params name_sub_disc_params;
	struct bt_gatt_subscribe_params technology_sub_params;
	struct bt_gatt_discover_params technology_sub_disc_params;
	struct bt_gatt_subscribe_params signal_strength_sub_params;
	struct bt_gatt_discover_params signal_strength_sub_disc_params;
	struct bt_gatt_subscribe_params current_calls_sub_params;
	struct bt_gatt_discover_params current_calls_sub_disc_params;
	struct bt_gatt_subscribe_params in_target_uri_sub_params;
	struct bt_gatt_discover_params in_target_uri_sub_disc_params;
	struct bt_gatt_subscribe_params status_flags_sub_params;
	struct bt_gatt_discover_params status_sub_disc_params;
	struct bt_gatt_subscribe_params call_state_sub_params;
	struct bt_gatt_discover_params call_state_sub_disc_params;
	struct bt_gatt_subscribe_params call_cp_sub_params;
	struct bt_gatt_discover_params call_cp_sub_disc_params;
	struct bt_gatt_subscribe_params termination_sub_params;
	struct bt_gatt_discover_params termination_sub_disc_params;
	struct bt_gatt_subscribe_params incoming_call_sub_params;
	struct bt_gatt_discover_params incoming_call_sub_disc_params;
	struct bt_gatt_subscribe_params friendly_name_sub_params;
	struct bt_gatt_discover_params friendly_name_sub_disc_params;

	struct bt_gatt_read_params read_params;
	uint8_t read_buf[BT_ATT_MAX_ATTRIBUTE_LEN];
	struct net_buf_simple net_buf;
};

struct bt_tbs_server_inst {
	struct bt_tbs_instance tbs_insts[BT_TBS_INSTANCE_MAX_CNT];
	struct bt_gatt_discover_params discover_params;
	struct bt_tbs_instance *current_inst;
	uint8_t inst_cnt;
	bool gtbs_found;
	bool subscribe_all;
};

static const struct bt_tbs_client_cb *tbs_client_cbs;

static struct bt_tbs_server_inst srv_insts[CONFIG_BT_MAX_CONN];
static const struct bt_uuid *tbs_uuid = BT_UUID_TBS;
static const struct bt_uuid *gtbs_uuid = BT_UUID_GTBS;

static void discover_next_instance(struct bt_conn *conn, uint8_t index);

static bool valid_inst_index(struct bt_conn *conn, uint8_t idx)
{
	uint8_t conn_index;

	__ASSERT(conn, "NULL conn");

	conn_index = bt_conn_index(conn);

	if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) && idx == BT_TBS_GTBS_INDEX) {
		return true;
	} else {
		return idx < srv_insts[conn_index].inst_cnt;
	}
}

static struct bt_tbs_instance *get_inst_by_index(struct bt_conn *conn,
						 uint8_t idx)
{
	uint8_t conn_index;

	__ASSERT(conn, "NULL conn");

	conn_index = bt_conn_index(conn);

	if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) && idx == BT_TBS_GTBS_INDEX) {
		return &srv_insts[conn_index].tbs_insts[GTBS_INDEX];
	} else {
		return &srv_insts[conn_index].tbs_insts[idx];
	}
}

static bool free_call_spot(struct bt_tbs_instance *inst)
{
	for (int i = 0; i < CONFIG_BT_TBS_CLIENT_MAX_CALLS; i++) {
		if (inst->calls[i].index == BT_TBS_FREE_CALL_INDEX) {
			return true;
		}
	}

	return false;
}

static struct bt_tbs_instance *lookup_inst_by_handle(struct bt_conn *conn,
							 uint16_t handle)
{
	uint8_t conn_index;
	struct bt_tbs_server_inst *srv_inst;

	__ASSERT(conn, "NULL conn");

	conn_index = bt_conn_index(conn);
	srv_inst = &srv_insts[conn_index];

	for (size_t i = 0; i < ARRAY_SIZE(srv_inst->tbs_insts); i++) {
		if (srv_inst->tbs_insts[i].start_handle <= handle &&
		    srv_inst->tbs_insts[i].end_handle >= handle) {
			return &srv_inst->tbs_insts[i];
		}
	}
	BT_DBG("Could not find instance with handle 0x%04x", handle);

	return NULL;
}

static uint8_t net_buf_pull_call_state(struct net_buf_simple *buf,
				       struct bt_tbs_client_call_state *call_state)
{
	if (buf->len < sizeof(*call_state)) {
		BT_DBG("Invalid buffer length %u", buf->len);
		return BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
	}

	call_state->index = net_buf_simple_pull_u8(buf);
	call_state->state = net_buf_simple_pull_u8(buf);
	call_state->flags = net_buf_simple_pull_u8(buf);

	return 0;
}


static uint8_t net_buf_pull_call(struct net_buf_simple *buf,
				 struct bt_tbs_client_call *call)
{
	const size_t min_item_len = sizeof(call->call_info) + BT_TBS_MIN_URI_LEN;
	uint8_t item_len;
	uint8_t uri_len;
	uint8_t err;
	uint8_t *uri;

	__ASSERT(buf, "NULL buf");
	__ASSERT(call, "NULL call");

	if (buf->len < sizeof(item_len) + min_item_len) {
		BT_DBG("Invalid buffer length %u", buf->len);
		return BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
	}

	item_len = net_buf_simple_pull_u8(buf);
	uri_len = item_len - sizeof(call->call_info);

	if (item_len > buf->len || item_len < min_item_len) {
		BT_DBG("Invalid current call item length %u", item_len);
		return BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
	}

	err = net_buf_pull_call_state(buf, &call->call_info);
	if (err != 0) {
		return err;
	}

	uri = net_buf_simple_pull_mem(buf, uri_len);
	if (uri_len > sizeof(call->remote_uri) - 1) {
		BT_WARN("Current call (index %u) uri length larger than supported %u/%zu",
			call->call_info.index, uri_len,
			sizeof(call->remote_uri) - 1);
		return BT_ATT_ERR_INSUFFICIENT_RESOURCES;
	}

	(void)memcpy(call->remote_uri, uri, uri_len);
	call->remote_uri[uri_len] = '\0';

	return 0;
}

static void call_cp_callback_handler(struct bt_conn *conn, int err,
				     uint8_t index, uint8_t opcode,
				     uint8_t call_index)
{
	bt_tbs_client_cp_cb cp_cb = NULL;

	BT_DBG("Status: %s for the %s opcode for call 0x%02x",
	       bt_tbs_status_str(err), bt_tbs_opcode_str(opcode), call_index);

	if (tbs_client_cbs == NULL) {
		return;
	}

	switch (opcode) {
	case BT_TBS_CALL_OPCODE_ACCEPT:
		cp_cb = tbs_client_cbs->accept_call;
		break;
	case BT_TBS_CALL_OPCODE_TERMINATE:
		cp_cb = tbs_client_cbs->terminate_call;
		break;
	case BT_TBS_CALL_OPCODE_HOLD:
		cp_cb = tbs_client_cbs->hold_call;
		break;
	case BT_TBS_CALL_OPCODE_RETRIEVE:
		cp_cb = tbs_client_cbs->retrieve_call;
		break;
	case BT_TBS_CALL_OPCODE_ORIGINATE:
		cp_cb = tbs_client_cbs->originate_call;
		break;
	case BT_TBS_CALL_OPCODE_JOIN:
		cp_cb = tbs_client_cbs->join_calls;
		break;
	default:
		break;
	}

	if (cp_cb != 0) {
		cp_cb(conn, err, index, call_index);
	}
}

static const char *parse_string_value(const void *data, uint16_t length,
				      uint16_t max_len)
{
	static char string_val[CONFIG_BT_TBS_MAX_URI_LENGTH + 1];
	const size_t len = MIN(length, max_len);

	if (len != 0) {
		(void)memcpy(string_val, data, len);
	}

	string_val[len] = '\0';

	return string_val;
}

static void provider_name_notify_handler(struct bt_conn *conn,
					 const struct bt_tbs_instance *tbs_inst,
					 const void *data, uint16_t length)
{
	const char *name = parse_string_value(data, length,
					      CONFIG_BT_TBS_MAX_PROVIDER_NAME_LENGTH);

	BT_DBG("%s", name);

	if (tbs_client_cbs != NULL && tbs_client_cbs->bearer_provider_name != NULL) {
		tbs_client_cbs->bearer_provider_name(conn, 0, tbs_inst->index, name);
	}
}

static void technology_notify_handler(struct bt_conn *conn,
				      const struct bt_tbs_instance *tbs_inst,
				      const void *data, uint16_t length)
{
	uint8_t technology;

	BT_DBG("");

	if (length == sizeof(technology)) {
		(void)memcpy(&technology, data, length);
		BT_DBG("%s (0x%02x)",
		       bt_tbs_technology_str(technology), technology);

		if (tbs_client_cbs != NULL && tbs_client_cbs->technology != NULL) {
			tbs_client_cbs->technology(conn, 0, tbs_inst->index,
					    technology);
		}
	}
}

static void signal_strength_notify_handler(struct bt_conn *conn,
					   const struct bt_tbs_instance *tbs_inst,
					   const void *data, uint16_t length)
{
	uint8_t signal_strength;

	BT_DBG("");

	if (length == sizeof(signal_strength)) {
		(void)memcpy(&signal_strength, data, length);
		BT_DBG("0x%02x", signal_strength);

		if (tbs_client_cbs != NULL && tbs_client_cbs->signal_strength != NULL) {
			tbs_client_cbs->signal_strength(conn, 0, tbs_inst->index,
						 signal_strength);
		}
	}
}

static void current_calls_notify_handler(struct bt_conn *conn,
					 const struct bt_tbs_instance *tbs_inst,
					 const void *data, uint16_t length)
{
	struct bt_tbs_client_call calls[CONFIG_BT_TBS_CLIENT_MAX_CALLS];
	uint8_t cnt = 0;
	struct net_buf_simple buf;

	BT_DBG("");

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

	/* TODO: If length == MTU, do long read for all calls */

	while (buf.len) {
		struct bt_tbs_client_call *call = &calls[cnt];
		int err;

		err = net_buf_pull_call(&buf, call);
		if (err == BT_ATT_ERR_INSUFFICIENT_RESOURCES) {
			BT_WARN("Call with skipped due to too long URI");
			continue;
		} else if (err != 0) {
			BT_DBG("Invalid current call notification: %d", err);
			return;
		}

		cnt++;
		if (cnt == CONFIG_BT_TBS_CLIENT_MAX_CALLS) {
			BT_WARN("Could not parse all calls due to memory restrictions");
			break;
		}
	}

	if (tbs_client_cbs != NULL && tbs_client_cbs->current_calls != NULL) {
		tbs_client_cbs->current_calls(conn, 0, tbs_inst->index, cnt, calls);
	}
}

static void status_flags_notify_handler(struct bt_conn *conn,
					const struct bt_tbs_instance *tbs_inst,
					const void *data, uint16_t length)
{
	uint16_t status_flags;

	BT_DBG("");

	if (length == sizeof(status_flags)) {
		(void)memcpy(&status_flags, data, length);
		BT_DBG("0x%04x", status_flags);
		if (tbs_client_cbs != NULL && tbs_client_cbs->status_flags != NULL) {
			tbs_client_cbs->status_flags(conn, 0, tbs_inst->index,
					      status_flags);
		}
	}
}

static void incoming_uri_notify_handler(struct bt_conn *conn,
					const struct bt_tbs_instance *tbs_inst,
					const void *data, uint16_t length)
{
	const char *uri = parse_string_value(data, length,
					     CONFIG_BT_TBS_MAX_URI_LENGTH);

	BT_DBG("%s", uri);

	if (tbs_client_cbs != NULL && tbs_client_cbs->call_uri != NULL) {
		tbs_client_cbs->call_uri(conn, 0, tbs_inst->index, uri);
	}
}

static void call_state_notify_handler(struct bt_conn *conn,
				      const struct bt_tbs_instance *tbs_inst,
				      const void *data, uint16_t length)
{
	struct bt_tbs_client_call_state call_states[CONFIG_BT_TBS_CLIENT_MAX_CALLS];
	uint8_t cnt = 0;
	struct net_buf_simple buf;

	BT_DBG("");

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

	/* TODO: If length == MTU, do long read for all call states */

	while (buf.len) {
		struct bt_tbs_client_call_state *call_state = &call_states[cnt];
		int err;

		err = net_buf_pull_call_state(&buf, call_state);
		if (err != 0) {
			BT_DBG("Invalid current call notification: %d", err);
			return;
		}

		cnt++;
		if (cnt == CONFIG_BT_TBS_CLIENT_MAX_CALLS) {
			BT_WARN("Could not parse all calls due to memory restrictions");
			break;
		}
	}

	if (tbs_client_cbs != NULL && tbs_client_cbs->call_state != NULL) {
		tbs_client_cbs->call_state(conn, 0, tbs_inst->index, cnt, call_states);
	}
}

static void call_cp_notify_handler(struct bt_conn *conn,
				  const struct bt_tbs_instance *tbs_inst,
				  const void *data, uint16_t length)
{
	struct bt_tbs_call_cp_notify *ind_val;

	BT_DBG("");

	if (length == sizeof(*ind_val)) {
		ind_val = (struct bt_tbs_call_cp_notify *)data;
		BT_DBG("Status: %s for the %s opcode for call 0x%02X",
		       bt_tbs_status_str(ind_val->status),
		       bt_tbs_opcode_str(ind_val->opcode),
		       ind_val->call_index);

		call_cp_callback_handler(conn, ind_val->status, tbs_inst->index,
					 ind_val->opcode, ind_val->call_index);
	}
}

static void termination_reason_notify_handler(struct bt_conn *conn,
					      const struct bt_tbs_instance *tbs_inst,
					      const void *data, uint16_t length)
{
	struct bt_tbs_terminate_reason reason;

	BT_DBG("");

	if (length == sizeof(reason)) {
		(void)memcpy(&reason, data, length);
		BT_DBG("ID 0x%02X, reason %s",
		       reason.call_index,
		       bt_tbs_term_reason_str(reason.reason));

		if (tbs_client_cbs != NULL && tbs_client_cbs->termination_reason != NULL) {
			tbs_client_cbs->termination_reason(conn, 0, tbs_inst->index,
						    reason.call_index,
						    reason.reason);
		}
	}
}

static void in_call_notify_handler(struct bt_conn *conn,
				   const struct bt_tbs_instance *tbs_inst,
				   const void *data, uint16_t length)
{
	const char *uri = parse_string_value(data, length,
					     CONFIG_BT_TBS_MAX_URI_LENGTH);

	BT_DBG("%s", uri);

	if (tbs_client_cbs != NULL && tbs_client_cbs->remote_uri != NULL) {
		tbs_client_cbs->remote_uri(conn, 0, tbs_inst->index, uri);
	}
}

static void friendly_name_notify_handler(struct bt_conn *conn,
					 const struct bt_tbs_instance *tbs_inst,
					 const void *data, uint16_t length)
{
	const char *name = parse_string_value(data, length,
					      CONFIG_BT_TBS_MAX_URI_LENGTH);

	BT_DBG("%s", name);

	if (tbs_client_cbs != NULL && tbs_client_cbs->friendly_name != NULL) {
		tbs_client_cbs->friendly_name(conn, 0, tbs_inst->index, name);
	}
}

/** @brief Handles notifications and indications from the server */
static uint8_t notify_handler(struct bt_conn *conn,
			      struct bt_gatt_subscribe_params *params,
			      const void *data, uint16_t length)
{
	uint16_t handle = params->value_handle;
	struct bt_tbs_instance *tbs_inst = lookup_inst_by_handle(conn, handle);

	if (data == NULL) {
		BT_DBG("[UNSUBSCRIBED] 0x%04X", params->value_handle);
		params->value_handle = 0U;
		if (tbs_inst != NULL) {
			tbs_inst->subscribe_cnt--;
		}

		return BT_GATT_ITER_STOP;
	}

	if (tbs_inst != NULL) {
		if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) && tbs_inst->gtbs) {
			BT_DBG("GTBS");
		} else {
			BT_DBG("Index %u", tbs_inst->index);
		}

		BT_HEXDUMP_DBG(data, length, "notify handler value");

		if (handle == tbs_inst->provider_name_handle) {
			provider_name_notify_handler(conn, tbs_inst, data,
						     length);
		} else if (handle == tbs_inst->technology_handle) {
			technology_notify_handler(conn, tbs_inst, data, length);
		} else if (handle == tbs_inst->signal_strength_handle) {
			signal_strength_notify_handler(conn, tbs_inst, data,
						       length);
		} else if (handle == tbs_inst->status_flags_handle) {
			status_flags_notify_handler(conn, tbs_inst, data,
						    length);
		} else if (handle == tbs_inst->current_calls_handle) {
			current_calls_notify_handler(conn, tbs_inst, data,
						     length);
		} else if (handle == tbs_inst->in_uri_handle) {
			incoming_uri_notify_handler(conn, tbs_inst, data,
						    length);
		} else if (handle == tbs_inst->call_state_handle) {
			call_state_notify_handler(conn, tbs_inst, data, length);
		} else if (handle == tbs_inst->call_cp_handle) {
			call_cp_notify_handler(conn, tbs_inst, data, length);
		} else if (handle == tbs_inst->termination_reason_handle) {
			termination_reason_notify_handler(conn, tbs_inst, data,
							  length);
		} else if (handle == tbs_inst->in_call_handle) {
			in_call_notify_handler(conn, tbs_inst, data, length);
		} else if (handle == tbs_inst->friendly_name_handle) {
			friendly_name_notify_handler(conn, tbs_inst, data,
						     length);
		}
	} else {
		BT_DBG("Notification/Indication on unknown TBS inst");
	}

	return BT_GATT_ITER_CONTINUE;
}

static int tbs_client_common_call_control(struct bt_conn *conn,
					  uint8_t inst_index,
					  uint8_t call_index,
					  uint8_t opcode)
{
	const struct bt_tbs_instance *inst = get_inst_by_index(conn, inst_index);
	struct bt_tbs_call_cp_acc common;

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

	if (inst->call_cp_handle == 0) {
		BT_DBG("Handle not set");
		return -EINVAL;
	}

	common.opcode = opcode;
	common.call_index = call_index;

	return bt_gatt_write_without_response(conn, inst->call_cp_handle,
					      &common, sizeof(common), false);
}

static uint8_t read_bearer_provider_name_cb(struct bt_conn *conn, uint8_t err,
					    struct bt_gatt_read_params *params,
					    const void *data, uint16_t length)
{
	struct bt_tbs_instance *inst = CONTAINER_OF(params, struct bt_tbs_instance, read_params);

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

	if (inst != NULL) {
		const char *provider_name = NULL;

		if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) && inst->gtbs) {
			BT_DBG("GTBS");
		} else {
			BT_DBG("Index %u", inst->index);
		}

		if (err != 0) {
			BT_DBG("err: 0x%02X", err);
		} else if (data != NULL) {
			provider_name =
				parse_string_value(data, length,
					CONFIG_BT_TBS_MAX_PROVIDER_NAME_LENGTH);
			BT_DBG("%s", provider_name);
		}

		inst->busy = false;

		if (tbs_client_cbs != NULL && tbs_client_cbs->bearer_provider_name != NULL) {
			tbs_client_cbs->bearer_provider_name(conn, err, inst->index,
						      provider_name);
		}
	}

	return BT_GATT_ITER_STOP;
}

static uint8_t read_bearer_uci_cb(struct bt_conn *conn, uint8_t err,
				   struct bt_gatt_read_params *params,
				   const void *data, uint16_t length)
{
	struct bt_tbs_instance *inst = CONTAINER_OF(params, struct bt_tbs_instance, read_params);

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

	if (inst != NULL) {
		const char *bearer_uci = NULL;

		if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) && inst->gtbs) {
			BT_DBG("GTBS");
		} else {
			BT_DBG("Index %u", inst->index);
		}

		if (err != 0) {
			BT_DBG("err: 0x%02X", err);
		} else if (data != NULL) {
			bearer_uci = parse_string_value(data, length,
							BT_TBS_MAX_UCI_SIZE);
			BT_DBG("%s", bearer_uci);
		}

		inst->busy = false;

		if (tbs_client_cbs != NULL && tbs_client_cbs->bearer_uci != NULL) {
			tbs_client_cbs->bearer_uci(conn, err, inst->index, bearer_uci);
		}
	}

	return BT_GATT_ITER_STOP;
}

static uint8_t read_technology_cb(struct bt_conn *conn, uint8_t err,
				   struct bt_gatt_read_params *params,
				   const void *data, uint16_t length)
{
	struct bt_tbs_instance *inst = CONTAINER_OF(params, struct bt_tbs_instance, read_params);

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

	if (inst != NULL) {
		uint8_t cb_err = err;
		uint8_t technology = 0;

		if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) && inst->gtbs) {
			BT_DBG("GTBS");
		} else {
			BT_DBG("Index %u", inst->index);
		}

		if (err != 0) {
			BT_DBG("err: 0x%02X", err);
		} else if (data != NULL) {
			BT_HEXDUMP_DBG(data, length, "Data read");
			if (length == sizeof(technology)) {
				(void)memcpy(&technology, data, length);
				BT_DBG("%s (0x%02x)",
				       bt_tbs_technology_str(technology),
				       technology);
			} else {
				BT_DBG("Invalid length");
				cb_err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
			}
		}

		inst->busy = false;

		if (tbs_client_cbs != NULL && tbs_client_cbs->technology != NULL) {
			tbs_client_cbs->technology(conn, cb_err, inst->index,
					    technology);
		}
	}

	return BT_GATT_ITER_STOP;
}

static uint8_t read_uri_list_cb(struct bt_conn *conn, uint8_t err,
				    struct bt_gatt_read_params *params,
				    const void *data, uint16_t length)
{
	struct bt_tbs_instance *inst = CONTAINER_OF(params, struct bt_tbs_instance, read_params);

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

	if (inst != NULL) {
		const char *uri_scheme_list = NULL;

		if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) && inst->gtbs) {
			BT_DBG("GTBS");
		} else {
			BT_DBG("Index %u", inst->index);
		}

		if (err != 0) {
			BT_DBG("err: 0x%02X", err);
		} else if (data != NULL) {
			uri_scheme_list = parse_string_value(data, length,
						MAX_URI_SCHEME_LIST_SIZE);
			BT_DBG("%s", uri_scheme_list);
		}

		inst->busy = false;

		if (tbs_client_cbs != NULL && tbs_client_cbs->uri_list != NULL) {
			tbs_client_cbs->uri_list(conn, err, inst->index,
					  uri_scheme_list);
		}
	}

	return BT_GATT_ITER_STOP;
}

static uint8_t read_signal_strength_cb(struct bt_conn *conn, uint8_t err,
					struct bt_gatt_read_params *params,
					const void *data, uint16_t length)
{
	struct bt_tbs_instance *inst = CONTAINER_OF(params, struct bt_tbs_instance, read_params);

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

	if (inst != NULL) {
		uint8_t cb_err = err;
		uint8_t signal_strength = 0;

		if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) && inst->gtbs) {
			BT_DBG("GTBS");
		} else {
			BT_DBG("Index %u", inst->index);
		}

		if (err != 0) {
			BT_DBG("err: 0x%02X", err);
		} else if (data != NULL) {
			BT_HEXDUMP_DBG(data, length, "Data read");
			if (length == sizeof(signal_strength)) {
				(void)memcpy(&signal_strength, data, length);
				BT_DBG("0x%02x", signal_strength);
			} else {
				BT_DBG("Invalid length");
				cb_err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
			}
		}

		inst->busy = false;

		if (tbs_client_cbs != NULL && tbs_client_cbs->signal_strength != NULL) {
			tbs_client_cbs->signal_strength(conn, cb_err, inst->index,
						 signal_strength);
		}
	}

	return BT_GATT_ITER_STOP;
}

static uint8_t read_signal_interval_cb(struct bt_conn *conn, uint8_t err,
					struct bt_gatt_read_params *params,
					const void *data, uint16_t length)
{
	struct bt_tbs_instance *inst = CONTAINER_OF(params, struct bt_tbs_instance, read_params);

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

	if (inst != NULL) {
		uint8_t cb_err = err;
		uint8_t signal_interval = 0;

		if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) && inst->gtbs) {
			BT_DBG("GTBS");
		} else {
			BT_DBG("Index %u", inst->index);
		}

		if (err != 0) {
			BT_DBG("err: 0x%02X", err);
		} else if (data != NULL) {
			BT_HEXDUMP_DBG(data, length, "Data read");
			if (length == sizeof(signal_interval)) {
				(void)memcpy(&signal_interval, data, length);
				BT_DBG("0x%02x", signal_interval);
			} else {
				BT_DBG("Invalid length");
				cb_err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
			}
		}

		inst->busy = false;

		if (tbs_client_cbs && tbs_client_cbs->signal_interval) {
			tbs_client_cbs->signal_interval(conn, cb_err, inst->index,
						 signal_interval);
		}
	}

	return BT_GATT_ITER_STOP;
}

static uint8_t read_current_calls_cb(struct bt_conn *conn, uint8_t err,
				      struct bt_gatt_read_params *params,
				      const void *data, uint16_t length)
{
	struct bt_tbs_instance *inst = CONTAINER_OF(params, struct bt_tbs_instance, read_params);
	int tbs_err = err;
	struct bt_tbs_client_call calls[CONFIG_BT_TBS_CLIENT_MAX_CALLS];
	uint8_t cnt = 0;

	if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) && inst->gtbs) {
		BT_DBG("GTBS");
	} else {
		BT_DBG("Index %u", inst->index);
	}

	if (tbs_err != 0) {
		BT_DBG("err: %d", tbs_err);
		(void)memset(params, 0, sizeof(*params));
		if (tbs_client_cbs != NULL &&
		    tbs_client_cbs->current_calls != NULL) {
			tbs_client_cbs->current_calls(conn, tbs_err,
						      inst->index, 0, NULL);
		}

		return BT_GATT_ITER_STOP;
	}

	if (data != NULL) {
		BT_DBG("Current calls read (offset %u): %s",
		       params->single.offset, bt_hex(data, length));

		if (inst->net_buf.size < inst->net_buf.len + length) {
			BT_DBG("Could not read all data, aborting");
			(void)memset(params, 0, sizeof(*params));

			if (tbs_client_cbs != NULL &&
			    tbs_client_cbs->current_calls != NULL) {
				tbs_err = BT_ATT_ERR_INSUFFICIENT_RESOURCES;
				tbs_client_cbs->current_calls(conn, err,
							      inst->index,
							      0, NULL);
			}

			return BT_GATT_ITER_STOP;
		}

		net_buf_simple_add_mem(&inst->net_buf, data, length);

		/* Returning continue will try to read more using read long procedure */
		return BT_GATT_ITER_CONTINUE;
	}

	if (inst->net_buf.len == 0) {
		(void)memset(params, 0, sizeof(*params));
		if (tbs_client_cbs != NULL &&
		    tbs_client_cbs->current_calls != NULL) {
			tbs_client_cbs->current_calls(conn, 0, inst->index, 0,
						      NULL);
		}

		return BT_GATT_ITER_STOP;
	}

	/* Finished reading, start parsing */
	while (inst->net_buf.len != 0) {
		struct bt_tbs_client_call *call = &calls[cnt];

		tbs_err = net_buf_pull_call(&inst->net_buf, call);
		if (tbs_err == BT_ATT_ERR_INSUFFICIENT_RESOURCES) {
			BT_WARN("Call skipped due to too long URI");
			continue;
		} else if (tbs_err != 0) {
			BT_DBG("Invalid current call read: %d", err);
			break;
		}

		cnt++;
		if (cnt == CONFIG_BT_TBS_CLIENT_MAX_CALLS) {
			BT_WARN("Could not parse all calls due to memory restrictions");
			break;
		}
	}

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

	if (tbs_client_cbs != NULL && tbs_client_cbs->current_calls != NULL) {
		tbs_client_cbs->current_calls(conn, tbs_err, inst->index, cnt,
					      calls);
	}

	return BT_GATT_ITER_STOP;
}

static uint8_t read_ccid_cb(struct bt_conn *conn, uint8_t err,
			    struct bt_gatt_read_params *params,
			    const void *data, uint16_t length)
{
	struct bt_tbs_instance *inst = CONTAINER_OF(params, struct bt_tbs_instance, read_params);

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

	if (inst != NULL) {
		uint8_t cb_err = err;
		uint8_t ccid = 0;

		if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) && inst->gtbs) {
			BT_DBG("GTBS");
		} else {
			BT_DBG("Index %u", inst->index);
		}

		if (err != 0) {
			BT_DBG("err: 0x%02X", err);
		} else if (data != NULL) {
			BT_HEXDUMP_DBG(data, length, "Data read");
			if (length == sizeof(ccid)) {
				(void)memcpy(&ccid, data, length);
				BT_DBG("0x%02x", ccid);
			} else {
				BT_DBG("Invalid length");
				cb_err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
			}
		}

		inst->busy = false;

		if (tbs_client_cbs != NULL && tbs_client_cbs->ccid != NULL) {
			tbs_client_cbs->ccid(conn, cb_err, inst->index, ccid);
		}
	}

	return BT_GATT_ITER_STOP;
}

static uint8_t read_status_flags_cb(struct bt_conn *conn, uint8_t err,
				    struct bt_gatt_read_params *params,
				    const void *data, uint16_t length)
{
	struct bt_tbs_instance *inst = CONTAINER_OF(params, struct bt_tbs_instance, read_params);

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

	if (inst != NULL) {
		uint8_t cb_err = err;
		uint16_t status_flags = 0;

		if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) && inst->gtbs) {
			BT_DBG("GTBS");
		} else {
			BT_DBG("Index %u", inst->index);
		}

		if (err != 0) {
			BT_DBG("err: 0x%02X", err);
		} else if (data != NULL) {
			BT_HEXDUMP_DBG(data, length, "Data read");
			if (length == sizeof(status_flags)) {
				(void)memcpy(&status_flags, data, length);
				BT_DBG("0x%04x", status_flags);
			} else {
				BT_DBG("Invalid length");
				cb_err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
			}
		}

		inst->busy = false;

		if (tbs_client_cbs != NULL &&
		    tbs_client_cbs->status_flags != NULL) {
			tbs_client_cbs->status_flags(conn, cb_err, inst->index,
						     status_flags);
		}
	}

	return BT_GATT_ITER_STOP;
}

static uint8_t read_call_uri_cb(struct bt_conn *conn, uint8_t err,
				struct bt_gatt_read_params *params,
				const void *data, uint16_t length)
{
	struct bt_tbs_instance *inst = CONTAINER_OF(params, struct bt_tbs_instance, read_params);

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

	if (inst != NULL) {
		const char *in_target_uri = NULL;

		if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) && inst->gtbs) {
			BT_DBG("GTBS");
		} else {
			BT_DBG("Index %u", inst->index);
		}

		if (err != 0) {
			BT_DBG("err: 0x%02X", err);
		} else if (data != NULL) {
			in_target_uri = parse_string_value(
						data, length,
						CONFIG_BT_TBS_MAX_URI_LENGTH);
			BT_DBG("%s", in_target_uri);
		}

		inst->busy = false;

		if (tbs_client_cbs != NULL && tbs_client_cbs->call_uri != NULL) {
			tbs_client_cbs->call_uri(conn, err, inst->index,
						 in_target_uri);
		}
	}

	return BT_GATT_ITER_STOP;
}

static uint8_t read_call_state_cb(struct bt_conn *conn, uint8_t err,
				  struct bt_gatt_read_params *params,
				  const void *data, uint16_t length)
{
	struct bt_tbs_instance *inst = CONTAINER_OF(params, struct bt_tbs_instance, read_params);
	uint8_t cnt = 0;
	struct bt_tbs_client_call_state call_states[CONFIG_BT_TBS_CLIENT_MAX_CALLS];
	int tbs_err = err;

	if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) && inst->gtbs) {
		BT_DBG("GTBS");
	} else {
		BT_DBG("Index %u", inst->index);
	}

	if (tbs_err != 0) {
		BT_DBG("err: %d", tbs_err);
		(void)memset(params, 0, sizeof(*params));
		if (tbs_client_cbs != NULL &&
		    tbs_client_cbs->call_state != NULL) {
			tbs_client_cbs->call_state(conn, tbs_err, inst->index,
						   0, NULL);
		}

		return BT_GATT_ITER_STOP;
	}

	if (data != NULL) {
		BT_DBG("Call states read (offset %u): %s",
		       params->single.offset, bt_hex(data, length));

		if (inst->net_buf.size < inst->net_buf.len + length) {
			BT_DBG("Could not read all data, aborting");
			(void)memset(params, 0, sizeof(*params));

			if (tbs_client_cbs != NULL &&
			    tbs_client_cbs->call_state != NULL) {
				tbs_err = BT_ATT_ERR_INSUFFICIENT_RESOURCES;
				tbs_client_cbs->call_state(conn, err,
							   inst->index, 0,
							   NULL);
			}

			return BT_GATT_ITER_STOP;
		}

		net_buf_simple_add_mem(&inst->net_buf, data, length);

		/* Returning continue will try to read more using read long procedure */
		return BT_GATT_ITER_CONTINUE;
	}

	if (inst->net_buf.len == 0) {
		(void)memset(params, 0, sizeof(*params));
		if (tbs_client_cbs != NULL &&
		    tbs_client_cbs->call_state != NULL) {
			tbs_client_cbs->call_state(conn, 0, inst->index, 0,
						   NULL);
		}

		return BT_GATT_ITER_STOP;
	}

	/* Finished reading, start parsing */
	while (inst->net_buf.len != 0) {
		struct bt_tbs_client_call_state *call_state = &call_states[cnt];

		tbs_err = net_buf_pull_call_state(&inst->net_buf, call_state);
		if (tbs_err != 0) {
			BT_DBG("Invalid current call notification: %d", err);
			break;
		}

		cnt++;
		if (cnt == CONFIG_BT_TBS_CLIENT_MAX_CALLS) {
			BT_WARN("Could not parse all calls due to memory restrictions");
			break;
		}
	}

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

	if (tbs_client_cbs != NULL && tbs_client_cbs->call_state != NULL) {
		tbs_client_cbs->call_state(conn, tbs_err, inst->index, cnt,
					   call_states);
	}

	return BT_GATT_ITER_STOP;
}

static uint8_t read_optional_opcodes_cb(struct bt_conn *conn, uint8_t err,
					struct bt_gatt_read_params *params,
					const void *data, uint16_t length)
{
	struct bt_tbs_instance *inst = CONTAINER_OF(params, struct bt_tbs_instance, read_params);

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

	if (inst != NULL) {
		uint8_t cb_err = err;
		uint16_t optional_opcodes = 0;

		if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) && inst->gtbs) {
			BT_DBG("GTBS");
		} else {
			BT_DBG("Index %u", inst->index);
		}

		if (err != 0) {
			BT_DBG("err: 0x%02X", err);
		} else if (data != NULL) {
			BT_HEXDUMP_DBG(data, length, "Data read");
			if (length == sizeof(optional_opcodes)) {
				(void)memcpy(&optional_opcodes, data, length);
				BT_DBG("0x%04x", optional_opcodes);
			} else {
				BT_DBG("Invalid length");
				cb_err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
			}
		}

		inst->busy = false;

		if (tbs_client_cbs != NULL &&
		    tbs_client_cbs->optional_opcodes != NULL) {
			tbs_client_cbs->optional_opcodes(conn, cb_err,
							 inst->index,
							 optional_opcodes);
		}
	}

	return BT_GATT_ITER_STOP;
}

static uint8_t read_remote_uri_cb(struct bt_conn *conn, uint8_t err,
				  struct bt_gatt_read_params *params,
				  const void *data, uint16_t length)
{
	struct bt_tbs_instance *inst = CONTAINER_OF(params, struct bt_tbs_instance, read_params);

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

	if (inst != NULL) {
		const char *remote_uri = NULL;

		if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) && inst->gtbs) {
			BT_DBG("GTBS");
		} else {
			BT_DBG("Index %u", inst->index);
		}

		if (err != 0) {
			BT_DBG("err: 0x%02X", err);
		} else if (data != NULL) {
			remote_uri = parse_string_value(data, length,
							CONFIG_BT_TBS_MAX_URI_LENGTH);
			BT_DBG("%s", remote_uri);
		}

		inst->busy = false;

		if (tbs_client_cbs != NULL &&
		    tbs_client_cbs->remote_uri != NULL) {
			tbs_client_cbs->remote_uri(conn, err, inst->index,
						   remote_uri);
		}
	}

	return BT_GATT_ITER_STOP;
}

static uint8_t read_friendly_name_cb(struct bt_conn *conn, uint8_t err,
					 struct bt_gatt_read_params *params,
					 const void *data, uint16_t length)
{
	struct bt_tbs_instance *inst = CONTAINER_OF(params, struct bt_tbs_instance, read_params);

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

	if (inst != NULL) {
		const char *friendly_name = NULL;

		if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) && inst->gtbs) {
			BT_DBG("GTBS");
		} else {
			BT_DBG("Index %u", inst->index);
		}

		if (err != 0) {
			BT_DBG("err: 0x%02X", err);
		} else if (data != NULL) {
			friendly_name = parse_string_value(data, length,
							   CONFIG_BT_TBS_MAX_URI_LENGTH);
			BT_DBG("%s", friendly_name);
		}
		inst->busy = false;

		if (tbs_client_cbs != NULL &&
		    tbs_client_cbs->friendly_name != NULL) {
			tbs_client_cbs->friendly_name(conn, err, inst->index,
						      friendly_name);
		}
	}

	return BT_GATT_ITER_STOP;
}

/**
 * @brief This will discover all characteristics on the server, retrieving the
 * handles of the writeable characteristics and subscribing to all notify and
 * indicate characteristics.
 */
static uint8_t discover_func(struct bt_conn *conn,
			     const struct bt_gatt_attr *attr,
			     struct bt_gatt_discover_params *params)
{
	const uint8_t conn_index = bt_conn_index(conn);
	struct bt_tbs_server_inst *srv_inst = &srv_insts[conn_index];
	struct bt_tbs_instance *current_inst = srv_inst->current_inst;

	if (attr == NULL) {
		if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) &&
		    current_inst->index == GTBS_INDEX) {
			BT_DBG("Setup complete GTBS");
		} else {
			BT_DBG("Setup complete for %u / %u TBS",
			       current_inst->index + 1,
			       srv_inst->inst_cnt);
		}

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

		if (BT_TBS_INSTANCE_MAX_CNT > 1 &&
		    (((current_inst->index + 1) < srv_inst->inst_cnt) ||
			(IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) &&
			 srv_inst->gtbs_found &&
			 current_inst->index + 1 == GTBS_INDEX))) {
			discover_next_instance(conn, current_inst->index + 1);
		} else {
			srv_inst->current_inst = NULL;
			if (tbs_client_cbs != NULL &&
			    tbs_client_cbs->discover != NULL) {
				tbs_client_cbs->discover(conn, 0,
							 srv_inst->inst_cnt,
							 srv_inst->gtbs_found);
			}
		}

		return BT_GATT_ITER_STOP;
	}

	BT_DBG("[ATTRIBUTE] handle 0x%04X", attr->handle);

	if (params->type == BT_GATT_DISCOVER_CHARACTERISTIC) {
		const struct bt_gatt_chrc *chrc;
		struct bt_gatt_subscribe_params *sub_params = NULL;

		chrc = (struct bt_gatt_chrc *)attr->user_data;
		if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_PROVIDER_NAME) == 0) {
			BT_DBG("Provider name");
			current_inst->provider_name_handle = chrc->value_handle;
			sub_params = &current_inst->name_sub_params;
			sub_params->disc_params = &current_inst->name_sub_disc_params;
		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_UCI) == 0) {
			BT_DBG("Bearer UCI");
			current_inst->bearer_uci_handle = chrc->value_handle;
		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_TECHNOLOGY) == 0) {
			BT_DBG("Technology");
			current_inst->technology_handle = chrc->value_handle;
			sub_params = &current_inst->technology_sub_params;
			sub_params->disc_params = &current_inst->technology_sub_disc_params;
		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_URI_LIST) == 0) {
			BT_DBG("URI Scheme List");
			current_inst->uri_list_handle = chrc->value_handle;
		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_SIGNAL_STRENGTH) == 0) {
			BT_DBG("Signal strength");
			current_inst->signal_strength_handle = chrc->value_handle;
			sub_params = &current_inst->signal_strength_sub_params;
			sub_params->disc_params = &current_inst->signal_strength_sub_disc_params;
		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_SIGNAL_INTERVAL) == 0) {
			BT_DBG("Signal strength reporting interval");
			current_inst->signal_interval_handle = chrc->value_handle;
		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_LIST_CURRENT_CALLS) == 0) {
			BT_DBG("Current calls");
			current_inst->current_calls_handle = chrc->value_handle;
			sub_params = &current_inst->current_calls_sub_params;
			sub_params->disc_params = &current_inst->current_calls_sub_disc_params;
		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_CCID) == 0) {
			BT_DBG("CCID");
			current_inst->ccid_handle = chrc->value_handle;
		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_STATUS_FLAGS) == 0) {
			BT_DBG("Status flags");
			current_inst->status_flags_handle = chrc->value_handle;
			sub_params = &current_inst->status_flags_sub_params;
			sub_params->disc_params = &current_inst->status_sub_disc_params;
		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_INCOMING_URI) == 0) {
			BT_DBG("Incoming target URI");
			current_inst->in_uri_handle = chrc->value_handle;
			sub_params = &current_inst->in_target_uri_sub_params;
			sub_params->disc_params = &current_inst->in_target_uri_sub_disc_params;
		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_CALL_STATE) == 0) {
			BT_DBG("Call state");
			current_inst->call_state_handle = chrc->value_handle;
			sub_params = &current_inst->call_state_sub_params;
			sub_params->disc_params = &current_inst->call_state_sub_disc_params;
		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_CALL_CONTROL_POINT) == 0) {
			BT_DBG("Call control point");
			current_inst->call_cp_handle = chrc->value_handle;
			sub_params = &current_inst->call_cp_sub_params;
			sub_params->disc_params = &current_inst->call_cp_sub_disc_params;
		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_OPTIONAL_OPCODES) == 0) {
			BT_DBG("Supported opcodes");
			current_inst->optional_opcodes_handle = chrc->value_handle;
		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_TERMINATE_REASON) == 0) {
			BT_DBG("Termination reason");
			current_inst->termination_reason_handle = chrc->value_handle;
			sub_params = &current_inst->termination_sub_params;
			sub_params->disc_params = &current_inst->termination_sub_disc_params;
		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_FRIENDLY_NAME) == 0) {
			BT_DBG("Incoming friendly name");
			current_inst->friendly_name_handle = chrc->value_handle;
			sub_params = &current_inst->friendly_name_sub_params;
			sub_params->disc_params = &current_inst->friendly_name_sub_disc_params;
		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_TBS_INCOMING_CALL) == 0) {
			BT_DBG("Incoming call");
			current_inst->in_call_handle = chrc->value_handle;
			sub_params = &current_inst->incoming_call_sub_params;
			sub_params->disc_params = &current_inst->incoming_call_sub_disc_params;
		}

		if (srv_insts[conn_index].subscribe_all && sub_params != NULL) {
			sub_params->value = 0;
			if (chrc->properties & BT_GATT_CHRC_NOTIFY) {
				sub_params->value = BT_GATT_CCC_NOTIFY;
			} else if (chrc->properties & BT_GATT_CHRC_INDICATE) {
				sub_params->value = BT_GATT_CCC_INDICATE;
			}

			if (sub_params->value != 0) {
				int err;

				/* Setting ccc_handle = will use auto discovery feature */
				sub_params->ccc_handle = 0;
				sub_params->end_handle = current_inst->end_handle;
				sub_params->value_handle = chrc->value_handle;
				sub_params->notify = notify_handler;
				err = bt_gatt_subscribe(conn, sub_params);
				if (err != 0) {
					BT_DBG("Could not subscribe to "
					       "characterstic at handle 0x%04X"
					       "(%d)",
					       sub_params->value_handle, err);
				} else {
					BT_DBG("Subscribed to characterstic at "
					       "handle 0x%04X",
					       sub_params->value_handle);
				}
			}
		}
	}

	return BT_GATT_ITER_CONTINUE;
}

static void discover_next_instance(struct bt_conn *conn, uint8_t index)
{
	int err;
	uint8_t conn_index = bt_conn_index(conn);
	struct bt_tbs_server_inst *srv_inst = &srv_insts[conn_index];

	srv_inst->current_inst = &srv_inst->tbs_insts[index];
	(void)memset(&srv_inst->discover_params, 0, sizeof(srv_inst->discover_params));
	srv_inst->discover_params.uuid = NULL;
	srv_inst->discover_params.start_handle = srv_inst->current_inst->start_handle;
	srv_inst->discover_params.end_handle = srv_inst->current_inst->end_handle;
	srv_inst->discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
	srv_inst->discover_params.func = discover_func;

	err = bt_gatt_discover(conn, &srv_inst->discover_params);
	if (err != 0) {
		BT_DBG("Discover failed (err %d)", err);
		srv_inst->current_inst = NULL;
		if (tbs_client_cbs != NULL &&
		    tbs_client_cbs->discover != NULL) {
			tbs_client_cbs->discover(conn, err, srv_inst->inst_cnt,
						 srv_inst->gtbs_found);
		}
	}
}

/**
 * @brief This will discover all characteristics on the server, retrieving the
 * handles of the writeable characteristics and subscribing to all notify and
 * indicate characteristics.
 */
static uint8_t primary_discover_func(struct bt_conn *conn,
				     const struct bt_gatt_attr *attr,
				     struct bt_gatt_discover_params *params)
{
	const uint8_t conn_index = bt_conn_index(conn);
	struct bt_tbs_server_inst *srv_inst = &srv_insts[conn_index];

	/*
	 * TODO: Since we know the ranges of each instance, we could do
	 * discover of more than just prim_service->start and
	 * prim_service->end_handle, so that we can detect multiple instances
	 * faster
	 */

	if (attr == NULL || srv_inst->inst_cnt == BT_TBS_INSTANCE_MAX_CNT) {
		if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) &&
		    bt_uuid_cmp(params->uuid, BT_UUID_GTBS) == 0) {
			int err;
			/* Didn't find GTBS; look for TBS */
			params->uuid = tbs_uuid;
			params->start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;

			err = bt_gatt_discover(conn, params);
			if (err != 0) {
				BT_DBG("Discover failed (err %d)", err);
				srv_inst->current_inst = NULL;
				if (tbs_client_cbs != NULL &&
				    tbs_client_cbs->discover != NULL) {
					tbs_client_cbs->discover(conn, err, 0,
								 false);
				}
			}

			return BT_GATT_ITER_STOP;
		}

		if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS)) {
			srv_inst->gtbs_found = srv_inst->tbs_insts[GTBS_INDEX].gtbs;
			BT_DBG("Discover complete, found %u instances "
			       "(GTBS%s found)",
				srv_inst->inst_cnt,
				srv_inst->gtbs_found ? "" : " not");
		} else {
			BT_DBG("Discover complete, found %u instances",
			       srv_inst->inst_cnt);
		}

		if (srv_inst->inst_cnt != 0) {
			discover_next_instance(conn, 0);
		} else if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) &&
			   srv_inst->gtbs_found) {
			discover_next_instance(conn, GTBS_INDEX);
		} else {
			srv_inst->current_inst = NULL;
			if (tbs_client_cbs != NULL &&
			    tbs_client_cbs->discover != NULL) {
				tbs_client_cbs->discover(conn, 0,
							 srv_inst->inst_cnt,
							 srv_inst->gtbs_found);
			}
		}

		return BT_GATT_ITER_STOP;
	}

	BT_DBG("[ATTRIBUTE] handle 0x%04X", attr->handle);

	if (params->type == BT_GATT_DISCOVER_PRIMARY) {
		const struct bt_gatt_service_val *prim_service;

		prim_service = (struct bt_gatt_service_val *)attr->user_data;
		params->start_handle = attr->handle + 1;

		srv_inst->current_inst = &srv_inst->tbs_insts[srv_inst->inst_cnt];
		srv_inst->current_inst->index = srv_inst->inst_cnt;

		if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS) &&
		    bt_uuid_cmp(params->uuid, BT_UUID_GTBS) == 0) {
			int err;

			/* GTBS is placed as the "last" instance */
			srv_inst->current_inst = &srv_inst->tbs_insts[GTBS_INDEX];
			srv_inst->current_inst->index = GTBS_INDEX;
			srv_inst->current_inst->gtbs = true;
			srv_inst->current_inst->start_handle = attr->handle + 1;
			srv_inst->current_inst->end_handle = prim_service->end_handle;

			params->uuid = tbs_uuid;
			params->start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;

			err = bt_gatt_discover(conn, params);
			if (err != 0) {
				BT_DBG("Discover failed (err %d)", err);
				srv_inst->current_inst = NULL;
				if (tbs_client_cbs != NULL &&
				    tbs_client_cbs->discover != NULL) {
					tbs_client_cbs->discover(conn, err, 0,
								 false);
				}
			}

			return BT_GATT_ITER_STOP;
		}

		srv_inst->current_inst->start_handle = attr->handle + 1;
		srv_inst->current_inst->end_handle = prim_service->end_handle;
		srv_inst->inst_cnt++;
	}

	return BT_GATT_ITER_CONTINUE;
}

/****************************** PUBLIC API ******************************/

int bt_tbs_client_hold_call(struct bt_conn *conn, uint8_t inst_index,
			    uint8_t call_index)
{
	return tbs_client_common_call_control(conn, inst_index, call_index,
					      BT_TBS_CALL_OPCODE_HOLD);
}

int bt_tbs_client_accept_call(struct bt_conn *conn, uint8_t inst_index,
			      uint8_t call_index)
{
	return tbs_client_common_call_control(conn, inst_index, call_index,
					      BT_TBS_CALL_OPCODE_ACCEPT);
}

int bt_tbs_client_retrieve_call(struct bt_conn *conn, uint8_t inst_index,
				uint8_t call_index)
{
	return tbs_client_common_call_control(conn, inst_index, call_index,
					      BT_TBS_CALL_OPCODE_RETRIEVE);
}

int bt_tbs_client_terminate_call(struct bt_conn *conn, uint8_t inst_index,
				 uint8_t call_index)
{
	return tbs_client_common_call_control(conn, inst_index, call_index,
					      BT_TBS_CALL_OPCODE_TERMINATE);
}

int bt_tbs_client_originate_call(struct bt_conn *conn, uint8_t inst_index,
				 const char *uri)
{
	struct bt_tbs_instance *inst;
	uint8_t write_buf[CONFIG_BT_L2CAP_TX_MTU];
	struct bt_tbs_call_cp_originate *originate;
	size_t uri_len;
	const size_t max_uri_len = sizeof(write_buf) - sizeof(*originate);

	if (conn == NULL) {
		return -ENOTCONN;
	} else if (!valid_inst_index(conn, inst_index)) {
		return -EINVAL;
	} else if (!bt_tbs_valid_uri(uri)) {
		BT_DBG("Invalid URI: %s", uri);
		return -EINVAL;
	}

	inst = get_inst_by_index(conn, inst_index);

	/* Check if there are free spots */
	if (!free_call_spot(inst)) {
		BT_DBG("Cannot originate more calls");
		return -ENOMEM;
	}

	uri_len = strlen(uri);

	if (uri_len > max_uri_len) {
		BT_DBG("URI len (%zu) longer than maximum writable %zu",
		       uri_len, max_uri_len);
		return -ENOMEM;
	}

	originate = (struct bt_tbs_call_cp_originate *)write_buf;
	originate->opcode = BT_TBS_CALL_OPCODE_ORIGINATE;
	(void)memcpy(originate->uri, uri, uri_len);

	return bt_gatt_write_without_response(conn, inst->call_cp_handle,
					      originate,
					      sizeof(*originate) + uri_len,
					      false);
}

int bt_tbs_client_join_calls(struct bt_conn *conn, uint8_t inst_index,
			     const uint8_t *call_indexes, uint8_t count)
{
	if (conn == NULL) {
		return -ENOTCONN;
	}

	/* Write to call control point */
	if (call_indexes && count > 1 &&
	    count <= CONFIG_BT_TBS_CLIENT_MAX_CALLS) {
		struct bt_tbs_instance *inst;
		struct bt_tbs_call_cp_join *join;
		uint8_t write_buf[CONFIG_BT_L2CAP_TX_MTU];
		const size_t max_call_cnt = sizeof(write_buf) - sizeof(join->opcode);

		inst = get_inst_by_index(conn, inst_index);
		if (inst == NULL) {
			return -EINVAL;
		} else if (inst->call_cp_handle == 0) {
			BT_DBG("Handle not set");
			return -EINVAL;
		}

		if (count > max_call_cnt) {
			BT_DBG("Call count (%u) larger than maximum writable %zu",
			       count, max_call_cnt);
			return -ENOMEM;
		}

		join = (struct bt_tbs_call_cp_join *)write_buf;

		join->opcode = BT_TBS_CALL_OPCODE_JOIN;
		(void)memcpy(join->call_indexes, call_indexes, count);

		return bt_gatt_write_without_response(conn,
						      inst->call_cp_handle,
						      join,
						      sizeof(*join) + count,
						      false);
	}

	return -EINVAL;
}

int bt_tbs_client_set_signal_strength_interval(struct bt_conn *conn,
					       uint8_t inst_index,
					       uint8_t interval)
{
	struct bt_tbs_instance *inst;

	if (conn == NULL) {
		return -ENOTCONN;
	} else if (!valid_inst_index(conn, inst_index)) {
		return -EINVAL;
	}

	inst = get_inst_by_index(conn, inst_index);
	/* Populate Outgoing Remote URI */
	if (inst->signal_interval_handle == 0) {
		BT_DBG("Handle not set");
		return -EINVAL;
	}

	return bt_gatt_write_without_response(conn,
					      inst->signal_interval_handle,
					      &interval, sizeof(interval),
					      false);
}

int bt_tbs_client_read_bearer_provider_name(struct bt_conn *conn,
					    uint8_t inst_index)
{
	int err;
	struct bt_tbs_instance *inst;

	if (conn == NULL) {
		return -ENOTCONN;
	} else if (!valid_inst_index(conn, inst_index)) {
		return -EINVAL;
	}

	inst = get_inst_by_index(conn, inst_index);

	if (inst->provider_name_handle == 0) {
		BT_DBG("Handle not set");
		return -EINVAL;
	}

	inst->read_params.func = read_bearer_provider_name_cb;
	inst->read_params.handle_count = 1;
	inst->read_params.single.handle = inst->provider_name_handle;
	inst->read_params.single.offset = 0U;

	err = bt_gatt_read(conn, &inst->read_params);
	if (err != 0) {
		(void)memset(&inst->read_params, 0, sizeof(inst->read_params));
	}

	return err;
}

int bt_tbs_client_read_bearer_uci(struct bt_conn *conn, uint8_t inst_index)
{
	int err;
	struct bt_tbs_instance *inst;

	if (conn == NULL) {
		return -ENOTCONN;
	} else if (!valid_inst_index(conn, inst_index)) {
		return -EINVAL;
	}

	inst = get_inst_by_index(conn, inst_index);

	if (inst->bearer_uci_handle == 0) {
		BT_DBG("Handle not set");
		return -EINVAL;
	}

	inst->read_params.func = read_bearer_uci_cb;
	inst->read_params.handle_count = 1;
	inst->read_params.single.handle = inst->bearer_uci_handle;
	inst->read_params.single.offset = 0U;

	err = bt_gatt_read(conn, &inst->read_params);
	if (err != 0) {
		(void)memset(&inst->read_params, 0, sizeof(inst->read_params));
	}

	return err;
}

int bt_tbs_client_read_technology(struct bt_conn *conn, uint8_t inst_index)
{
	int err;
	struct bt_tbs_instance *inst;

	if (conn == NULL) {
		return -ENOTCONN;
	} else if (!valid_inst_index(conn, inst_index)) {
		return -EINVAL;
	}

	inst = get_inst_by_index(conn, inst_index);

	if (inst->technology_handle == 0) {
		BT_DBG("Handle not set");
		return -EINVAL;
	}

	inst->read_params.func = read_technology_cb;
	inst->read_params.handle_count = 1;
	inst->read_params.single.handle = inst->technology_handle;
	inst->read_params.single.offset = 0U;

	err = bt_gatt_read(conn, &inst->read_params);
	if (err != 0) {
		(void)memset(&inst->read_params, 0, sizeof(inst->read_params));
	}

	return err;
}

int bt_tbs_client_read_uri_list(struct bt_conn *conn, uint8_t inst_index)
{
	int err;
	struct bt_tbs_instance *inst;

	if (conn == NULL) {
		return -ENOTCONN;
	} else if (!valid_inst_index(conn, inst_index)) {
		return -EINVAL;
	}

	inst = get_inst_by_index(conn, inst_index);

	if (inst->uri_list_handle == 0) {
		BT_DBG("Handle not set");
		return -EINVAL;
	}

	inst->read_params.func = read_uri_list_cb;
	inst->read_params.handle_count = 1;
	inst->read_params.single.handle = inst->uri_list_handle;
	inst->read_params.single.offset = 0U;

	err = bt_gatt_read(conn, &inst->read_params);
	if (err != 0) {
		(void)memset(&inst->read_params, 0, sizeof(inst->read_params));
	}

	return err;
}

int bt_tbs_client_read_signal_strength(struct bt_conn *conn, uint8_t inst_index)
{
	int err;
	struct bt_tbs_instance *inst;

	if (conn == NULL) {
		return -ENOTCONN;
	} else if (!valid_inst_index(conn, inst_index)) {
		return -EINVAL;
	}

	inst = get_inst_by_index(conn, inst_index);

	if (inst->signal_strength_handle == 0) {
		BT_DBG("Handle not set");
		return -EINVAL;
	}

	inst->read_params.func = read_signal_strength_cb;
	inst->read_params.handle_count = 1;
	inst->read_params.single.handle = inst->signal_strength_handle;
	inst->read_params.single.offset = 0U;

	err = bt_gatt_read(conn, &inst->read_params);
	if (err != 0) {
		(void)memset(&inst->read_params, 0, sizeof(inst->read_params));
	}

	return err;
}

int bt_tbs_client_read_signal_interval(struct bt_conn *conn, uint8_t inst_index)
{
	int err;
	struct bt_tbs_instance *inst;

	if (conn == NULL) {
		return -ENOTCONN;
	} else if (!valid_inst_index(conn, inst_index)) {
		return -EINVAL;
	}

	inst = get_inst_by_index(conn, inst_index);

	if (inst->signal_interval_handle == 0) {
		BT_DBG("Handle not set");
		return -EINVAL;
	}

	inst->read_params.func = read_signal_interval_cb;
	inst->read_params.handle_count = 1;
	inst->read_params.single.handle = inst->signal_interval_handle;
	inst->read_params.single.offset = 0U;

	err = bt_gatt_read(conn, &inst->read_params);
	if (err != 0) {
		(void)memset(&inst->read_params, 0, sizeof(inst->read_params));
	}

	return err;
}

int bt_tbs_client_read_current_calls(struct bt_conn *conn, uint8_t inst_index)
{
	int err;
	struct bt_tbs_instance *inst;

	if (conn == NULL) {
		return -ENOTCONN;
	} else if (!valid_inst_index(conn, inst_index)) {
		return -EINVAL;
	}

	inst = get_inst_by_index(conn, inst_index);

	if (inst->current_calls_handle == 0) {
		BT_DBG("Handle not set");
		return -EINVAL;
	}

	inst->read_params.func = read_current_calls_cb;
	inst->read_params.handle_count = 1;
	inst->read_params.single.handle = inst->current_calls_handle;
	inst->read_params.single.offset = 0U;

	err = bt_gatt_read(conn, &inst->read_params);
	if (err != 0) {
		(void)memset(&inst->read_params, 0, sizeof(inst->read_params));
	}

	return err;
}

int bt_tbs_client_read_ccid(struct bt_conn *conn, uint8_t inst_index)
{
	int err;
	struct bt_tbs_instance *inst;

	if (conn == NULL) {
		return -ENOTCONN;
	} else if (!valid_inst_index(conn, inst_index)) {
		return -EINVAL;
	}

	inst = get_inst_by_index(conn, inst_index);

	if (inst->ccid_handle == 0) {
		BT_DBG("Handle not set");
		return -EINVAL;
	}

	inst->read_params.func = read_ccid_cb;
	inst->read_params.handle_count = 1;
	inst->read_params.single.handle = inst->ccid_handle;
	inst->read_params.single.offset = 0U;

	err = bt_gatt_read(conn, &inst->read_params);
	if (err != 0) {
		(void)memset(&inst->read_params, 0, sizeof(inst->read_params));
	}

	return err;
}

int bt_tbs_client_read_status_flags(struct bt_conn *conn, uint8_t inst_index)
{
	int err;
	struct bt_tbs_instance *inst;

	if (conn == NULL) {
		return -ENOTCONN;
	} else if (!valid_inst_index(conn, inst_index)) {
		return -EINVAL;
	}

	inst = get_inst_by_index(conn, inst_index);

	if (inst->status_flags_handle == 0) {
		BT_DBG("Handle not set");
		return -EINVAL;
	}

	inst->read_params.func = read_status_flags_cb;
	inst->read_params.handle_count = 1;
	inst->read_params.single.handle = inst->status_flags_handle;
	inst->read_params.single.offset = 0U;

	err = bt_gatt_read(conn, &inst->read_params);
	if (err != 0) {
		(void)memset(&inst->read_params, 0, sizeof(inst->read_params));
	}

	return err;
}

int bt_tbs_client_read_call_uri(struct bt_conn *conn, uint8_t inst_index)
{
	int err;
	struct bt_tbs_instance *inst;

	if (conn == NULL) {
		return -ENOTCONN;
	} else if (!valid_inst_index(conn, inst_index)) {
		return -EINVAL;
	}

	inst = get_inst_by_index(conn, inst_index);

	if (inst->in_uri_handle == 0) {
		BT_DBG("Handle not set");
		return -EINVAL;
	}

	inst->read_params.func = read_call_uri_cb;
	inst->read_params.handle_count = 1;
	inst->read_params.single.handle = inst->in_uri_handle;
	inst->read_params.single.offset = 0U;

	err = bt_gatt_read(conn, &inst->read_params);
	if (err != 0) {
		(void)memset(&inst->read_params, 0, sizeof(inst->read_params));
	}

	return err;
}

int bt_tbs_client_read_call_state(struct bt_conn *conn, uint8_t inst_index)
{
	int err;
	struct bt_tbs_instance *inst;

	if (conn == NULL) {
		return -ENOTCONN;
	} else if (!valid_inst_index(conn, inst_index)) {
		return -EINVAL;
	}

	inst = get_inst_by_index(conn, inst_index);

	if (inst->call_state_handle == 0) {
		BT_DBG("Handle not set");
		return -EINVAL;
	}

	inst->read_params.func = read_call_state_cb;
	inst->read_params.handle_count = 1;
	inst->read_params.single.handle = inst->call_state_handle;
	inst->read_params.single.offset = 0U;

	err = bt_gatt_read(conn, &inst->read_params);
	if (err != 0) {
		(void)memset(&inst->read_params, 0, sizeof(inst->read_params));
	}

	return err;
}

int bt_tbs_client_read_optional_opcodes(struct bt_conn *conn,
					uint8_t inst_index)
{
	int err;
	struct bt_tbs_instance *inst;

	if (conn == NULL) {
		return -ENOTCONN;
	} else if (!valid_inst_index(conn, inst_index)) {
		return -EINVAL;
	}

	inst = get_inst_by_index(conn, inst_index);

	if (inst->optional_opcodes_handle == 0) {
		BT_DBG("Handle not set");
		return -EINVAL;
	}

	inst->read_params.func = read_optional_opcodes_cb;
	inst->read_params.handle_count = 1;
	inst->read_params.single.handle = inst->optional_opcodes_handle;
	inst->read_params.single.offset = 0U;

	err = bt_gatt_read(conn, &inst->read_params);
	if (err != 0) {
		(void)memset(&inst->read_params, 0, sizeof(inst->read_params));
	}

	return err;
}

int bt_tbs_client_read_remote_uri(struct bt_conn *conn, uint8_t inst_index)
{
	int err;
	struct bt_tbs_instance *inst;

	if (conn == NULL) {
		return -ENOTCONN;
	} else if (!valid_inst_index(conn, inst_index)) {
		return -EINVAL;
	}

	inst = get_inst_by_index(conn, inst_index);

	if (inst->in_call_handle == 0) {
		BT_DBG("Handle not set");
		return -EINVAL;
	}

	inst->read_params.func = read_remote_uri_cb;
	inst->read_params.handle_count = 1;
	inst->read_params.single.handle = inst->in_call_handle;
	inst->read_params.single.offset = 0U;

	err = bt_gatt_read(conn, &inst->read_params);
	if (err != 0) {
		(void)memset(&inst->read_params, 0, sizeof(inst->read_params));
	}

	return err;
}

int bt_tbs_client_read_friendly_name(struct bt_conn *conn, uint8_t inst_index)
{
	int err;
	struct bt_tbs_instance *inst;

	if (conn == NULL) {
		return -ENOTCONN;
	} else if (!valid_inst_index(conn, inst_index)) {
		return -EINVAL;
	}

	inst = get_inst_by_index(conn, inst_index);

	if (inst->friendly_name_handle == 0) {
		BT_DBG("Handle not set");
		return -EINVAL;
	}

	inst->read_params.func = read_friendly_name_cb;
	inst->read_params.handle_count = 1;
	inst->read_params.single.handle = inst->friendly_name_handle;
	inst->read_params.single.offset = 0U;

	err = bt_gatt_read(conn, &inst->read_params);
	if (err != 0) {
		(void)memset(&inst->read_params, 0, sizeof(inst->read_params));
	}

	return err;
}

int bt_tbs_client_discover(struct bt_conn *conn, bool subscribe)
{
	uint8_t conn_index;
	struct bt_tbs_server_inst *srv_inst;

	if (conn == NULL) {
		return -ENOTCONN;
	}

	conn_index = bt_conn_index(conn);
	srv_inst = &srv_insts[conn_index];

	if (srv_inst->current_inst) {
		return -EBUSY;
	}

	(void)memset(srv_inst->tbs_insts, 0, sizeof(srv_inst->tbs_insts)); /* reset data */
	srv_inst->inst_cnt = 0;
	srv_inst->gtbs_found = false;
	/* Discover TBS on peer, setup handles and notify/indicate */
	srv_inst->subscribe_all = subscribe;
	(void)memset(&srv_inst->discover_params, 0, sizeof(srv_inst->discover_params));
	if (IS_ENABLED(CONFIG_BT_TBS_CLIENT_GTBS)) {
		BT_DBG("Discovering GTBS");
		srv_inst->discover_params.uuid = gtbs_uuid;
	} else {
		srv_inst->discover_params.uuid = tbs_uuid;
	}
	srv_inst->discover_params.func = primary_discover_func;
	srv_inst->discover_params.type = BT_GATT_DISCOVER_PRIMARY;
	srv_inst->discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
	srv_inst->discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;

	return bt_gatt_discover(conn, &srv_inst->discover_params);
}

void bt_tbs_client_register_cb(const struct bt_tbs_client_cb *cbs)
{
	tbs_client_cbs = cbs;
}
