/* @file
 * @brief Bluetooth Unicast Client
 */

/*
 * Copyright (c) 2020 Intel Corporation
 * Copyright (c) 2022-2023 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/check.h>

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/audio/audio.h>
#include <zephyr/bluetooth/audio/bap.h>

#include "../host/hci_core.h"
#include "../host/conn_internal.h"
#include "../host/iso_internal.h"

#include "bap_iso.h"
#include "audio_internal.h"
#include "bap_endpoint.h"
#include "pacs_internal.h"
#include "bap_unicast_client_internal.h"

#include <zephyr/logging/log.h>

BUILD_ASSERT(CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0 ||
		     CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0,
	     "CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT or "
	     "CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT shall be non-zero");

BUILD_ASSERT(CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT == 0 ||
		     CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 1,
	     "CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT shall be either 0 or > 1");

BUILD_ASSERT(CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT == 0 ||
		     CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 1,
	     "CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT shall be either 0 or > 1");

LOG_MODULE_REGISTER(bt_bap_unicast_client, CONFIG_BT_BAP_UNICAST_CLIENT_LOG_LEVEL);

#define PAC_DIR_UNUSED(dir) ((dir) != BT_AUDIO_DIR_SINK && (dir) != BT_AUDIO_DIR_SOURCE)
struct bt_bap_unicast_client_ep {
	uint16_t handle;
	uint16_t cp_handle;
	struct bt_gatt_subscribe_params subscribe;
	struct bt_gatt_discover_params discover;
	struct bt_bap_ep ep;
	struct k_work_delayable ase_read_work;

	/* Bool to help handle different order of CP and ASE notification when releasing */
	bool release_requested;
	bool cp_ntf_pending;
};

static const struct bt_uuid *snk_uuid = BT_UUID_PACS_SNK;
static const struct bt_uuid *src_uuid = BT_UUID_PACS_SRC;
static const struct bt_uuid *pacs_context_uuid = BT_UUID_PACS_SUPPORTED_CONTEXT;
static const struct bt_uuid *pacs_snk_loc_uuid = BT_UUID_PACS_SNK_LOC;
static const struct bt_uuid *pacs_src_loc_uuid = BT_UUID_PACS_SRC_LOC;
static const struct bt_uuid *pacs_avail_ctx_uuid = BT_UUID_PACS_AVAILABLE_CONTEXT;
static const struct bt_uuid *ase_snk_uuid = BT_UUID_ASCS_ASE_SNK;
static const struct bt_uuid *ase_src_uuid = BT_UUID_ASCS_ASE_SRC;
static const struct bt_uuid *cp_uuid = BT_UUID_ASCS_ASE_CP;

static struct bt_bap_unicast_group unicast_groups[UNICAST_GROUP_CNT];

static struct unicast_client {
#if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0
	struct bt_bap_unicast_client_ep snks[CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT];
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0 */
#if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0
	struct bt_bap_unicast_client_ep srcs[CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT];
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0 */

	struct bt_gatt_subscribe_params cp_subscribe;
	struct bt_gatt_subscribe_params snk_loc_subscribe;
	struct bt_gatt_subscribe_params src_loc_subscribe;
	struct bt_gatt_subscribe_params avail_ctx_subscribe;

	/* TODO: We should be able to reduce the number of discover params for
	 * CCCD discovery, but requires additional work if it is to support an
	 * arbitrary number of EATT bearers, as control point and location CCCD
	 * discovery needs to be done in serial to avoid using the same discover
	 * parameters twice
	 */
	struct bt_gatt_discover_params loc_cc_disc;
	struct bt_gatt_discover_params avail_ctx_cc_disc;

	/* Discovery parameters */
	enum bt_audio_dir dir;
	bool busy;
	union {
		struct bt_gatt_read_params read_params;
		struct bt_gatt_discover_params disc_params;
		struct bt_gatt_write_params write_params;
	};

	/* The att_buf needs to use the maximum ATT attribute size as a single
	 * PAC record may use the full size
	 */
	uint8_t att_buf[BT_ATT_MAX_ATTRIBUTE_LEN];
	struct net_buf_simple net_buf;
} uni_cli_insts[CONFIG_BT_MAX_CONN];

static const struct bt_bap_unicast_client_cb *unicast_client_cbs;

/* TODO: Move the functions to avoid these prototypes */
static int unicast_client_ep_set_metadata(struct bt_bap_ep *ep, void *data, uint8_t len,
					  struct bt_audio_codec_cfg *codec_cfg);

static int unicast_client_ep_set_codec_cfg(struct bt_bap_ep *ep, uint8_t id, uint16_t cid,
					   uint16_t vid, void *data, uint8_t len,
					   struct bt_audio_codec_cfg *codec_cfg);
static int unicast_client_ep_start(struct bt_bap_ep *ep,
				   struct net_buf_simple *buf);

static int unicast_client_ase_discover(struct bt_conn *conn, uint16_t start_handle);

static void unicast_client_reset(struct bt_bap_ep *ep, uint8_t reason);

static void delayed_ase_read_handler(struct k_work *work);
static void unicast_client_ep_set_status(struct bt_bap_ep *ep, struct net_buf_simple *buf);

static int unicast_client_send_start(struct bt_bap_ep *ep)
{
	if (ep->receiver_ready != true || ep->dir != BT_AUDIO_DIR_SOURCE) {
		LOG_DBG("Invalid ep %p %u %s",
			ep, ep->receiver_ready, bt_audio_dir_str(ep->dir));

		return -EINVAL;
	}

	struct bt_ascs_start_op *req;
	struct net_buf_simple *buf;
	int err;

	buf = bt_bap_unicast_client_ep_create_pdu(ep->stream->conn, BT_ASCS_START_OP);
	if (buf == NULL) {
		LOG_DBG("Could not create PDU");
		return -EBUSY;
	}

	req = net_buf_simple_add(buf, sizeof(*req));
	req->num_ases = 1U;

	err = unicast_client_ep_start(ep, buf);
	if (err != 0) {
		LOG_DBG("unicast_client_ep_start failed: %d",
			err);

		return err;
	}

	err = bt_bap_unicast_client_ep_send(ep->stream->conn, ep, buf);
	if (err != 0) {
		LOG_DBG("bt_bap_unicast_client_ep_send failed: %d", err);

		return err;
	}

	return 0;
}

static void unicast_client_ep_idle_state(struct bt_bap_ep *ep);

static struct bt_bap_stream *audio_stream_by_ep_id(const struct bt_conn *conn,
						     uint8_t id)
{
#if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0 || CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0
	const uint8_t conn_index = bt_conn_index(conn);
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0 ||                                        \
	* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0                                           \
	*/

#if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0
	for (size_t i = 0U; i < ARRAY_SIZE(uni_cli_insts[conn_index].snks); i++) {
		const struct bt_bap_unicast_client_ep *client_ep =
			&uni_cli_insts[conn_index].snks[i];

		if (client_ep->ep.status.id == id) {
			return client_ep->ep.stream;
		}
	}
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0 */

#if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0
	for (size_t i = 0U; i < ARRAY_SIZE(uni_cli_insts[conn_index].srcs); i++) {
		const struct bt_bap_unicast_client_ep *client_ep =
			&uni_cli_insts[conn_index].srcs[i];

		if (client_ep->ep.status.id == id) {
			return client_ep->ep.stream;
		}
	}
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0 */

	return NULL;
}

static void reset_att_buf(struct unicast_client *client)
{
	net_buf_simple_init_with_data(&client->net_buf, &client->att_buf, sizeof(client->att_buf));
	net_buf_simple_reset(&client->net_buf);
}

#if defined(CONFIG_BT_AUDIO_RX)
static void unicast_client_ep_iso_recv(struct bt_iso_chan *chan,
				       const struct bt_iso_recv_info *info, struct net_buf *buf)
{
	struct bt_bap_iso *iso = CONTAINER_OF(chan, struct bt_bap_iso, chan);
	const struct bt_bap_stream_ops *ops;
	struct bt_bap_stream *stream;
	struct bt_bap_ep *ep = iso->rx.ep;

	if (ep == NULL) {
		/* In the case that the CIS has been setup as bidirectional, and
		 * only one of the directions have an ASE configured yet,
		 * we should only care about valid ISO packets when doing this
		 * check. The reason is that some controllers send HCI ISO data
		 * packets to the host, even if no SDU was sent on the remote
		 * side. This basically means that empty PDUs are sent to the
		 * host as HCI ISO data packets, which we should just ignore
		 */
		if ((info->flags & BT_ISO_FLAGS_VALID) != 0) {
			LOG_DBG("Valid ISO packet of len %zu received for iso %p not bound with ep",
				net_buf_frags_len(buf), chan);
		}

		return;
	}

	if (ep->status.state != BT_BAP_EP_STATE_STREAMING) {
		if (IS_ENABLED(CONFIG_BT_BAP_DEBUG_STREAM_DATA)) {
			LOG_DBG("ep %p is not in the streaming state: %s", ep,
				bt_bap_ep_state_str(ep->status.state));
		}

		return;
	}

	stream = ep->stream;
	if (stream == NULL) {
		LOG_ERR("No stream for ep %p", ep);
		return;
	}

	ops = stream->ops;

	if (IS_ENABLED(CONFIG_BT_BAP_DEBUG_STREAM_DATA)) {
		LOG_DBG("stream %p ep %p len %zu", stream, ep, net_buf_frags_len(buf));
	}

	if (ops != NULL && ops->recv != NULL) {
		ops->recv(stream, info, buf);
	} else {
		LOG_WRN("No callback for recv set");
	}
}
#endif /* CONFIG_BT_AUDIO_RX */

#if defined(CONFIG_BT_AUDIO_TX)
static void unicast_client_ep_iso_sent(struct bt_iso_chan *chan)
{
	struct bt_bap_iso *iso = CONTAINER_OF(chan, struct bt_bap_iso, chan);
	struct bt_bap_stream *stream;
	struct bt_bap_ep *ep = iso->tx.ep;

	if (ep == NULL) {
		LOG_ERR("iso %p not bound with ep", chan);
		return;
	}

	stream = ep->stream;
	if (stream == NULL) {
		LOG_ERR("No stream for ep %p", ep);
		return;
	}

	if (IS_ENABLED(CONFIG_BT_BAP_DEBUG_STREAM_DATA)) {
		LOG_DBG("stream %p ep %p", stream, ep);
	}

	if (stream->ops != NULL && stream->ops->sent != NULL) {
		stream->ops->sent(stream);
	}
}
#endif /* CONFIG_BT_AUDIO_TX */

static void unicast_client_ep_iso_connected(struct bt_bap_ep *ep)
{
	const struct bt_bap_stream_ops *stream_ops;
	struct bt_bap_stream *stream;

	if (ep->status.state != BT_BAP_EP_STATE_ENABLING) {
		LOG_DBG("endpoint not in enabling state: %s",
			bt_bap_ep_state_str(ep->status.state));
		return;
	}

	stream = ep->stream;
	if (stream == NULL) {
		LOG_ERR("No stream for ep %p", ep);
		return;
	}

	LOG_DBG("stream %p ep %p dir %s receiver_ready %u",
		stream, ep, bt_audio_dir_str(ep->dir), ep->receiver_ready);

#if defined(CONFIG_BT_BAP_DEBUG_STREAM_SEQ_NUM)
	/* reset sequence number */
	stream->_prev_seq_num = 0U;
#endif /* CONFIG_BT_BAP_DEBUG_STREAM_SEQ_NUM */

	stream_ops = stream->ops;
	if (stream_ops != NULL && stream_ops->connected != NULL) {
		stream_ops->connected(stream);
	}

	if (ep->receiver_ready && ep->dir == BT_AUDIO_DIR_SOURCE) {
		const int err = unicast_client_send_start(ep);

		if (err != 0) {
			LOG_DBG("Failed to send start: %d", err);

			/* TBD: Should we release the stream then? */
			ep->receiver_ready = false;
		}
	}
}

static void unicast_client_iso_connected(struct bt_iso_chan *chan)
{
	struct bt_bap_iso *iso = CONTAINER_OF(chan, struct bt_bap_iso, chan);

	if (iso->rx.ep == NULL && iso->tx.ep == NULL) {
		LOG_ERR("iso %p not bound with ep", chan);
		return;
	}

	if (iso->rx.ep != NULL) {
		unicast_client_ep_iso_connected(iso->rx.ep);
	}

	if (iso->tx.ep != NULL) {
		unicast_client_ep_iso_connected(iso->tx.ep);
	}
}

static void unicast_client_ep_iso_disconnected(struct bt_bap_ep *ep, uint8_t reason)
{
	const struct bt_bap_stream_ops *stream_ops;
	struct bt_bap_stream *stream;

	stream = ep->stream;
	if (stream == NULL) {
		LOG_ERR("Stream not associated with an ep");
		return;
	}

	LOG_DBG("stream %p ep %p reason 0x%02x", stream, ep, reason);
	ep->reason = reason;

	stream_ops = stream->ops;
	if (stream_ops != NULL && stream_ops->disconnected != NULL) {
		stream_ops->disconnected(stream, reason);
	}

	/* If we were in the idle state when we started the ISO disconnection
	 * then we need to call unicast_client_ep_idle_state again when
	 * the ISO has finalized the disconnection
	 */
	if (ep->status.state == BT_BAP_EP_STATE_IDLE) {

		unicast_client_ep_idle_state(ep);

		if (stream->conn != NULL) {
			struct bt_conn_info conn_info;
			int err;

			err = bt_conn_get_info(stream->conn, &conn_info);
			if (err != 0 || conn_info.state == BT_CONN_STATE_DISCONNECTED) {
				/* Retrigger the reset of the EP if the ACL is disconnected before
				 * the ISO is disconnected
				 */
				unicast_client_reset(ep, reason);
			}
		}
	}
}

static void unicast_client_iso_disconnected(struct bt_iso_chan *chan, uint8_t reason)
{
	struct bt_bap_iso *iso = CONTAINER_OF(chan, struct bt_bap_iso, chan);

	if (iso->rx.ep == NULL && iso->tx.ep == NULL) {
		LOG_ERR("iso %p not bound with ep", chan);
		return;
	}

	if (iso->rx.ep != NULL) {
		unicast_client_ep_iso_disconnected(iso->rx.ep, reason);
	}

	if (iso->tx.ep != NULL) {
		unicast_client_ep_iso_disconnected(iso->tx.ep, reason);
	}
}

static struct bt_iso_chan_ops unicast_client_iso_ops = {
#if defined(CONFIG_BT_AUDIO_RX)
	.recv = unicast_client_ep_iso_recv,
#endif /* CONFIG_BT_AUDIO_RX */
#if defined(CONFIG_BT_AUDIO_TX)
	.sent = unicast_client_ep_iso_sent,
#endif /* CONFIG_BT_AUDIO_TX */
	.connected = unicast_client_iso_connected,
	.disconnected = unicast_client_iso_disconnected,
};

bool bt_bap_ep_is_unicast_client(const struct bt_bap_ep *ep)
{
	for (size_t i = 0U; i < ARRAY_SIZE(uni_cli_insts); i++) {
#if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0
		if (PART_OF_ARRAY(uni_cli_insts[i].snks, ep)) {
			return true;
		}
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0 */

#if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0
		if (PART_OF_ARRAY(uni_cli_insts[i].srcs, ep)) {
			return true;
		}
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0 */
	}

	return false;
}

static void unicast_client_ep_init(struct bt_bap_ep *ep, uint16_t handle, uint8_t dir)
{
	struct bt_bap_unicast_client_ep *client_ep;

	LOG_DBG("ep %p dir %s handle 0x%04x", ep, bt_audio_dir_str(dir), handle);

	client_ep = CONTAINER_OF(ep, struct bt_bap_unicast_client_ep, ep);

	(void)memset(ep, 0, sizeof(*ep));
	client_ep->handle = handle;
	ep->status.id = 0U;
	ep->dir = dir;
	ep->reason = BT_HCI_ERR_SUCCESS;
	k_work_init_delayable(&client_ep->ase_read_work, delayed_ase_read_handler);
}

static struct bt_bap_ep *unicast_client_ep_find(struct bt_conn *conn, uint16_t handle)
{
	uint8_t index;

