/*  Bluetooth Audio Stream */

/*
 * Copyright (c) 2020 Intel Corporation
 * Copyright (c) 2021-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/iso.h>
#include <zephyr/bluetooth/audio/audio.h>
#include <zephyr/bluetooth/audio/bap.h>

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

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

#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(bt_bap_stream, CONFIG_BT_BAP_STREAM_LOG_LEVEL);

void bt_audio_codec_cfg_to_iso_path(struct bt_iso_chan_path *path,
				    struct bt_audio_codec_cfg *codec_cfg)
{
	path->pid = codec_cfg->path_id;
	path->format = codec_cfg->id;
	path->cid = codec_cfg->cid;
	path->vid = codec_cfg->vid;
	path->delay = 0; /* TODO: Add to bt_audio_codec_cfg? Use presentation delay? */
	path->cc_len = codec_cfg->data_len;
	path->cc = codec_cfg->data;
}

#if defined(CONFIG_BT_BAP_UNICAST_CLIENT) || defined(CONFIG_BT_BAP_BROADCAST_SOURCE) ||            \
	defined(CONFIG_BT_BAP_BROADCAST_SINK)
void bt_audio_codec_qos_to_iso_qos(struct bt_iso_chan_io_qos *io,
				   const struct bt_audio_codec_qos *codec_qos)
{
	io->sdu = codec_qos->sdu;
	io->phy = codec_qos->phy;
	io->rtn = codec_qos->rtn;
#if defined(CONFIG_BT_ISO_TEST_PARAMS)
	io->burst_number = codec_qos->burst_number;
	io->max_pdu = codec_qos->max_pdu;
#endif /* CONFIG_BT_ISO_TEST_PARAMS */
}
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT ||                                                          \
	* CONFIG_BT_BAP_BROADCAST_SOURCE ||                                                        \
	* CONFIG_BT_BAP_BROADCAST_SINK                                                             \
	*/

void bt_bap_stream_init(struct bt_bap_stream *stream)
{
	struct bt_bap_stream_ops *ops;
	void *user_data;

	/* Save the stream->ops and stream->user_data owned by API user */
	ops = stream->ops;
	user_data = stream->user_data;

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

	/* Restore */
	stream->ops = ops;
	stream->user_data = user_data;
}

void bt_bap_stream_attach(struct bt_conn *conn, struct bt_bap_stream *stream, struct bt_bap_ep *ep,
			  struct bt_audio_codec_cfg *codec_cfg)
{
	LOG_DBG("conn %p stream %p ep %p codec_cfg %p", (void *)conn, stream, ep, codec_cfg);

	if (conn != NULL) {
		__ASSERT(stream->conn == NULL || stream->conn == conn,
			 "stream->conn %p already attached", (void *)stream->conn);
		if (stream->conn == NULL) {
			stream->conn = bt_conn_ref(conn);
		}
	}
	stream->codec_cfg = codec_cfg;
	stream->ep = ep;
	ep->stream = stream;
}

struct bt_iso_chan *bt_bap_stream_iso_chan_get(struct bt_bap_stream *stream)
{
	if (stream != NULL && stream->ep != NULL && stream->ep->iso != NULL) {
		return &stream->ep->iso->chan;
	}

	return NULL;
}

void bt_bap_stream_cb_register(struct bt_bap_stream *stream,
				 struct bt_bap_stream_ops *ops)
{
	stream->ops = ops;
}

