/* @file
 * @brief Bluetooth ASCS
 */
/*
 * 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/iso.h>
#include <zephyr/bluetooth/audio/audio.h>
#include <zephyr/bluetooth/audio/bap.h>
#include <zephyr/bluetooth/audio/pacs.h>

#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(bt_ascs, CONFIG_BT_ASCS_LOG_LEVEL);

#include "common/bt_str.h"
#include "common/assert.h"

#include "../host/att_internal.h"

#include "audio_internal.h"
#include "bap_iso.h"
#include "bap_endpoint.h"
#include "bap_unicast_server.h"
#include "pacs_internal.h"
#include "cap_internal.h"

#define ASE_BUF_SEM_TIMEOUT K_MSEC(CONFIG_BT_ASCS_ASE_BUF_TIMEOUT)

#define MAX_ASES_SESSIONS CONFIG_BT_MAX_CONN * \
				(CONFIG_BT_ASCS_ASE_SNK_COUNT + \
				 CONFIG_BT_ASCS_ASE_SRC_COUNT)

BUILD_ASSERT(CONFIG_BT_ASCS_MAX_ACTIVE_ASES <= MAX(MAX_ASES_SESSIONS,
						   CONFIG_BT_ISO_MAX_CHAN),
	     "Max active ASEs are set to more than actual number of ASEs or ISOs");

#if defined(CONFIG_BT_BAP_UNICAST_SERVER)

#define ASE_ID(_ase) ase->ep.status.id
#define ASE_DIR(_id) \
	(_id > CONFIG_BT_ASCS_ASE_SNK_COUNT ? BT_AUDIO_DIR_SOURCE : BT_AUDIO_DIR_SINK)
#define ASE_UUID(_id) \
	(_id > CONFIG_BT_ASCS_ASE_SNK_COUNT ? BT_UUID_ASCS_ASE_SRC : BT_UUID_ASCS_ASE_SNK)
#define ASE_COUNT (CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT)
#define BT_BAP_ASCS_RSP_NULL ((struct bt_bap_ascs_rsp[]) { BT_BAP_ASCS_RSP(0, 0) })

static struct bt_ascs_ase {
	struct bt_conn *conn;
	struct bt_bap_ep ep;
	const struct bt_gatt_attr *attr;
	struct k_work_delayable disconnect_work;
	struct k_work_delayable state_transition_work;
	enum bt_bap_ep_state state_pending;
	bool unexpected_iso_link_loss;
} ase_pool[CONFIG_BT_ASCS_MAX_ACTIVE_ASES];

/* Minimum state size when in the codec configured state */
#define MIN_CONFIG_STATE_SIZE (1 + 1 + 1 + 1 + 1 + 2 + 3 + 3 + 3 + 3 + 5 + 1)
/* Minimum state size when in the QoS configured state */
#define MIN_QOS_STATE_SIZE    (1 + 1 + 1 + 1 + 3 + 1 + 1 + 2 + 1 + 2 + 3 + 1 + 1 + 1)

/* Calculate the size requirement of the ASE BUF, based on the maximum possible
 * size of the Codec Configured state or the QoS Configured state, as either
 * of them can be the largest state
 */
#define ASE_BUF_SIZE                                                                               \
	MIN(BT_ATT_MAX_ATTRIBUTE_LEN,                                                              \
	    MAX(MIN_CONFIG_STATE_SIZE + CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE,                   \
		MIN_QOS_STATE_SIZE + CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE))

/* Verify that the prepare count is large enough to cover the maximum value we support a client
 * writing
 */
BUILD_ASSERT(
	BT_ATT_BUF_SIZE - 3 >= ASE_BUF_SIZE ||
		DIV_ROUND_UP(ASE_BUF_SIZE, (BT_ATT_BUF_SIZE - 3)) <= CONFIG_BT_ATT_PREPARE_COUNT,
	"CONFIG_BT_ATT_PREPARE_COUNT not large enough to cover the maximum supported ASCS value");

/* It is mandatory to support long writes in ASCS unconditionally, and thus
 * CONFIG_BT_ATT_PREPARE_COUNT must be at least 1 to support the feature
 */
BUILD_ASSERT(CONFIG_BT_ATT_PREPARE_COUNT > 0, "CONFIG_BT_ATT_PREPARE_COUNT shall be at least 1");

static const struct bt_bap_unicast_server_cb *unicast_server_cb;

static K_SEM_DEFINE(ase_buf_sem, 1, 1);
NET_BUF_SIMPLE_DEFINE_STATIC(ase_buf, ASE_BUF_SIZE);

static int control_point_notify(struct bt_conn *conn, const void *data, uint16_t len);
static int ascs_ep_get_status(struct bt_bap_ep *ep, struct net_buf_simple *buf);

static void ascs_app_rsp_warn_valid(const struct bt_bap_ascs_rsp *rsp)
{
	/* Validate application error code */
	switch (rsp->code) {
	case BT_BAP_ASCS_RSP_CODE_SUCCESS:
	case BT_BAP_ASCS_RSP_CODE_CAP_UNSUPPORTED:
	case BT_BAP_ASCS_RSP_CODE_NO_MEM:
	case BT_BAP_ASCS_RSP_CODE_UNSPECIFIED:
	case BT_BAP_ASCS_RSP_CODE_CONF_UNSUPPORTED:
	case BT_BAP_ASCS_RSP_CODE_CONF_REJECTED:
	case BT_BAP_ASCS_RSP_CODE_METADATA_UNSUPPORTED:
	case BT_BAP_ASCS_RSP_CODE_METADATA_REJECTED:
		break;
	default:
		LOG_WRN("Invalid application error code: %u", rsp->code);
		return;
	}

	/* Validate application error code and reason combinations */
	switch (rsp->code) {
	case BT_BAP_ASCS_RSP_CODE_SUCCESS:
	case BT_BAP_ASCS_RSP_CODE_CAP_UNSUPPORTED:
	case BT_BAP_ASCS_RSP_CODE_NO_MEM:
	case BT_BAP_ASCS_RSP_CODE_UNSPECIFIED:
		if (rsp->reason != BT_BAP_ASCS_REASON_NONE) {
			LOG_WRN("Invalid reason %u for code %u", rsp->reason, rsp->code);
		}
		break;
	case BT_BAP_ASCS_RSP_CODE_CONF_UNSUPPORTED:
	case BT_BAP_ASCS_RSP_CODE_CONF_REJECTED:
		if (!IN_RANGE(rsp->reason, BT_BAP_ASCS_REASON_NONE, BT_BAP_ASCS_REASON_CIS)) {
			LOG_WRN("Invalid reason %u for code %u", rsp->reason, rsp->code);
		}
		break;
	case BT_BAP_ASCS_RSP_CODE_METADATA_UNSUPPORTED:
	case BT_BAP_ASCS_RSP_CODE_METADATA_REJECTED:
		if (!BT_AUDIO_METADATA_TYPE_IS_KNOWN(rsp->metadata_type)) {
			LOG_WRN("Invalid metadata type %u for code %u", rsp->metadata_type,
				rsp->code);
		}
		break;
	default:
		break;
	}
}

static bool is_valid_ase_id(uint8_t ase_id)
{
	return IN_RANGE(ase_id, 1, ASE_COUNT);
}

static enum bt_bap_ep_state ascs_ep_get_state(struct bt_bap_ep *ep)
{
	return ep->status.state;
}

static void ase_free(struct bt_ascs_ase *ase)
{
	__ASSERT(ase && ase->conn, "Non-existing ASE");

	LOG_DBG("conn %p ase %p id 0x%02x", (void *)ase->conn, ase, ase->ep.status.id);

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

	bt_conn_unref(ase->conn);
	ase->conn = NULL;

	(void)k_work_cancel_delayable(&ase->disconnect_work);
	(void)k_work_cancel_delayable(&ase->state_transition_work);
}

static int ase_state_notify(struct bt_ascs_ase *ase)
{
	const uint8_t att_ntf_header_size = 3; /* opcode (1) + handle (2) */
	struct bt_conn *conn = ase->conn;
	struct bt_conn_info conn_info;
	uint16_t max_ntf_size;
	uint16_t ntf_size;
	int err;

	__ASSERT_NO_MSG(conn != NULL);

	err = bt_conn_get_info(conn, &conn_info);
	__ASSERT_NO_MSG(err == 0);

	if (conn_info.state != BT_CONN_STATE_CONNECTED ||
	    !bt_gatt_is_subscribed(conn, ase->attr, BT_GATT_CCC_NOTIFY)) {
		return 0;
	}

	err = k_sem_take(&ase_buf_sem, ASE_BUF_SEM_TIMEOUT);
	if (err != 0) {
		LOG_WRN("Failed to take ase_buf_sem: %d", err);

		return err;
	}

	ascs_ep_get_status(&ase->ep, &ase_buf);

	max_ntf_size = bt_gatt_get_mtu(conn) - att_ntf_header_size;

	ntf_size = MIN(max_ntf_size, ase_buf.len);
	if (ntf_size < ase_buf.len) {
		LOG_DBG("Sending truncated notification (%u / %u)",
			ntf_size, ase_buf.len);
	}

	err = bt_gatt_notify(conn, ase->attr, ase_buf.data, ntf_size);

	k_sem_give(&ase_buf_sem);

	return err;
}