	index = bt_conn_index(conn);

#if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0
	for (size_t i = 0U; i < ARRAY_SIZE(uni_cli_insts[index].snks); i++) {
		struct bt_bap_unicast_client_ep *client_ep = &uni_cli_insts[index].snks[i];

		if ((handle && client_ep->handle == handle) || (!handle && client_ep->handle)) {
			return &client_ep->ep;
		}
	}
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0 */

#if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0
	for (size_t i = 0U; i < ARRAY_SIZE(uni_cli_insts[index].srcs); i++) {
		struct bt_bap_unicast_client_ep *client_ep = &uni_cli_insts[index].srcs[i];

		if ((handle && client_ep->handle == handle) || (!handle && client_ep->handle)) {
			return &client_ep->ep;
		}
	}
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0 */

	return NULL;
}

struct bt_bap_iso *bt_bap_unicast_client_new_audio_iso(void)
{
	struct bt_bap_iso *bap_iso;

	bap_iso = bt_bap_iso_new();
	if (bap_iso == NULL) {
		return NULL;
	}

	bt_bap_iso_init(bap_iso, &unicast_client_iso_ops);

	LOG_DBG("New bap_iso %p", bap_iso);

	return bap_iso;
}

static struct bt_bap_ep *unicast_client_ep_new(struct bt_conn *conn, enum bt_audio_dir dir,
					       uint16_t handle)
{
	size_t i, size;
	uint8_t index;
	struct bt_bap_unicast_client_ep *cache;

	index = bt_conn_index(conn);

	switch (dir) {
#if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0
	case BT_AUDIO_DIR_SINK:
		cache = uni_cli_insts[index].snks;
		size = ARRAY_SIZE(uni_cli_insts[index].snks);
		break;
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0 */
#if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0
	case BT_AUDIO_DIR_SOURCE:
		cache = uni_cli_insts[index].srcs;
		size = ARRAY_SIZE(uni_cli_insts[index].srcs);
		break;
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0 */
	default:
		return NULL;
	}

	for (i = 0; i < size; i++) {
		struct bt_bap_unicast_client_ep *client_ep = &cache[i];

		if (!client_ep->handle) {
			unicast_client_ep_init(&client_ep->ep, handle, dir);
			return &client_ep->ep;
		}
	}

	return NULL;
}

static struct bt_bap_ep *unicast_client_ep_get(struct bt_conn *conn, enum bt_audio_dir dir,
					       uint16_t handle)
{
	struct bt_bap_ep *ep;

	ep = unicast_client_ep_find(conn, handle);
	if (ep || !handle) {
		return ep;
	}

	return unicast_client_ep_new(conn, dir, handle);
}

static void unicast_client_ep_set_local_idle_state(struct bt_bap_ep *ep)
{
	struct bt_ascs_ase_status status = {
		.id = ep->status.id,
		.state = BT_BAP_EP_STATE_IDLE,
	};
	struct net_buf_simple buf;

	net_buf_simple_init_with_data(&buf, &status, sizeof(status));

	unicast_client_ep_set_status(ep, &buf);
}

static void unicast_client_ep_idle_state(struct bt_bap_ep *ep)
{
	struct bt_bap_unicast_client_ep *client_ep =
		CONTAINER_OF(ep, struct bt_bap_unicast_client_ep, ep);
	struct bt_bap_stream *stream = ep->stream;
	const struct bt_bap_stream_ops *ops;

	if (stream == NULL) {
		return;
	}

	/* If CIS is connected, disconnect and wait for CIS disconnection */
	if (bt_bap_stream_can_disconnect(stream)) {
		int err;

		LOG_DBG("Disconnecting stream");
		err = bt_bap_stream_disconnect(stream);

		if (err != 0) {
			LOG_ERR("Failed to disconnect stream: %d", err);
		}

		return;
	} else if (ep->iso != NULL && ep->iso->chan.state == BT_ISO_STATE_DISCONNECTING) {
		/* Wait for disconnection */
		return;
	}

	bt_bap_stream_reset(stream);

	/* Notify upper layer */
	if (client_ep->release_requested) {
		client_ep->release_requested = false;

		if (client_ep->cp_ntf_pending) {
			/* In case that we get the idle state notification before the CP
			 * notification we trigger the CP callback now, as after this we won't be
			 * able to find the stream by the ASE ID
			 */
			client_ep->cp_ntf_pending = false;

			if (unicast_client_cbs != NULL && unicast_client_cbs->release != NULL) {
				unicast_client_cbs->release(stream, BT_BAP_ASCS_RSP_CODE_SUCCESS,
							    BT_BAP_ASCS_REASON_NONE);
			}
		}
	}

	ops = stream->ops;
	if (ops != NULL && ops->released != NULL) {
		ops->released(stream);
	} else {
		LOG_WRN("No callback for released set");
	}
}

static void unicast_client_ep_qos_update(struct bt_bap_ep *ep,
					 const struct bt_ascs_ase_status_qos *qos)
{
	struct bt_iso_chan_io_qos *iso_io_qos;

	LOG_DBG("ep %p dir %s bap_iso %p", ep, bt_audio_dir_str(ep->dir), ep->iso);

	if (ep->dir == BT_AUDIO_DIR_SOURCE) {
		/* If the endpoint is a source, then we need to
		 * reset our RX parameters
		 */
		iso_io_qos = &ep->iso->rx.qos;
	} else if (ep->dir == BT_AUDIO_DIR_SINK) {
		/* If the endpoint is a sink, then we need to
		 * reset our TX parameters
		 */
		iso_io_qos = &ep->iso->tx.qos;
	} else {
		__ASSERT(false, "Invalid ep->dir: %u", ep->dir);
		return;
	}

	iso_io_qos->phy = qos->phy;
	iso_io_qos->sdu = sys_le16_to_cpu(qos->sdu);
	iso_io_qos->rtn = qos->rtn;
}

static void unicast_client_ep_config_state(struct bt_bap_ep *ep, struct net_buf_simple *buf)
{
	struct bt_bap_unicast_client_ep *client_ep =
		CONTAINER_OF(ep, struct bt_bap_unicast_client_ep, ep);
	struct bt_ascs_ase_status_config *cfg;
	struct bt_audio_codec_qos_pref *pref;
	struct bt_bap_stream *stream;
	void *cc;

	if (client_ep->release_requested) {
		LOG_DBG("Released was requested, change local state to idle");
		ep->reason = BT_HCI_ERR_LOCALHOST_TERM_CONN;
		unicast_client_ep_set_local_idle_state(ep);
		return;
	}

	if (buf->len < sizeof(*cfg)) {
		LOG_ERR("Config status too short");
		return;
	}

	stream = ep->stream;
	if (stream == NULL) {
		LOG_WRN("No stream active for endpoint");
		return;
	}

	cfg = net_buf_simple_pull_mem(buf, sizeof(*cfg));

	if (stream->codec_cfg == NULL) {
		LOG_ERR("Stream %p does not have a codec configured", stream);
		return;
	} else if (stream->codec_cfg->id != cfg->codec.id) {
		LOG_ERR("Codec configuration mismatched: %u, %u", stream->codec_cfg->id,
			cfg->codec.id);
		/* TODO: Release the stream? */
		return;
	}

	if (buf->len < cfg->cc_len) {
		LOG_ERR("Malformed ASE Config status: buf->len %u < %u cc_len", buf->len,
			cfg->cc_len);
		return;
	}

	cc = net_buf_simple_pull_mem(buf, cfg->cc_len);

	pref = &stream->ep->qos_pref;

	/* Convert to interval representation so they can be matched by QoS */
	pref->unframed_supported = cfg->framing == BT_ASCS_QOS_FRAMING_UNFRAMED;
	pref->phy = cfg->phy;
	pref->rtn = cfg->rtn;
	pref->latency = sys_le16_to_cpu(cfg->latency);
	pref->pd_min = sys_get_le24(cfg->pd_min);
	pref->pd_max = sys_get_le24(cfg->pd_max);
	pref->pref_pd_min = sys_get_le24(cfg->prefer_pd_min);
	pref->pref_pd_max = sys_get_le24(cfg->prefer_pd_max);

	LOG_DBG("dir %s unframed_supported 0x%02x phy 0x%02x rtn %u "
		"latency %u pd_min %u pd_max %u pref_pd_min %u pref_pd_max %u codec 0x%02x ",
		bt_audio_dir_str(ep->dir), pref->unframed_supported, pref->phy, pref->rtn,
		pref->latency, pref->pd_min, pref->pd_max, pref->pref_pd_min, pref->pref_pd_max,
		stream->codec_cfg->id);

	unicast_client_ep_set_codec_cfg(ep, cfg->codec.id, sys_le16_to_cpu(cfg->codec.cid),
					sys_le16_to_cpu(cfg->codec.vid), cc, cfg->cc_len, NULL);

	/* Notify upper layer */
	if (stream->ops != NULL && stream->ops->configured != NULL) {
		stream->ops->configured(stream, pref);
	} else {
		LOG_WRN("No callback for configured set");
	}
}

static void unicast_client_ep_qos_state(struct bt_bap_ep *ep, struct net_buf_simple *buf,
					uint8_t old_state)
{
	const struct bt_bap_stream_ops *ops;
	struct bt_ascs_ase_status_qos *qos;
	struct bt_bap_stream *stream;

	if (buf->len < sizeof(*qos)) {
		LOG_ERR("QoS status too short");
		return;
	}

	stream = ep->stream;
	if (stream == NULL) {
		LOG_ERR("No stream active for endpoint");
		return;
	}
	ops = stream->ops;

	if (ops != NULL) {
		if (ep->dir == BT_AUDIO_DIR_SINK && ops->disabled != NULL) {
			/* If the old state was enabling or streaming, then the sink
			 * ASE has been disabled. Since the sink ASE does not have a
			 * disabling state, we can check if by comparing the old_state
			 */
			const bool disabled = old_state == BT_BAP_EP_STATE_ENABLING ||
					      old_state == BT_BAP_EP_STATE_STREAMING;

			if (disabled) {
				ops->disabled(stream);
			}
		} else if (ep->dir == BT_AUDIO_DIR_SOURCE &&
			   old_state == BT_BAP_EP_STATE_DISABLING && ops->stopped != NULL) {
			/* We left the disabling state, let the upper layers know that the stream is
			 * stopped
			 */
			uint8_t reason = ep->reason;

			if (reason == BT_HCI_ERR_SUCCESS) {
				/* Default to BT_HCI_ERR_UNSPECIFIED if no other reason is set */
				reason = BT_HCI_ERR_UNSPECIFIED;
			} else {
				/* Reset reason */
				ep->reason = BT_HCI_ERR_SUCCESS;
			}

			ops->stopped(stream, reason);
		}
	}

	qos = net_buf_simple_pull_mem(buf, sizeof(*qos));

	/* Update existing QoS configuration */
	unicast_client_ep_qos_update(ep, qos);

	ep->cig_id = qos->cig_id;
	ep->cis_id = qos->cis_id;
	(void)memcpy(&stream->qos->interval, sys_le24_to_cpu(qos->interval), sizeof(qos->interval));
	stream->qos->framing = qos->framing;
	stream->qos->phy = qos->phy;
	stream->qos->sdu = sys_le16_to_cpu(qos->sdu);
	stream->qos->rtn = qos->rtn;
	stream->qos->latency = sys_le16_to_cpu(qos->latency);
	(void)memcpy(&stream->qos->pd, sys_le24_to_cpu(qos->pd), sizeof(qos->pd));

	LOG_DBG("dir %s cig 0x%02x cis 0x%02x codec 0x%02x interval %u "
		"framing 0x%02x phy 0x%02x rtn %u latency %u pd %u",
		bt_audio_dir_str(ep->dir), ep->cig_id, ep->cis_id, stream->codec_cfg->id,
		stream->qos->interval, stream->qos->framing, stream->qos->phy, stream->qos->rtn,
		stream->qos->latency, stream->qos->pd);

	/* Disconnect ISO if connected */
	if (bt_bap_stream_can_disconnect(stream)) {
		const int err = bt_bap_stream_disconnect(stream);

		if (err != 0) {
			LOG_ERR("Failed to disconnect stream: %d", err);
		}
	} else {
		/* We setup the data path here, as this is the earliest where
		 * we have the ISO <-> EP coupling completed (due to setting
		 * the CIS ID in the QoS procedure).
		 */

		bt_bap_iso_configure_data_path(ep, stream->codec_cfg);
	}

	/* Notify upper layer */
	if (stream->ops != NULL && stream->ops->qos_set != NULL) {
		stream->ops->qos_set(stream);
	} else {
		LOG_WRN("No callback for qos_set set");
	}
}

static void unicast_client_ep_enabling_state(struct bt_bap_ep *ep, struct net_buf_simple *buf,
					     bool state_changed)
{
	struct bt_ascs_ase_status_enable *enable;
	struct bt_bap_stream *stream;
	void *metadata;

	if (buf->len < sizeof(*enable)) {
		LOG_ERR("Enabling status too short");
		return;
	}

	stream = ep->stream;
	if (stream == NULL) {
		LOG_ERR("No stream active for endpoint");
		return;
	}

	enable = net_buf_simple_pull_mem(buf, sizeof(*enable));

	if (buf->len < enable->metadata_len) {
		LOG_ERR("Malformed PDU: remaining len %u expected %u", buf->len,
			enable->metadata_len);
		return;
	}

	metadata = net_buf_simple_pull_mem(buf, enable->metadata_len);

	LOG_DBG("dir %s cig 0x%02x cis 0x%02x", bt_audio_dir_str(ep->dir), ep->cig_id, ep->cis_id);

	unicast_client_ep_set_metadata(ep, metadata, enable->metadata_len, NULL);

	/* Notify upper layer
	 *
	 * If the state did not change then only the metadata was changed
	 */
	if (state_changed) {
		if (stream->ops != NULL && stream->ops->enabled != NULL) {
			stream->ops->enabled(stream);
		} else {
			LOG_WRN("No callback for enabled set");
		}
	} else {
		if (stream->ops != NULL && stream->ops->metadata_updated != NULL) {
			stream->ops->metadata_updated(stream);
		} else {
			LOG_WRN("No callback for metadata_updated set");
		}
	}
}

static void unicast_client_ep_streaming_state(struct bt_bap_ep *ep, struct net_buf_simple *buf,
					      bool state_changed)
{
	struct bt_ascs_ase_status_stream *stream_status;
	struct bt_bap_stream *stream;

	if (buf->len < sizeof(*stream_status)) {
		LOG_ERR("Streaming status too short");
		return;
	}

	stream = ep->stream;
	if (stream == NULL) {
		LOG_ERR("No stream active for endpoint");
		return;
	}

	stream_status = net_buf_simple_pull_mem(buf, sizeof(*stream_status));

	LOG_DBG("dir %s cig 0x%02x cis 0x%02x", bt_audio_dir_str(ep->dir), ep->cig_id, ep->cis_id);

	/* Notify upper layer
	 *
	 * If the state did not change then only the metadata was changed
	 */
	if (state_changed) {
		if (stream->ops != NULL && stream->ops->started != NULL) {
			stream->ops->started(stream);
		} else {
			LOG_WRN("No callback for started set");
		}
	} else {
		if (stream->ops != NULL && stream->ops->metadata_updated != NULL) {
			stream->ops->metadata_updated(stream);
		} else {
			LOG_WRN("No callback for metadata_updated set");
		}
	}
}

static void unicast_client_ep_disabling_state(struct bt_bap_ep *ep, struct net_buf_simple *buf)
{
	struct bt_ascs_ase_status_disable *disable;
	struct bt_bap_stream *stream;

	if (buf->len < sizeof(*disable)) {
		LOG_ERR("Disabling status too short");
		return;
	}

	stream = ep->stream;
	if (stream == NULL) {
		LOG_ERR("No stream active for endpoint");
		return;
	}

	disable = net_buf_simple_pull_mem(buf, sizeof(*disable));

	LOG_DBG("dir %s cig 0x%02x cis 0x%02x", bt_audio_dir_str(ep->dir), ep->cig_id, ep->cis_id);

	/* Notify upper layer */
	if (stream->ops != NULL && stream->ops->disabled != NULL) {
		stream->ops->disabled(stream);
	} else {
		LOG_WRN("No callback for disabled set");
	}
}