int bt_bap_ep_get_info(const struct bt_bap_ep *ep, struct bt_bap_ep_info *info)
{
	enum bt_audio_dir dir = ep->dir;

	info->id = ep->status.id;
	info->state = ep->status.state;
	info->dir = dir;

	if (ep->iso == NULL) {
		info->paired_ep = NULL;
	} else {
		info->paired_ep = bt_bap_iso_get_paired_ep(ep);
	}

	info->can_send = false;
	if (IS_ENABLED(CONFIG_BT_AUDIO_TX) && ep->stream != NULL) {
		if (IS_ENABLED(CONFIG_BT_BAP_BROADCAST_SOURCE) && bt_bap_ep_is_broadcast_src(ep)) {
			info->can_send = true;
		} else if (IS_ENABLED(CONFIG_BT_CONN) && ep->stream->conn != NULL) {
			struct bt_conn_info conn_info;
			uint8_t role;
			int err;

			err = bt_conn_get_info(ep->stream->conn, &conn_info);
			if (err != 0) {
				LOG_DBG("Could not get conn info: %d", err);

				return err;
			}

			role = conn_info.role;
			if ((role == BT_CONN_ROLE_CENTRAL && dir == BT_AUDIO_DIR_SINK) ||
			    (role == BT_CONN_ROLE_PERIPHERAL && dir == BT_AUDIO_DIR_SOURCE)) {
				info->can_send = true;
			}
		}
	}

	return 0;
}

enum bt_bap_ascs_reason bt_audio_verify_qos(const struct bt_audio_codec_qos *qos)
{
	if (qos->interval < BT_ISO_SDU_INTERVAL_MIN ||
	    qos->interval > BT_ISO_SDU_INTERVAL_MAX) {
		LOG_DBG("Interval not within allowed range: %u (%u-%u)", qos->interval,
			BT_ISO_SDU_INTERVAL_MIN, BT_ISO_SDU_INTERVAL_MAX);
		return BT_BAP_ASCS_REASON_INTERVAL;
	}

	if (qos->framing > BT_AUDIO_CODEC_QOS_FRAMING_FRAMED) {
		LOG_DBG("Invalid Framing 0x%02x", qos->framing);
		return BT_BAP_ASCS_REASON_FRAMING;
	}

	if (qos->phy != BT_AUDIO_CODEC_QOS_1M &&
	    qos->phy != BT_AUDIO_CODEC_QOS_2M &&
	    qos->phy != BT_AUDIO_CODEC_QOS_CODED) {
		LOG_DBG("Invalid PHY 0x%02x", qos->phy);
		return BT_BAP_ASCS_REASON_PHY;
	}

	if (qos->sdu > BT_ISO_MAX_SDU) {
		LOG_DBG("Invalid SDU %u", qos->sdu);
		return BT_BAP_ASCS_REASON_SDU;
	}

#if defined(CONFIG_BT_BAP_BROADCAST_SOURCE) || defined(CONFIG_BT_BAP_UNICAST)
	if (qos->latency < BT_ISO_LATENCY_MIN ||
	    qos->latency > BT_ISO_LATENCY_MAX) {
		LOG_DBG("Invalid Latency %u", qos->latency);
		return BT_BAP_ASCS_REASON_LATENCY;
	}
#endif /* CONFIG_BT_BAP_BROADCAST_SOURCE || CONFIG_BT_BAP_UNICAST */

	if (qos->pd > BT_AUDIO_PD_MAX) {
		LOG_DBG("Invalid presentation delay %u", qos->pd);
		return BT_BAP_ASCS_REASON_PD;
	}

	return BT_BAP_ASCS_REASON_NONE;
}

bool bt_audio_valid_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg)
{
	if (codec_cfg == NULL) {
		LOG_DBG("codec is NULL");
		return false;
	}

	if (codec_cfg->id == BT_HCI_CODING_FORMAT_LC3) {
		if (codec_cfg->cid != 0U) {
			LOG_DBG("codec_cfg->cid (%u) is invalid", codec_cfg->cid);
			return false;
		}

		if (codec_cfg->vid != 0U) {
			LOG_DBG("codec_cfg->vid (%u) is invalid", codec_cfg->vid);
			return false;
		}
	}

#if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0
	/* Verify that codec configuration length is 0 when using
	 * BT_HCI_CODING_FORMAT_TRANSPARENT as per the core spec, 5.4, Vol 4, Part E, 7.8.109
	 */
	if (codec_cfg->id == BT_HCI_CODING_FORMAT_TRANSPARENT && codec_cfg->data_len != 0) {
		LOG_DBG("Invalid data_len %zu for codec_id %u", codec_cfg->data_len, codec_cfg->id);
		return false;
	}

	if (codec_cfg->data_len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE) {
		LOG_DBG("codec_cfg->data_len (%zu) is invalid", codec_cfg->data_len);
		return false;
	}
#endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */

#if CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0
	if (codec_cfg->meta_len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE) {
		LOG_DBG("codec_cfg->meta_len (%zu) is invalid", codec_cfg->meta_len);
		return false;
	}
#endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 */

	return true;
}