static void ascs_disconnect_stream_work_handler(struct k_work *work)
{
	struct k_work_delayable *d_work = k_work_delayable_from_work(work);
	struct bt_ascs_ase *ase = CONTAINER_OF(d_work, struct bt_ascs_ase,
					       disconnect_work);
	struct bt_bap_ep *ep = &ase->ep;
	struct bt_bap_stream *stream = ep->stream;
	struct bt_bap_stream *pair_stream;

	__ASSERT(ep != NULL && ep->iso && stream != NULL,
		 "Invalid endpoint %p, iso %p or stream %p",
		 ep, ep == NULL ? NULL : ep->iso, stream);

	if (ep->dir == BT_AUDIO_DIR_SINK) {
		pair_stream = ep->iso->tx.stream;
	} else {
		pair_stream = ep->iso->rx.stream;
	}

	LOG_DBG("ase %p ep %p stream %p pair_stream %p",
		ase, ep, stream, pair_stream);

	if (pair_stream != NULL) {
		struct bt_ascs_ase *pair_ase;

		__ASSERT(pair_stream->ep != NULL, "Invalid pair_stream %p",
			 pair_stream);

		if (pair_stream->ep->status.state == BT_BAP_EP_STATE_STREAMING) {
			/* Should not disconnect ISO if the stream is paired
			 * with another one in the streaming state
			 */

			return;
		}

		pair_ase = CONTAINER_OF(pair_stream->ep, struct bt_ascs_ase,
					ep);

		/* Cancel pair ASE disconnect work if pending */
		(void)k_work_cancel_delayable(&pair_ase->disconnect_work);
	}

	if (stream != NULL &&
	    ep->iso != NULL &&
	    (ep->iso->chan.state == BT_ISO_STATE_CONNECTED ||
	     ep->iso->chan.state == BT_ISO_STATE_CONNECTING)) {
		const int err = bt_bap_stream_disconnect(stream);

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

static int ascs_disconnect_stream(struct bt_bap_stream *stream)
{
	struct bt_ascs_ase *ase = CONTAINER_OF(stream->ep, struct bt_ascs_ase,
					       ep);

	LOG_DBG("%p", stream);

	return k_work_reschedule(&ase->disconnect_work,
				 K_MSEC(CONFIG_BT_ASCS_ISO_DISCONNECT_DELAY));
}

static void ase_enter_state_idle(struct bt_ascs_ase *ase)
{
	struct bt_bap_stream *stream = ase->ep.stream;
	struct bt_bap_stream_ops *ops;

	__ASSERT_NO_MSG(stream != NULL);

	ase->ep.receiver_ready = false;

	if (stream->conn != NULL) {
		bt_conn_unref(stream->conn);
		stream->conn = NULL;
	}

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

	ase_free(ase);
}

static void ase_enter_state_codec_configured(struct bt_ascs_ase *ase)
{
	struct bt_bap_stream *stream = ase->ep.stream;
	struct bt_bap_stream_ops *ops;

	__ASSERT_NO_MSG(stream != NULL);

	ase->ep.receiver_ready = false;

	ops = stream->ops;
	if (ops != NULL && ops->configured != NULL) {
		ops->configured(stream, &ase->ep.qos_pref);
	}
}

static void ase_enter_state_qos_configured(struct bt_ascs_ase *ase)
{
	struct bt_bap_stream *stream = ase->ep.stream;
	struct bt_bap_stream_ops *ops;

	__ASSERT_NO_MSG(stream != NULL);

	ase->ep.receiver_ready = false;

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

static void ase_enter_state_enabling(struct bt_ascs_ase *ase)
{
	struct bt_bap_stream *stream = ase->ep.stream;
	struct bt_bap_stream_ops *ops;

	__ASSERT_NO_MSG(stream != NULL);

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

	/* SINK ASEs can autonomously go into the streaming state if the CIS is connected */
	if (ase->ep.dir == BT_AUDIO_DIR_SINK && ase->ep.receiver_ready && ase->ep.iso != NULL &&
	    ase->ep.iso->chan.state == BT_ISO_STATE_CONNECTED) {
		ascs_ep_set_state(&ase->ep, BT_BAP_EP_STATE_STREAMING);
	}
}

static void ase_enter_state_streaming(struct bt_ascs_ase *ase)
{
	struct bt_bap_stream *stream = ase->ep.stream;
	struct bt_bap_stream_ops *ops;

	__ASSERT_NO_MSG(stream != NULL);

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

static void ase_metadata_updated(struct bt_ascs_ase *ase)
{
	struct bt_bap_stream *stream = ase->ep.stream;
	struct bt_bap_stream_ops *ops;

	__ASSERT_NO_MSG(stream != NULL);

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

static void ase_exit_state_streaming(struct bt_ascs_ase *ase)
{
	struct bt_bap_stream *stream = ase->ep.stream;
	struct bt_bap_stream_ops *ops;
	const enum bt_bap_ep_state next_state = ascs_ep_get_state(&ase->ep);
	uint8_t reason = ase->ep.reason;

	__ASSERT_NO_MSG(stream != NULL);

	if (reason == BT_HCI_ERR_SUCCESS) {
		/* Default to BT_HCI_ERR_UNSPECIFIED if no other reason is set */
		reason = BT_HCI_ERR_UNSPECIFIED;
	}

	ops = stream->ops;

	/*
	 * On link-loss we go from streaming state to QOS configured state,
	 * and it makes sense to do the disabled callback before entering the
	 * QOS configured state
	 */
	if (next_state == BT_BAP_EP_STATE_QOS_CONFIGURED) {
		if (ops != NULL && ops->disabled != NULL) {
			ops->disabled(stream);
		} else {
			LOG_WRN("No callback for disabled set");
		}
	}

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

static void ase_exit_state_enabling(struct bt_ascs_ase *ase)
{
	struct bt_bap_stream *stream = ase->ep.stream;
	struct bt_bap_stream_ops *ops;
	const enum bt_bap_ep_state next_state = ascs_ep_get_state(&ase->ep);

	ops = stream->ops;

	/*
	 * When the EP direction is BT_AUDIO_DIR_SOURCE the state machine goes from
	 * enabled to disabled where the disabled calback will be called,
	 * for BT_AUDIO_DIR_SINK we go from enabled to qos_configured,
	 * and logically we have to do the disabled callback first
	 */
	if (next_state == BT_BAP_EP_STATE_QOS_CONFIGURED && ase->ep.dir == BT_AUDIO_DIR_SINK) {
		if (ops != NULL && ops->disabled != NULL) {
			ops->disabled(stream);
		} else {
			LOG_WRN("No callback for disabled set");
		}
	}
}

static void ase_enter_state_disabling(struct bt_ascs_ase *ase)
{
	struct bt_bap_stream *stream = ase->ep.stream;
	struct bt_bap_stream_ops *ops;

	__ASSERT_NO_MSG(stream != NULL);

	ase->ep.receiver_ready = false;

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

static void ase_enter_state_releasing(struct bt_ascs_ase *ase)
{
	struct bt_bap_stream *stream = ase->ep.stream;

	__ASSERT_NO_MSG(stream != NULL);

	ase->ep.receiver_ready = false;

	/* Either the client or the server may disconnect the CISes when entering the releasing
	 * state.
	 */
	if (bt_bap_stream_can_disconnect(stream)) {
		int err;

		err = ascs_disconnect_stream(stream);
		if (err < 0) {
			LOG_ERR("Failed to disconnect stream %p: %d", stream, err);
		}
	} else {
		ascs_ep_set_state(&ase->ep, BT_BAP_EP_STATE_IDLE);
	}
}

static void state_transition_work_handler(struct k_work *work)
{
	struct k_work_delayable *d_work = k_work_delayable_from_work(work);
	struct bt_ascs_ase *ase = CONTAINER_OF(d_work, struct bt_ascs_ase, state_transition_work);
	const enum bt_bap_ep_state old_state = ascs_ep_get_state(&ase->ep);
	const enum bt_bap_ep_state new_state = ase->state_pending;
	int err;

	ase->ep.status.state = new_state;

	/* Notify ASE state */
	if (ase->conn != NULL) {
		err = ase_state_notify(ase);
		if (err == -ENOMEM) {
			struct bt_conn_info info;
			uint32_t retry_delay_ms;

			/* Revert back to old state */
			ase->ep.status.state = old_state;

			err = bt_conn_get_info(ase->conn, &info);
			__ASSERT_NO_MSG(err == 0);

			retry_delay_ms = BT_CONN_INTERVAL_TO_MS(info.le.interval);

			/* Reschedule the state transition */
			err = k_work_reschedule(d_work, K_MSEC(retry_delay_ms));
			if (err >= 0) {
				LOG_WRN("Out of buffers for ase state notification. "
					"Will retry in %dms", retry_delay_ms);
				return;
			}
		}

		if (err < 0) {
			LOG_ERR("Failed to notify ASE state (err %d)", err);
		}
	}

	LOG_DBG("ase %p ep %p id 0x%02x %s -> %s", ase, &ase->ep, ase->ep.status.id,
		bt_bap_ep_state_str(old_state), bt_bap_ep_state_str(new_state));

	if (old_state == new_state) {
		switch (new_state) {
		case BT_BAP_EP_STATE_ENABLING:
		case BT_BAP_EP_STATE_STREAMING:
			ase_metadata_updated(ase);
			return;
		default:
			break;
		}
	}

	/* Actions needed for exiting the old state */
	switch (old_state) {
	case BT_BAP_EP_STATE_STREAMING:
		ase_exit_state_streaming(ase);
		break;
	case BT_BAP_EP_STATE_ENABLING:
		ase_exit_state_enabling(ase);
		break;
	default:
		break;
	}

	/* Actions needed for entering the new state */
	switch (new_state) {
	case BT_BAP_EP_STATE_IDLE:
		ase_enter_state_idle(ase);
		break;
	case BT_BAP_EP_STATE_CODEC_CONFIGURED:
		ase_enter_state_codec_configured(ase);
		break;
	case BT_BAP_EP_STATE_QOS_CONFIGURED:
		ase_enter_state_qos_configured(ase);
		break;
	case BT_BAP_EP_STATE_ENABLING:
		ase_enter_state_enabling(ase);
		break;
	case BT_BAP_EP_STATE_STREAMING:
		ase_enter_state_streaming(ase);
		break;
	case BT_BAP_EP_STATE_DISABLING:
		ase_enter_state_disabling(ase);
		break;
	case BT_BAP_EP_STATE_RELEASING:
		ase_enter_state_releasing(ase);
		break;
	default:
		__ASSERT_PRINT("Invalid state %d", new_state);
	}
}

int ascs_ep_set_state(struct bt_bap_ep *ep, uint8_t state)
{
	struct bt_ascs_ase *ase = CONTAINER_OF(ep, struct bt_ascs_ase, ep);
	const enum bt_bap_ep_state old_state = ascs_ep_get_state(&ase->ep);
	bool valid_state_transition = false;
	int err;

	switch (state) {
	case BT_BAP_EP_STATE_IDLE:
		valid_state_transition = true;
		break;
	case BT_BAP_EP_STATE_CODEC_CONFIGURED:
		switch (old_state) {
		case BT_BAP_EP_STATE_IDLE:
		case BT_BAP_EP_STATE_CODEC_CONFIGURED:
		case BT_BAP_EP_STATE_QOS_CONFIGURED:
		case BT_BAP_EP_STATE_RELEASING:
			valid_state_transition = true;
			break;
		default:
			break;
		} break;
	case BT_BAP_EP_STATE_QOS_CONFIGURED:
		switch (old_state) {
		case BT_BAP_EP_STATE_CODEC_CONFIGURED:
		case BT_BAP_EP_STATE_QOS_CONFIGURED:
			valid_state_transition = true;
			break;
		case BT_BAP_EP_STATE_DISABLING:
			valid_state_transition = ase->ep.dir == BT_AUDIO_DIR_SOURCE;
			break;
		case BT_BAP_EP_STATE_ENABLING:
		case BT_BAP_EP_STATE_STREAMING:
			/* Source ASE transition Streaming->QoS configured is valid on case of CIS
			 * link-loss.
			 */
			valid_state_transition = ase->ep.dir == BT_AUDIO_DIR_SINK ||
						 ase->unexpected_iso_link_loss;
			break;
		default:
			break;
		} break;
	case BT_BAP_EP_STATE_ENABLING:
		switch (old_state) {
		case BT_BAP_EP_STATE_QOS_CONFIGURED:
		case BT_BAP_EP_STATE_ENABLING:
			valid_state_transition = true;
			break;
		default:
			break;
		} break;
	case BT_BAP_EP_STATE_STREAMING:
		switch (old_state) {
		case BT_BAP_EP_STATE_ENABLING:
		case BT_BAP_EP_STATE_STREAMING:
			valid_state_transition = true;
			break;
		default:
			break;
		} break;
	case BT_BAP_EP_STATE_DISABLING:
		switch (old_state) {
		case BT_BAP_EP_STATE_ENABLING:
		case BT_BAP_EP_STATE_STREAMING:
			valid_state_transition = ase->ep.dir == BT_AUDIO_DIR_SOURCE;
			break;
		default:
			break;
		} break;
	case BT_BAP_EP_STATE_RELEASING:
		switch (old_state) {
		case BT_BAP_EP_STATE_CODEC_CONFIGURED:
		case BT_BAP_EP_STATE_QOS_CONFIGURED:
		case BT_BAP_EP_STATE_ENABLING:
		case BT_BAP_EP_STATE_STREAMING:
			valid_state_transition = true;
			break;
		case BT_BAP_EP_STATE_DISABLING:
			valid_state_transition = ase->ep.dir == BT_AUDIO_DIR_SOURCE;
			break;
		default:
			break;
		} break;
	}

	if (!valid_state_transition) {
		BT_ASSERT_MSG(false, "Invalid state transition: %s -> %s",
			      bt_bap_ep_state_str(old_state), bt_bap_ep_state_str(state));

		return -EBADMSG;
	}

	ase->state_pending = state;

	err = k_work_schedule(&ase->state_transition_work, K_NO_WAIT);
	if (err < 0) {
		LOG_ERR("Failed to schedule state transition work err %d", err);
		return err;
	}

	return 0;
}

static void ascs_ep_get_status_config(struct bt_bap_ep *ep, struct net_buf_simple *buf)
{
	struct bt_ascs_ase_status_config *cfg;
	struct bt_audio_codec_qos_pref *pref = &ep->qos_pref;

	cfg = net_buf_simple_add(buf, sizeof(*cfg));
	cfg->framing = pref->unframed_supported ? BT_ASCS_QOS_FRAMING_UNFRAMED
						: BT_ASCS_QOS_FRAMING_FRAMED;
	cfg->phy = pref->phy;
	cfg->rtn = pref->rtn;
	cfg->latency = sys_cpu_to_le16(pref->latency);
	sys_put_le24(pref->pd_min, cfg->pd_min);
	sys_put_le24(pref->pd_max, cfg->pd_max);
	sys_put_le24(pref->pref_pd_min, cfg->prefer_pd_min);
	sys_put_le24(pref->pref_pd_max, cfg->prefer_pd_max);
	cfg->codec.id = ep->codec_cfg.id;
	cfg->codec.cid = sys_cpu_to_le16(ep->codec_cfg.cid);
	cfg->codec.vid = sys_cpu_to_le16(ep->codec_cfg.vid);

	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 id 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,
		ep->stream->codec_cfg->id);

	cfg->cc_len = ep->codec_cfg.data_len;
	net_buf_simple_add_mem(buf, ep->codec_cfg.data, ep->codec_cfg.data_len);
}

static void ascs_ep_get_status_qos(struct bt_bap_ep *ep, struct net_buf_simple *buf)
{
	struct bt_ascs_ase_status_qos *qos;

	qos = net_buf_simple_add(buf, sizeof(*qos));
	qos->cig_id = ep->cig_id;
	qos->cis_id = ep->cis_id;
	sys_put_le24(ep->stream->qos->interval, qos->interval);
	qos->framing = ep->stream->qos->framing;
	qos->phy = ep->stream->qos->phy;
	qos->sdu = sys_cpu_to_le16(ep->stream->qos->sdu);
	qos->rtn = ep->stream->qos->rtn;
	qos->latency = sys_cpu_to_le16(ep->stream->qos->latency);
	sys_put_le24(ep->stream->qos->pd, qos->pd);

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

static void ascs_ep_get_status_enable(struct bt_bap_ep *ep, struct net_buf_simple *buf)
{
	struct bt_ascs_ase_status_enable *enable;

	enable = net_buf_simple_add(buf, sizeof(*enable));
	enable->cig_id = ep->cig_id;
	enable->cis_id = ep->cis_id;

	enable->metadata_len = ep->codec_cfg.meta_len;
	net_buf_simple_add_mem(buf, ep->codec_cfg.meta, ep->codec_cfg.meta_len);

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

static ssize_t ascs_ase_read_status_idle(struct bt_conn *conn, const struct bt_gatt_attr *attr,
					 void *buf, uint16_t len, uint16_t offset)
{
	struct bt_ascs_ase_status status = {
		.id = POINTER_TO_UINT(BT_AUDIO_CHRC_USER_DATA(attr)),
		.state = BT_BAP_EP_STATE_IDLE,
	};

	LOG_DBG("conn %p id 0x%02x", (void *)conn, status.id);

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

static int ascs_ep_get_status(struct bt_bap_ep *ep, struct net_buf_simple *buf)
{
	if (!ep || !buf) {
		return -EINVAL;
	}

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

	/* Reset if buffer before using */
	net_buf_simple_reset(buf);

	(void)net_buf_simple_add_mem(buf, &ep->status, sizeof(ep->status));

	switch (ep->status.state) {
	case BT_BAP_EP_STATE_IDLE:
	/* Fallthrough */
	case BT_BAP_EP_STATE_RELEASING:
		break;
	case BT_BAP_EP_STATE_CODEC_CONFIGURED:
		ascs_ep_get_status_config(ep, buf);
		break;
	case BT_BAP_EP_STATE_QOS_CONFIGURED:
		ascs_ep_get_status_qos(ep, buf);
		break;
	case BT_BAP_EP_STATE_ENABLING:
	/* Fallthrough */
	case BT_BAP_EP_STATE_STREAMING:
	/* Fallthrough */
	case BT_BAP_EP_STATE_DISABLING:
		ascs_ep_get_status_enable(ep, buf);
		break;
	default:
		LOG_ERR("Invalid Endpoint state");
		break;
	}

	return 0;
}

static int ascs_iso_accept(const struct bt_iso_accept_info *info, struct bt_iso_chan **iso_chan)
{
	LOG_DBG("conn %p", (void *)info->acl);

	for (size_t i = 0; i < ARRAY_SIZE(ase_pool); i++) {
		struct bt_ascs_ase *ase = &ase_pool[i];
		enum bt_bap_ep_state state;
		struct bt_iso_chan *chan;

		if (ase->conn != info->acl ||
		    ase->ep.cig_id != info->cig_id ||
		    ase->ep.cis_id != info->cis_id) {
			continue;
		}

		state = ascs_ep_get_state(&ase->ep);
		if (state != BT_BAP_EP_STATE_ENABLING && state != BT_BAP_EP_STATE_QOS_CONFIGURED) {
			LOG_WRN("ase %p cannot accept ISO connection", ase);
			break;
		}

		__ASSERT(ase->ep.iso != NULL, "ep %p not bound with ISO", &ase->ep);

		chan = &ase->ep.iso->chan;
		if (chan->iso != NULL) {
			LOG_WRN("ase %p chan %p already connected", ase, chan);
			return -EALREADY;
		}

		*iso_chan = chan;

		LOG_DBG("iso_chan %p", *iso_chan);

		return 0;
	}

	return -EACCES;
}

#if defined(CONFIG_BT_AUDIO_RX)
static void ascs_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;

	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, 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 ascs_iso_sent(struct bt_iso_chan *chan)
{
	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;

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

	ops = stream->ops;

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

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

static void ascs_update_sdu_size(struct bt_bap_ep *ep)
{
	struct bt_iso_chan_io_qos *io_qos;
	struct bt_audio_codec_qos *codec_qos = &ep->qos;

	if (ep->dir == BT_AUDIO_DIR_SINK) {
		io_qos = ep->iso->chan.qos->rx;
	} else if (ep->dir == BT_AUDIO_DIR_SOURCE) {
		io_qos = ep->iso->chan.qos->tx;
	} else {
		return;
	}

	io_qos->sdu = codec_qos->sdu;
	io_qos->rtn = codec_qos->rtn;
}

static void ascs_ep_iso_connected(struct bt_bap_ep *ep)
{
	struct bt_ascs_ase *ase = CONTAINER_OF(ep, struct bt_ascs_ase, 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("ep %p not in enabling 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;
	}

	/* Reset reason */
	ep->reason = BT_HCI_ERR_SUCCESS;
	ase->unexpected_iso_link_loss = false;

	/* Some values are not provided by the HCI events when the CIS is established for the
	 * peripheral, so we update them here based on the parameters provided by the BAP Unicast
	 * Client
	 */
	ascs_update_sdu_size(ep);

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

#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->dir == BT_AUDIO_DIR_SINK && ep->receiver_ready) {
		/* Source ASEs shall be ISO connected first, and then receive
		 * the receiver start ready command to enter the streaming
		 * state
		 */
		ascs_ep_set_state(ep, BT_BAP_EP_STATE_STREAMING);
	}
}

static void ascs_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) {
		ascs_ep_iso_connected(iso->rx.ep);
	}

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

static void ascs_ep_iso_disconnected(struct bt_bap_ep *ep, uint8_t reason)
{
	struct bt_ascs_ase *ase = CONTAINER_OF(ep, struct bt_ascs_ase, ep);
	const struct bt_bap_stream_ops *stream_ops;
	struct bt_bap_stream *stream;

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

	LOG_DBG("stream %p ep %p state %s reason 0x%02x", stream, stream->ep,
		bt_bap_ep_state_str(ep->status.state), reason);

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

	/* Cancel ASE disconnect work if pending */
	(void)k_work_cancel_delayable(&ase->disconnect_work);
	ep->reason = reason;

	if (ep->status.state == BT_BAP_EP_STATE_RELEASING) {
		ascs_ep_set_state(ep, BT_BAP_EP_STATE_IDLE);
	} else if (ep->status.state == BT_BAP_EP_STATE_STREAMING ||
		   ep->status.state == BT_BAP_EP_STATE_DISABLING) {
		/* ASCS_v1.0 3.2 ASE state machine transitions
		 *
		 * If the server detects link loss of a CIS for an ASE in the Streaming
		 * state or the Disabling state, the server shall immediately transition
		 * that ASE to the QoS Configured state.
		 */
		ase->unexpected_iso_link_loss = true;

		ascs_ep_set_state(ep, BT_BAP_EP_STATE_QOS_CONFIGURED);
	}
}

static void ascs_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) {
		return;
	}

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

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

static struct bt_iso_chan_ops ascs_iso_ops = {
#if defined(CONFIG_BT_AUDIO_RX)
	.recv = ascs_iso_recv,
#endif /* CONFIG_BT_AUDIO_RX */
#if defined(CONFIG_BT_AUDIO_TX)
	.sent = ascs_iso_sent,
#endif /* CONFIG_BT_AUDIO_TX */
	.connected = ascs_iso_connected,
	.disconnected = ascs_iso_disconnected,
};

static void ascs_ase_cfg_changed(const struct bt_gatt_attr *attr,
				 uint16_t value)
{
	LOG_DBG("attr %p value 0x%04x", attr, value);
}

NET_BUF_SIMPLE_DEFINE_STATIC(rsp_buf, CONFIG_BT_L2CAP_TX_MTU);

static void ascs_cp_rsp_init(uint8_t op)
{
	struct bt_ascs_cp_rsp *rsp;

	net_buf_simple_reset(&rsp_buf);

	rsp = net_buf_simple_add(&rsp_buf, sizeof(*rsp));
	rsp->op = op;
	rsp->num_ase = 0;
}

/* Add response to an opcode/ASE ID */
static void ascs_cp_rsp_add(uint8_t id, uint8_t code, uint8_t reason)
{
	struct bt_ascs_cp_rsp *rsp = (void *)rsp_buf.__buf;
	struct bt_ascs_cp_ase_rsp *ase_rsp;

	LOG_DBG("id 0x%02x code %s (0x%02x) reason %s (0x%02x)", id,
		bt_ascs_rsp_str(code), code, bt_ascs_reason_str(reason), reason);

	if (rsp->num_ase == 0xff) {
		return;
	}

	switch (code) {
	/* If the Response_Code value is 0x01 or 0x02, Number_of_ASEs shall be
	 * set to 0xFF.
	 */
	case BT_BAP_ASCS_RSP_CODE_NOT_SUPPORTED:
	case BT_BAP_ASCS_RSP_CODE_INVALID_LENGTH:
		rsp->num_ase = BT_ASCS_UNSUPP_OR_LENGTH_ERR_NUM_ASE;
		break;
	default:
		rsp->num_ase++;
		break;
	}

	ase_rsp = net_buf_simple_add(&rsp_buf, sizeof(*ase_rsp));
	ase_rsp->id = id;
	ase_rsp->code = code;
	ase_rsp->reason = reason;
}

static void ascs_cp_rsp_success(uint8_t id)
{
	ascs_cp_rsp_add(id, BT_BAP_ASCS_RSP_CODE_SUCCESS, BT_BAP_ASCS_REASON_NONE);
}

static int ase_release(struct bt_ascs_ase *ase, uint8_t reason, struct bt_bap_ascs_rsp *rsp)
{
	enum bt_bap_ep_state state = ascs_ep_get_state(&ase->ep);
	int err;

	if (state == BT_BAP_EP_STATE_IDLE || state == BT_BAP_EP_STATE_RELEASING) {
		LOG_WRN("Invalid operation in state: %s", bt_bap_ep_state_str(state));
		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
				       BT_BAP_ASCS_REASON_NONE);
		return -EBADMSG;
	}

	if (unicast_server_cb == NULL || unicast_server_cb->release == NULL) {
		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
				       BT_BAP_ASCS_REASON_NONE);
		return -ENOTSUP;
	}

	err = unicast_server_cb->release(ase->ep.stream, rsp);
	if (err) {
		if (rsp->code == BT_BAP_ASCS_RSP_CODE_SUCCESS) {
			*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
					       BT_BAP_ASCS_REASON_NONE);
		}

		LOG_ERR("Release failed: err %d, code %u, reason %u", err, rsp->code, rsp->reason);
		return err;
	}

	/* Set reason in case this exits the streaming state */
	ase->ep.reason = reason;

	ascs_ep_set_state(&ase->ep, BT_BAP_EP_STATE_RELEASING);

	*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_SUCCESS, BT_BAP_ASCS_REASON_NONE);
	return 0;
}

int bt_ascs_release_ase(struct bt_bap_ep *ep)
{
	struct bt_ascs_ase *ase = CONTAINER_OF(ep, struct bt_ascs_ase, ep);
	const enum bt_bap_ep_state state = ascs_ep_get_state(&ase->ep);

	if (state == BT_BAP_EP_STATE_IDLE) {
		ase_free(ase);
		return 0;
	}

	return ase_release(ase, BT_HCI_ERR_LOCALHOST_TERM_CONN, BT_BAP_ASCS_RSP_NULL);
}

static int ase_disable(struct bt_ascs_ase *ase, uint8_t reason, struct bt_bap_ascs_rsp *rsp)
{
	struct bt_bap_stream *stream;
	struct bt_bap_ep *ep;
	int err;

	LOG_DBG("ase %p", ase);

	ep = &ase->ep;

	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_WRN("Invalid operation in state: %s", bt_bap_ep_state_str(ep->status.state));
		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
				       BT_BAP_ASCS_REASON_NONE);
		return -EBADMSG;
	}

	stream = ep->stream;

	if (unicast_server_cb == NULL || unicast_server_cb->disable == NULL) {
		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED, BT_BAP_ASCS_REASON_NONE);
		return -ENOTSUP;
	}

	err = unicast_server_cb->disable(stream, rsp);
	if (err) {
		if (rsp->code == BT_BAP_ASCS_RSP_CODE_SUCCESS) {
			*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
					       BT_BAP_ASCS_REASON_NONE);
		}

		LOG_ERR("Disable failed: err %d, code %u, reason %u", err, rsp->code, rsp->reason);
		return err;
	}

	/* Set reason in case this exits the streaming state */
	ep->reason = reason;

	/* The ASE state machine goes into different states from this operation
	 * based on whether it is a source or a sink ASE.
	 */
	if (ep->dir == BT_AUDIO_DIR_SOURCE) {
		ascs_ep_set_state(ep, BT_BAP_EP_STATE_DISABLING);
	} else {
		ascs_ep_set_state(ep, BT_BAP_EP_STATE_QOS_CONFIGURED);
	}

	*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_SUCCESS, BT_BAP_ASCS_REASON_NONE);
	return 0;
}