static void unicast_client_ep_releasing_state(struct bt_bap_ep *ep, struct net_buf_simple *buf)
{
	struct bt_bap_stream *stream;

	stream = ep->stream;
	if (stream == NULL) {
		LOG_ERR("No stream active for endpoint");
		return;
	}

	LOG_DBG("dir %s", bt_audio_dir_str(ep->dir));

	if (bt_bap_stream_can_disconnect(stream)) {
		/* The Unicast Client shall terminate any CIS established for
		 * that ASE by following the Connected Isochronous Stream
		 * Terminate procedure defined in Volume 3, Part C,
		 * Section 9.3.15 in when the Unicast Client has determined
		 * that the ASE is in the Releasing state.
		 */
		const int err = bt_bap_stream_disconnect(stream);

		if (err != 0) {
			LOG_ERR("Failed to disconnect stream: %d", err);
		}
	}
}

static void unicast_client_ep_set_status(struct bt_bap_ep *ep, struct net_buf_simple *buf)
{
	struct bt_ascs_ase_status *status;
	struct bt_bap_unicast_client_ep *client_ep;
	bool state_changed;
	uint8_t old_state;

	if (!ep) {
		return;
	}

	client_ep = CONTAINER_OF(ep, struct bt_bap_unicast_client_ep, ep);

	status = net_buf_simple_pull_mem(buf, sizeof(*status));

	old_state = ep->status.state;
	ep->status = *status;
	state_changed = old_state != ep->status.state;

	if (state_changed && old_state == BT_BAP_EP_STATE_STREAMING) {
		/* We left the streaming state, let the upper layers know that the stream is stopped
		 */
		struct bt_bap_stream *stream = ep->stream;

		if (stream != NULL) {
			struct bt_bap_stream_ops *ops = stream->ops;
			uint8_t reason = ep->reason;

			if (reason == BT_HCI_ERR_SUCCESS) {
				/* Default to BT_HCI_ERR_UNSPECIFIED if no other reason is set */
				reason = BT_HCI_ERR_UNSPECIFIED;
			} else {
				/* Reset reason */
				ep->reason = BT_HCI_ERR_SUCCESS;
			}

			if (ops != NULL && ops->stopped != NULL) {
				ops->stopped(stream, reason);
			} else {
				LOG_WRN("No callback for stopped set");
			}
		}
	}

	LOG_DBG("ep %p handle 0x%04x id 0x%02x dir %s state %s -> %s", ep, client_ep->handle,
		status->id, bt_audio_dir_str(ep->dir), bt_bap_ep_state_str(old_state),
		bt_bap_ep_state_str(status->state));

	switch (status->state) {
	case BT_BAP_EP_STATE_IDLE:
		ep->receiver_ready = false;
		unicast_client_ep_idle_state(ep);
		break;
	case BT_BAP_EP_STATE_CODEC_CONFIGURED:
		switch (old_state) {
		/* Valid only if ASE_State field = 0x00 (Idle) */
		case BT_BAP_EP_STATE_IDLE:
			/* or 0x01 (Codec Configured) */
		case BT_BAP_EP_STATE_CODEC_CONFIGURED:
			/* or 0x02 (QoS Configured) */
		case BT_BAP_EP_STATE_QOS_CONFIGURED:
			/* or 0x06 (Releasing) */
		case BT_BAP_EP_STATE_RELEASING:
			break;
		default:
			LOG_WRN("Invalid state transition: %s -> %s",
				bt_bap_ep_state_str(old_state),
				bt_bap_ep_state_str(ep->status.state));
			return;
		}

		ep->receiver_ready = false;

		unicast_client_ep_config_state(ep, buf);
		break;
	case BT_BAP_EP_STATE_QOS_CONFIGURED:
		/* QoS configured have different allowed states depending on the endpoint type */
		if (ep->dir == BT_AUDIO_DIR_SOURCE) {
			switch (old_state) {
			/* Valid only if ASE_State field = 0x01 (Codec Configured) */
			case BT_BAP_EP_STATE_CODEC_CONFIGURED:
			/* or 0x02 (QoS Configured) */
			case BT_BAP_EP_STATE_QOS_CONFIGURED:
			/* or 0x04 (Streaming) if there is a disconnect */
			case BT_BAP_EP_STATE_STREAMING:
			/* or 0x05 (Disabling) */
			case BT_BAP_EP_STATE_DISABLING:
				break;
			default:
				LOG_WRN("Invalid state transition: %s -> %s",
					bt_bap_ep_state_str(old_state),
					bt_bap_ep_state_str(ep->status.state));
				return;
			}
		} else {
			switch (old_state) {
			/* Valid only if ASE_State field = 0x01 (Codec Configured) */
			case BT_BAP_EP_STATE_CODEC_CONFIGURED:
			/* or 0x02 (QoS Configured) */
			case BT_BAP_EP_STATE_QOS_CONFIGURED:
			/* or 0x03 (Enabling) */
			case BT_BAP_EP_STATE_ENABLING:
			/* or 0x04 (Streaming)*/
			case BT_BAP_EP_STATE_STREAMING:
				break;
			default:
				LOG_WRN("Invalid state transition: %s -> %s",
					bt_bap_ep_state_str(old_state),
					bt_bap_ep_state_str(ep->status.state));
				return;
			}
		}

		ep->receiver_ready = false;

		unicast_client_ep_qos_state(ep, buf, old_state);
		break;
	case BT_BAP_EP_STATE_ENABLING:
		switch (old_state) {
		/* Valid only if ASE_State field = 0x02 (QoS Configured) */
		case BT_BAP_EP_STATE_QOS_CONFIGURED:
			/* or 0x03 (Enabling) */
		case BT_BAP_EP_STATE_ENABLING:
			break;
		default:
			LOG_WRN("Invalid state transition: %s -> %s",
				bt_bap_ep_state_str(old_state),
				bt_bap_ep_state_str(ep->status.state));
			return;
		}

		unicast_client_ep_enabling_state(ep, buf, state_changed);
		break;
	case BT_BAP_EP_STATE_STREAMING:
		switch (old_state) {
		/* Valid only if ASE_State field = 0x03 (Enabling)*/
		case BT_BAP_EP_STATE_ENABLING:
			/* or 0x04 (Streaming)*/
		case BT_BAP_EP_STATE_STREAMING:
			break;
		default:
			LOG_WRN("Invalid state transition: %s -> %s",
				bt_bap_ep_state_str(old_state),
				bt_bap_ep_state_str(ep->status.state));
			return;
		}

		unicast_client_ep_streaming_state(ep, buf, state_changed);
		break;
	case BT_BAP_EP_STATE_DISABLING:
		if (ep->dir == BT_AUDIO_DIR_SOURCE) {
			switch (old_state) {
			/* Valid only if ASE_State field = 0x03 (Enabling) */
			case BT_BAP_EP_STATE_ENABLING:
			/* or 0x04 (Streaming) */
			case BT_BAP_EP_STATE_STREAMING:
				break;
			default:
				LOG_WRN("Invalid state transition: %s -> %s",
					bt_bap_ep_state_str(old_state),
					bt_bap_ep_state_str(ep->status.state));
				return;
			}
		} else {
			/* Sinks cannot go into the disabling state */
			LOG_WRN("Invalid state transition: %s -> %s",
				bt_bap_ep_state_str(old_state),
				bt_bap_ep_state_str(ep->status.state));
			return;
		}

		ep->receiver_ready = false;

		unicast_client_ep_disabling_state(ep, buf);
		break;
	case BT_BAP_EP_STATE_RELEASING:
		switch (old_state) {
		/* Valid only if ASE_State field = 0x01 (Codec Configured) */
		case BT_BAP_EP_STATE_CODEC_CONFIGURED:
			/* or 0x02 (QoS Configured) */
		case BT_BAP_EP_STATE_QOS_CONFIGURED:
			/* or 0x03 (Enabling) */
		case BT_BAP_EP_STATE_ENABLING:
			/* or 0x04 (Streaming) */
		case BT_BAP_EP_STATE_STREAMING:
			break;
			/* or 0x04 (Disabling) */
		case BT_BAP_EP_STATE_DISABLING:
			if (ep->dir == BT_AUDIO_DIR_SOURCE) {
				break;
			} /* else fall through for sink */

			/* fall through */
		default:
			LOG_WRN("Invalid state transition: %s -> %s",
				bt_bap_ep_state_str(old_state),
				bt_bap_ep_state_str(ep->status.state));
			return;
		}

		ep->receiver_ready = false;

		unicast_client_ep_releasing_state(ep, buf);
		break;
	}
}

static bool valid_ltv_cb(struct bt_data *data, void *user_data)
{
	/* just return true to continue parsing as bt_data_parse will validate for us */
	return true;
}

static int unicast_client_ep_set_codec_cfg(struct bt_bap_ep *ep, uint8_t id, uint16_t cid,
					   uint16_t vid, void *data, uint8_t len,
					   struct bt_audio_codec_cfg *codec_cfg)
{
	if (!ep && !codec_cfg) {
		return -EINVAL;
	}

	LOG_DBG("ep %p codec id 0x%02x cid 0x%04x vid 0x%04x len %u", ep, id, cid, vid, len);

	if (!codec_cfg) {
		codec_cfg = &ep->codec_cfg;
	}

	if (len > sizeof(codec_cfg->data)) {
		LOG_DBG("Cannot store %u octets of codec data", len);

		return -ENOMEM;
	}

	codec_cfg->id = id;
	codec_cfg->cid = cid;
	codec_cfg->vid = vid;

	codec_cfg->data_len = len;
	memcpy(codec_cfg->data, data, len);

	return 0;
}

static int unicast_client_set_codec_cap(uint8_t id, uint16_t cid, uint16_t vid, void *data,
					uint8_t data_len, void *meta, uint8_t meta_len,
					struct bt_audio_codec_cap *codec_cap)
{
	struct net_buf_simple buf;

	if (!codec_cap) {
		return -EINVAL;
	}

	LOG_DBG("codec id 0x%02x cid 0x%04x vid 0x%04x data_len %u meta_len %u", id, cid, vid,
		data_len, meta_len);

	/* Reset current data */
	(void)memset(codec_cap, 0, sizeof(*codec_cap));

	codec_cap->id = id;
	codec_cap->cid = cid;
	codec_cap->vid = vid;

	if (data_len > 0U) {
		if (data_len > sizeof(codec_cap->data)) {
			return -ENOMEM;
		}

		net_buf_simple_init_with_data(&buf, data, data_len);

		/* If codec is LC3, then it shall be LTV encoded - We verify this before storing the
		 * data For any non-LC3 codecs, we cannot verify anything
		 */
		if (id == BT_HCI_CODING_FORMAT_LC3) {
			bt_data_parse(&buf, valid_ltv_cb, NULL);

			/* Check if all entries could be parsed */
			if (buf.len) {
				LOG_ERR("Unable to parse Codec capabilities: len %u", buf.len);
				return -EINVAL;
			}
		}
		memcpy(codec_cap->data, data, data_len);
		codec_cap->data_len = data_len;
	}

	if (meta_len > 0U) {
		if (meta_len > sizeof(codec_cap->meta)) {
			return -ENOMEM;
		}

		net_buf_simple_init_with_data(&buf, meta, meta_len);

		bt_data_parse(&buf, valid_ltv_cb, NULL);

		/* Check if all entries could be parsed */
		if (buf.len) {
			LOG_ERR("Unable to parse Codec metadata: len %u", buf.len);
			return -EINVAL;
		}

		memcpy(codec_cap->meta, meta, meta_len);
		codec_cap->meta_len = meta_len;
	}

	return 0;
}

static int unicast_client_ep_set_metadata(struct bt_bap_ep *ep, void *data, uint8_t len,
					  struct bt_audio_codec_cfg *codec_cfg)
{
	if (!ep && !codec_cfg) {
		return -EINVAL;
	}

	LOG_DBG("ep %p len %u codec_cfg %p", ep, len, codec_cfg);

	if (!codec_cfg) {
		codec_cfg = &ep->codec_cfg;
	}

	if (len > sizeof(codec_cfg->meta)) {
		LOG_DBG("Cannot store %u octets of metadata", len);

		return -ENOMEM;
	}

	/* Reset current metadata */
	codec_cfg->meta_len = len;
	(void)memcpy(codec_cfg->meta, data, len);

	return 0;
}

static uint8_t unicast_client_cp_notify(struct bt_conn *conn,
					struct bt_gatt_subscribe_params *params, const void *data,
					uint16_t length)
{
	struct bt_ascs_cp_rsp *rsp;
	struct net_buf_simple buf;

	LOG_DBG("conn %p len %u", conn, length);

	if (!data) {
		LOG_DBG("Unsubscribed");
		params->value_handle = 0x0000;
		return BT_GATT_ITER_STOP;
	}

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

	if (buf.len < sizeof(*rsp)) {
		LOG_ERR("Control Point Notification too small");
		return BT_GATT_ITER_STOP;
	}

	rsp = net_buf_simple_pull_mem(&buf, sizeof(*rsp));

	if (rsp->num_ase == BT_ASCS_UNSUPP_OR_LENGTH_ERR_NUM_ASE) {
		/* This is a special case where num_ase == BT_ASCS_UNSUPP_OR_LENGTH_ERR_NUM_ASE
		 * but really there is only one ASE response
		 */
		rsp->num_ase = 1U;
	}

	for (uint8_t i = 0U; i < rsp->num_ase; i++) {
		struct bt_bap_unicast_client_ep *client_ep = NULL;
		struct bt_ascs_cp_ase_rsp *ase_rsp;
		struct bt_bap_stream *stream;

		if (buf.len < sizeof(*ase_rsp)) {
			LOG_ERR("Control Point Notification too small: %u", buf.len);
			return BT_GATT_ITER_STOP;
		}

		ase_rsp = net_buf_simple_pull_mem(&buf, sizeof(*ase_rsp));

		LOG_DBG("op %s (0x%02x) id 0x%02x code %s (0x%02x) "
			"reason %s (0x%02x)", bt_ascs_op_str(rsp->op), rsp->op,
			ase_rsp->id, bt_ascs_rsp_str(ase_rsp->code),
			ase_rsp->code, bt_ascs_reason_str(ase_rsp->reason),
			ase_rsp->reason);

		if (unicast_client_cbs == NULL) {
			continue;
		}

		stream = audio_stream_by_ep_id(conn, ase_rsp->id);
		if (stream == NULL) {
			LOG_DBG("Could not find stream by id %u", ase_rsp->id);
		} else {
			client_ep = CONTAINER_OF(stream->ep, struct bt_bap_unicast_client_ep, ep);
			client_ep->cp_ntf_pending = false;
		}

		switch (rsp->op) {
		case BT_ASCS_CONFIG_OP:
			if (unicast_client_cbs->config != NULL) {
				unicast_client_cbs->config(stream, ase_rsp->code, ase_rsp->reason);
			}
			break;
		case BT_ASCS_QOS_OP:
			if (unicast_client_cbs->qos != NULL) {
				unicast_client_cbs->qos(stream, ase_rsp->code, ase_rsp->reason);
			}
			break;
		case BT_ASCS_ENABLE_OP:
			if (unicast_client_cbs->enable != NULL) {
				unicast_client_cbs->enable(stream, ase_rsp->code, ase_rsp->reason);
			}
			break;
		case BT_ASCS_START_OP:
			if (unicast_client_cbs->start != NULL) {
				unicast_client_cbs->start(stream, ase_rsp->code, ase_rsp->reason);
			}
			break;
		case BT_ASCS_DISABLE_OP:
			if (unicast_client_cbs->disable != NULL) {
				unicast_client_cbs->disable(stream, ase_rsp->code, ase_rsp->reason);
			}
			break;
		case BT_ASCS_STOP_OP:
			if (unicast_client_cbs->stop != NULL) {
				unicast_client_cbs->stop(stream, ase_rsp->code, ase_rsp->reason);
			}
			break;
		case BT_ASCS_METADATA_OP:
			if (unicast_client_cbs->metadata != NULL) {
				unicast_client_cbs->metadata(stream, ase_rsp->code,
							     ase_rsp->reason);
			}
			break;
		case BT_ASCS_RELEASE_OP:
			/* client_ep->release_requested is set to false if handled by the
			 * endpoint notification handler
			 */
			if (client_ep != NULL && client_ep->release_requested) {
				/* If request was reject, do not expect endpoint notifications */
				if (ase_rsp->code != BT_BAP_ASCS_RSP_CODE_SUCCESS) {
					client_ep->cp_ntf_pending = false;
					client_ep->release_requested = false;
				}

				if (unicast_client_cbs->release != NULL) {
					unicast_client_cbs->release(stream, ase_rsp->code,
								    ase_rsp->reason);
				}
			}
			break;
		default:
			break;
		}
	}

	return BT_GATT_ITER_CONTINUE;
}