#if defined(CONFIG_BT_AUDIO_TX)
static bool bt_bap_stream_can_send(const struct bt_bap_stream *stream)
{
	struct bt_bap_ep_info info;
	int err;

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

	err = bt_bap_ep_get_info(stream->ep, &info);
	if (err != 0) {
		return false;
	}

	return info.can_send;
}

int bt_bap_stream_send(struct bt_bap_stream *stream, struct net_buf *buf,
			 uint16_t seq_num, uint32_t ts)
{
	struct bt_bap_ep *ep;

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

	if (!bt_bap_stream_can_send(stream)) {
		LOG_DBG("Stream is not configured for TX");

		return -EINVAL;
	}

	ep = stream->ep;

	if (ep->status.state != BT_BAP_EP_STATE_STREAMING) {
		LOG_DBG("Channel %p not ready for streaming (state: %s)", stream,
			bt_bap_ep_state_str(ep->status.state));
		return -EBADMSG;
	}

#if defined(CONFIG_BT_BAP_DEBUG_STREAM_SEQ_NUM)
	if (stream->_prev_seq_num != 0U && seq_num != 0U &&
	    (stream->_prev_seq_num + 1U) != seq_num) {
		LOG_WRN("Unexpected seq_num diff between %u and %u for %p", stream->_prev_seq_num,
			seq_num, stream);
	}

	stream->_prev_seq_num = seq_num;
#endif /* CONFIG_BT_BAP_DEBUG_STREAM_SEQ_NUM */

	/* TODO: Add checks for broadcast sink */

	return bt_iso_chan_send(bt_bap_stream_iso_chan_get(stream),
				buf, seq_num, ts);
}

int bt_bap_stream_get_tx_sync(struct bt_bap_stream *stream, struct bt_iso_tx_info *info)
{
	struct bt_iso_chan *iso_chan;

	CHECKIF(stream == NULL) {
		LOG_DBG("stream is null");

		return -EINVAL;
	}

	CHECKIF(info == NULL) {
		LOG_DBG("info is null");

		return -EINVAL;
	}

	if (!bt_bap_stream_can_send(stream)) {
		LOG_DBG("Stream is not configured for TX");

		return -EINVAL;
	}

	iso_chan = bt_bap_stream_iso_chan_get(stream);
	if (iso_chan == NULL) {
		LOG_DBG("Could not get iso channel from stream %p", stream);
		return -EINVAL;
	}

	return bt_iso_chan_get_tx_sync(iso_chan, info);
}
#endif /* CONFIG_BT_AUDIO_TX */

#if defined(CONFIG_BT_BAP_UNICAST)

/** Checks if the stream can terminate the CIS
 *
 * If the CIS is used for another stream, or if the CIS is not in the connected
 * state it will return false.
 */
bool bt_bap_stream_can_disconnect(const struct bt_bap_stream *stream)
{
	const struct bt_bap_ep *stream_ep;
	enum bt_iso_state iso_state;

	if (stream == NULL) {
		return false;
	}

	stream_ep = stream->ep;

	if (stream_ep == NULL || stream_ep->iso == NULL) {
		return false;
	}

	iso_state = stream_ep->iso->chan.state;

	if (iso_state == BT_ISO_STATE_CONNECTED || iso_state == BT_ISO_STATE_CONNECTING) {
		const struct bt_bap_ep *pair_ep;

		pair_ep = bt_bap_iso_get_paired_ep(stream_ep);

		/* If there are no paired endpoint, or the paired endpoint is
		 * not in the streaming state, we can disconnect the CIS
		 */
		if (pair_ep == NULL || pair_ep->status.state != BT_BAP_EP_STATE_STREAMING) {
			return true;
		}
	}

	return false;
}