int bt_ascs_disable_ase(struct bt_bap_ep *ep)
{
	struct bt_ascs_ase *ase = CONTAINER_OF(ep, struct bt_ascs_ase, ep);

	return ase_disable(ase, BT_HCI_ERR_LOCALHOST_TERM_CONN, BT_BAP_ASCS_RSP_NULL);
}

static void disconnected(struct bt_conn *conn, uint8_t reason)
{
	for (size_t i = 0; i < ARRAY_SIZE(ase_pool); i++) {
		struct bt_ascs_ase *ase = &ase_pool[i];

		if (ase->conn != conn) {
			continue;
		}

		if (ase->ep.status.state != BT_BAP_EP_STATE_IDLE) {
			/* We must set the state to idle when the ACL is disconnected immediately,
			 * as when the ACL disconnect callbacks have been called, the application
			 * should expect there to be only a single reference to the bt_conn pointer
			 * from the stack.
			 * We trigger the work handler directly rather than e.g. calling
			 * ase_enter_state_idle to trigger "regular" state change behavior (such) as
			 * calling stream->stopped when leaving the streaming state.
			 */
			ase->ep.reason = reason;
			ase->state_pending = BT_BAP_EP_STATE_IDLE;
			state_transition_work_handler(&ase->state_transition_work.work);
			/* At this point, `ase` object have been free'd */
		}
	}
}