static uint8_t unicast_client_ase_ntf_read_func(struct bt_conn *conn, uint8_t err,
						struct bt_gatt_read_params *read, const void *data,
						uint16_t length)
{
	uint16_t handle = read->single.handle;
	struct net_buf_simple buf_clone;
	struct unicast_client *client;
	struct net_buf_simple *buf;
	struct bt_bap_ep *ep;

	LOG_DBG("conn %p err 0x%02x len %u", conn, err, length);

	if (err) {
		LOG_DBG("Failed to read ASE: %u", err);

		return BT_GATT_ITER_STOP;
	}

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

	client = &uni_cli_insts[bt_conn_index(conn)];
	buf = &client->net_buf;

	if (data != NULL) {
		if (net_buf_simple_tailroom(buf) < length) {
			LOG_DBG("Buffer full, invalid server response of size %u",
				length + client->net_buf.len);
			client->busy = false;
			reset_att_buf(client);

			return BT_GATT_ITER_STOP;
		}

		/* store data*/
		net_buf_simple_add_mem(buf, data, length);

		return BT_GATT_ITER_CONTINUE;
	}

	memset(read, 0, sizeof(*read));

	if (buf->len < sizeof(struct bt_ascs_ase_status)) {
		LOG_DBG("Read response too small (%u)", buf->len);
		reset_att_buf(client);
		client->busy = false;

		return BT_GATT_ITER_STOP;
	}

	/* Clone the buffer so that we can reset it while still providing the data to the upper
	 * layers
	 */
	net_buf_simple_clone(buf, &buf_clone);
	reset_att_buf(client);
	client->busy = false;

	ep = unicast_client_ep_get(conn, client->dir, handle);
	if (!ep) {
		LOG_DBG("Unknown %s ep for handle 0x%04X", bt_audio_dir_str(client->dir), handle);
	} else {
		/* Set reason in case this exits the streaming state, unless already set */
		if (ep->reason == BT_HCI_ERR_SUCCESS) {
			ep->reason = BT_HCI_ERR_REMOTE_USER_TERM_CONN;
		}

		unicast_client_ep_set_status(ep, &buf_clone);
	}

	return BT_GATT_ITER_STOP;
}

static void long_ase_read(struct bt_bap_unicast_client_ep *client_ep)
{
	/* Perform long read if notification is maximum size */
	struct bt_conn *conn = client_ep->ep.stream->conn;
	struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];
	struct net_buf_simple *long_read_buf = &client->net_buf;
	int err;

	LOG_DBG("conn %p ep %p 0x%04X busy %u", conn, &client_ep->ep, client_ep->handle,
		client->busy);

	if (client->busy) {
		/* If the client is busy reading or writing something else, reschedule the
		 * long read.
		 */
		struct bt_conn_info conn_info;

		err = bt_conn_get_info(conn, &conn_info);
		if (err != 0) {
			LOG_DBG("Failed to get conn info, use default interval");

			conn_info.le.interval = BT_GAP_INIT_CONN_INT_MIN;
		}

		/* Wait a connection interval to retry */
		err = k_work_reschedule(&client_ep->ase_read_work,
					K_USEC(BT_CONN_INTERVAL_TO_US(conn_info.le.interval)));
		if (err < 0) {
			LOG_DBG("Failed to reschedule ASE long read work: %d", err);
		}

		return;
	}

	client->read_params.func = unicast_client_ase_ntf_read_func;
	client->read_params.handle_count = 1U;
	client->read_params.single.handle = client_ep->handle;
	client->read_params.single.offset = long_read_buf->len;

	err = bt_gatt_read(conn, &client->read_params);
	if (err != 0) {
		LOG_DBG("Failed to read ASE: %d", err);
	} else {
		client->busy = true;
	}
}

static void delayed_ase_read_handler(struct k_work *work)
{
	struct k_work_delayable *dwork = k_work_delayable_from_work(work);
	struct bt_bap_unicast_client_ep *client_ep =
		CONTAINER_OF(dwork, struct bt_bap_unicast_client_ep, ase_read_work);

	LOG_DBG("ep %p 0x%04X", &client_ep->ep, client_ep->handle);

	/* Try reading again */
	long_ase_read(client_ep);
}

static uint8_t unicast_client_ep_notify(struct bt_conn *conn,
					struct bt_gatt_subscribe_params *params, const void *data,
					uint16_t length)
{
	struct net_buf_simple buf;
	struct bt_bap_unicast_client_ep *client_ep;
	const uint8_t att_ntf_header_size = 3; /* opcode (1) + handle (2) */
	const uint16_t max_ntf_size = bt_gatt_get_mtu(conn) - att_ntf_header_size;
	struct bt_bap_ep *ep;

	client_ep = CONTAINER_OF(params, struct bt_bap_unicast_client_ep, subscribe);
	ep = &client_ep->ep;

	LOG_DBG("conn %p ep %p len %u", conn, ep, length);

	/* Cancel any pending long reads for the endpoint */
	(void)k_work_cancel_delayable(&client_ep->ase_read_work);

	if (!data) {
		LOG_DBG("Unsubscribed");
		params->value_handle = 0x0000;
		return BT_GATT_ITER_STOP;
	}

	if (length == max_ntf_size) {
		struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];

		if (!client->busy) {
			struct net_buf_simple *long_read_buf = &client->net_buf;

			/* store data*/
			net_buf_simple_add_mem(long_read_buf, data, length);
		}

		long_ase_read(client_ep);

		return BT_GATT_ITER_CONTINUE;
	}

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

	if (buf.len < sizeof(struct bt_ascs_ase_status)) {
		LOG_ERR("Notification too small");
		return BT_GATT_ITER_STOP;
	}

	/* Set reason in case this exits the streaming state, unless already set */
	if (ep->reason == BT_HCI_ERR_SUCCESS) {
		ep->reason = BT_HCI_ERR_REMOTE_USER_TERM_CONN;
	}

	unicast_client_ep_set_status(ep, &buf);

	return BT_GATT_ITER_CONTINUE;
}

static int unicast_client_ep_subscribe(struct bt_conn *conn, struct bt_bap_ep *ep)
{
	struct bt_bap_unicast_client_ep *client_ep;
	int err;

	client_ep = CONTAINER_OF(ep, struct bt_bap_unicast_client_ep, ep);

	LOG_DBG("ep %p handle 0x%02x", ep, client_ep->handle);

	if (client_ep->subscribe.value_handle) {
		return 0;
	}

	client_ep->subscribe.value_handle = client_ep->handle;
	client_ep->subscribe.ccc_handle = 0x0000;
	client_ep->subscribe.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
	client_ep->subscribe.disc_params = &client_ep->discover;
	client_ep->subscribe.notify = unicast_client_ep_notify;
	client_ep->subscribe.value = BT_GATT_CCC_NOTIFY;
	atomic_set_bit(client_ep->subscribe.flags, BT_GATT_SUBSCRIBE_FLAG_VOLATILE);

	err = bt_gatt_subscribe(conn, &client_ep->subscribe);
	if (err != 0 && err != -EALREADY) {
		return err;
	}

	return 0;
}

static void pac_record_cb(struct bt_conn *conn, const struct bt_audio_codec_cap *codec_cap)
{
	if (unicast_client_cbs != NULL && unicast_client_cbs->pac_record != NULL) {
		struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];
		const enum bt_audio_dir dir = client->dir;

		/* TBD: Since the PAC records are optionally notifyable we may want to supply the
		 * index and total count of records in the callback, so that it easier for the
		 * upper layers to determine when a new set of PAC records is being reported.
		 */
		unicast_client_cbs->pac_record(conn, dir, codec_cap);
	}
}

static void endpoint_cb(struct bt_conn *conn, struct bt_bap_ep *ep)
{
	if (unicast_client_cbs != NULL && unicast_client_cbs->endpoint != NULL) {
		struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];
		const enum bt_audio_dir dir = client->dir;

		unicast_client_cbs->endpoint(conn, dir, ep);
	}
}

static void discover_cb(struct bt_conn *conn, int err)
{
	struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];
	const enum bt_audio_dir dir = client->dir;

	/* Discover complete - Reset discovery values */
	client->dir = 0U;
	reset_att_buf(client);
	client->busy = false;

	if (unicast_client_cbs != NULL && unicast_client_cbs->discover != NULL) {
		unicast_client_cbs->discover(conn, err, dir);
	}
}

static void unicast_client_cp_sub_cb(struct bt_conn *conn, uint8_t err,
				     struct bt_gatt_subscribe_params *sub_params)
{

	LOG_DBG("conn %p err %u", conn, err);

	discover_cb(conn, err);
}

static void unicast_client_ep_set_cp(struct bt_conn *conn, uint16_t handle)
{
	struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];

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

#if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0
	for (size_t i = 0U; i < ARRAY_SIZE(client->snks); i++) {
		struct bt_bap_unicast_client_ep *client_ep = &client->snks[i];

		if (client_ep->handle) {
			client_ep->cp_handle = handle;
		}
	}
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0 */

#if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0
	for (size_t i = 0U; i < ARRAY_SIZE(client->srcs); i++) {
		struct bt_bap_unicast_client_ep *client_ep = &client->srcs[i];

		if (client_ep->handle) {
			client_ep->cp_handle = handle;
		}
	}
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0 */

	if (!client->cp_subscribe.value_handle) {
		int err;

		client->cp_subscribe.value_handle = handle;
		client->cp_subscribe.ccc_handle = 0x0000;
		client->cp_subscribe.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
		client->cp_subscribe.disc_params = &client->disc_params;
		client->cp_subscribe.notify = unicast_client_cp_notify;
		client->cp_subscribe.value = BT_GATT_CCC_NOTIFY;
		client->cp_subscribe.subscribe = unicast_client_cp_sub_cb;
		atomic_set_bit(client->cp_subscribe.flags, BT_GATT_SUBSCRIBE_FLAG_VOLATILE);

		err = bt_gatt_subscribe(conn, &client->cp_subscribe);
		if (err != 0 && err != -EALREADY) {
			LOG_DBG("Failed to subscribe: %d", err);

			discover_cb(conn, err);

			return;
		}
	} else { /* already subscribed */
		discover_cb(conn, 0);
	}
}

struct net_buf_simple *bt_bap_unicast_client_ep_create_pdu(struct bt_conn *conn, uint8_t op)
{
	struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];
	struct bt_ascs_ase_cp *hdr;

	if (client->busy) {
		return NULL;
	}

	hdr = net_buf_simple_add(&client->net_buf, sizeof(*hdr));
	hdr->op = op;

	return &client->net_buf;
}

static int unicast_client_ep_config(struct bt_bap_ep *ep, struct net_buf_simple *buf,
				    const struct bt_audio_codec_cfg *codec_cfg)
{
	struct bt_ascs_config *req;
	uint8_t cc_len;

	LOG_DBG("ep %p buf %p codec %p", ep, buf, codec_cfg);

	if (!ep) {
		return -EINVAL;
	}

	switch (ep->status.state) {
	/* Valid only if ASE_State field = 0x00 (Idle) */
	case BT_BAP_EP_STATE_IDLE:
		/* or 0x01 (Codec Configured) */
	case BT_BAP_EP_STATE_CODEC_CONFIGURED:
		/* or 0x02 (QoS Configured) */
	case BT_BAP_EP_STATE_QOS_CONFIGURED:
		break;
	default:
		LOG_ERR("Invalid state: %s", bt_bap_ep_state_str(ep->status.state));
		return -EINVAL;
	}

	LOG_DBG("id 0x%02x dir %s codec 0x%02x", ep->status.id, bt_audio_dir_str(ep->dir),
		codec_cfg->id);

	req = net_buf_simple_add(buf, sizeof(*req));
	req->ase = ep->status.id;
	req->latency = 0x02; /* TODO: Select target latency based on additional input? */
	req->phy = 0x02;     /* TODO: Select target PHY based on additional input? */
	req->codec.id = codec_cfg->id;
	req->codec.cid = codec_cfg->cid;
	req->codec.vid = codec_cfg->vid;

	cc_len = buf->len;
	req->cc_len = codec_cfg->data_len;
	net_buf_simple_add_mem(buf, codec_cfg->data, codec_cfg->data_len);

	return 0;
}

int bt_bap_unicast_client_ep_qos(struct bt_bap_ep *ep, struct net_buf_simple *buf,
				 struct bt_audio_codec_qos *qos)
{
	struct bt_ascs_qos *req;
	struct bt_conn_iso *conn_iso;

	LOG_DBG("ep %p buf %p qos %p", ep, buf, qos);

	if (!ep) {
		return -EINVAL;
	}

	switch (ep->status.state) {
	/* Valid only if ASE_State field = 0x01 (Codec Configured) */
	case BT_BAP_EP_STATE_CODEC_CONFIGURED:
		/* or 0x02 (QoS Configured) */
	case BT_BAP_EP_STATE_QOS_CONFIGURED:
		break;
	default:
		LOG_ERR("Invalid state: %s", bt_bap_ep_state_str(ep->status.state));
		return -EINVAL;
	}

	conn_iso = &ep->iso->chan.iso->iso;

	LOG_DBG("id 0x%02x cig 0x%02x cis 0x%02x interval %u framing 0x%02x "
		"phy 0x%02x sdu %u rtn %u latency %u pd %u",
		ep->status.id, conn_iso->cig_id, conn_iso->cis_id, qos->interval, qos->framing,
		qos->phy, qos->sdu, qos->rtn, qos->latency, qos->pd);

	req = net_buf_simple_add(buf, sizeof(*req));
	req->ase = ep->status.id;
	/* TODO: don't hardcode CIG and CIS, they should come from ISO */
	req->cig = conn_iso->cig_id;
	req->cis = conn_iso->cis_id;
	sys_put_le24(qos->interval, req->interval);
	req->framing = qos->framing;
	req->phy = qos->phy;
	req->sdu = qos->sdu;
	req->rtn = qos->rtn;
	req->latency = sys_cpu_to_le16(qos->latency);
	sys_put_le24(qos->pd, req->pd);

	return 0;
}

static int unicast_client_ep_enable(struct bt_bap_ep *ep, struct net_buf_simple *buf,
				    const uint8_t meta[], size_t meta_len)
{
	struct bt_ascs_metadata *req;

	LOG_DBG("ep %p buf %p meta_len %zu", ep, buf, meta_len);

	if (!ep) {
		return -EINVAL;
	}

	if (ep->status.state != BT_BAP_EP_STATE_QOS_CONFIGURED) {
		LOG_ERR("Invalid state: %s", bt_bap_ep_state_str(ep->status.state));
		return -EINVAL;
	}

	LOG_DBG("id 0x%02x", ep->status.id);

	req = net_buf_simple_add(buf, sizeof(*req));
	req->ase = ep->status.id;

	req->len = meta_len;
	net_buf_simple_add_mem(buf, meta, meta_len);

	return 0;
}

static int unicast_client_ep_metadata(struct bt_bap_ep *ep, struct net_buf_simple *buf,
				      const uint8_t meta[], size_t meta_len)
{
	struct bt_ascs_metadata *req;

	LOG_DBG("ep %p buf %p meta_len %zu", ep, buf, meta_len);

	if (!ep) {
		return -EINVAL;
	}

	switch (ep->status.state) {
	/* Valid for an ASE only if ASE_State field = 0x03 (Enabling) */
	case BT_BAP_EP_STATE_ENABLING:
	/* or 0x04 (Streaming) */
	case BT_BAP_EP_STATE_STREAMING:
		break;
	default:
		LOG_ERR("Invalid state: %s", bt_bap_ep_state_str(ep->status.state));
		return -EINVAL;
	}

	LOG_DBG("id 0x%02x", ep->status.id);

	req = net_buf_simple_add(buf, sizeof(*req));
	req->ase = ep->status.id;

	req->len = meta_len;
	net_buf_simple_add_mem(buf, meta, meta_len);

	return 0;
}

static int unicast_client_ep_start(struct bt_bap_ep *ep, struct net_buf_simple *buf)
{
	LOG_DBG("ep %p buf %p", ep, buf);

	if (!ep) {
		return -EINVAL;
	}

	if (ep->status.state != BT_BAP_EP_STATE_ENABLING &&
	    ep->status.state != BT_BAP_EP_STATE_DISABLING) {
		LOG_ERR("Invalid state: %s", bt_bap_ep_state_str(ep->status.state));
		return -EINVAL;
	}

	LOG_DBG("id 0x%02x", ep->status.id);

	net_buf_simple_add_u8(buf, ep->status.id);

	return 0;
}