static bool bt_bap_stream_is_broadcast(const struct bt_bap_stream *stream)
{
	return (IS_ENABLED(CONFIG_BT_BAP_BROADCAST_SOURCE) &&
		bt_bap_ep_is_broadcast_src(stream->ep)) ||
	       (IS_ENABLED(CONFIG_BT_BAP_BROADCAST_SINK) && bt_bap_ep_is_broadcast_snk(stream->ep));
}

enum bt_bap_ascs_reason bt_bap_stream_verify_qos(const struct bt_bap_stream *stream,
						 const struct bt_audio_codec_qos *qos)
{
	const struct bt_audio_codec_qos_pref *qos_pref = &stream->ep->qos_pref;

	if (qos_pref->latency < qos->latency) {
		/* Latency is a preferred value. Print debug info but do not fail. */
		LOG_DBG("Latency %u higher than preferred max %u", qos->latency, qos_pref->latency);
	}

	if (!IN_RANGE(qos->pd, qos_pref->pd_min, qos_pref->pd_max)) {
		LOG_DBG("Presentation Delay not within range: min %u max %u pd %u",
			qos_pref->pd_min, qos_pref->pd_max, qos->pd);
		return BT_BAP_ASCS_REASON_PD;
	}

	return BT_BAP_ASCS_REASON_NONE;
}

void bt_bap_stream_detach(struct bt_bap_stream *stream)
{
	const bool is_broadcast = bt_bap_stream_is_broadcast(stream);

	LOG_DBG("stream %p", stream);

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

	if (!is_broadcast) {
		bt_bap_stream_disconnect(stream);
	}
}

int bt_bap_stream_disconnect(struct bt_bap_stream *stream)
{
	struct bt_iso_chan *iso_chan = bt_bap_stream_iso_chan_get(stream);

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

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

	if (iso_chan == NULL || iso_chan->iso == NULL) {
		return -ENOTCONN;
	}

	return bt_iso_chan_disconnect(iso_chan);
}

void bt_bap_stream_reset(struct bt_bap_stream *stream)
{
	LOG_DBG("stream %p", stream);

	if (stream == NULL) {
		return;
	}

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

	bt_bap_stream_detach(stream);
}

static uint8_t conn_get_role(const struct bt_conn *conn)
{
	struct bt_conn_info info;
	int err;

	err = bt_conn_get_info(conn, &info);
	__ASSERT(err == 0, "Failed to get conn info");

	return info.role;
}

#if defined(CONFIG_BT_BAP_UNICAST_CLIENT)

int bt_bap_stream_config(struct bt_conn *conn, struct bt_bap_stream *stream, struct bt_bap_ep *ep,
			 struct bt_audio_codec_cfg *codec_cfg)
{
	uint8_t role;
	int err;

	LOG_DBG("conn %p stream %p, ep %p codec_cfg %p codec id 0x%02x "
	       "codec cid 0x%04x codec vid 0x%04x", (void *)conn, stream, ep,
	       codec_cfg, codec_cfg ? codec_cfg->id : 0, codec_cfg ? codec_cfg->cid : 0,
	       codec_cfg ? codec_cfg->vid : 0);

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

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

	role = conn_get_role(conn);
	if (role != BT_HCI_ROLE_CENTRAL) {
		LOG_DBG("Invalid conn role: %u, shall be central", role);
		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 -EBADMSG;
	}

	bt_bap_stream_attach(conn, stream, ep, codec_cfg);

	err = bt_bap_unicast_client_config(stream, codec_cfg);
	if (err != 0) {
		LOG_DBG("Failed to configure stream: %d", err);
		return err;
	}

	return 0;
}