BT_CONN_CB_DEFINE(conn_cb) = {
	.disconnected = disconnected,
};

struct bap_iso_find_params {
	struct bt_conn *acl;
	uint8_t cig_id;
	uint8_t cis_id;
};

static bool bap_iso_find_func(struct bt_bap_iso *iso, void *user_data)
{
	struct bap_iso_find_params *params = user_data;
	const struct bt_bap_ep *ep;

	if (iso->rx.ep != NULL) {
		ep = iso->rx.ep;
	} else if (iso->tx.ep != NULL) {
		ep = iso->tx.ep;
	} else {
		return false;
	}

	return ep->stream->conn == params->acl &&
	       ep->cig_id == params->cig_id &&
	       ep->cis_id == params->cis_id;
}

static struct bt_bap_iso *bap_iso_get_or_new(struct bt_conn *conn, uint8_t cig_id, uint8_t cis_id)
{
	struct bt_bap_iso *iso;
	struct bap_iso_find_params params = {
		.acl = bt_conn_ref(conn),
		.cig_id = cig_id,
		.cis_id = cis_id,
	};

	iso = bt_bap_iso_find(bap_iso_find_func, &params);
	bt_conn_unref(conn);

	if (iso) {
		return iso;
	}

	iso = bt_bap_iso_new();
	if (!iso) {
		return NULL;
	}

	bt_bap_iso_init(iso, &ascs_iso_ops);

	return iso;
}

static uint8_t ase_attr_cb(const struct bt_gatt_attr *attr, uint16_t handle,
			   void *user_data)
{
	struct bt_ascs_ase *ase = user_data;

	if (ase->ep.status.id == POINTER_TO_UINT(BT_AUDIO_CHRC_USER_DATA(attr))) {
		ase->attr = attr;

		return BT_GATT_ITER_STOP;
	}

	return BT_GATT_ITER_CONTINUE;
}

void ascs_ep_init(struct bt_bap_ep *ep, uint8_t id)
{
	LOG_DBG("ep %p id 0x%02x", ep, id);

	(void)memset(ep, 0, sizeof(*ep));
	ep->status.id = id;
	ep->dir = ASE_DIR(id);
	ep->reason = BT_HCI_ERR_SUCCESS;
}

static void ase_init(struct bt_ascs_ase *ase, struct bt_conn *conn, uint8_t id)
{
	memset(ase, 0, sizeof(*ase));

	ascs_ep_init(&ase->ep, id);

	ase->conn = bt_conn_ref(conn);

	/* Lookup ASE characteristic */
	bt_gatt_foreach_attr_type(0x0001, 0xffff, ASE_UUID(id), NULL, 0, ase_attr_cb, ase);

	__ASSERT(ase->attr, "ASE characteristic not found\n");

	k_work_init_delayable(&ase->disconnect_work, ascs_disconnect_stream_work_handler);
	k_work_init_delayable(&ase->state_transition_work, state_transition_work_handler);
}

static struct bt_ascs_ase *ase_new(struct bt_conn *conn, uint8_t id)
{
	struct bt_ascs_ase *ase = NULL;

	__ASSERT(id > 0 && id <= ASE_COUNT, "invalid ASE_ID 0x%02x", id);

	for (size_t i = 0; i < ARRAY_SIZE(ase_pool); i++) {
		if (ase_pool[i].conn == NULL) {
			ase = &ase_pool[i];
			break;
		}
	}

	if (ase == NULL) {
		return NULL;
	}

	ase_init(ase, conn, id);

	LOG_DBG("conn %p new ase %p id 0x%02x", (void *)conn, ase, id);

	return ase;
}

static struct bt_ascs_ase *ase_find(struct bt_conn *conn, uint8_t id)
{
	for (size_t i = 0; i < ARRAY_SIZE(ase_pool); i++) {
		struct bt_ascs_ase *ase = &ase_pool[i];

		if (ase->conn == conn && ase->ep.status.id == id) {
			return ase;
		}
	}

	return NULL;
}

static ssize_t ascs_ase_read(struct bt_conn *conn,
			     const struct bt_gatt_attr *attr, void *buf,
			     uint16_t len, uint16_t offset)
{
	uint8_t ase_id = POINTER_TO_UINT(BT_AUDIO_CHRC_USER_DATA(attr));
	struct bt_ascs_ase *ase = NULL;
	ssize_t ret_val;
	int err;

	LOG_DBG("conn %p attr %p buf %p len %u offset %u", (void *)conn, attr, buf, len, offset);

	/* The callback can be used locally to read the ASE_ID in which case conn won't be set. */
	if (conn != NULL) {
		ase = ase_find(conn, ase_id);
	}

	/* If NULL, we haven't assigned an ASE, this also means that we are currently in IDLE */
	if (ase == NULL) {
		return ascs_ase_read_status_idle(conn, attr, buf, len, offset);
	}

	err = k_sem_take(&ase_buf_sem, ASE_BUF_SEM_TIMEOUT);
	if (err != 0) {
		LOG_DBG("Failed to take ase_buf_sem: %d", err);

		return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
	}

	ascs_ep_get_status(&ase->ep, &ase_buf);

	ret_val = bt_gatt_attr_read(conn, attr, buf, len, offset, ase_buf.data, ase_buf.len);

	k_sem_give(&ase_buf_sem);

	return ret_val;
}

static void ascs_cp_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
{
	LOG_DBG("attr %p value 0x%04x", attr, value);
}

struct codec_cap_lookup_id_data {
	uint8_t id;
	uint16_t cid;
	uint16_t vid;
	const struct bt_audio_codec_cap *codec_cap;
};

static bool codec_lookup_id(const struct bt_pacs_cap *cap, void *user_data)
{
	struct codec_cap_lookup_id_data *data = user_data;

	if (cap->codec_cap->id == data->id && cap->codec_cap->cid == data->cid &&
	    cap->codec_cap->vid == data->vid) {
		data->codec_cap = cap->codec_cap;

		return false;
	}

	return true;
}

static int ascs_ep_set_codec(struct bt_bap_ep *ep, uint8_t id, uint16_t cid, uint16_t vid,
			     uint8_t *cc, uint8_t len, struct bt_bap_ascs_rsp *rsp)
{
	struct bt_audio_codec_cfg *codec_cfg;
	struct codec_cap_lookup_id_data lookup_data = {
		.id = id,
		.cid = cid,
		.vid = vid,
	};

	if (ep == NULL) {
		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_CONF_INVALID,
				       BT_BAP_ASCS_REASON_CODEC_DATA);
		return -EINVAL;
	}

	codec_cfg = &ep->codec_cfg;

	LOG_DBG("ep %p dir %s codec id 0x%02x cid 0x%04x vid 0x%04x len %u",
		ep, bt_audio_dir_str(ep->dir), id, cid, vid, len);

	bt_pacs_cap_foreach(ep->dir, codec_lookup_id, &lookup_data);

	if (lookup_data.codec_cap == NULL) {
		LOG_DBG("Codec with id %u for dir %s is not supported by our capabilities",
			id, bt_audio_dir_str(ep->dir));

		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_CONF_INVALID,
				       BT_BAP_ASCS_REASON_CODEC);
		return -ENOENT;
	}

	codec_cfg->id = id;
	codec_cfg->cid = cid;
	codec_cfg->vid = vid;
	codec_cfg->data_len = len;
	memcpy(codec_cfg->data, cc, len);
	codec_cfg->path_id = lookup_data.codec_cap->path_id;

	*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_SUCCESS, BT_BAP_ASCS_REASON_NONE);

	return 0;
}