static int unicast_client_ep_disable(struct bt_bap_ep *ep, struct net_buf_simple *buf)
{
	LOG_DBG("ep %p buf %p", ep, buf);

	if (!ep) {
		return -EINVAL;
	}

	switch (ep->status.state) {
	/* Valid only if ASE_State field = 0x03 (Enabling) */
	case BT_BAP_EP_STATE_ENABLING:
		/* or 0x04 (Streaming) */
	case BT_BAP_EP_STATE_STREAMING:
		break;
	default:
		LOG_ERR("Invalid state: %s", bt_bap_ep_state_str(ep->status.state));
		return -EINVAL;
	}

	LOG_DBG("id 0x%02x", ep->status.id);

	net_buf_simple_add_u8(buf, ep->status.id);

	return 0;
}

static int unicast_client_ep_stop(struct bt_bap_ep *ep, struct net_buf_simple *buf)
{
	LOG_DBG("ep %p buf %p", ep, buf);

	if (!ep) {
		return -EINVAL;
	}

	/* Valid only if ASE_State field value = 0x05 (Disabling). */
	if (ep->status.state != BT_BAP_EP_STATE_DISABLING) {
		LOG_ERR("Invalid state: %s", bt_bap_ep_state_str(ep->status.state));
		return -EINVAL;
	}

	LOG_DBG("id 0x%02x", ep->status.id);

	net_buf_simple_add_u8(buf, ep->status.id);

	return 0;
}

static int unicast_client_ep_release(struct bt_bap_ep *ep, struct net_buf_simple *buf)
{
	LOG_DBG("ep %p buf %p", ep, buf);

	if (!ep) {
		return -EINVAL;
	}

	switch (ep->status.state) {
	/* Valid only if ASE_State field = 0x01 (Codec Configured) */
	case BT_BAP_EP_STATE_CODEC_CONFIGURED:
		/* or 0x02 (QoS Configured) */
	case BT_BAP_EP_STATE_QOS_CONFIGURED:
		/* or 0x03 (Enabling) */
	case BT_BAP_EP_STATE_ENABLING:
		/* or 0x04 (Streaming) */
	case BT_BAP_EP_STATE_STREAMING:
		/* or 0x05 (Disabling) */
	case BT_BAP_EP_STATE_DISABLING:
		break;
	default:
		LOG_ERR("Invalid state: %s", bt_bap_ep_state_str(ep->status.state));
		return -EINVAL;
	}

	LOG_DBG("id 0x%02x", ep->status.id);

	net_buf_simple_add_u8(buf, ep->status.id);

	return 0;
}

static void gatt_write_cb(struct bt_conn *conn, uint8_t err, struct bt_gatt_write_params *params)
{
	struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];

	LOG_DBG("conn %p err %u", conn, err);

	memset(params, 0, sizeof(*params));
	reset_att_buf(client);
	client->busy = false;

	/* TBD: Should we do anything in case of error here? */
}

int bt_bap_unicast_client_ep_send(struct bt_conn *conn, struct bt_bap_ep *ep,
				  struct net_buf_simple *buf)
{
	const uint8_t att_write_header_size = 3; /* opcode (1) + handle (2) */
	const uint16_t max_write_size = bt_gatt_get_mtu(conn) - att_write_header_size;
	struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];
	struct bt_bap_unicast_client_ep *client_ep =
		CONTAINER_OF(ep, struct bt_bap_unicast_client_ep, ep);
	int err;

	LOG_DBG("conn %p ep %p buf %p len %u", conn, ep, buf, buf->len);

	if (buf->len > max_write_size) {
		if (client->busy) {
			LOG_DBG("Client connection is busy");
			return -EBUSY;
		}

		client->write_params.func = gatt_write_cb;
		client->write_params.handle = client_ep->cp_handle;
		client->write_params.offset = 0U;
		client->write_params.data = buf->data;
		client->write_params.length = buf->len;
#if defined(CONFIG_BT_EATT)
		client->write_params.chan_opt = BT_ATT_CHAN_OPT_NONE;
#endif /* CONFIG_BT_EATT */

		err = bt_gatt_write(conn, &client->write_params);
		if (err != 0) {
			LOG_DBG("bt_gatt_write failed: %d", err);
		}

		client->busy = true;
	} else {
		err = bt_gatt_write_without_response(conn, client_ep->cp_handle, buf->data,
						     buf->len, false);
		if (err != 0) {
			LOG_DBG("bt_gatt_write_without_response failed: %d", err);
		}

		/* No callback for writing without response, so reset the buffer here */
		reset_att_buf(client);
	}

	if (err == 0) {
		client_ep->cp_ntf_pending = true;
	}

	return err;
}

static void unicast_client_reset(struct bt_bap_ep *ep, uint8_t reason)
{
	struct bt_bap_unicast_client_ep *client_ep =
		CONTAINER_OF(ep, struct bt_bap_unicast_client_ep, ep);

	LOG_DBG("ep %p", ep);
	ep->reason = reason;

	/* Pretend we received an idle state notification from the server to trigger all cleanup */
	unicast_client_ep_set_local_idle_state(ep);

	if (ep->iso != NULL && ep->iso->chan.state == BT_ISO_STATE_DISCONNECTING) {
		/* Wait for ISO disconnected event */
		return;
	}

	(void)k_work_cancel_delayable(&client_ep->ase_read_work);
	(void)memset(ep, 0, sizeof(*ep));

	client_ep->cp_handle = 0U;
	client_ep->handle = 0U;
	(void)memset(&client_ep->discover, 0, sizeof(client_ep->discover));
	client_ep->release_requested = false;
	client_ep->cp_ntf_pending = false;
	/* Need to keep the subscribe params intact for the callback */
}

static void unicast_client_ep_reset(struct bt_conn *conn, uint8_t reason)
{
	struct unicast_client *client;
	uint8_t index;

	LOG_DBG("conn %p", conn);

	index = bt_conn_index(conn);

#if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0
	for (size_t i = 0U; i < ARRAY_SIZE(uni_cli_insts[index].snks); i++) {
		struct bt_bap_ep *ep = &uni_cli_insts[index].snks[i].ep;

		unicast_client_reset(ep, reason);
	}
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0 */

#if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0
	for (size_t i = 0U; i < ARRAY_SIZE(uni_cli_insts[index].srcs); i++) {
		struct bt_bap_ep *ep = &uni_cli_insts[index].srcs[i].ep;

		unicast_client_reset(ep, reason);
	}
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0 */

	client = &uni_cli_insts[index];
	client->busy = false;
	client->dir = 0U;
	reset_att_buf(client);
}

static void bt_audio_codec_qos_to_cig_param(struct bt_iso_cig_param *cig_param,
					    const struct bt_audio_codec_qos *qos,
					    const struct bt_bap_unicast_group_param *group_param)
{
	cig_param->framing = qos->framing;
	cig_param->packing = BT_ISO_PACKING_SEQUENTIAL; /*  TODO: Add to QoS struct */
	cig_param->c_to_p_interval = qos->interval;
	cig_param->p_to_c_interval = qos->interval;
	cig_param->c_to_p_latency = qos->latency;
	cig_param->p_to_c_latency = qos->latency;
	cig_param->sca = BT_GAP_SCA_UNKNOWN;

	if (group_param != NULL) {
		cig_param->packing = group_param->packing;
#if defined(CONFIG_BT_ISO_TEST_PARAMS)
		cig_param->c_to_p_ft = group_param->c_to_p_ft;
		cig_param->p_to_c_ft = group_param->p_to_c_ft;
		cig_param->iso_interval = group_param->iso_interval;
#endif /* CONFIG_BT_ISO_TEST_PARAMS */
	}
}

/* FIXME: Remove `qos` parameter. Some of the QoS related CIG can be different
 * between CIS'es. The implementation shall take the CIG parameters from
 * unicast_group instead.
 */
static int bt_audio_cig_create(struct bt_bap_unicast_group *group,
			       const struct bt_audio_codec_qos *qos,
			       const struct bt_bap_unicast_group_param *group_param)
{
	struct bt_iso_cig_param param;
	uint8_t cis_count;
	int err;

	LOG_DBG("group %p qos %p", group, qos);

	cis_count = 0U;
	for (size_t i = 0U; i < ARRAY_SIZE(group->cis); i++) {
		if (group->cis[i] == NULL) {
			/* A NULL CIS acts as a NULL terminater */
			break;
		}

		cis_count++;
	}

	param.num_cis = cis_count;
	param.cis_channels = group->cis;
	bt_audio_codec_qos_to_cig_param(&param, qos, group_param);

	err = bt_iso_cig_create(&param, &group->cig);
	if (err != 0) {
		LOG_ERR("bt_iso_cig_create failed: %d", err);
		return err;
	}

	group->qos = qos;

	return 0;
}

static int bt_audio_cig_reconfigure(struct bt_bap_unicast_group *group,
				    const struct bt_audio_codec_qos *qos)
{
	struct bt_iso_cig_param param;
	uint8_t cis_count;
	int err;

	LOG_DBG("group %p qos %p", group, qos);

	cis_count = 0U;
	for (size_t i = 0U; i < ARRAY_SIZE(group->cis); i++) {
		if (group->cis[i] == NULL) {
			/* A NULL CIS acts as a NULL terminater */
			break;
		}

		cis_count++;
	}

	param.num_cis = cis_count;
	param.cis_channels = group->cis;
	bt_audio_codec_qos_to_cig_param(&param, qos, NULL);

	err = bt_iso_cig_reconfigure(group->cig, &param);
	if (err != 0) {
		LOG_ERR("bt_iso_cig_create failed: %d", err);
		return err;
	}

	group->qos = qos;

	return 0;
}

static void audio_stream_qos_cleanup(const struct bt_conn *conn,
				     struct bt_bap_unicast_group *group)
{
	struct bt_bap_stream *stream;

	SYS_SLIST_FOR_EACH_CONTAINER(&group->streams, stream, _node) {
		if (stream->conn != conn) {
			/* Channel not part of this ACL, skip */
			continue;
		}

		if (stream->ep == NULL) {
			/* Stream did not have a endpoint configured yet */
			continue;
		}

		bt_bap_iso_unbind_ep(stream->ep->iso, stream->ep);
	}
}

static int unicast_client_cig_terminate(struct bt_bap_unicast_group *group)
{
	LOG_DBG("group %p", group);

	return bt_iso_cig_terminate(group->cig);
}

static int unicast_client_stream_connect(struct bt_bap_stream *stream)
{
	struct bt_iso_connect_param param;
	struct bt_iso_chan *iso_chan;

	iso_chan = bt_bap_stream_iso_chan_get(stream);

	LOG_DBG("stream %p iso %p", stream, iso_chan);

	if (stream == NULL || iso_chan == NULL) {
		return -EINVAL;
	}

	param.acl = stream->conn;
	param.iso_chan = iso_chan;

	switch (iso_chan->state) {
	case BT_ISO_STATE_DISCONNECTED:
		return bt_iso_chan_connect(&param, 1);
	case BT_ISO_STATE_CONNECTING:
		return -EBUSY;
	case BT_ISO_STATE_CONNECTED:
		return -EALREADY;
	default:
		return bt_iso_chan_connect(&param, 1);
	}
}

static int unicast_group_add_iso(struct bt_bap_unicast_group *group, struct bt_bap_iso *iso)
{
	struct bt_iso_chan **chan_slot = NULL;

	__ASSERT_NO_MSG(group != NULL);
	__ASSERT_NO_MSG(iso != NULL);

	/* Append iso channel to the group->cis array */
	for (size_t i = 0U; i < ARRAY_SIZE(group->cis); i++) {
		/* Return if already there */
		if (group->cis[i] == &iso->chan) {
			return 0;
		}

		if (chan_slot == NULL && group->cis[i] == NULL) {
			chan_slot = &group->cis[i];
		}
	}

	if (chan_slot == NULL) {
		return -ENOMEM;
	}

	*chan_slot = &iso->chan;

	return 0;
}

static void unicast_group_del_iso(struct bt_bap_unicast_group *group, struct bt_bap_iso *iso)
{
	struct bt_bap_stream *stream;

	__ASSERT_NO_MSG(group != NULL);
	__ASSERT_NO_MSG(iso != NULL);

	SYS_SLIST_FOR_EACH_CONTAINER(&group->streams, stream, _node) {
		if (stream->ep->iso == iso) {
			/* still in use by some other stream */
			return;
		}
	}

	for (size_t i = 0U; i < ARRAY_SIZE(group->cis); i++) {
		if (group->cis[i] == &iso->chan) {
			group->cis[i] = NULL;
			return;
		}
	}
}

static void unicast_client_codec_qos_to_iso_qos(struct bt_bap_iso *iso,
						const struct bt_audio_codec_qos *qos,
						enum bt_audio_dir dir)
{
	struct bt_iso_chan_io_qos *io_qos;
	struct bt_iso_chan_io_qos *other_io_qos;

	if (dir == BT_AUDIO_DIR_SINK) {
		/* If the endpoint is a sink, then we need to
		 * configure our TX parameters
		 */
		io_qos = iso->chan.qos->tx;
		if (bt_bap_iso_get_ep(true, iso, BT_AUDIO_DIR_SOURCE) == NULL) {
			other_io_qos = iso->chan.qos->rx;
		} else {
			other_io_qos = NULL;
		}
	} else {
		/* If the endpoint is a source, then we need to
		 * configure our RX parameters
		 */
		io_qos = iso->chan.qos->rx;
		if (bt_bap_iso_get_ep(true, iso, BT_AUDIO_DIR_SINK) == NULL) {
			other_io_qos = iso->chan.qos->tx;
		} else {
			other_io_qos = NULL;
		}
	}

	bt_audio_codec_qos_to_iso_qos(io_qos, qos);
#if defined(CONFIG_BT_ISO_TEST_PARAMS)
	iso->chan.qos->num_subevents = qos->num_subevents;
#endif /* CONFIG_BT_ISO_TEST_PARAMS */

	if (other_io_qos != NULL) {
		/* If the opposing ASE of the CIS is not yet configured, we
		 * still need to set the PHY value when creating the CIG.
		 */
		other_io_qos->phy = io_qos->phy;
	}
}

static void unicast_group_add_stream(struct bt_bap_unicast_group *group,
				     struct bt_bap_unicast_group_stream_param *param,
				     struct bt_bap_iso *iso, enum bt_audio_dir dir)
{
	struct bt_bap_stream *stream = param->stream;
	struct bt_audio_codec_qos *qos = param->qos;

	LOG_DBG("group %p stream %p qos %p iso %p dir %u", group, stream, qos, iso, dir);

	__ASSERT_NO_MSG(stream->ep == NULL || (stream->ep != NULL && stream->ep->iso == NULL));

	stream->qos = qos;
	stream->group = group;

	/* iso initialized already */
	bt_bap_iso_bind_stream(iso, stream, dir);
	if (stream->ep != NULL) {
		bt_bap_iso_bind_ep(iso, stream->ep);
	}

	/* Store the Codec QoS in the bap_iso */
	unicast_client_codec_qos_to_iso_qos(iso, qos, dir);

	sys_slist_append(&group->streams, &stream->_node);
}

static int unicast_group_add_stream_pair(struct bt_bap_unicast_group *group,
					 struct bt_bap_unicast_group_stream_pair_param *param)
{
	struct bt_bap_iso *iso;
	int err;

	__ASSERT_NO_MSG(group != NULL);
	__ASSERT_NO_MSG(param != NULL);
	__ASSERT_NO_MSG(param->rx_param != NULL || param->tx_param != NULL);

	iso = bt_bap_unicast_client_new_audio_iso();
	if (iso == NULL) {
		return -ENOMEM;
	}

	err = unicast_group_add_iso(group, iso);
	if (err < 0) {
		bt_bap_iso_unref(iso);
		return err;
	}

	if (param->rx_param != NULL) {
		unicast_group_add_stream(group, param->rx_param, iso, BT_AUDIO_DIR_SOURCE);
	}

	if (param->tx_param != NULL) {
		unicast_group_add_stream(group, param->tx_param, iso, BT_AUDIO_DIR_SINK);
	}

	bt_bap_iso_unref(iso);

	return 0;
}

static void unicast_group_del_stream(struct bt_bap_unicast_group *group,
				     struct bt_bap_stream *stream, enum bt_audio_dir dir)
{
	__ASSERT_NO_MSG(group != NULL);
	__ASSERT_NO_MSG(stream != NULL);