int bt_bap_stream_qos(struct bt_conn *conn, struct bt_bap_unicast_group *group)
{
	uint8_t role;
	int err;

	LOG_DBG("conn %p group %p", (void *)conn, group);

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

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

	if (sys_slist_is_empty(&group->streams)) {
		LOG_DBG("group stream list is empty");
		return -ENOEXEC;
	}

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

	err = bt_bap_unicast_client_qos(conn, group);
	if (err != 0) {
		LOG_DBG("Failed to configure stream: %d", err);
		return err;
	}

	return 0;
}

int bt_bap_stream_enable(struct bt_bap_stream *stream, const uint8_t meta[], size_t meta_len)
{
	uint8_t role;
	int err;

	LOG_DBG("stream %p", stream);

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

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

	/* Valid for an ASE only if ASE_State field = 0x02 (QoS Configured) */
	if (stream->ep->status.state != BT_BAP_EP_STATE_QOS_CONFIGURED) {
		LOG_ERR("Invalid state: %s", bt_bap_ep_state_str(stream->ep->status.state));
		return -EBADMSG;
	}

	err = bt_bap_unicast_client_enable(stream, meta, meta_len);
	if (err != 0) {
		LOG_DBG("Failed to enable stream: %d", err);
		return err;
	}

	return 0;
}

int bt_bap_stream_stop(struct bt_bap_stream *stream)
{
	struct bt_bap_ep *ep;
	uint8_t role;
	int err;

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

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

	ep = stream->ep;

	switch (ep->status.state) {
	/* Valid only if ASE_State field = 0x03 (Disabling) */
	case BT_BAP_EP_STATE_DISABLING:
		break;
	default:
		LOG_ERR("Invalid state: %s", bt_bap_ep_state_str(ep->status.state));
		return -EBADMSG;
	}

	err = bt_bap_unicast_client_stop(stream);
	if (err != 0) {
		LOG_DBG("Stopping stream failed: %d", err);
		return err;
	}

	return 0;
}
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT */

int bt_bap_stream_reconfig(struct bt_bap_stream *stream,
			     struct bt_audio_codec_cfg *codec_cfg)
{
	uint8_t state;
	uint8_t role;
	int err;

	LOG_DBG("stream %p codec_cfg %p", stream, codec_cfg);

	CHECKIF(stream == NULL || stream->ep == NULL || stream->conn == NULL) {
		LOG_DBG("Invalid stream");
		return -EINVAL;
	}

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

	state = stream->ep->status.state;
	switch (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(state));
		return -EBADMSG;
	}

	role = conn_get_role(stream->conn);
	if (IS_ENABLED(CONFIG_BT_BAP_UNICAST_CLIENT) && role == BT_HCI_ROLE_CENTRAL) {
		err = bt_bap_unicast_client_config(stream, codec_cfg);
	} else if (IS_ENABLED(CONFIG_BT_BAP_UNICAST_SERVER) && role == BT_HCI_ROLE_PERIPHERAL) {
		err = bt_bap_unicast_server_reconfig(stream, codec_cfg);
	} else {
		err = -EOPNOTSUPP;
	}

	if (err != 0) {
		LOG_DBG("reconfiguring stream failed: %d", err);
	} else {
		stream->codec_cfg = codec_cfg;
	}

	return 0;
}

int bt_bap_stream_start(struct bt_bap_stream *stream)
{
	uint8_t state;
	uint8_t role;
	int err;

	LOG_DBG("stream %p ep %p", stream, stream == NULL ? NULL : stream->ep);

	CHECKIF(stream == NULL || stream->ep == NULL || stream->conn == NULL) {
		LOG_DBG("Invalid stream");
		return -EINVAL;
	}

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

	role = conn_get_role(stream->conn);
	if (IS_ENABLED(CONFIG_BT_BAP_UNICAST_CLIENT) && role == BT_HCI_ROLE_CENTRAL) {
		err = bt_bap_unicast_client_start(stream);
	} else if (IS_ENABLED(CONFIG_BT_BAP_UNICAST_SERVER) && role == BT_HCI_ROLE_PERIPHERAL) {
		err = bt_bap_unicast_server_start(stream);
	} else {
		err = -EOPNOTSUPP;
	}

	if (err != 0) {
		LOG_DBG("Starting stream failed: %d", err);
		return err;
	}

	return 0;
}