static int ase_config(struct bt_ascs_ase *ase, const struct bt_ascs_config *cfg)
{
	struct bt_bap_stream *stream;
	struct bt_audio_codec_cfg codec_cfg;
	struct bt_bap_ascs_rsp rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_SUCCESS,
						     BT_BAP_ASCS_REASON_NONE);
	int err;

	LOG_DBG("ase %p latency 0x%02x phy 0x%02x codec 0x%02x "
		"cid 0x%04x vid 0x%04x codec config len 0x%02x",
		ase, cfg->latency, cfg->phy, cfg->codec.id, cfg->codec.cid, cfg->codec.vid,
		cfg->cc_len);

	if (cfg->latency < BT_ASCS_CONFIG_LATENCY_LOW ||
	    cfg->latency > BT_ASCS_CONFIG_LATENCY_HIGH) {
		LOG_WRN("Invalid latency: 0x%02x", cfg->latency);
		ascs_cp_rsp_add(ASE_ID(ase), BT_BAP_ASCS_RSP_CODE_CONF_INVALID,
				BT_BAP_ASCS_REASON_LATENCY);
		return -EINVAL;
	}

	if (cfg->phy < BT_ASCS_CONFIG_PHY_LE_1M ||
	    cfg->phy > BT_ASCS_CONFIG_PHY_LE_CODED) {
		LOG_WRN("Invalid PHY: 0x%02x", cfg->phy);
		ascs_cp_rsp_add(ASE_ID(ase), BT_BAP_ASCS_RSP_CODE_CONF_INVALID,
				BT_BAP_ASCS_REASON_PHY);
		return -EINVAL;
	}

	if (cfg->cc_len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE) {
		LOG_DBG("Can not store %u codec configuration data", cfg->cc_len);

		return -ENOMEM;
	}

	switch (ase->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_WRN("Invalid operation in state: %s",
			bt_bap_ep_state_str(ase->ep.status.state));
		ascs_cp_rsp_add(ASE_ID(ase), BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
				BT_BAP_ASCS_REASON_NONE);
		return -EINVAL;
	}

	/* Store current codec configuration to be able to restore it
	 * in case of error.
	 */
	(void)memcpy(&codec_cfg, &ase->ep.codec_cfg, sizeof(codec_cfg));

	err = ascs_ep_set_codec(&ase->ep, cfg->codec.id, sys_le16_to_cpu(cfg->codec.cid),
				sys_le16_to_cpu(cfg->codec.vid), (uint8_t *)cfg->cc, cfg->cc_len,
				&rsp);
	if (err) {
		ascs_app_rsp_warn_valid(&rsp);
		(void)memcpy(&ase->ep.codec_cfg, &codec_cfg, sizeof(codec_cfg));
		ascs_cp_rsp_add(ASE_ID(ase), rsp.code, rsp.reason);
		return err;
	}

	if (ase->ep.stream != NULL) {
		if (unicast_server_cb != NULL &&
		    unicast_server_cb->reconfig != NULL) {
			err = unicast_server_cb->reconfig(ase->ep.stream, ase->ep.dir,
							  &ase->ep.codec_cfg, &ase->ep.qos_pref,
							  &rsp);
		} else {
			err = -ENOTSUP;
			rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
					      BT_BAP_ASCS_REASON_NONE);
		}

		if (err) {
			ascs_app_rsp_warn_valid(&rsp);

			if (rsp.code == BT_BAP_ASCS_RSP_CODE_SUCCESS) {
				rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
						      BT_BAP_ASCS_REASON_NONE);
			}

			LOG_ERR("Reconfig failed: err %d, code %u, reason %u",
				err, rsp.code, rsp.reason);

			(void)memcpy(&ase->ep.codec_cfg, &codec_cfg, sizeof(codec_cfg));
			ascs_cp_rsp_add(ASE_ID(ase), rsp.code, rsp.reason);

			return err;
		}

		stream = ase->ep.stream;
	} else {
		stream = NULL;
		if (unicast_server_cb != NULL &&
		    unicast_server_cb->config != NULL) {
			err = unicast_server_cb->config(ase->conn, &ase->ep, ase->ep.dir,
							&ase->ep.codec_cfg, &stream,
							&ase->ep.qos_pref, &rsp);
		} else {
			err = -ENOTSUP;
			rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
					      BT_BAP_ASCS_REASON_NONE);
		}

		if (err || stream == NULL) {
			ascs_app_rsp_warn_valid(&rsp);

			if (rsp.code == BT_BAP_ASCS_RSP_CODE_SUCCESS) {
				rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
						      BT_BAP_ASCS_REASON_NONE);
			}

			LOG_ERR("Config failed: err %d, stream %p, code %u, reason %u",
				err, stream, rsp.code, rsp.reason);

			(void)memcpy(&ase->ep.codec_cfg, &codec_cfg, sizeof(codec_cfg));
			ascs_cp_rsp_add(ASE_ID(ase), rsp.code, rsp.reason);

			return err ? err : -ENOMEM;
		}

		bt_bap_stream_init(stream);
	}

	ascs_cp_rsp_success(ASE_ID(ase));

	bt_bap_stream_attach(ase->conn, stream, &ase->ep, &ase->ep.codec_cfg);

	ascs_ep_set_state(&ase->ep, BT_BAP_EP_STATE_CODEC_CONFIGURED);

	return 0;
}

static struct bt_bap_ep *ep_lookup_stream(struct bt_conn *conn, struct bt_bap_stream *stream)
{
	for (size_t i = 0; i < ARRAY_SIZE(ase_pool); i++) {
		struct bt_ascs_ase *ase = &ase_pool[i];

		if (ase->conn == conn && ase->ep.stream == stream) {
			return &ase->ep;
		}
	}

	return NULL;
}

int bt_ascs_config_ase(struct bt_conn *conn, struct bt_bap_stream *stream,
		       struct bt_audio_codec_cfg *codec_cfg,
		       const struct bt_audio_codec_qos_pref *qos_pref)
{
	int err;
	struct bt_ascs_ase *ase = NULL;
	struct bt_bap_ep *ep;
	struct codec_cap_lookup_id_data lookup_data;

	CHECKIF(conn == NULL || stream == NULL || codec_cfg == NULL || qos_pref == NULL) {
		LOG_DBG("NULL value(s) supplied)");
		return -EINVAL;
	}

	ep = ep_lookup_stream(conn, stream);
	if (ep != NULL) {
		LOG_DBG("Stream already configured for conn %p", (void *)stream->conn);
		return -EALREADY;
	}

	/* Get a free ASE or NULL if all ASE instances are aready in use */
	for (int i = 1; i <= ASE_COUNT; i++) {
		if (ase_find(conn, i) == NULL) {
			ase = ase_new(conn, i);
			break;
		}
	}

	if (ase == NULL) {
		LOG_WRN("No free ASE found.");
		return -ENOTSUP;
	}

	ep = &ase->ep;

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

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

	bt_pacs_cap_foreach(ep->dir, codec_lookup_id, &lookup_data);

	if (lookup_data.codec_cap == NULL) {
		LOG_DBG("Codec with id %u for dir %s is not supported by our capabilities",
			codec_cfg->id, bt_audio_dir_str(ep->dir));
		return -ENOENT;
	}

	(void)memcpy(&ep->codec_cfg, codec_cfg, sizeof(ep->codec_cfg));

	ep->qos_pref = *qos_pref;

	bt_bap_stream_attach(conn, stream, ep, &ep->codec_cfg);

	err = ascs_ep_set_state(ep, BT_BAP_EP_STATE_CODEC_CONFIGURED);
	if (err != 0) {
		bt_bap_stream_detach(stream);
		ase_free(ase);
		return err;
	}

	return 0;
}

static bool is_valid_config_len(struct net_buf_simple *buf)
{
	const struct bt_ascs_config_op *op;
	struct net_buf_simple_state state;

	net_buf_simple_save(buf, &state);

	if (buf->len < sizeof(*op)) {
		LOG_WRN("Invalid length %u < %zu", buf->len, sizeof(*op));
		return false;
	}

	op = net_buf_simple_pull_mem(buf, sizeof(*op));
	if (op->num_ases < 1) {
		LOG_WRN("Number_of_ASEs parameter value is less than 1");
		return false;
	}

	for (uint8_t i = 0U; i < op->num_ases; i++) {
		const struct bt_ascs_config *config;

		if (buf->len < sizeof(*config)) {
			LOG_WRN("Malformed params array");
			return false;
		}

		config = net_buf_simple_pull_mem(buf, sizeof(*config));
		if (buf->len < config->cc_len) {
			LOG_WRN("Malformed codec specific config");
			return false;
		}

		(void)net_buf_simple_pull_mem(buf, config->cc_len);
	}

	if (buf->len > 0) {
		LOG_WRN("Unexpected data");
		return false;
	}

	net_buf_simple_restore(buf, &state);

	return true;
}

static ssize_t ascs_config(struct bt_conn *conn, struct net_buf_simple *buf)
{
	const struct bt_ascs_config_op *req;
	const struct bt_ascs_config *cfg;

	if (!is_valid_config_len(buf)) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
	}

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

	LOG_DBG("num_ases %u", req->num_ases);

	for (uint8_t i = 0; i < req->num_ases; i++) {
		struct bt_ascs_ase *ase;
		int err;

		cfg = net_buf_simple_pull_mem(buf, sizeof(*cfg));
		(void)net_buf_simple_pull(buf, cfg->cc_len);

		LOG_DBG("ase 0x%02x cc_len %u", cfg->ase, cfg->cc_len);

		if (!cfg->ase || cfg->ase > ASE_COUNT) {
			LOG_WRN("Invalid ASE ID: %u", cfg->ase);
			ascs_cp_rsp_add(cfg->ase, BT_BAP_ASCS_RSP_CODE_INVALID_ASE,
					BT_BAP_ASCS_REASON_NONE);
			continue;
		}

		ase = ase_find(conn, cfg->ase);
		if (ase != NULL) {
			ase_config(ase, cfg);
			continue;
		}

		ase = ase_new(conn, cfg->ase);
		if (!ase) {
			ascs_cp_rsp_add(cfg->ase, BT_BAP_ASCS_RSP_CODE_NO_MEM,
					BT_BAP_ASCS_REASON_NONE);
			LOG_WRN("No free ASE found for config ASE ID 0x%02x", cfg->ase);
			continue;
		}

		err = ase_config(ase, cfg);
		if (err != 0) {
			ase_free(ase);
		}
	}

	return buf->size;
}

void bt_ascs_foreach_ep(struct bt_conn *conn, bt_bap_ep_func_t func, void *user_data)
{
	for (size_t i = 0; i < ARRAY_SIZE(ase_pool); i++) {
		struct bt_ascs_ase *ase = &ase_pool[i];

		if (ase->conn == conn) {
			func(&ase->ep, user_data);
		}
	}
}

static void ase_qos(struct bt_ascs_ase *ase, uint8_t cig_id, uint8_t cis_id,
		    struct bt_audio_codec_qos *qos, struct bt_bap_ascs_rsp *rsp)
{
	struct bt_bap_ep *ep = &ase->ep;
	struct bt_bap_stream *stream;

	LOG_DBG("ase %p cig 0x%02x cis 0x%02x interval %u framing 0x%02x phy 0x%02x sdu %u rtn %u "
		"latency %u pd %u", ase, cig_id, cis_id, qos->interval, qos->framing, qos->phy,
		qos->sdu, qos->rtn, qos->latency, qos->pd);

	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_WRN("Invalid operation in state: %s", bt_bap_ep_state_str(ep->status.state));
		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
				       BT_BAP_ASCS_REASON_NONE);
		return;
	}

	stream = ep->stream;
	if (stream == NULL) {
		LOG_ERR("NULL stream");
		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED, BT_BAP_ASCS_REASON_NONE);
		return;
	}

	if (stream->ep == NULL) {
		LOG_ERR("NULL stream->ep");
		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED, BT_BAP_ASCS_REASON_NONE);
		return;
	}

	rsp->reason = bt_audio_verify_qos(qos);
	if (rsp->reason != BT_BAP_ASCS_REASON_NONE) {
		rsp->code = BT_BAP_ASCS_RSP_CODE_CONF_INVALID;
		return;
	}

	rsp->reason = bt_bap_stream_verify_qos(stream, qos);
	if (rsp->reason != BT_BAP_ASCS_REASON_NONE) {
		rsp->code = BT_BAP_ASCS_RSP_CODE_CONF_INVALID;
		return;
	}

	if (unicast_server_cb != NULL && unicast_server_cb->qos != NULL) {
		int err = unicast_server_cb->qos(stream, qos, rsp);

		if (err) {
			if (rsp->code == BT_BAP_ASCS_RSP_CODE_SUCCESS) {
				*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
						       BT_BAP_ASCS_REASON_NONE);
			}

			LOG_DBG("Application returned error: err %d status %u reason %u",
				err, rsp->code, rsp->reason);
			return;
		}
	}

	/* QoS->QoS transition. Unbind ISO if CIG/CIS changed. */
	if (ep->iso != NULL && (ep->cig_id != cig_id || ep->cis_id != cis_id)) {
		bt_bap_iso_unbind_ep(ep->iso, ep);
	}

	if (ep->iso == NULL) {
		struct bt_bap_iso *iso;

		iso = bap_iso_get_or_new(ase->conn, cig_id, cis_id);
		if (iso == NULL) {
			LOG_ERR("Could not allocate bap_iso");
			*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_NO_MEM,
					       BT_BAP_ASCS_REASON_NONE);
			return;
		}

		if (bt_bap_iso_get_ep(false, iso, ep->dir) != NULL) {
			LOG_ERR("iso %p already in use in dir %s",
			       &iso->chan, bt_audio_dir_str(ep->dir));
			bt_bap_iso_unref(iso);
			*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_CONF_INVALID,
					       BT_BAP_ASCS_REASON_CIS);
			return;
		}

		bt_bap_iso_bind_ep(iso, ep);
		bt_bap_iso_unref(iso);
	}

	/* Store the QoS once accepted */
	ep->qos = *qos;
	stream->qos = &ep->qos;

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

	ep->cig_id = cig_id;
	ep->cis_id = cis_id;

	ascs_ep_set_state(ep, BT_BAP_EP_STATE_QOS_CONFIGURED);

	*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_SUCCESS, BT_BAP_ASCS_REASON_NONE);
}