	if (sys_slist_find_and_remove(&group->streams, &stream->_node)) {
		struct bt_bap_ep *ep = stream->ep;

		if (stream->bap_iso != NULL) {
			bt_bap_iso_unbind_stream(stream->bap_iso, stream, dir);
		}

		if (ep != NULL && ep->iso != NULL) {
			unicast_group_del_iso(group, ep->iso);

			bt_bap_iso_unbind_ep(ep->iso, ep);
		}

		stream->group = NULL;
	}
}

static void unicast_group_del_stream_pair(struct bt_bap_unicast_group *group,
					  struct bt_bap_unicast_group_stream_pair_param *param)
{
	__ASSERT_NO_MSG(group != NULL);
	__ASSERT_NO_MSG(param != NULL);
	__ASSERT_NO_MSG(param->rx_param != NULL || param->tx_param != NULL);

	if (param->rx_param != NULL) {
		__ASSERT_NO_MSG(param->rx_param->stream);
		unicast_group_del_stream(group, param->rx_param->stream, BT_AUDIO_DIR_SOURCE);
	}

	if (param->tx_param != NULL) {
		__ASSERT_NO_MSG(param->tx_param->stream);
		unicast_group_del_stream(group, param->tx_param->stream, BT_AUDIO_DIR_SINK);
	}
}

static struct bt_bap_unicast_group *unicast_group_alloc(void)
{
	struct bt_bap_unicast_group *group = NULL;

	for (size_t i = 0U; i < ARRAY_SIZE(unicast_groups); i++) {
		if (!unicast_groups[i].allocated) {
			group = &unicast_groups[i];

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

			group->allocated = true;
			group->index = i;

			break;
		}
	}

	return group;
}

static void unicast_group_free(struct bt_bap_unicast_group *group)
{
	struct bt_bap_stream *stream, *next;

	__ASSERT_NO_MSG(group != NULL);

	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&group->streams, stream, next, _node) {
		struct bt_bap_iso *bap_iso = stream->bap_iso;
		struct bt_bap_ep *ep = stream->ep;

		stream->group = NULL;
		if (bap_iso != NULL) {
			if (bap_iso->rx.stream == stream) {
				bt_bap_iso_unbind_stream(stream->bap_iso, stream,
							 BT_AUDIO_DIR_SOURCE);
			} else if (bap_iso->tx.stream == stream) {
				bt_bap_iso_unbind_stream(stream->bap_iso, stream,
							 BT_AUDIO_DIR_SINK);
			} else {
				__ASSERT_PRINT("stream %p has invalid bap_iso %p", stream, bap_iso);
			}
		}

		if (ep != NULL && ep->iso != NULL) {
			bt_bap_iso_unbind_ep(ep->iso, ep);
		}

		sys_slist_remove(&group->streams, NULL, &stream->_node);
	}

	group->allocated = false;
}

static int stream_param_check(const struct bt_bap_unicast_group_stream_param *param)
{
	CHECKIF(param->stream == NULL)
	{
		LOG_ERR("param->stream is NULL");
		return -EINVAL;
	}

	CHECKIF(param->qos == NULL)
	{
		LOG_ERR("param->qos is NULL");
		return -EINVAL;
	}

	if (param->stream != NULL && param->stream->group != NULL) {
		LOG_WRN("stream %p already part of group %p", param->stream, param->stream->group);
		return -EALREADY;
	}

	CHECKIF(bt_audio_verify_qos(param->qos) != BT_BAP_ASCS_REASON_NONE)
	{
		LOG_ERR("Invalid QoS");
		return -EINVAL;
	}

	return 0;
}

static int stream_pair_param_check(const struct bt_bap_unicast_group_stream_pair_param *param)
{
	int err;

	CHECKIF(param->rx_param == NULL && param->tx_param == NULL)
	{
		LOG_DBG("Invalid stream parameters");
		return -EINVAL;
	}

	if (param->rx_param != NULL) {
		err = stream_param_check(param->rx_param);
		if (err < 0) {
			return err;
		}
	}

	if (param->tx_param != NULL) {
		err = stream_param_check(param->tx_param);
		if (err < 0) {
			return err;
		}
	}

	return 0;
}

static int group_qos_common_set(const struct bt_audio_codec_qos **group_qos,
				const struct bt_bap_unicast_group_stream_pair_param *param)
{
	if (param->rx_param != NULL && *group_qos == NULL) {
		*group_qos = param->rx_param->qos;
	}

	if (param->tx_param != NULL && *group_qos == NULL) {
		*group_qos = param->tx_param->qos;
	}

	return 0;
}

int bt_bap_unicast_group_create(struct bt_bap_unicast_group_param *param,
				  struct bt_bap_unicast_group **out_unicast_group)
{
	struct bt_bap_unicast_group *unicast_group;
	const struct bt_audio_codec_qos *group_qos = NULL;
	int err;

	CHECKIF(out_unicast_group == NULL)
	{
		LOG_DBG("out_unicast_group is NULL");
		return -EINVAL;
	}
	/* Set out_unicast_group to NULL until the source has actually been created */
	*out_unicast_group = NULL;

	CHECKIF(param == NULL)
	{
		LOG_DBG("streams is NULL");
		return -EINVAL;
	}

	CHECKIF(param->params_count > UNICAST_GROUP_STREAM_CNT)
	{
		LOG_DBG("Too many streams provided: %u/%u", param->params_count,
			UNICAST_GROUP_STREAM_CNT);
		return -EINVAL;
	}

	unicast_group = unicast_group_alloc();
	if (unicast_group == NULL) {
		LOG_DBG("Could not allocate any more unicast groups");
		return -ENOMEM;
	}

	for (size_t i = 0U; i < param->params_count; i++) {
		struct bt_bap_unicast_group_stream_pair_param *stream_param;

		stream_param = &param->params[i];

		err = stream_pair_param_check(stream_param);
		if (err < 0) {
			return err;
		}

		err = group_qos_common_set(&group_qos, stream_param);
		if (err < 0) {
			return err;
		}

		err = unicast_group_add_stream_pair(unicast_group, stream_param);
		if (err < 0) {
			LOG_DBG("unicast_group_add_stream failed: %d", err);
			unicast_group_free(unicast_group);

			return err;
		}
	}

	err = bt_audio_cig_create(unicast_group, group_qos, param);
	if (err != 0) {
		LOG_DBG("bt_audio_cig_create failed: %d", err);
		unicast_group_free(unicast_group);

		return err;
	}

	*out_unicast_group = unicast_group;

	return 0;
}

int bt_bap_unicast_group_add_streams(struct bt_bap_unicast_group *unicast_group,
				       struct bt_bap_unicast_group_stream_pair_param params[],
				       size_t num_param)
{
	const struct bt_audio_codec_qos *group_qos = unicast_group->qos;
	struct bt_bap_stream *tmp_stream;
	size_t total_stream_cnt;
	struct bt_iso_cig *cig;
	size_t num_added;
	int err;

	CHECKIF(unicast_group == NULL)
	{
		LOG_DBG("unicast_group is NULL");
		return -EINVAL;
	}

	CHECKIF(params == NULL)
	{
		LOG_DBG("params is NULL");
		return -EINVAL;
	}

	CHECKIF(num_param == 0)
	{
		LOG_DBG("num_param is 0");
		return -EINVAL;
	}

	total_stream_cnt = num_param;
	SYS_SLIST_FOR_EACH_CONTAINER(&unicast_group->streams, tmp_stream, _node) {
		total_stream_cnt++;
	}

	if (total_stream_cnt > UNICAST_GROUP_STREAM_CNT) {
		LOG_DBG("Too many streams provided: %u/%u", total_stream_cnt,
			UNICAST_GROUP_STREAM_CNT);
		return -EINVAL;
	}

	/* We can just check the CIG state to see if any streams have started as
	 * that would start the ISO connection procedure
	 */
	cig = unicast_group->cig;
	if (cig != NULL && cig->state != BT_ISO_CIG_STATE_CONFIGURED) {
		LOG_DBG("At least one unicast group stream is started");
		return -EBADMSG;
	}

	for (num_added = 0U; num_added < num_param; num_added++) {
		struct bt_bap_unicast_group_stream_pair_param *stream_param;

		stream_param = &params[num_added];

		err = stream_pair_param_check(stream_param);
		if (err < 0) {
			return err;
		}

		err = group_qos_common_set(&group_qos, stream_param);
		if (err < 0) {
			return err;
		}

		err = unicast_group_add_stream_pair(unicast_group, stream_param);
		if (err < 0) {
			LOG_DBG("unicast_group_add_stream failed: %d", err);
			goto fail;
		}
	}

	err = bt_audio_cig_reconfigure(unicast_group, group_qos);
	if (err != 0) {
		LOG_DBG("bt_audio_cig_reconfigure failed: %d", err);
		goto fail;
	}

	return 0;

fail:
	/* Restore group by removing the newly added streams */
	while (num_added--) {
		unicast_group_del_stream_pair(unicast_group, &params[num_added]);
	}

	return err;
}

int bt_bap_unicast_group_delete(struct bt_bap_unicast_group *unicast_group)
{
	struct bt_bap_stream *stream;

	CHECKIF(unicast_group == NULL)
	{
		LOG_DBG("unicast_group is NULL");
		return -EINVAL;
	}

	SYS_SLIST_FOR_EACH_CONTAINER(&unicast_group->streams, stream, _node) {
		/* If a stream has an endpoint, it is not ready to be removed
		 * from a group, as it is not in an idle state
		 */
		if (stream->ep != NULL) {
			LOG_DBG("stream %p is not released", stream);
			return -EINVAL;
		}
	}

	if (unicast_group->cig != NULL) {
		const int err = unicast_client_cig_terminate(unicast_group);

		if (err != 0) {
			LOG_DBG("unicast_client_cig_terminate failed with err %d", err);

			return err;
		}
	}

	unicast_group_free(unicast_group);

	return 0;
}

int bt_bap_unicast_client_config(struct bt_bap_stream *stream,
				 const struct bt_audio_codec_cfg *codec_cfg)
{
	struct bt_bap_ep *ep = stream->ep;
	struct bt_ascs_config_op *op;
	struct net_buf_simple *buf;
	int err;

	LOG_DBG("stream %p", stream);

	if (stream->conn == NULL) {
		LOG_DBG("Stream %p does not have a connection", stream);

		return -ENOTCONN;
	}

	buf = bt_bap_unicast_client_ep_create_pdu(stream->conn, BT_ASCS_CONFIG_OP);
	if (buf == NULL) {
		LOG_DBG("Could not create PDU");
		return -EBUSY;
	}

	op = net_buf_simple_add(buf, sizeof(*op));
	op->num_ases = 0x01;

	err = unicast_client_ep_config(ep, buf, codec_cfg);
	if (err != 0) {
		return err;
	}

	err = bt_bap_unicast_client_ep_send(stream->conn, ep, buf);
	if (err != 0) {
		return err;
	}

	return 0;
}

int bt_bap_unicast_client_qos(struct bt_conn *conn, struct bt_bap_unicast_group *group)
{
	struct bt_bap_stream *stream;
	struct bt_ascs_config_op *op;
	struct net_buf_simple *buf;
	struct bt_bap_ep *ep;
	bool conn_stream_found;
	bool cig_connected;
	int err;

	if (conn == NULL) {
		LOG_DBG("conn is NULL");

		return -ENOTCONN;
	}

	/* Used to determine if a stream for the supplied connection pointer
	 * was actually found
	 */
	conn_stream_found = false;

	/* User to determine if any stream in the group is in
	 * the connected state
	 */
	cig_connected = false;

	/* Validate streams before starting the QoS execution */
	SYS_SLIST_FOR_EACH_CONTAINER(&group->streams, stream, _node) {
		if (stream->conn != conn) {
			/* Channel not part of this ACL, skip */
			continue;
		}
		conn_stream_found = true;

		ep = stream->ep;
		if (ep == NULL) {
			LOG_DBG("stream->ep is NULL");
			return -EINVAL;
		}

		/* Can only be done if all the streams are in the codec
		 * configured state or the QoS configured state
		 */
		switch (ep->status.state) {
		case BT_BAP_EP_STATE_CODEC_CONFIGURED:
		case BT_BAP_EP_STATE_QOS_CONFIGURED:
			break;
		default:
			LOG_DBG("Invalid state: %s", bt_bap_ep_state_str(stream->ep->status.state));
			return -EINVAL;
		}

		if (bt_bap_stream_verify_qos(stream, stream->qos) != BT_BAP_ASCS_REASON_NONE) {
			return -EINVAL;
		}

		/* Verify ep->dir */
		switch (ep->dir) {
		case BT_AUDIO_DIR_SINK:
		case BT_AUDIO_DIR_SOURCE:
			break;
		default:
			__ASSERT(false, "invalid endpoint dir: %u", ep->dir);
			return -EINVAL;
		}

		if (stream->bap_iso == NULL) {
			/* This can only happen if the stream was somehow added
			 * to a group without the bap_iso being bound to it
			 */
			LOG_ERR("Could not find bap_iso for stream %p", stream);
			return -EINVAL;
		}
	}

	if (!conn_stream_found) {
		LOG_DBG("No streams in the group %p for conn %p", group, conn);
		return -EINVAL;
	}

	/* Generate the control point write */
	buf = bt_bap_unicast_client_ep_create_pdu(conn, BT_ASCS_QOS_OP);
	if (buf == NULL) {
		LOG_DBG("Could not create PDU");
		return -EBUSY;
	}

	op = net_buf_simple_add(buf, sizeof(*op));

	(void)memset(op, 0, sizeof(*op));
	ep = NULL; /* Needed to find the control point handle */
	SYS_SLIST_FOR_EACH_CONTAINER(&group->streams, stream, _node) {
		if (stream->conn != conn) {
			/* Channel not part of this ACL, skip */
			continue;
		}

		op->num_ases++;

		if (stream->ep->iso == NULL) {
			/* Not yet bound with the bap_iso */
			bt_bap_iso_bind_ep(stream->bap_iso, stream->ep);
		}

		err = bt_bap_unicast_client_ep_qos(stream->ep, buf, stream->qos);
		if (err != 0) {
			audio_stream_qos_cleanup(conn, group);

			return err;
		}

		if (ep == NULL) {
			ep = stream->ep;
		}
	}

	err = bt_bap_unicast_client_ep_send(conn, ep, buf);
	if (err != 0) {
		LOG_DBG("Could not send config QoS: %d", err);
		audio_stream_qos_cleanup(conn, group);

		return err;
	}

	return 0;
}

int bt_bap_unicast_client_enable(struct bt_bap_stream *stream, const uint8_t meta[],
				 size_t meta_len)
{
	struct bt_bap_ep *ep = stream->ep;
	struct net_buf_simple *buf;
	struct bt_ascs_enable_op *req;
	int err;

	LOG_DBG("stream %p", stream);

	if (stream->conn == NULL) {
		LOG_DBG("Stream %p does not have a connection", stream);

		return -ENOTCONN;
	}

	buf = bt_bap_unicast_client_ep_create_pdu(stream->conn, BT_ASCS_ENABLE_OP);
	if (buf == NULL) {
		LOG_DBG("Could not create PDU");
		return -EBUSY;
	}

	req = net_buf_simple_add(buf, sizeof(*req));
	req->num_ases = 0x01;

	err = unicast_client_ep_enable(ep, buf, meta, meta_len);
	if (err) {
		return err;
	}

	return bt_bap_unicast_client_ep_send(stream->conn, ep, buf);
}

int bt_bap_unicast_client_metadata(struct bt_bap_stream *stream, const uint8_t meta[],
				   size_t meta_len)
{
	struct bt_bap_ep *ep = stream->ep;
	struct net_buf_simple *buf;
	struct bt_ascs_enable_op *req;
	int err;

	LOG_DBG("stream %p", stream);

	if (stream->conn == NULL) {
		LOG_DBG("Stream %p does not have a connection", stream);

		return -ENOTCONN;
	}

	buf = bt_bap_unicast_client_ep_create_pdu(stream->conn, BT_ASCS_METADATA_OP);
	if (buf == NULL) {
		LOG_DBG("Could not create PDU");
		return -EBUSY;
	}

	req = net_buf_simple_add(buf, sizeof(*req));
	req->num_ases = 0x01;

	err = unicast_client_ep_metadata(ep, buf, meta, meta_len);
	if (err) {
		return err;
	}

	return bt_bap_unicast_client_ep_send(stream->conn, ep, buf);
}