int bt_bap_stream_metadata(struct bt_bap_stream *stream, const uint8_t meta[], size_t meta_len)
{
	uint8_t state;
	uint8_t role;
	int err;

	LOG_DBG("stream %p meta_len %zu", stream, meta_len);

	CHECKIF(stream == NULL || stream->ep == NULL || stream->conn == NULL) {
		LOG_DBG("Invalid stream");
		return -EINVAL;
	}

	CHECKIF((meta == NULL && meta_len != 0U) || (meta != NULL && meta_len == 0U)) {
		LOG_DBG("Invalid meta (%p) or len (%zu)", meta, meta_len);
		return -EINVAL;
	}

	state = stream->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_ERR("Invalid state: %s", bt_bap_ep_state_str(state));
		return -EBADMSG;
	}

	role = conn_get_role(stream->conn);
	if (IS_ENABLED(CONFIG_BT_BAP_UNICAST_CLIENT) && role == BT_HCI_ROLE_CENTRAL) {
		err = bt_bap_unicast_client_metadata(stream, meta, meta_len);
	} else if (IS_ENABLED(CONFIG_BT_BAP_UNICAST_SERVER) && role == BT_HCI_ROLE_PERIPHERAL) {
		err = bt_bap_unicast_server_metadata(stream, meta, meta_len);
	} else {
		err = -EOPNOTSUPP;
	}

	if (err != 0) {
		LOG_DBG("Updating metadata failed: %d", err);
		return err;
	}

	return 0;
}

int bt_bap_stream_disable(struct bt_bap_stream *stream)
{
	uint8_t state;
	uint8_t role;
	int err;

	LOG_DBG("stream %p", stream);

	CHECKIF(stream == NULL || stream->ep == NULL || stream->conn == NULL) {
		LOG_DBG("Invalid stream");
		return -EINVAL;
	}

	state = stream->ep->status.state;
	switch (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(state));
		return -EBADMSG;
	}

	role = conn_get_role(stream->conn);
	if (IS_ENABLED(CONFIG_BT_BAP_UNICAST_CLIENT) && role == BT_HCI_ROLE_CENTRAL) {
		err = bt_bap_unicast_client_disable(stream);
	} else if (IS_ENABLED(CONFIG_BT_BAP_UNICAST_SERVER) && role == BT_HCI_ROLE_PERIPHERAL) {
		err = bt_bap_unicast_server_disable(stream);
	} else {
		err = -EOPNOTSUPP;
	}

	if (err != 0) {
		LOG_DBG("Disabling stream failed: %d", err);
		return err;
	}

	return 0;
}

int bt_bap_stream_release(struct bt_bap_stream *stream)
{
	uint8_t state;
	uint8_t role;
	int err;

	LOG_DBG("stream %p", stream);

	CHECKIF(stream == NULL || stream->ep == NULL || stream->conn == NULL) {
		LOG_DBG("Invalid stream (ep %p, conn %p)", stream->ep, (void *)stream->conn);
		return -EINVAL;
	}

	state = stream->ep->status.state;
	switch (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 0x04 (Disabling) */
	case BT_BAP_EP_STATE_DISABLING:
		break;
	default:
		LOG_ERR("Invalid state: %s", bt_bap_ep_state_str(state));
		return -EBADMSG;
	}

	role = conn_get_role(stream->conn);
	if (IS_ENABLED(CONFIG_BT_BAP_UNICAST_CLIENT) && role == BT_HCI_ROLE_CENTRAL) {
		err = bt_bap_unicast_client_release(stream);
	} else if (IS_ENABLED(CONFIG_BT_BAP_UNICAST_SERVER) && role == BT_HCI_ROLE_PERIPHERAL) {
		err = bt_bap_unicast_server_release(stream);
	} else {
		err = -EOPNOTSUPP;
	}

	if (err != 0) {
		LOG_DBG("Releasing stream failed: %d", err);
		return err;
	}

	return 0;
}
#endif /* CONFIG_BT_BAP_UNICAST */