static bool is_valid_qos_len(struct net_buf_simple *buf)
{
	const struct bt_ascs_qos_op *op;
	struct net_buf_simple_state state;
	size_t params_size;

	net_buf_simple_save(buf, &state);

	if (buf->len < sizeof(*op)) {
		LOG_WRN("Invalid length %u < %zu", buf->len, sizeof(*op));
		return false;
	}

	op = net_buf_simple_pull_mem(buf, sizeof(*op));
	if (op->num_ases < 1) {
		LOG_WRN("Number_of_ASEs parameter value is less than 1");
		return false;
	}

	params_size = sizeof(struct bt_ascs_qos) * op->num_ases;
	if (buf->len < params_size) {
		LOG_WRN("Malformed params array");
		return false;
	}

	(void)net_buf_simple_pull_mem(buf, params_size);

	if (buf->len > 0) {
		LOG_WRN("Unexpected data");
		return false;
	}

	net_buf_simple_restore(buf, &state);

	return true;
}

static ssize_t ascs_qos(struct bt_conn *conn, struct net_buf_simple *buf)
{
	const struct bt_ascs_qos_op *req;

	if (!is_valid_qos_len(buf)) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
	}

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

	LOG_DBG("num_ases %u", req->num_ases);

	for (uint8_t i = 0; i < req->num_ases; i++) {
		struct bt_bap_ascs_rsp rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
							     BT_BAP_ASCS_REASON_NONE);
		struct bt_audio_codec_qos cqos;
		const struct bt_ascs_qos *qos;
		struct bt_ascs_ase *ase;

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

		LOG_DBG("ase 0x%02x", qos->ase);

		if (!is_valid_ase_id(qos->ase)) {
			ascs_cp_rsp_add(qos->ase, BT_BAP_ASCS_RSP_CODE_INVALID_ASE,
					BT_BAP_ASCS_REASON_NONE);
			LOG_WRN("Unknown ase 0x%02x", qos->ase);
			continue;
		}

		ase = ase_find(conn, qos->ase);
		if (!ase) {
			LOG_DBG("Invalid operation for idle ASE");
			ascs_cp_rsp_add(qos->ase, BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
					BT_BAP_ASCS_REASON_NONE);
			continue;
		}

		cqos.interval = sys_get_le24(qos->interval);
		cqos.framing = qos->framing;
		cqos.phy = qos->phy;
		cqos.sdu = sys_le16_to_cpu(qos->sdu);
		cqos.rtn = qos->rtn;
		cqos.latency = sys_le16_to_cpu(qos->latency);
		cqos.pd = sys_get_le24(qos->pd);

		ase_qos(ase, qos->cig, qos->cis, &cqos, &rsp);
		ascs_cp_rsp_add(qos->ase, rsp.code, rsp.reason);
	}

	return buf->size;
}

struct ascs_parse_result {
	int err;
	struct bt_conn *conn;
	struct bt_bap_ascs_rsp *rsp;
	const struct bt_bap_ep *ep;
};

static bool is_context_available(struct bt_conn *conn, enum bt_audio_dir dir, uint16_t context)
{
	return (context & bt_pacs_get_available_contexts_for_conn(conn, dir)) == context;
}

static bool ascs_parse_metadata(struct bt_data *data, void *user_data)
{
	struct ascs_parse_result *result = user_data;
	const struct bt_bap_ep *ep = result->ep;
	const uint8_t data_len = data->data_len;
	const uint8_t data_type = data->type;
	const uint8_t *data_value = data->data;

	LOG_DBG("type 0x%02x len %u", data_type, data_len);

	if (!BT_AUDIO_METADATA_TYPE_IS_KNOWN(data_type)) {
		LOG_WRN("Unknown metadata type 0x%02x", data_type);
		return true;
	}

	switch (data_type) {
	/* TODO: Consider rejecting BT_AUDIO_METADATA_TYPE_PREF_CONTEXT type */
	case BT_AUDIO_METADATA_TYPE_PREF_CONTEXT:
	case BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT: {
		uint16_t context;

		if (data_len != sizeof(context)) {
			*result->rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_METADATA_INVALID,
						       data_type);
			result->err = -EBADMSG;
			return false;
		}

		context = sys_get_le16(data_value);
		if (context == BT_AUDIO_CONTEXT_TYPE_PROHIBITED) {
			*result->rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_METADATA_INVALID,
						       data_type);
			result->err = -EINVAL;
			return false;
		}

		/* The CAP acceptor shall not accept metadata with unsupported stream context. */
		if (IS_ENABLED(CONFIG_BT_CAP_ACCEPTOR) &&
		    data_type == BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT) {
			if (!is_context_available(result->conn, ep->dir, context)) {
				LOG_WRN("Context 0x%04x is unavailable", context);
				*result->rsp = BT_BAP_ASCS_RSP(
					BT_BAP_ASCS_RSP_CODE_METADATA_REJECTED, data_type);
				result->err = -EACCES;
				return false;
			}
		}

		break;
	}
	case BT_AUDIO_METADATA_TYPE_STREAM_LANG:
		if (data_len != 3) {
			*result->rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_METADATA_INVALID,
						       data_type);
			result->err = -EBADMSG;
			return false;
		}

		break;
	case BT_AUDIO_METADATA_TYPE_CCID_LIST: {
		/* Verify that the CCID is a known CCID on the writing device */
		if (IS_ENABLED(CONFIG_BT_CAP_ACCEPTOR)) {
			for (uint8_t i = 0; i < data_len; i++) {
				const uint8_t ccid = data_value[i];

				if (!bt_cap_acceptor_ccid_exist(ep->stream->conn, ccid)) {
					LOG_WRN("CCID %u is unknown", ccid);

					/* TBD:
					 * Should we reject the Metadata?
					 *
					 * Should unknown CCIDs trigger a
					 * discovery procedure for TBS or MCS?
					 *
					 * Or should we just accept as is, and
					 * then let the application decide?
					 */
				}
			}
		}

		break;
	}
	case BT_AUDIO_METADATA_TYPE_PARENTAL_RATING:
		if (data_len != 1) {
			*result->rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_METADATA_INVALID,
						       data_type);
			result->err = -EBADMSG;
			return false;
		}

		break;
	case BT_AUDIO_METADATA_TYPE_AUDIO_STATE: {
		uint8_t state;

		if (data_len != sizeof(state)) {
			*result->rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_METADATA_INVALID,
						       data_type);
			result->err = -EBADMSG;
			return false;
		}

		break;
	}
	/* TODO: Consider rejecting BT_AUDIO_METADATA_TYPE_BROADCAST_IMMEDIATE type */
	case BT_AUDIO_METADATA_TYPE_BROADCAST_IMMEDIATE:
		if (data_len != 0) {
			*result->rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_METADATA_INVALID,
						       data_type);
			result->err = -EBADMSG;
			return false;
		}

		break;
	default:
		break;
	}

	return true;
}

static int ascs_verify_metadata(struct bt_bap_ep *ep, const struct bt_ascs_metadata *meta,
				struct bt_bap_ascs_rsp *rsp)
{
	struct bt_ascs_ase *ase = CONTAINER_OF(ep, struct bt_ascs_ase, ep);
	struct ascs_parse_result result = {
		.conn = ase->conn,
		.rsp = rsp,
		.err = 0,
		.ep = ep,
	};
	int err;

	if (meta->len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE) {
		LOG_WRN("Not enough space for Codec Config Metadata: %u > %d", meta->len,
			CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE);
		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_NO_MEM, BT_BAP_ASCS_REASON_NONE);

		return -ENOMEM;
	}

	/* Parse LTV entries */
	err = bt_audio_data_parse(meta->data, meta->len, ascs_parse_metadata, &result);
	if (err != 0 && err != -ECANCELED) {
		/* ECANCELED is called if the callback stops the parsing prematurely, in which case
		 * result.err will be set
		 */
		LOG_DBG("Failed to parse metadata: %d", err);
		*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_METADATA_INVALID,
				       BT_BAP_ASCS_REASON_NONE);

		return err;
	}

	return result.err;
}

static void ase_metadata(struct bt_ascs_ase *ase, struct bt_ascs_metadata *meta)
{
	struct bt_bap_stream *stream;
	struct bt_bap_ep *ep;
	struct bt_bap_ascs_rsp rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_SUCCESS,
						     BT_BAP_ASCS_REASON_NONE);
	uint8_t state;
	int err;

	LOG_DBG("ase %p meta->len %u", ase, meta->len);

	ep = &ase->ep;
	state = ep->status.state;

	switch (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_WRN("Invalid operation in state: %s", bt_bap_ep_state_str(state));
		ascs_cp_rsp_add(ASE_ID(ase), BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
				BT_BAP_ASCS_REASON_NONE);
		return;
	}

	stream = ep->stream;

	err = ascs_verify_metadata(ep, meta, &rsp);
	if (err != 0) {
		LOG_DBG("Invalid metadata from client: %d", err);

		/* rsp will be set by ascs_verify_metadata*/
	} else if (unicast_server_cb != NULL && unicast_server_cb->metadata != NULL) {
		err = unicast_server_cb->metadata(stream, meta->data, meta->len, &rsp);
	} else {
		err = -ENOTSUP;
		rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
				      BT_BAP_ASCS_REASON_NONE);
	}

	if (err) {
		ascs_app_rsp_warn_valid(&rsp);

		if (rsp.code == BT_BAP_ASCS_RSP_CODE_SUCCESS) {
			rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
					      BT_BAP_ASCS_REASON_NONE);
		}

		LOG_ERR("Metadata failed: err %d, code %u, reason %u", err, rsp.code, rsp.reason);
		ascs_cp_rsp_add(ASE_ID(ase), rsp.code, rsp.reason);
		return;
	}

	ep->codec_cfg.meta_len = meta->len;
	(void)memcpy(ep->codec_cfg.meta, meta->data, meta->len);

	/* Set the state to the same state to trigger the notifications */
	ascs_ep_set_state(ep, ep->status.state);
	ascs_cp_rsp_success(ASE_ID(ase));
}

static int ase_enable(struct bt_ascs_ase *ase, struct bt_ascs_metadata *meta)
{
	struct bt_bap_stream *stream;
	struct bt_bap_ep *ep;
	struct bt_bap_ascs_rsp rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_SUCCESS,
						     BT_BAP_ASCS_REASON_NONE);
	int err;

	LOG_DBG("ase %p meta->len %u", ase, meta->len);

	ep = &ase->ep;

	/* Valid for an ASE only if ASE_State field = 0x02 (QoS Configured) */
	if (ep->status.state != BT_BAP_EP_STATE_QOS_CONFIGURED) {
		err = -EBADMSG;
		LOG_WRN("Invalid operation in state: %s", bt_bap_ep_state_str(ep->status.state));
		ascs_cp_rsp_add(ASE_ID(ase), BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
				BT_BAP_ASCS_REASON_NONE);
		return err;
	}

	stream = ep->stream;

	err = ascs_verify_metadata(ep, meta, &rsp);
	if (err != 0) {
		LOG_DBG("Invalid metadata from client: %d", err);

		/* rsp will be set by ascs_verify_metadata*/
	} else if (unicast_server_cb != NULL && unicast_server_cb->enable != NULL) {
		err = unicast_server_cb->enable(stream, meta->data, meta->len, &rsp);
	} else {
		err = -ENOTSUP;
		rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
				      BT_BAP_ASCS_REASON_NONE);
	}

	if (err) {
		ascs_app_rsp_warn_valid(&rsp);

		if (rsp.code == BT_BAP_ASCS_RSP_CODE_SUCCESS) {
			rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
					      BT_BAP_ASCS_REASON_NONE);
		}

		LOG_ERR("Enable rejected: err %d, code %u, reason %u", err, rsp.code, rsp.reason);
		ascs_cp_rsp_add(ASE_ID(ase), rsp.code, rsp.reason);

		return -EFAULT;
	}

	ep->codec_cfg.meta_len = meta->len;
	(void)memcpy(ep->codec_cfg.meta, meta->data, meta->len);

	ascs_ep_set_state(ep, BT_BAP_EP_STATE_ENABLING);

	ascs_cp_rsp_success(ASE_ID(ase));

	return 0;
}