int bt_bap_unicast_client_start(struct bt_bap_stream *stream)
{
	struct bt_bap_ep *ep = stream->ep;
	int err;

	LOG_DBG("stream %p", stream);

	if (stream->conn == NULL) {
		LOG_DBG("Stream %p does not have a connection", stream);

		return -ENOTCONN;
	}

	/* If an ASE is in the Enabling state, and if the Unicast Client has
	 * not yet established a CIS for that ASE, the Unicast Client shall
	 * attempt to establish a CIS by using the Connected Isochronous Stream
	 * Central Establishment procedure.
	 */
	err = unicast_client_stream_connect(stream);
	if (err == 0) {
		if (ep->dir == BT_AUDIO_DIR_SOURCE) {
			/* Set bool and wait for ISO to be connected to send the
			 * receiver start ready
			 */
			ep->receiver_ready = true;
		}
	} else if (err == -EALREADY) {
		LOG_DBG("ISO %p already connected", bt_bap_stream_iso_chan_get(stream));

		if (ep->dir == BT_AUDIO_DIR_SOURCE) {
			ep->receiver_ready = true;

			err = unicast_client_send_start(ep);
			if (err != 0) {
				LOG_DBG("Failed to send start: %d", err);

				/* TBD: Should we release the stream then? */
				ep->receiver_ready = false;

				return err;
			}
		}
	} else {
		LOG_DBG("unicast_client_stream_connect failed: %d", err);

		return err;
	}

	return 0;
}

int bt_bap_unicast_client_disable(struct bt_bap_stream *stream)
{
	struct bt_bap_ep *ep = stream->ep;
	struct net_buf_simple *buf;
	struct bt_ascs_disable_op *req;
	int err;

	LOG_DBG("stream %p", stream);

	if (stream->conn == NULL) {
		LOG_DBG("Stream %p does not have a connection", stream);

		return -ENOTCONN;
	}

	buf = bt_bap_unicast_client_ep_create_pdu(stream->conn, BT_ASCS_DISABLE_OP);
	if (buf == NULL) {
		LOG_DBG("Could not create PDU");
		return -EBUSY;
	}

	req = net_buf_simple_add(buf, sizeof(*req));
	req->num_ases = 0x01;

	err = unicast_client_ep_disable(ep, buf);
	if (err) {
		return err;
	}

	return bt_bap_unicast_client_ep_send(stream->conn, ep, buf);
}

int bt_bap_unicast_client_stop(struct bt_bap_stream *stream)
{
	struct bt_bap_ep *ep = stream->ep;
	struct net_buf_simple *buf;
	struct bt_ascs_start_op *req;
	int err;

	LOG_DBG("stream %p", stream);

	if (stream->conn == NULL) {
		LOG_DBG("Stream %p does not have a connection", stream);

		return -ENOTCONN;
	}

	buf = bt_bap_unicast_client_ep_create_pdu(stream->conn, BT_ASCS_STOP_OP);
	if (buf == NULL) {
		LOG_DBG("Could not create PDU");
		return -EBUSY;
	}

	req = net_buf_simple_add(buf, sizeof(*req));
	req->num_ases = 0x00;

	/* When initiated by the client, valid only if Direction field
	 * parameter value = 0x02 (Server is Audio Source)
	 */
	if (ep->dir == BT_AUDIO_DIR_SOURCE) {
		err = unicast_client_ep_stop(ep, buf);
		if (err) {
			return err;
		}
		req->num_ases++;

		return bt_bap_unicast_client_ep_send(stream->conn, ep, buf);
	}

	return 0;
}

int bt_bap_unicast_client_release(struct bt_bap_stream *stream)
{
	struct bt_bap_unicast_client_ep *client_ep;
	struct bt_bap_ep *ep = stream->ep;
	struct net_buf_simple *buf;
	struct bt_ascs_disable_op *req;
	int err, len;

	LOG_DBG("stream %p", stream);

	if (stream->conn == NULL) {
		LOG_DBG("Stream %p does not have a connection", stream);

		return -ENOTCONN;
	}

	buf = bt_bap_unicast_client_ep_create_pdu(stream->conn, BT_ASCS_RELEASE_OP);
	if (buf == NULL) {
		LOG_DBG("Could not create PDU");
		return -EBUSY;
	}

	req = net_buf_simple_add(buf, sizeof(*req));
	req->num_ases = 0x01;
	len = buf->len;

	/* Only attempt to release if not IDLE already */
	if (stream->ep->status.state == BT_BAP_EP_STATE_IDLE) {
		bt_bap_stream_reset(stream);
	} else {
		err = unicast_client_ep_release(ep, buf);
		if (err) {
			return err;
		}
	}

	/* Check if anything needs to be send */
	if (len == buf->len) {
		return 0;
	}

	err = bt_bap_unicast_client_ep_send(stream->conn, ep, buf);
	if (err != 0) {
		return err;
	}

	client_ep = CONTAINER_OF(ep, struct bt_bap_unicast_client_ep, ep);
	client_ep->release_requested = true;

	return 0;
}

static uint8_t unicast_client_cp_discover_func(struct bt_conn *conn,
					       const struct bt_gatt_attr *attr,
					       struct bt_gatt_discover_params *discover)
{
	struct bt_gatt_chrc *chrc;
	uint16_t value_handle;

	if (!attr) {
		LOG_ERR("Unable to find ASE Control Point");

		discover_cb(conn, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND);
		return BT_GATT_ITER_STOP;
	}

	chrc = attr->user_data;
	value_handle = chrc->value_handle;
	memset(discover, 0, sizeof(*discover));

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

	unicast_client_ep_set_cp(conn, value_handle);

	return BT_GATT_ITER_STOP;
}

static int unicast_client_ase_cp_discover(struct bt_conn *conn)
{
	struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];

	LOG_DBG("conn %p", conn);

	client->disc_params.uuid = cp_uuid;
	client->disc_params.func = unicast_client_cp_discover_func;
	client->disc_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
	client->disc_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
	client->disc_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;

	return bt_gatt_discover(conn, &client->disc_params);
}

static uint8_t unicast_client_ase_read_func(struct bt_conn *conn, uint8_t err,
					    struct bt_gatt_read_params *read, const void *data,
					    uint16_t length)
{
	uint16_t handle = read->single.handle;
	struct unicast_client *client;
	struct net_buf_simple *buf;
	struct bt_bap_ep *ep;
	int cb_err;

	LOG_DBG("conn %p err 0x%02x len %u", conn, err, length);

	if (err) {
		cb_err = err;
		goto fail;
	}

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

	client = &uni_cli_insts[bt_conn_index(conn)];
	buf = &client->net_buf;

	if (data != NULL) {
		if (net_buf_simple_tailroom(buf) < length) {
			LOG_DBG("Buffer full, invalid server response of size %u",
				length + client->net_buf.len);

			cb_err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;

			goto fail;
		}

		/* store data*/
		net_buf_simple_add_mem(buf, data, length);

		return BT_GATT_ITER_CONTINUE;
	}

	memset(read, 0, sizeof(*read));

	if (buf->len < sizeof(struct bt_ascs_ase_status)) {
		LOG_DBG("Read response too small (%u)", buf->len);

		cb_err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;

		goto fail;
	}

	ep = unicast_client_ep_get(conn, client->dir, handle);
	if (!ep) {
		/* The BAP spec declares that the unicast client shall subscribe to all ASEs.
		 * In case that we cannot support this due to memory restrictions, we should
		 * consider the discovery procedure as failing.
		 */
		LOG_WRN("No space left to parse ASE");
		cb_err = -ENOMEM;

		goto fail;
	}

	unicast_client_ep_set_status(ep, buf);
	cb_err = unicast_client_ep_subscribe(conn, ep);
	if (cb_err != 0) {
		LOG_DBG("Failed to subcribe to ep %p: %d", ep, cb_err);
		goto fail;
	}

	reset_att_buf(client);

	endpoint_cb(conn, ep);

	cb_err = unicast_client_ase_discover(conn, handle);
	if (cb_err != 0) {
		LOG_DBG("Failed to read ASE: %d", cb_err);
		goto fail;
	}

	return BT_GATT_ITER_STOP;

fail:
	discover_cb(conn, cb_err);
	return BT_GATT_ITER_STOP;
}

static uint8_t unicast_client_ase_discover_cb(struct bt_conn *conn,
					      const struct bt_gatt_attr *attr,
					      struct bt_gatt_discover_params *discover)
{
	struct unicast_client *client;
	struct bt_gatt_chrc *chrc;
	uint16_t value_handle;
	int err;

	if (attr == NULL) {
		err = unicast_client_ase_cp_discover(conn);
		if (err != 0) {
			LOG_ERR("Unable to discover ASE Control Point");

			discover_cb(conn, err);
		}

		return BT_GATT_ITER_STOP;
	}

	chrc = attr->user_data;
	value_handle = chrc->value_handle;
	memset(discover, 0, sizeof(*discover));

	client = &uni_cli_insts[bt_conn_index(conn)];

	LOG_DBG("conn %p attr %p handle 0x%04x dir %s", conn, attr, value_handle,
		bt_audio_dir_str(client->dir));

	client->read_params.func = unicast_client_ase_read_func;
	client->read_params.handle_count = 1U;
	client->read_params.single.handle = value_handle;
	client->read_params.single.offset = 0U;

	err = bt_gatt_read(conn, &client->read_params);
	if (err != 0) {
		LOG_DBG("Failed to read PAC records: %d", err);

		discover_cb(conn, err);
	}

	return BT_GATT_ITER_STOP;
}

static int unicast_client_ase_discover(struct bt_conn *conn, uint16_t start_handle)
{
	struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];

	LOG_DBG("conn %p ", conn);

	if (client->dir == BT_AUDIO_DIR_SINK) {
		client->disc_params.uuid = ase_snk_uuid;
	} else if (client->dir == BT_AUDIO_DIR_SOURCE) {
		client->disc_params.uuid = ase_src_uuid;
	} else {
		return -EINVAL;
	}

	client->disc_params.func = unicast_client_ase_discover_cb;
	client->disc_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
	client->disc_params.start_handle = start_handle;
	client->disc_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;

	return bt_gatt_discover(conn, &client->disc_params);
}

static uint8_t unicast_client_pacs_avail_ctx_read_func(struct bt_conn *conn, uint8_t err,
						       struct bt_gatt_read_params *read,
						       const void *data, uint16_t length)
{
	struct bt_pacs_context context;
	struct net_buf_simple buf;
	int cb_err;

	memset(read, 0, sizeof(*read));

	LOG_DBG("conn %p err 0x%02x len %u", conn, err, length);

	if (err || data == NULL || length != sizeof(context)) {
		LOG_DBG("Could not read available context: %d, %p, %u", err, data, length);

		if (err == BT_ATT_ERR_SUCCESS) {
			err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
		}

		discover_cb(conn, err);

		return BT_GATT_ITER_STOP;
	}

	net_buf_simple_init_with_data(&buf, (void *)data, length);
	context.snk = net_buf_simple_pull_le16(&buf);
	context.src = net_buf_simple_pull_le16(&buf);

	LOG_DBG("sink context %u, source context %u", context.snk, context.src);

	if (unicast_client_cbs != NULL && unicast_client_cbs->available_contexts != NULL) {
		unicast_client_cbs->available_contexts(conn, context.snk, context.src);
	}

	/* Read ASE instances */
	cb_err = unicast_client_ase_discover(conn, BT_ATT_FIRST_ATTRIBUTE_HANDLE);
	if (cb_err != 0) {
		LOG_ERR("Unable to read ASE: %d", cb_err);

		discover_cb(conn, cb_err);
	}

	return BT_GATT_ITER_STOP;
}

static uint8_t unicast_client_pacs_avail_ctx_notify_cb(struct bt_conn *conn,
						       struct bt_gatt_subscribe_params *params,
						       const void *data, uint16_t length)
{
	struct bt_pacs_context context;
	struct net_buf_simple buf;

	LOG_DBG("conn %p len %u", conn, length);

	if (!data) {
		LOG_DBG("Unsubscribed");
		params->value_handle = 0x0000;
		return BT_GATT_ITER_STOP;
	}

	/* Terminate early if there's no callbacks */
	if (unicast_client_cbs == NULL || unicast_client_cbs->available_contexts == NULL) {
		return BT_GATT_ITER_CONTINUE;
	}

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

	if (buf.len != sizeof(context)) {
		LOG_ERR("Avail_ctx notification incorrect size: %u", length);
		return BT_GATT_ITER_STOP;
	}

	net_buf_simple_init_with_data(&buf, (void *)data, length);
	context.snk = net_buf_simple_pull_le16(&buf);
	context.src = net_buf_simple_pull_le16(&buf);

	LOG_DBG("sink context %u, source context %u", context.snk, context.src);

	if (unicast_client_cbs != NULL && unicast_client_cbs->available_contexts != NULL) {
		unicast_client_cbs->available_contexts(conn, context.snk, context.src);
	}

	return BT_GATT_ITER_CONTINUE;
}

static int unicast_client_pacs_avail_ctx_read(struct bt_conn *conn, uint16_t handle)
{
	struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];

	LOG_DBG("conn %p", conn);

	client->read_params.func = unicast_client_pacs_avail_ctx_read_func;
	client->read_params.handle_count = 1U;
	client->read_params.single.handle = handle;
	client->read_params.single.offset = 0U;

	return bt_gatt_read(conn, &client->read_params);
}

static uint8_t unicast_client_pacs_avail_ctx_discover_cb(struct bt_conn *conn,
							 const struct bt_gatt_attr *attr,
							 struct bt_gatt_discover_params *discover)
{
	uint8_t index = bt_conn_index(conn);
	const struct bt_gatt_chrc *chrc;
	uint8_t chrc_properties;
	uint16_t value_handle;
	int err;

	if (!attr) {
		/* If available_ctx is not found, we terminate the discovery as
		 * the characteristic is mandatory
		 */

		discover_cb(conn, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND);

		return BT_GATT_ITER_STOP;
	}

	chrc = attr->user_data;
	chrc_properties = chrc->properties;
	value_handle = chrc->value_handle;
	memset(discover, 0, sizeof(*discover));

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

	if (chrc_properties & BT_GATT_CHRC_NOTIFY) {
		struct bt_gatt_subscribe_params *sub_params;

		sub_params = &uni_cli_insts[index].avail_ctx_subscribe;

		if (sub_params->value_handle == 0) {
			LOG_DBG("Subscribing to handle %u", value_handle);
			sub_params->value_handle = value_handle;
			sub_params->ccc_handle = 0x0000; /* auto discover ccc */
			sub_params->end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
			sub_params->disc_params = &uni_cli_insts[index].avail_ctx_cc_disc;
			sub_params->notify = unicast_client_pacs_avail_ctx_notify_cb;
			sub_params->value = BT_GATT_CCC_NOTIFY;
			atomic_set_bit(sub_params->flags, BT_GATT_SUBSCRIBE_FLAG_VOLATILE);

			err = bt_gatt_subscribe(conn, sub_params);
			if (err != 0 && err != -EALREADY) {
				LOG_ERR("Failed to subscribe to avail_ctx: %d", err);
			}
		} /* else already subscribed */
	} else {
		LOG_DBG("Invalid chrc->properties: %u", chrc_properties);
		/* If the characteristic is not subscribable we terminate the
		 * discovery as BT_GATT_CHRC_NOTIFY is mandatory
		 */
		discover_cb(conn, BT_ATT_ERR_NOT_SUPPORTED);

		return BT_GATT_ITER_STOP;
	}

	err = unicast_client_pacs_avail_ctx_read(conn, value_handle);
	if (err != 0) {
		LOG_DBG("Failed to read PACS avail_ctx: %d", err);

		discover_cb(conn, err);
	}

	return BT_GATT_ITER_STOP;
}

static int unicast_client_pacs_avail_ctx_discover(struct bt_conn *conn)
{
	struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];

	LOG_DBG("conn %p", conn);

	client->disc_params.uuid = pacs_avail_ctx_uuid;
	client->disc_params.func = unicast_client_pacs_avail_ctx_discover_cb;
	client->disc_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
	client->disc_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
	client->disc_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;

	return bt_gatt_discover(conn, &client->disc_params);
}