static bool is_valid_enable_len(struct net_buf_simple *buf)
{
	const struct bt_ascs_enable_op *op;
	struct net_buf_simple_state state;

	net_buf_simple_save(buf, &state);

	if (buf->len < sizeof(*op)) {
		LOG_WRN("Invalid length %u < %zu", buf->len, sizeof(*op));
		return false;
	}

	op = net_buf_simple_pull_mem(buf, sizeof(*op));
	if (op->num_ases < 1) {
		LOG_WRN("Number_of_ASEs parameter value is less than 1");
		return false;
	}

	for (uint8_t i = 0U; i < op->num_ases; i++) {
		const struct bt_ascs_metadata *metadata;

		if (buf->len < sizeof(*metadata)) {
			LOG_WRN("Malformed params array");
			return false;
		}

		metadata = net_buf_simple_pull_mem(buf, sizeof(*metadata));
		if (buf->len < metadata->len) {
			LOG_WRN("Malformed metadata");
			return false;
		}

		(void)net_buf_simple_pull_mem(buf, metadata->len);
	}

	if (buf->len > 0) {
		LOG_WRN("Unexpected data");
		return false;
	}

	net_buf_simple_restore(buf, &state);

	return true;
}

static ssize_t ascs_enable(struct bt_conn *conn, struct net_buf_simple *buf)
{
	const struct bt_ascs_enable_op *req;
	struct bt_ascs_metadata *meta;
	int i;

	if (!is_valid_enable_len(buf)) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
	}

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

	LOG_DBG("num_ases %u", req->num_ases);

	for (i = 0; i < req->num_ases; i++) {
		struct bt_ascs_ase *ase;

		meta = net_buf_simple_pull_mem(buf, sizeof(*meta));
		(void)net_buf_simple_pull(buf, meta->len);

		if (!is_valid_ase_id(meta->ase)) {
			ascs_cp_rsp_add(meta->ase, BT_BAP_ASCS_RSP_CODE_INVALID_ASE,
					BT_BAP_ASCS_REASON_NONE);
			LOG_WRN("Unknown ase 0x%02x", meta->ase);
			continue;
		}

		ase = ase_find(conn, meta->ase);
		if (!ase) {
			LOG_DBG("Invalid operation for idle ase 0x%02x", meta->ase);
			ascs_cp_rsp_add(meta->ase, BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
					BT_BAP_ASCS_REASON_NONE);
			continue;
		}

		ase_enable(ase, meta);
	}

	return buf->size;
}

static void ase_start(struct bt_ascs_ase *ase)
{
	struct bt_bap_ep *ep;
	struct bt_bap_ascs_rsp rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_SUCCESS,
						     BT_BAP_ASCS_REASON_NONE);
	int err;

	LOG_DBG("ase %p", ase);

	ep = &ase->ep;

	/* Valid for an ASE only if ASE_State field = 0x02 (QoS Configured) */
	if (ep->status.state != BT_BAP_EP_STATE_ENABLING) {
		LOG_WRN("Invalid operation in state: %s", bt_bap_ep_state_str(ep->status.state));
		ascs_cp_rsp_add(ASE_ID(ase), BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
				BT_BAP_ASCS_REASON_NONE);
		return;
	}

	if (ep->iso->chan.state != BT_ISO_STATE_CONNECTED) {
		/* An ASE may not go into the streaming state unless the CIS
		 * is connected
		 */
		LOG_WRN("Start failed: CIS not connected: %u",
			ep->iso->chan.state);
		ascs_cp_rsp_add(ASE_ID(ase), BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
				BT_BAP_ASCS_REASON_NONE);
		return;
	}

	if (unicast_server_cb != NULL && unicast_server_cb->start != NULL) {
		err = unicast_server_cb->start(ep->stream, &rsp);
	} else {
		err = -ENOTSUP;
		rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
				      BT_BAP_ASCS_REASON_NONE);
	}

	if (err) {
		ascs_app_rsp_warn_valid(&rsp);

		if (rsp.code == BT_BAP_ASCS_RSP_CODE_SUCCESS) {
			rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
					      BT_BAP_ASCS_REASON_NONE);
		}

		LOG_ERR("Start failed: err %d, code %u, reason %u", err, rsp.code, rsp.reason);
		ascs_cp_rsp_add(ASE_ID(ase), rsp.code, rsp.reason);

		return;
	}

	ep->receiver_ready = true;

	ascs_ep_set_state(ep, BT_BAP_EP_STATE_STREAMING);

	ascs_cp_rsp_success(ASE_ID(ase));
}

static bool is_valid_start_len(struct net_buf_simple *buf)
{
	const struct bt_ascs_start_op *op;
	struct net_buf_simple_state state;

	net_buf_simple_save(buf, &state);

	if (buf->len < sizeof(*op)) {
		LOG_WRN("Invalid length %u < %zu", buf->len, sizeof(*op));
		return false;
	}

	op = net_buf_simple_pull_mem(buf, sizeof(*op));
	if (op->num_ases < 1) {
		LOG_WRN("Number_of_ASEs parameter value is less than 1");
		return false;
	}

	if (buf->len != op->num_ases) {
		LOG_WRN("Number_of_ASEs mismatch");
		return false;
	}

	net_buf_simple_restore(buf, &state);

	return true;
}

static ssize_t ascs_start(struct bt_conn *conn, struct net_buf_simple *buf)
{
	const struct bt_ascs_start_op *req;
	int i;

	if (!is_valid_start_len(buf)) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
	}

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

	LOG_DBG("num_ases %u", req->num_ases);

	for (i = 0; i < req->num_ases; i++) {
		struct bt_ascs_ase *ase;
		uint8_t id;

		id = net_buf_simple_pull_u8(buf);

		LOG_DBG("ase 0x%02x", id);

		if (!is_valid_ase_id(id)) {
			ascs_cp_rsp_add(id, BT_BAP_ASCS_RSP_CODE_INVALID_ASE,
					BT_BAP_ASCS_REASON_NONE);
			LOG_WRN("Unknown ase 0x%02x", id);
			continue;
		}

		/* If the ASE_ID  written by the client represents a Sink ASE, the
		 * server shall not accept the Receiver Start Ready operation for that
		 * ASE. The server shall send a notification of the ASE Control Point
		 * characteristic to the client, and the server shall set the
		 * Response_Code value for that ASE to 0x05 (Invalid ASE direction).
		 */
		if (ASE_DIR(id) == BT_AUDIO_DIR_SINK) {
			LOG_WRN("Start failed: invalid operation for Sink");
			ascs_cp_rsp_add(id, BT_BAP_ASCS_RSP_CODE_INVALID_DIR,
					BT_BAP_ASCS_REASON_NONE);
			continue;
		}

		ase = ase_find(conn, id);
		if (!ase) {
			LOG_DBG("Invalid operation for idle ASE");
			ascs_cp_rsp_add(id, BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
					BT_BAP_ASCS_REASON_NONE);
			continue;
		}

		ase_start(ase);
	}

	return buf->size;
}

static bool is_valid_disable_len(struct net_buf_simple *buf)
{
	const struct bt_ascs_disable_op *op;
	struct net_buf_simple_state state;

	net_buf_simple_save(buf, &state);

	if (buf->len < sizeof(*op)) {
		LOG_WRN("Invalid length %u < %zu", buf->len, sizeof(*op));
		return false;
	}

	op = net_buf_simple_pull_mem(buf, sizeof(*op));
	if (op->num_ases < 1) {
		LOG_WRN("Number_of_ASEs parameter value is less than 1");
		return false;
	}

	if (buf->len != op->num_ases) {
		LOG_WRN("Number_of_ASEs mismatch");
		return false;
	}

	net_buf_simple_restore(buf, &state);

	return true;
}

static ssize_t ascs_disable(struct bt_conn *conn, struct net_buf_simple *buf)
{
	const struct bt_ascs_disable_op *req;

	if (!is_valid_disable_len(buf)) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
	}

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

	LOG_DBG("num_ases %u", req->num_ases);

	for (uint8_t i = 0; i < req->num_ases; i++) {
		struct bt_bap_ascs_rsp rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
							     BT_BAP_ASCS_REASON_NONE);
		struct bt_ascs_ase *ase;
		uint8_t id;

		id = net_buf_simple_pull_u8(buf);

		LOG_DBG("ase 0x%02x", id);

		if (!is_valid_ase_id(id)) {
			ascs_cp_rsp_add(id, BT_BAP_ASCS_RSP_CODE_INVALID_ASE,
					BT_BAP_ASCS_REASON_NONE);
			LOG_WRN("Unknown ase 0x%02x", id);
			continue;
		}

		ase = ase_find(conn, id);
		if (!ase) {
			LOG_DBG("Invalid operation for idle ASE");
			ascs_cp_rsp_add(id, BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
					BT_BAP_ASCS_REASON_NONE);
			continue;
		}

		ase_disable(ase, BT_HCI_ERR_REMOTE_USER_TERM_CONN, &rsp);
		ascs_cp_rsp_add(id, rsp.code, rsp.reason);
	}

	return buf->size;
}

static void ase_stop(struct bt_ascs_ase *ase)
{
	struct bt_bap_stream *stream;
	struct bt_bap_ep *ep;
	struct bt_bap_ascs_rsp rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_SUCCESS,
						     BT_BAP_ASCS_REASON_NONE);
	int err;

	LOG_DBG("ase %p", ase);

	ep = &ase->ep;

	if (ep->status.state != BT_BAP_EP_STATE_DISABLING) {
		LOG_WRN("Invalid operation in state: %s", bt_bap_ep_state_str(ep->status.state));
		ascs_cp_rsp_add(ASE_ID(ase), BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
				BT_BAP_ASCS_REASON_NONE);
		return;
	}

	stream = ep->stream;
	if (unicast_server_cb != NULL && unicast_server_cb->stop != NULL) {
		err = unicast_server_cb->stop(stream, &rsp);
	} else {
		err = -ENOTSUP;
		rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
				      BT_BAP_ASCS_REASON_NONE);
	}

	if (err) {
		ascs_app_rsp_warn_valid(&rsp);

		if (rsp.code == BT_BAP_ASCS_RSP_CODE_SUCCESS) {
			rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
					      BT_BAP_ASCS_REASON_NONE);
		}

		LOG_ERR("Stop failed: err %d, code %u, reason %u", err, rsp.code, rsp.reason);
		ascs_cp_rsp_add(ASE_ID(ase), rsp.code, rsp.reason);
		return;
	}

	/* If the Receiver Stop Ready operation has completed successfully the
	 * Unicast Client or the Unicast Server may terminate a CIS established
	 * for that ASE by following the Connected Isochronous Stream Terminate
	 * procedure defined in Volume 3, Part C, Section 9.3.15.
	 */
	if (bt_bap_stream_can_disconnect(stream)) {
		err = ascs_disconnect_stream(stream);
		if (err < 0) {
			LOG_ERR("Failed to disconnect stream %p: %d", stream, err);
		}
	}

	ascs_ep_set_state(ep, BT_BAP_EP_STATE_QOS_CONFIGURED);

	ascs_cp_rsp_success(ASE_ID(ase));
}

static bool is_valid_stop_len(struct net_buf_simple *buf)
{
	const struct bt_ascs_stop_op *op;
	struct net_buf_simple_state state;

	net_buf_simple_save(buf, &state);

	if (buf->len < sizeof(*op)) {
		LOG_WRN("Invalid length %u < %zu", buf->len, sizeof(*op));
		return false;
	}

	op = net_buf_simple_pull_mem(buf, sizeof(*op));
	if (op->num_ases < 1) {
		LOG_WRN("Number_of_ASEs parameter value is less than 1");
		return false;
	}

	if (buf->len != op->num_ases) {
		LOG_WRN("Number_of_ASEs mismatch");
		return false;
	}

	net_buf_simple_restore(buf, &state);

	return true;
}

static ssize_t ascs_stop(struct bt_conn *conn, struct net_buf_simple *buf)
{
	const struct bt_ascs_start_op *req;
	int i;

	if (!is_valid_stop_len(buf)) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
	}

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

	LOG_DBG("num_ases %u", req->num_ases);

	for (i = 0; i < req->num_ases; i++) {
		struct bt_ascs_ase *ase;
		uint8_t id;

		id = net_buf_simple_pull_u8(buf);

		LOG_DBG("ase 0x%02x", id);

		if (!is_valid_ase_id(id)) {
			ascs_cp_rsp_add(id, BT_BAP_ASCS_RSP_CODE_INVALID_ASE,
					BT_BAP_ASCS_REASON_NONE);
			LOG_WRN("Unknown ase 0x%02x", id);
			continue;
		}

		/* If the ASE_ID  written by the client represents a Sink ASE, the
		 * server shall not accept the Receiver Stop Ready operation for that
		 * ASE. The server shall send a notification of the ASE Control Point
		 * characteristic to the client, and the server shall set the
		 * Response_Code value for that ASE to 0x05 (Invalid ASE direction).
		 */
		if (ASE_DIR(id) == BT_AUDIO_DIR_SINK) {
			LOG_WRN("Stop failed: invalid operation for Sink");
			ascs_cp_rsp_add(id, BT_BAP_ASCS_RSP_CODE_INVALID_DIR,
					BT_BAP_ASCS_REASON_NONE);
			continue;
		}

		ase = ase_find(conn, id);
		if (!ase) {
			LOG_DBG("Invalid operation for idle ASE");
			ascs_cp_rsp_add(id, BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
					BT_BAP_ASCS_REASON_NONE);
			continue;
		}

		ase_stop(ase);
	}

	return buf->size;
}

static bool is_valid_metadata_len(struct net_buf_simple *buf)
{
	const struct bt_ascs_metadata_op *op;
	struct net_buf_simple_state state;

	net_buf_simple_save(buf, &state);

	if (buf->len < sizeof(*op)) {
		LOG_WRN("Invalid length %u < %zu", buf->len, sizeof(*op));
		return false;
	}

	op = net_buf_simple_pull_mem(buf, sizeof(*op));
	if (op->num_ases < 1) {
		LOG_WRN("Number_of_ASEs parameter value is less than 1");
		return false;
	}

	for (uint8_t i = 0U; i < op->num_ases; i++) {
		const struct bt_ascs_metadata *metadata;

		if (buf->len < sizeof(*metadata)) {
			LOG_WRN("Malformed params array");
			return false;
		}

		metadata = net_buf_simple_pull_mem(buf, sizeof(*metadata));
		if (buf->len < metadata->len) {
			LOG_WRN("Malformed metadata");
			return false;
		}

		(void)net_buf_simple_pull_mem(buf, metadata->len);
	}

	if (buf->len > 0) {
		LOG_WRN("Unexpected data");
		return false;
	}

	net_buf_simple_restore(buf, &state);

	return true;
}

static ssize_t ascs_metadata(struct bt_conn *conn, struct net_buf_simple *buf)
{
	const struct bt_ascs_metadata_op *req;
	struct bt_ascs_metadata *meta;
	int i;

	if (!is_valid_metadata_len(buf)) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
	}

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

	LOG_DBG("num_ases %u", req->num_ases);

	for (i = 0; i < req->num_ases; i++) {
		struct bt_ascs_ase *ase;

		meta = net_buf_simple_pull_mem(buf, sizeof(*meta));
		(void)net_buf_simple_pull(buf, meta->len);

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

			ascs_cp_rsp_add(meta->ase, BT_BAP_ASCS_RSP_CODE_NO_MEM,
					BT_BAP_ASCS_REASON_NONE);
			continue;
		}

		if (!is_valid_ase_id(meta->ase)) {
			ascs_cp_rsp_add(meta->ase, BT_BAP_ASCS_RSP_CODE_INVALID_ASE,
					BT_BAP_ASCS_REASON_NONE);
			LOG_WRN("Unknown ase 0x%02x", meta->ase);
			continue;
		}

		ase = ase_find(conn, meta->ase);
		if (!ase) {
			LOG_DBG("Invalid operation for idle ase 0x%02x", meta->ase);
			ascs_cp_rsp_add(meta->ase, BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
					BT_BAP_ASCS_REASON_NONE);
			continue;
		}

		ase_metadata(ase, meta);
	}

	return buf->size;
}

static bool is_valid_release_len(struct net_buf_simple *buf)
{
	const struct bt_ascs_release_op *op;
	struct net_buf_simple_state state;

	net_buf_simple_save(buf, &state);

	if (buf->len < sizeof(*op)) {
		LOG_WRN("Invalid length %u < %zu", buf->len, sizeof(*op));
		return false;
	}

	op = net_buf_simple_pull_mem(buf, sizeof(*op));
	if (op->num_ases < 1) {
		LOG_WRN("Number_of_ASEs parameter value is less than 1");
		return false;
	}

	if (buf->len != op->num_ases) {
		LOG_WRN("Number_of_ASEs mismatch");
		return false;
	}

	net_buf_simple_restore(buf, &state);

	return true;
}

static ssize_t ascs_release(struct bt_conn *conn, struct net_buf_simple *buf)
{
	const struct bt_ascs_release_op *req;
	int i;

	if (!is_valid_release_len(buf)) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
	}

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

	LOG_DBG("num_ases %u", req->num_ases);

	for (i = 0; i < req->num_ases; i++) {
		struct bt_bap_ascs_rsp rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_UNSPECIFIED,
							     BT_BAP_ASCS_REASON_NONE);
		struct bt_ascs_ase *ase;
		uint8_t id;

		id = net_buf_simple_pull_u8(buf);

		LOG_DBG("ase 0x%02x", id);

		if (!is_valid_ase_id(id)) {
			ascs_cp_rsp_add(id, BT_BAP_ASCS_RSP_CODE_INVALID_ASE,
					BT_BAP_ASCS_REASON_NONE);
			LOG_WRN("Unknown ase 0x%02x", id);
			continue;
		}

		ase = ase_find(conn, id);
		if (!ase) {
			LOG_DBG("Invalid operation for idle ASE");
			ascs_cp_rsp_add(id, BT_BAP_ASCS_RSP_CODE_INVALID_ASE_STATE,
					BT_BAP_ASCS_REASON_NONE);
			continue;
		}

		ase_release(ase, BT_HCI_ERR_REMOTE_USER_TERM_CONN, &rsp);
		ascs_cp_rsp_add(id, rsp.code, rsp.reason);
	}

	return buf->size;
}

static ssize_t ascs_cp_write(struct bt_conn *conn,
			     const struct bt_gatt_attr *attr, const void *data,
			     uint16_t len, uint16_t offset, uint8_t flags)
{
	const struct bt_ascs_ase_cp *req;
	struct net_buf_simple buf;
	ssize_t ret;

	if (flags & BT_GATT_WRITE_FLAG_PREPARE) {
		/* Return 0 to allow long writes */
		return 0;
	}

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

	if (len < sizeof(*req)) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
	}

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

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

	LOG_DBG("conn %p attr %p buf %p len %u op %s (0x%02x)",
		(void *)conn, attr, data, len, bt_ascs_op_str(req->op), req->op);

	ascs_cp_rsp_init(req->op);

	switch (req->op) {
	case BT_ASCS_CONFIG_OP:
		ret = ascs_config(conn, &buf);
		break;
	case BT_ASCS_QOS_OP:
		ret = ascs_qos(conn, &buf);
		break;
	case BT_ASCS_ENABLE_OP:
		ret = ascs_enable(conn, &buf);
		break;
	case BT_ASCS_START_OP:
		ret = ascs_start(conn, &buf);
		break;
	case BT_ASCS_DISABLE_OP:
		ret = ascs_disable(conn, &buf);
		break;
	case BT_ASCS_STOP_OP:
		ret = ascs_stop(conn, &buf);
		break;
	case BT_ASCS_METADATA_OP:
		ret = ascs_metadata(conn, &buf);
		break;
	case BT_ASCS_RELEASE_OP:
		ret = ascs_release(conn, &buf);
		break;
	default:
		ascs_cp_rsp_add(BT_ASCS_ASE_ID_NONE, BT_BAP_ASCS_RSP_CODE_NOT_SUPPORTED,
				BT_BAP_ASCS_REASON_NONE);
		LOG_DBG("Unknown opcode");
		goto respond;
	}

	if (ret == BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN)) {
		ascs_cp_rsp_add(BT_ASCS_ASE_ID_NONE, BT_BAP_ASCS_RSP_CODE_INVALID_LENGTH,
				BT_BAP_ASCS_REASON_NONE);
	}

respond:
	control_point_notify(conn, rsp_buf.data, rsp_buf.len);

	return len;
}

#define BT_ASCS_ASE_DEFINE(_uuid, _id) \
	BT_AUDIO_CHRC(_uuid, \
		      BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
		      BT_GATT_PERM_READ_ENCRYPT, \
		      ascs_ase_read, NULL, UINT_TO_POINTER(_id)), \
	BT_AUDIO_CCC(ascs_ase_cfg_changed)
#define BT_ASCS_ASE_SNK_DEFINE(_n, ...) BT_ASCS_ASE_DEFINE(BT_UUID_ASCS_ASE_SNK, (_n) + 1)
#define BT_ASCS_ASE_SRC_DEFINE(_n, ...) BT_ASCS_ASE_DEFINE(BT_UUID_ASCS_ASE_SRC, (_n) + 1 + \
							   CONFIG_BT_ASCS_ASE_SNK_COUNT)

BT_GATT_SERVICE_DEFINE(ascs_svc,
	BT_GATT_PRIMARY_SERVICE(BT_UUID_ASCS),
	BT_AUDIO_CHRC(BT_UUID_ASCS_ASE_CP,
		      BT_GATT_CHRC_WRITE | BT_GATT_CHRC_WRITE_WITHOUT_RESP | BT_GATT_CHRC_NOTIFY,
		      BT_GATT_PERM_WRITE_ENCRYPT | BT_GATT_PERM_PREPARE_WRITE,
		      NULL, ascs_cp_write, NULL),
	BT_AUDIO_CCC(ascs_cp_cfg_changed),
#if CONFIG_BT_ASCS_ASE_SNK_COUNT > 0
	LISTIFY(CONFIG_BT_ASCS_ASE_SNK_COUNT, BT_ASCS_ASE_SNK_DEFINE, (,)),
#endif /* CONFIG_BT_ASCS_ASE_SNK_COUNT > 0 */
#if CONFIG_BT_ASCS_ASE_SRC_COUNT > 0
	LISTIFY(CONFIG_BT_ASCS_ASE_SRC_COUNT, BT_ASCS_ASE_SRC_DEFINE, (,)),
#endif /* CONFIG_BT_ASCS_ASE_SRC_COUNT > 0 */
);

static int control_point_notify(struct bt_conn *conn, const void *data, uint16_t len)
{
	return bt_gatt_notify_uuid(conn, BT_UUID_ASCS_ASE_CP, ascs_svc.attrs, data, len);
}

static struct bt_iso_server iso_server = {
	.sec_level = BT_SECURITY_L2,
	.accept = ascs_iso_accept,
};

int bt_ascs_init(const struct bt_bap_unicast_server_cb *cb)
{
	int err;

	if (unicast_server_cb != NULL) {
		return -EALREADY;
	}

	err = bt_iso_server_register(&iso_server);
	if (err) {
		LOG_ERR("Failed to register ISO server %d", err);
		return err;
	}

	unicast_server_cb = cb;

	return 0;
}

void bt_ascs_cleanup(void)
{
	for (size_t i = 0; i < ARRAY_SIZE(ase_pool); i++) {
		struct bt_ascs_ase *ase = &ase_pool[i];

		if (ase->conn != NULL) {
			bt_ascs_release_ase(&ase->ep);
		}
	}

	if (unicast_server_cb != NULL) {
		bt_iso_server_unregister(&iso_server);
		unicast_server_cb = NULL;
	}
}
#endif /* BT_BAP_UNICAST_SERVER */