static uint8_t unicast_client_pacs_location_read_func(struct bt_conn *conn, uint8_t err,
						      struct bt_gatt_read_params *read,
						      const void *data, uint16_t length)
{
	struct unicast_client *client;
	struct net_buf_simple buf;
	uint32_t location;
	int cb_err;

	memset(read, 0, sizeof(*read));

	client = &uni_cli_insts[bt_conn_index(conn)];

	LOG_DBG("conn %p err 0x%02x len %u", conn, err, length);

	if (err || data == NULL || length != sizeof(location)) {
		LOG_DBG("Unable to read PACS location for dir %s: %u, %p, %u",
			bt_audio_dir_str(client->dir), err, data, length);

		if (err == BT_ATT_ERR_SUCCESS) {
			err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
		}

		discover_cb(conn, err);

		return BT_GATT_ITER_STOP;
	}

	net_buf_simple_init_with_data(&buf, (void *)data, length);
	location = net_buf_simple_pull_le32(&buf);

	LOG_DBG("dir %s loc %X", bt_audio_dir_str(client->dir), location);

	if (unicast_client_cbs != NULL && unicast_client_cbs->location != NULL) {
		unicast_client_cbs->location(conn, client->dir, (enum bt_audio_location)location);
	}

	/* Read available contexts */
	cb_err = unicast_client_pacs_avail_ctx_discover(conn);
	if (cb_err != 0) {
		LOG_ERR("Unable to read available contexts: %d", cb_err);

		discover_cb(conn, cb_err);
	}

	return BT_GATT_ITER_STOP;
}

static uint8_t unicast_client_pacs_location_notify_cb(struct bt_conn *conn,
						      struct bt_gatt_subscribe_params *params,
						      const void *data, uint16_t length)
{
	struct net_buf_simple buf;
	enum bt_audio_dir dir;
	uint32_t location;

	LOG_DBG("conn %p len %u", conn, length);

	if (!data) {
		LOG_DBG("Unsubscribed");
		params->value_handle = 0x0000;
		return BT_GATT_ITER_STOP;
	}

	/* Terminate early if there's no callbacks */
	if (unicast_client_cbs == NULL || unicast_client_cbs->location == NULL) {
		return BT_GATT_ITER_CONTINUE;
	}

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

	if (buf.len != sizeof(location)) {
		LOG_ERR("Location notification incorrect size: %u", length);
		return BT_GATT_ITER_STOP;
	}

	if (params == &uni_cli_insts[bt_conn_index(conn)].snk_loc_subscribe) {
		dir = BT_AUDIO_DIR_SINK;
	} else if (params == &uni_cli_insts[bt_conn_index(conn)].src_loc_subscribe) {
		dir = BT_AUDIO_DIR_SOURCE;
	} else {
		LOG_ERR("Invalid notification");

		return BT_GATT_ITER_CONTINUE;
	}

	net_buf_simple_init_with_data(&buf, (void *)data, length);
	location = net_buf_simple_pull_le32(&buf);

	LOG_DBG("dir %s loc %X", bt_audio_dir_str(dir), location);

	if (unicast_client_cbs != NULL && unicast_client_cbs->location != NULL) {
		unicast_client_cbs->location(conn, dir, (enum bt_audio_location)location);
	}

	return BT_GATT_ITER_CONTINUE;
}

static int unicast_client_pacs_location_read(struct bt_conn *conn, uint16_t handle)
{
	struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];

	LOG_DBG("conn %p", conn);

	client->read_params.func = unicast_client_pacs_location_read_func;
	client->read_params.handle_count = 1U;
	client->read_params.single.handle = handle;
	client->read_params.single.offset = 0U;

	return bt_gatt_read(conn, &client->read_params);
}

static uint8_t unicast_client_pacs_location_discover_cb(struct bt_conn *conn,
							const struct bt_gatt_attr *attr,
							struct bt_gatt_discover_params *discover)
{
	uint8_t index = bt_conn_index(conn);
	const struct bt_gatt_chrc *chrc;
	uint16_t value_handle;
	int err;

	if (!attr) {
		/* If location is not found, we just continue reading the
		 * available contexts, as location is optional.
		 */
		err = unicast_client_pacs_avail_ctx_discover(conn);
		if (err != 0) {
			LOG_ERR("Unable to read available contexts: %d", err);

			discover_cb(conn, err);
		}

		return BT_GATT_ITER_STOP;
	}

	chrc = attr->user_data;
	value_handle = chrc->value_handle;
	memset(discover, 0, sizeof(*discover));

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

	if (chrc->properties & BT_GATT_CHRC_NOTIFY) {
		const struct unicast_client *client = &uni_cli_insts[index];
		struct bt_gatt_subscribe_params *sub_params;

		if (client->dir == BT_AUDIO_DIR_SINK) {
			sub_params = &uni_cli_insts[index].snk_loc_subscribe;
		} else {
			sub_params = &uni_cli_insts[index].src_loc_subscribe;
		}

		sub_params->value_handle = value_handle;
		sub_params->ccc_handle = 0x0000; /* auto discover ccc */
		sub_params->end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
		sub_params->disc_params = &uni_cli_insts[index].loc_cc_disc;
		sub_params->notify = unicast_client_pacs_location_notify_cb;
		sub_params->value = BT_GATT_CCC_NOTIFY;
		atomic_set_bit(sub_params->flags, BT_GATT_SUBSCRIBE_FLAG_VOLATILE);

		err = bt_gatt_subscribe(conn, sub_params);
		if (err != 0 && err != -EALREADY) {
			LOG_ERR("Failed to subscribe to location: %d", err);
		}
	}

	err = unicast_client_pacs_location_read(conn, value_handle);
	if (err != 0) {
		LOG_DBG("Failed to read PACS location: %d", err);

		discover_cb(conn, err);
	}

	return BT_GATT_ITER_STOP;
}

static int unicast_client_pacs_location_discover(struct bt_conn *conn)
{
	struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];

	LOG_DBG("conn %p dir %s", conn, bt_audio_dir_str(client->dir));

	if (client->dir == BT_AUDIO_DIR_SINK) {
		client->disc_params.uuid = pacs_snk_loc_uuid;
	} else if (client->dir == BT_AUDIO_DIR_SOURCE) {
		client->disc_params.uuid = pacs_src_loc_uuid;
	} else {
		return -EINVAL;
	}

	client->disc_params.func = unicast_client_pacs_location_discover_cb;
	client->disc_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
	client->disc_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
	client->disc_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;

	return bt_gatt_discover(conn, &client->disc_params);
}

static uint8_t unicast_client_pacs_context_read_func(struct bt_conn *conn, uint8_t err,
						     struct bt_gatt_read_params *read,
						     const void *data, uint16_t length)
{
	struct net_buf_simple buf;
	struct bt_pacs_context *context;
	int cb_err;
	int index;

	memset(read, 0, sizeof(*read));

	LOG_DBG("conn %p err 0x%02x len %u", conn, err, length);

	if (err || length < sizeof(uint16_t) * 2) {
		goto discover_loc;
	}

	net_buf_simple_init_with_data(&buf, (void *)data, length);
	context = net_buf_simple_pull_mem(&buf, sizeof(*context));

	index = bt_conn_index(conn);

discover_loc:
	/* Read ASE instances */
	cb_err = unicast_client_pacs_location_discover(conn);
	if (cb_err != 0) {
		LOG_ERR("Unable to read PACS location: %d", cb_err);

		discover_cb(conn, cb_err);
	}

	return BT_GATT_ITER_STOP;
}

static uint8_t unicast_client_pacs_context_discover_cb(struct bt_conn *conn,
						       const struct bt_gatt_attr *attr,
						       struct bt_gatt_discover_params *discover)
{
	struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];
	struct bt_gatt_chrc *chrc;
	uint16_t value_handle;
	int err;

	if (attr == NULL) {
		LOG_ERR("Unable to find %s PAC context", bt_audio_dir_str(client->dir));

		discover_cb(conn, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND);

		return BT_GATT_ITER_STOP;
	}

	chrc = attr->user_data;
	value_handle = chrc->value_handle;
	memset(discover, 0, sizeof(*discover));

	LOG_DBG("conn %p attr %p handle 0x%04x dir %s", conn, attr, value_handle,
		bt_audio_dir_str(client->dir));

	/* TODO: Subscribe to PAC context */

	client->read_params.func = unicast_client_pacs_context_read_func;
	client->read_params.handle_count = 1U;
	client->read_params.single.handle = value_handle;
	client->read_params.single.offset = 0U;

	err = bt_gatt_read(conn, &client->read_params);
	if (err != 0) {
		LOG_DBG("Failed to read PAC records: %d", err);

		discover_cb(conn, err);
	}

	return BT_GATT_ITER_STOP;
}

static int unicast_client_pacs_context_discover(struct bt_conn *conn)
{
	struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];

	LOG_DBG("conn %p", conn);

	client->disc_params.uuid = pacs_context_uuid;
	client->disc_params.func = unicast_client_pacs_context_discover_cb;
	client->disc_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
	client->disc_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
	client->disc_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;

	return bt_gatt_discover(conn, &client->disc_params);
}

static uint8_t unicast_client_read_func(struct bt_conn *conn, uint8_t err,
					struct bt_gatt_read_params *read, const void *data,
					uint16_t length)
{
	uint16_t handle = read->single.handle;
	struct unicast_client *client;
	struct bt_pacs_read_rsp *rsp;
	struct net_buf_simple *buf;
	int cb_err = err;
	uint8_t i;

	LOG_DBG("conn %p err 0x%02x len %u", conn, err, length);

	if (cb_err != BT_ATT_ERR_SUCCESS) {
		goto fail;
	}

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

	client = &uni_cli_insts[bt_conn_index(conn)];
	buf = &client->net_buf;

	if (data != NULL) {
		if (net_buf_simple_tailroom(buf) < length) {
			LOG_DBG("Buffer full, invalid server response of size %u",
				length + client->net_buf.len);

			cb_err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;

			goto fail;
		}

		/* store data*/
		net_buf_simple_add_mem(buf, data, length);

		return BT_GATT_ITER_CONTINUE;
	}

	memset(read, 0, sizeof(*read));

	if (buf->len < sizeof(*rsp)) {
		LOG_DBG("Read response too small (%u)", buf->len);

		cb_err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;

		goto fail;
	}

	rsp = net_buf_simple_pull_mem(buf, sizeof(*rsp));

	/* If no PAC was found don't bother discovering ASE and ASE CP */
	if (!rsp->num_pac) {
		goto fail;
	}

	for (i = 0U; i < rsp->num_pac; i++) {
		struct bt_audio_codec_cap codec_cap;
		struct bt_pac_codec *pac_codec;
		struct bt_pac_ltv_data *meta, *cc;
		void *cc_ltv, *meta_ltv;

		LOG_DBG("pac #%u/%u", i + 1, rsp->num_pac);

		if (buf->len < sizeof(*pac_codec)) {
			LOG_ERR("Malformed PAC: remaining len %u expected %zu",
				buf->len, sizeof(*pac_codec));
			break;
		}

		pac_codec = net_buf_simple_pull_mem(buf, sizeof(*pac_codec));

		if (buf->len < sizeof(*cc)) {
			LOG_ERR("Malformed PAC: remaining len %u expected %zu",
				buf->len, sizeof(*cc));
			break;
		}

		cc = net_buf_simple_pull_mem(buf, sizeof(*cc));
		if (buf->len < cc->len) {
			LOG_ERR("Malformed PAC: remaining len %u expected %zu",
				buf->len, cc->len);
			break;
		}

		cc_ltv = net_buf_simple_pull_mem(buf, cc->len);

		if (buf->len < sizeof(*meta)) {
			LOG_ERR("Malformed PAC: remaining len %u expected %zu",
				buf->len, sizeof(*meta));
			break;
		}

		meta = net_buf_simple_pull_mem(buf, sizeof(*meta));
		if (buf->len < meta->len) {
			LOG_ERR("Malformed PAC: remaining len %u expected %u",
				buf->len, meta->len);
			break;
		}

		meta_ltv = net_buf_simple_pull_mem(buf, meta->len);

		if (unicast_client_set_codec_cap(pac_codec->id, sys_le16_to_cpu(pac_codec->cid),
						 sys_le16_to_cpu(pac_codec->vid), cc_ltv, cc->len,
						 meta_ltv, meta->len, &codec_cap)) {
			LOG_ERR("Unable to parse Codec");
			break;
		}

		LOG_DBG("codec 0x%02x capabilities len %u meta len %u ", codec_cap.id,
			codec_cap.data_len, codec_cap.meta_len);

		pac_record_cb(conn, &codec_cap);
	}

	reset_att_buf(client);

	if (i != rsp->num_pac) {
		LOG_DBG("Failed to process all PAC records (%u/%u)", i, rsp->num_pac);
		cb_err = BT_ATT_ERR_INVALID_PDU;
		goto fail;
	}

	/* Read PACS contexts */
	cb_err = unicast_client_pacs_context_discover(conn);
	if (cb_err != 0) {
		LOG_ERR("Unable to read PACS context: %d", cb_err);
		goto fail;
	}

	return BT_GATT_ITER_STOP;

fail:
	discover_cb(conn, cb_err);
	return BT_GATT_ITER_STOP;
}

static uint8_t unicast_client_pac_discover_cb(struct bt_conn *conn,
					      const struct bt_gatt_attr *attr,
					      struct bt_gatt_discover_params *discover)
{
	struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];
	struct bt_gatt_chrc *chrc;
	uint16_t value_handle;
	int err;

	if (attr == NULL) {
		LOG_ERR("Unable to find %s PAC", bt_audio_dir_str(client->dir));

		discover_cb(conn, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND);

		return BT_GATT_ITER_STOP;
	}

	chrc = attr->user_data;
	value_handle = chrc->value_handle;
	memset(discover, 0, sizeof(*discover));

	LOG_DBG("conn %p attr %p handle 0x%04x dir %s", conn, attr, value_handle,
		bt_audio_dir_str(client->dir));

	/* TODO: Subscribe to PAC */

	/* Reset to use for long read */
	reset_att_buf(client);

	client->read_params.func = unicast_client_read_func;
	client->read_params.handle_count = 1U;
	client->read_params.single.handle = value_handle;
	client->read_params.single.offset = 0U;

	err = bt_gatt_read(conn, &client->read_params);
	if (err != 0) {
		LOG_DBG("Failed to read PAC records: %d", err);

		discover_cb(conn, err);
	}

	return BT_GATT_ITER_STOP;
}

static void unicast_client_disconnected(struct bt_conn *conn, uint8_t reason)
{
	LOG_DBG("conn %p reason 0x%02x", conn, reason);

	unicast_client_ep_reset(conn, reason);
}

static struct bt_conn_cb conn_cbs = {
	.disconnected = unicast_client_disconnected,
};

int bt_bap_unicast_client_discover(struct bt_conn *conn, enum bt_audio_dir dir)
{
	struct unicast_client *client;
	static bool conn_cb_registered;
	uint8_t role;
	int err;

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

	role = conn->role;
	if (role != BT_HCI_ROLE_CENTRAL) {
		LOG_DBG("Invalid conn role: %u, shall be central", role);
		return -EINVAL;
	}

	client = &uni_cli_insts[bt_conn_index(conn)];
	if (client->busy) {
		LOG_DBG("Client connection is busy");
		return -EBUSY;
	}

	if (dir == BT_AUDIO_DIR_SINK) {
		client->disc_params.uuid = snk_uuid;
	} else if (dir == BT_AUDIO_DIR_SOURCE) {
		client->disc_params.uuid = src_uuid;
	} else {
		return -EINVAL;
	}

	client->disc_params.func = unicast_client_pac_discover_cb;
	client->disc_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
	client->disc_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
	client->disc_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;

	if (!conn_cb_registered) {
		bt_conn_cb_register(&conn_cbs);
		conn_cb_registered = true;
	}

	err = bt_gatt_discover(conn, &client->disc_params);
	if (err != 0) {
		return err;
	}

	client->dir = dir;
	client->busy = true;

	return 0;
}

int bt_bap_unicast_client_register_cb(const struct bt_bap_unicast_client_cb *cbs)
{
	CHECKIF(cbs == NULL) {
		LOG_DBG("cbs is NULL");
		return -EINVAL;
	}

	if (unicast_client_cbs != NULL) {
		LOG_DBG("Callbacks already registered");
		return -EALREADY;
	}

	unicast_client_cbs = cbs;

	return 0;
}
