/*  Bluetooth BAP Broadcast Assistant */

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

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

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

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/bluetooth/att.h>
#include <zephyr/bluetooth/l2cap.h>
#include <zephyr/bluetooth/buf.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/check.h>

#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(bt_bap_broadcast_assistant, CONFIG_BT_BAP_BROADCAST_ASSISTANT_LOG_LEVEL);

#include "common/bt_str.h"

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

#define MINIMUM_RECV_STATE_LEN          15

struct bap_broadcast_assistant_instance {
	struct bt_conn *conn;
	bool scanning;
	uint8_t pa_sync;
	uint8_t recv_state_cnt;
	/* Source ID cache so that we can notify application about
	 * which source ID was removed
	 */
	uint8_t src_ids[CONFIG_BT_BAP_BROADCAST_ASSISTANT_RECV_STATE_COUNT];
	/** Cached PAST available */
	bool past_avail[CONFIG_BT_BAP_BROADCAST_ASSISTANT_RECV_STATE_COUNT];

	uint16_t start_handle;
	uint16_t end_handle;
	uint16_t cp_handle;
	uint16_t recv_state_handles[CONFIG_BT_BAP_BROADCAST_ASSISTANT_RECV_STATE_COUNT];

	bool busy;
	struct bt_gatt_subscribe_params recv_state_sub_params
		[CONFIG_BT_BAP_BROADCAST_ASSISTANT_RECV_STATE_COUNT];
	struct bt_gatt_discover_params recv_state_disc_params
		[CONFIG_BT_BAP_BROADCAST_ASSISTANT_RECV_STATE_COUNT];
	struct bt_gatt_read_params read_params;
	struct bt_gatt_write_params write_params;
	struct bt_gatt_discover_params disc_params;

	struct k_work_delayable bap_read_work;
	uint16_t long_read_handle;
};

static sys_slist_t broadcast_assistant_cbs = SYS_SLIST_STATIC_INIT(&broadcast_assistant_cbs);

static struct bap_broadcast_assistant_instance broadcast_assistant;
static struct bt_uuid_16 uuid = BT_UUID_INIT_16(0);

#define ATT_BUF_SIZE BT_ATT_MAX_ATTRIBUTE_LEN
NET_BUF_SIMPLE_DEFINE_STATIC(att_buf, ATT_BUF_SIZE);

static int16_t lookup_index_by_handle(uint16_t handle)
{
	for (int i = 0; i < ARRAY_SIZE(broadcast_assistant.recv_state_handles); i++) {
		if (broadcast_assistant.recv_state_handles[i] == handle) {
			return i;
		}
	}

	LOG_ERR("Unknown handle 0x%04x", handle);

	return -1;
}

static void bap_broadcast_assistant_discover_complete(struct bt_conn *conn, int err,
						      uint8_t recv_state_count)
{
	struct bt_bap_broadcast_assistant_cb *listener, *next;

	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&broadcast_assistant_cbs,
					  listener, next, _node) {
		if (listener->discover) {
			listener->discover(conn, err, recv_state_count);
		}
	}
}

static void bap_broadcast_assistant_recv_state_changed(
	struct bt_conn *conn, int err, const struct bt_bap_scan_delegator_recv_state *state)
{
	struct bt_bap_broadcast_assistant_cb *listener, *next;

	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&broadcast_assistant_cbs,
					  listener, next, _node) {
		if (listener->recv_state) {
			listener->recv_state(conn, err, state);
		}
	}
}

static void bap_broadcast_assistant_recv_state_removed(struct bt_conn *conn, int err,
						       uint8_t src_id)
{
	struct bt_bap_broadcast_assistant_cb *listener, *next;

	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&broadcast_assistant_cbs,
					  listener, next, _node) {
		if (listener->recv_state_removed) {
			listener->recv_state_removed(conn, err, src_id);
		}
	}
}

static void bap_broadcast_assistant_scan_results(const struct bt_le_scan_recv_info *info,
						 uint32_t broadcast_id)
{
	struct bt_bap_broadcast_assistant_cb *listener, *next;

	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&broadcast_assistant_cbs, listener, next, _node) {
		if (listener->scan) {
			listener->scan(info, broadcast_id);
		}
	}
}

static bool past_available(const struct bt_conn *conn,
			   const bt_addr_le_t *adv_addr,
			   uint8_t sid)
{
	LOG_DBG("%p remote %s PAST, local %s PAST", (void *)conn,
		BT_FEAT_LE_PAST_RECV(conn->le.features) ? "supports" : "does not support",
		BT_FEAT_LE_PAST_SEND(bt_dev.le.features) ? "supports" : "does not support");

	return BT_FEAT_LE_PAST_RECV(conn->le.features) &&
	       BT_FEAT_LE_PAST_SEND(bt_dev.le.features) &&
	       bt_le_per_adv_sync_lookup_addr(adv_addr, sid) != NULL;
}

static int parse_recv_state(const void *data, uint16_t length,
			    struct bt_bap_scan_delegator_recv_state *recv_state)
{
	struct net_buf_simple buf;
	bt_addr_t *addr;

	__ASSERT(recv_state, "NULL receive state");

	if (data == NULL || length == 0) {
		LOG_DBG("NULL data");
		return -EINVAL;
	}

	if (length < MINIMUM_RECV_STATE_LEN) {
		LOG_DBG("Invalid receive state length %u, expected at least %u",
			length, MINIMUM_RECV_STATE_LEN);
		return -EINVAL;
	}

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

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

	recv_state->src_id = net_buf_simple_pull_u8(&buf);
	recv_state->addr.type = net_buf_simple_pull_u8(&buf);
	addr = net_buf_simple_pull_mem(&buf, sizeof(*addr));
	bt_addr_copy(&recv_state->addr.a, addr);
	recv_state->adv_sid = net_buf_simple_pull_u8(&buf);
	recv_state->broadcast_id = net_buf_simple_pull_le24(&buf);
	recv_state->pa_sync_state = net_buf_simple_pull_u8(&buf);
	recv_state->encrypt_state = net_buf_simple_pull_u8(&buf);
	if (recv_state->encrypt_state == BT_BAP_BIG_ENC_STATE_BAD_CODE) {
		uint8_t *broadcast_code;
		const size_t minimum_size = sizeof(recv_state->bad_code) +
					    sizeof(recv_state->num_subgroups);

		if (buf.len < minimum_size) {
			LOG_DBG("Invalid receive state length %u, expected at least %zu",
			       buf.len, minimum_size);
			return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
		}

		broadcast_code = net_buf_simple_pull_mem(&buf,
							 BT_AUDIO_BROADCAST_CODE_SIZE);
		(void)memcpy(recv_state->bad_code, broadcast_code,
			     sizeof(recv_state->bad_code));
	}

	recv_state->num_subgroups = net_buf_simple_pull_u8(&buf);
	for (int i = 0; i < recv_state->num_subgroups; i++) {
		struct bt_bap_bass_subgroup *subgroup = &recv_state->subgroups[i];
		uint8_t *metadata;

		if (buf.len < sizeof(subgroup->bis_sync)) {
			LOG_DBG("Invalid receive state length %u, expected at least %zu",
			       buf.len, buf.len + sizeof(subgroup->bis_sync));
			return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
		}

		subgroup->bis_sync = net_buf_simple_pull_le32(&buf);

		if (buf.len < sizeof(subgroup->metadata_len)) {
			LOG_DBG("Invalid receive state length %u, expected at least %zu",
			       buf.len, buf.len + sizeof(subgroup->metadata_len));
			return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
		}
		subgroup->metadata_len = net_buf_simple_pull_u8(&buf);

		if (buf.len < subgroup->metadata_len) {
			LOG_DBG("Invalid receive state length %u, expected at least %u",
			       buf.len, buf.len + subgroup->metadata_len);
			return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
		}

		if (subgroup->metadata_len > sizeof(subgroup->metadata)) {
			LOG_DBG("Metadata too long: %u/%zu",
			       subgroup->metadata_len,
			       sizeof(subgroup->metadata));
			return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
		}

		metadata = net_buf_simple_pull_mem(&buf,
						   subgroup->metadata_len);
		(void)memcpy(subgroup->metadata, metadata,
			     subgroup->metadata_len);
	}

	if (buf.len != 0) {
		LOG_DBG("Invalid receive state length %u, but only %u was parsed",
		       length, length - buf.len);
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
	}

	return 0;
}

static void bap_long_op_reset(void)
{
	broadcast_assistant.busy = false;
	broadcast_assistant.long_read_handle = 0;
	net_buf_simple_reset(&att_buf);
}

static uint8_t parse_and_send_recv_state(struct bt_conn *conn, uint16_t handle,
					 const void *data, uint16_t length,
					 struct bt_bap_scan_delegator_recv_state *recv_state)
{
	int err;
	int16_t index;

	err = parse_recv_state(data, length, recv_state);
	if (err != 0) {
		LOG_WRN("Invalid receive state received");

		return BT_GATT_ITER_STOP;
	}

	index = lookup_index_by_handle(handle);
	if (index < 0) {
		LOG_DBG("Invalid index");

		return BT_GATT_ITER_STOP;
	}

	broadcast_assistant.src_ids[index] = recv_state->src_id;
	broadcast_assistant.past_avail[index] = past_available(conn,
							       &recv_state->addr,
							       recv_state->adv_sid);

	bap_broadcast_assistant_recv_state_changed(conn, 0, recv_state);

	return BT_GATT_ITER_CONTINUE;
}

static uint8_t broadcast_assistant_bap_ntf_read_func(struct bt_conn *conn, uint8_t err,
						     struct bt_gatt_read_params *read,
						     const void *data, uint16_t length)
{
	struct bt_bap_scan_delegator_recv_state recv_state;
	uint16_t handle = read->single.handle;
	uint16_t data_length;

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

	if (err) {
		LOG_DBG("Failed to read: %u", err);
		memset(read, 0, sizeof(*read));
		bap_long_op_reset();

		return BT_GATT_ITER_STOP;
	}

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

	if (data != NULL) {
		if (net_buf_simple_tailroom(&att_buf) < length) {
			LOG_DBG("Buffer full, invalid server response of size %u",
				length + att_buf.len);
			memset(read, 0, sizeof(*read));
			bap_long_op_reset();

			return BT_GATT_ITER_STOP;
		}

		/* store data*/
		net_buf_simple_add_mem(&att_buf, data, length);

		return BT_GATT_ITER_CONTINUE;
	}

	/* we reset the buffer so that it is ready for new data */
	memset(read, 0, sizeof(*read));
	data_length = att_buf.len;
	bap_long_op_reset();

	/* do the parse and callback to send  notify to application*/
	parse_and_send_recv_state(conn, handle,
				  att_buf.data, data_length, &recv_state);

	return BT_GATT_ITER_STOP;
}

static void long_bap_read(struct bt_conn *conn, uint16_t handle)
{
	int err;

	LOG_DBG("conn %p busy %u", conn, broadcast_assistant.busy);

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

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

			conn_info.le.interval = BT_GAP_INIT_CONN_INT_MIN;
		}

		/* Wait a connection interval to retry */
		err = k_work_reschedule(&broadcast_assistant.bap_read_work,
					K_USEC(BT_CONN_INTERVAL_TO_US(conn_info.le.interval)));
		if (err < 0) {
			LOG_DBG("Failed to reschedule read work: %d", err);
			bap_long_op_reset();
		}

		return;
	}

	broadcast_assistant.read_params.func = broadcast_assistant_bap_ntf_read_func;
	broadcast_assistant.read_params.handle_count = 1U;
	broadcast_assistant.read_params.single.handle = handle;
	broadcast_assistant.read_params.single.offset = att_buf.len;

	err = bt_gatt_read(conn, &broadcast_assistant.read_params);
	if (err != 0) {
		LOG_DBG("Failed to read: %d", err);
		bap_long_op_reset();
	} else {
		broadcast_assistant.busy = true;
	}
}

static void delayed_bap_read_handler(struct k_work *work)
{
	long_bap_read(broadcast_assistant.conn, broadcast_assistant.long_read_handle);
}

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

	if (data == NULL) {
		LOG_DBG("[UNSUBSCRIBED] %u", handle);
		params->value_handle = 0U;

		return BT_GATT_ITER_STOP;
	}

	LOG_HEXDUMP_DBG(data, length, "Receive state notification:");

	index = lookup_index_by_handle(handle);
	if (index < 0) {
		LOG_DBG("Invalid index");

		return BT_GATT_ITER_STOP;
	}

	if (length != 0) {
		const uint8_t att_ntf_header_size = 3; /* opcode (1) + handle (2) */
		uint16_t max_ntf_size;

		/* Cancel any pending long reads containing now obsolete information */
		(void)k_work_cancel_delayable(&broadcast_assistant.bap_read_work);

		if (conn != NULL) {
			max_ntf_size = bt_gatt_get_mtu(conn) - att_ntf_header_size;
		} else {
			max_ntf_size = MIN(BT_L2CAP_RX_MTU, BT_L2CAP_TX_MTU) - att_ntf_header_size;
		}

		if (length == max_ntf_size) {
			/* TODO: if we are busy we should not overwrite the long_read_handle,
			 * we'll have to keep track of the handle and parameters separately
			 * for each characteristic, similar to the bt_bap_unicast_client_ep
			 * struct for the unicast client
			 */
			broadcast_assistant.long_read_handle = handle;

			if (!broadcast_assistant.busy) {
				net_buf_simple_add_mem(&att_buf, data, length);
			}
			long_bap_read(conn, handle);
		} else {
			return parse_and_send_recv_state(conn, handle, data, length, &recv_state);
		}
	} else {
		broadcast_assistant.past_avail[index] = false;
		bap_broadcast_assistant_recv_state_removed(conn, 0,
							   broadcast_assistant.src_ids[index]);
	}

	return BT_GATT_ITER_CONTINUE;
}

static uint8_t read_recv_state_cb(struct bt_conn *conn, uint8_t err,
				  struct bt_gatt_read_params *params,
				  const void *data, uint16_t length)
{
	uint16_t handle = params->single.handle;
	uint8_t last_handle_index = broadcast_assistant.recv_state_cnt - 1;
	uint16_t last_handle = broadcast_assistant.recv_state_handles[last_handle_index];
	struct bt_bap_scan_delegator_recv_state recv_state;
	int cb_err = err;
	bool active_recv_state = data != NULL && length != 0;

	/* TODO: Split discovery and receive state characteristic read */

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

	LOG_DBG("%s receive state", active_recv_state ? "Active " : "Inactive");

	if (cb_err == 0 && active_recv_state) {
		int16_t index;

		index = lookup_index_by_handle(handle);
		if (index < 0) {
			cb_err = BT_GATT_ERR(BT_ATT_ERR_INVALID_HANDLE);
		} else {
			cb_err = parse_recv_state(data, length, &recv_state);

			if (cb_err != 0) {
				LOG_DBG("Invalid receive state");
			} else {
				broadcast_assistant.src_ids[index] = recv_state.src_id;
				broadcast_assistant.past_avail[index] =
					past_available(conn, &recv_state.addr,
						       recv_state.adv_sid);
			}
		}
	}

	if (cb_err != 0) {
		LOG_DBG("err %d", cb_err);

		if (broadcast_assistant.busy) {
			broadcast_assistant.busy = false;
			bap_broadcast_assistant_discover_complete(conn, cb_err, 0);
		} else {
			bap_broadcast_assistant_recv_state_changed(conn, cb_err, NULL);
		}
	} else if (handle == last_handle) {
		if (broadcast_assistant.busy) {
			const uint8_t recv_state_cnt = broadcast_assistant.recv_state_cnt;

			broadcast_assistant.busy = false;
			bap_broadcast_assistant_discover_complete(conn, cb_err, recv_state_cnt);
		} else {
			bap_broadcast_assistant_recv_state_changed(conn, cb_err,
								   active_recv_state ?
								   &recv_state : NULL);
		}
	} else {
		for (uint8_t i = 0U; i < broadcast_assistant.recv_state_cnt; i++) {
			if (handle == broadcast_assistant.recv_state_handles[i]) {
				if (i + 1 < ARRAY_SIZE(broadcast_assistant.recv_state_handles)) {
					(void)bt_bap_broadcast_assistant_read_recv_state(conn,
											 i + 1);
				}
				break;
			}
		}
	}

	return BT_GATT_ITER_STOP;
}

static void discover_init(void)
{
	k_work_init_delayable(&broadcast_assistant.bap_read_work, delayed_bap_read_handler);

	net_buf_simple_reset(&att_buf);
}

/**
 * @brief This will discover all characteristics on the server, retrieving the
 * handles of the writeable characteristics and subscribing to all notify and
 * indicate characteristics.
 */
static uint8_t char_discover_func(struct bt_conn *conn,
				  const struct bt_gatt_attr *attr,
				  struct bt_gatt_discover_params *params)
{
	struct bt_gatt_subscribe_params *sub_params = NULL;
	int err;

	if (attr == NULL) {
		LOG_DBG("Found %u BASS receive states",
		       broadcast_assistant.recv_state_cnt);
		(void)memset(params, 0, sizeof(*params));

		err = bt_bap_broadcast_assistant_read_recv_state(conn, 0);
		if (err != 0) {
			broadcast_assistant.busy = false;
			bap_broadcast_assistant_discover_complete(conn, err, 0);
		}

		return BT_GATT_ITER_STOP;
	}

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

	if (params->type == BT_GATT_DISCOVER_CHARACTERISTIC) {
		struct bt_gatt_chrc *chrc =
			(struct bt_gatt_chrc *)attr->user_data;

		if (bt_uuid_cmp(chrc->uuid, BT_UUID_BASS_CONTROL_POINT) == 0) {
			LOG_DBG("Control Point");
			broadcast_assistant.cp_handle = attr->handle + 1;
		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_BASS_RECV_STATE) == 0) {
			if (broadcast_assistant.recv_state_cnt <
				CONFIG_BT_BAP_BROADCAST_ASSISTANT_RECV_STATE_COUNT) {
				uint8_t idx = broadcast_assistant.recv_state_cnt++;

				LOG_DBG("Receive State %u", broadcast_assistant.recv_state_cnt);
				broadcast_assistant.recv_state_handles[idx] =
					attr->handle + 1;
				sub_params = &broadcast_assistant.recv_state_sub_params[idx];
				sub_params->disc_params =
					&broadcast_assistant.recv_state_disc_params[idx];
			}
		}

		if (sub_params != NULL) {
			/* With ccc_handle == 0 it will use auto discovery */
			sub_params->end_handle = broadcast_assistant.end_handle;
			sub_params->ccc_handle = 0;
			sub_params->value = BT_GATT_CCC_NOTIFY;
			sub_params->value_handle = attr->handle + 1;
			sub_params->notify = notify_handler;
			atomic_set_bit(sub_params->flags, BT_GATT_SUBSCRIBE_FLAG_VOLATILE);

			err = bt_gatt_subscribe(conn, sub_params);
			if (err != 0) {
				LOG_DBG("Could not subscribe to handle 0x%04x: %d",
					sub_params->value_handle, err);

				broadcast_assistant.busy = false;
				LOG_DBG("no handle discover callback");

				bap_broadcast_assistant_discover_complete(conn, err, 0);

				return BT_GATT_ITER_STOP;
			}
		}
	}

	return BT_GATT_ITER_CONTINUE;
}

static uint8_t service_discover_func(struct bt_conn *conn,
				     const struct bt_gatt_attr *attr,
				     struct bt_gatt_discover_params *params)
{
	int err;
	struct bt_gatt_service_val *prim_service;

	if (attr == NULL) {
		LOG_DBG("Could not discover BASS");
		(void)memset(params, 0, sizeof(*params));

		broadcast_assistant.busy = false;
		err = BT_GATT_ERR(BT_ATT_ERR_NOT_SUPPORTED);

		bap_broadcast_assistant_discover_complete(conn, err, 0);

		return BT_GATT_ITER_STOP;
	}

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

	if (params->type == BT_GATT_DISCOVER_PRIMARY) {
		prim_service = (struct bt_gatt_service_val *)attr->user_data;
		broadcast_assistant.start_handle = attr->handle + 1;
		broadcast_assistant.end_handle = prim_service->end_handle;

		broadcast_assistant.disc_params.uuid = NULL;
		broadcast_assistant.disc_params.start_handle = broadcast_assistant.start_handle;
		broadcast_assistant.disc_params.end_handle = broadcast_assistant.end_handle;
		broadcast_assistant.disc_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
		broadcast_assistant.disc_params.func = char_discover_func;

		err = bt_gatt_discover(conn, &broadcast_assistant.disc_params);
		if (err != 0) {
			LOG_DBG("Discover failed (err %d)", err);
			broadcast_assistant.busy = false;
			bap_broadcast_assistant_discover_complete(conn, err, 0);
		}
	}

	return BT_GATT_ITER_STOP;
}

static void bap_broadcast_assistant_write_cp_cb(struct bt_conn *conn, uint8_t err,
						struct bt_gatt_write_params *params)
{
	struct bt_bap_broadcast_assistant_cb *listener, *next;
	uint8_t opcode = net_buf_simple_pull_u8(&att_buf);

	broadcast_assistant.busy = false;

	/* we reset the buffer, so that we are ready for new notifications and writes */
	net_buf_simple_reset(&att_buf);

	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&broadcast_assistant_cbs, listener, next, _node) {
		switch (opcode) {
		case BT_BAP_BASS_OP_SCAN_STOP:
			if (listener->scan_stop != NULL) {
				listener->scan_stop(conn, err);
			}
			break;
		case BT_BAP_BASS_OP_SCAN_START:
			if (listener->scan_start != NULL) {
				listener->scan_start(conn, err);
			}
			break;
		case BT_BAP_BASS_OP_ADD_SRC:
			if (listener->add_src != NULL) {
				listener->add_src(conn, err);
			}
			break;
		case BT_BAP_BASS_OP_MOD_SRC:
			if (listener->mod_src != NULL) {
				listener->mod_src(conn, err);
			}
			break;
		case BT_BAP_BASS_OP_BROADCAST_CODE:
			if (listener->broadcast_code != NULL) {
				listener->broadcast_code(conn, err);
			}
			break;
		case BT_BAP_BASS_OP_REM_SRC:
			if (listener->rem_src != NULL) {
				listener->rem_src(conn, err);
			}
			break;
		default:
			LOG_DBG("Unknown opcode 0x%02x", opcode);
			break;
		}
	}
}

static int bt_bap_broadcast_assistant_common_cp(struct bt_conn *conn,
				    const struct net_buf_simple *buf)
{
	int err;

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

		return -EINVAL;
	} else if (broadcast_assistant.cp_handle == 0) {
		LOG_DBG("Handle not set");
		return -EINVAL;
	}

	broadcast_assistant.write_params.offset = 0;
	broadcast_assistant.write_params.data = buf->data;
	broadcast_assistant.write_params.length = buf->len;
	broadcast_assistant.write_params.handle = broadcast_assistant.cp_handle;
	broadcast_assistant.write_params.func = bap_broadcast_assistant_write_cp_cb;

	err = bt_gatt_write(conn, &broadcast_assistant.write_params);
	if (err == 0) {
		broadcast_assistant.busy = true;
	}

	return err;
}


static bool broadcast_source_found(struct bt_data *data, void *user_data)
{
	const struct bt_le_scan_recv_info *info = user_data;
	struct bt_uuid_16 adv_uuid;
	uint32_t broadcast_id;

	if (data->type != BT_DATA_SVC_DATA16) {
		return true;
	}

	if (data->data_len < BT_UUID_SIZE_16 + BT_AUDIO_BROADCAST_ID_SIZE) {
		return true;
	}

	if (!bt_uuid_create(&adv_uuid.uuid, data->data, BT_UUID_SIZE_16)) {
		return true;
	}

	if (bt_uuid_cmp(&adv_uuid.uuid, BT_UUID_BROADCAST_AUDIO) != 0) {
		return true;
	}

	broadcast_id = sys_get_le24(data->data + BT_UUID_SIZE_16);

	LOG_DBG("Found BIS advertiser with address %s SID 0x%02X and broadcast_id 0x%06X",
		bt_addr_le_str(info->addr), info->sid, broadcast_id);

	bap_broadcast_assistant_scan_results(info, broadcast_id);

	return false;
}

void scan_recv(const struct bt_le_scan_recv_info *info,
	       struct net_buf_simple *ad)
{
	/* We are only interested in non-connectable periodic advertisers */
	if ((info->adv_props & BT_GAP_ADV_PROP_CONNECTABLE) != 0 ||
	    info->interval == 0) {
		return;
	}

	bt_data_parse(ad, broadcast_source_found, (void *)info);
}

static struct bt_le_scan_cb scan_cb = {
	.recv = scan_recv
};

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

static int broadcast_assistant_reset(struct bap_broadcast_assistant_instance *inst)
{
	inst->busy = false;
	inst->scanning = false;
	inst->pa_sync = 0U;
	inst->recv_state_cnt = 0U;
	inst->start_handle = 0U;
	inst->end_handle = 0U;
	inst->cp_handle = 0U;
	inst->long_read_handle = 0;
	(void)k_work_cancel_delayable(&inst->bap_read_work);

	for (int i = 0U; i < CONFIG_BT_BAP_BROADCAST_ASSISTANT_RECV_STATE_COUNT; i++) {
		inst->src_ids[i] = 0U;
		inst->past_avail[i] = false;
		inst->recv_state_handles[i] = 0U;
	}

	if (inst->conn != NULL) {
		struct bt_conn *conn = inst->conn;
		struct bt_conn_info info;
		int err;

		err = bt_conn_get_info(conn, &info);
		if (err != 0) {
			return err;
		}

		if (info.state == BT_CONN_STATE_CONNECTED) {
			for (size_t i = 0U; i < ARRAY_SIZE(inst->recv_state_sub_params); i++) {
				/* It's okay if this fail with -EINVAL as that means that they are
				 * not currently subscribed
				 */
				err = bt_gatt_unsubscribe(conn, &inst->recv_state_sub_params[i]);
				if (err != 0 && err != -EINVAL) {
					LOG_DBG("Failed to unsubscribe to state: %d", err);

					return err;
				}
			}
		}

		bt_conn_unref(conn);
		inst->conn = NULL;
	}

	/* The subscribe parameters must remain instact so they can get cleaned up by GATT */
	memset(&inst->disc_params, 0, sizeof(inst->disc_params));
	memset(&inst->recv_state_disc_params, 0, sizeof(inst->recv_state_disc_params));
	memset(&inst->read_params, 0, sizeof(inst->read_params));
	memset(&inst->write_params, 0, sizeof(inst->write_params));

	return 0;
}

static void disconnected_cb(struct bt_conn *conn, uint8_t reason)
{
	(void)broadcast_assistant_reset(&broadcast_assistant);
}

BT_CONN_CB_DEFINE(conn_callbacks) = {
	.disconnected = disconnected_cb,
};

int bt_bap_broadcast_assistant_discover(struct bt_conn *conn)
{
	int err;

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

		return -EINVAL;
	}

	if (broadcast_assistant.busy) {
		LOG_DBG("Instance is busy");
		return -EBUSY;
	}

	err = broadcast_assistant_reset(&broadcast_assistant);
	if (err != 0) {
		LOG_DBG("Failed to reset broadcast assistant: %d", err);

		return err;
	}

	/* Discover BASS on peer, setup handles and notify */
	discover_init();

	(void)memcpy(&uuid, BT_UUID_BASS, sizeof(uuid));
	broadcast_assistant.disc_params.func = service_discover_func;
	broadcast_assistant.disc_params.uuid = &uuid.uuid;
	broadcast_assistant.disc_params.type = BT_GATT_DISCOVER_PRIMARY;
	broadcast_assistant.disc_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
	broadcast_assistant.disc_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
	err = bt_gatt_discover(conn, &broadcast_assistant.disc_params);
	if (err != 0) {
		return err;
	}

	broadcast_assistant.busy = true;
	broadcast_assistant.conn = bt_conn_ref(conn);

	return 0;
}

/* TODO: naming is different from e.g. bt_vcp_vol_ctrl_cb_register */
int bt_bap_broadcast_assistant_register_cb(struct bt_bap_broadcast_assistant_cb *cb)
{
	struct bt_bap_broadcast_assistant_cb *tmp;

	CHECKIF(cb == NULL) {
		return -EINVAL;
	}

	SYS_SLIST_FOR_EACH_CONTAINER(&broadcast_assistant_cbs, tmp, _node) {
		if (tmp == cb) {
			LOG_DBG("Already registered");
			return -EALREADY;
		}
	}

	sys_slist_append(&broadcast_assistant_cbs, &cb->_node);

	return 0;
}

int bt_bap_broadcast_assistant_unregister_cb(struct bt_bap_broadcast_assistant_cb *cb)
{
	CHECKIF(cb == NULL) {
		return -EINVAL;
	}

	if (!sys_slist_find_and_remove(&broadcast_assistant_cbs, &cb->_node)) {
		return -EALREADY;
	}

	return 0;
}

int bt_bap_broadcast_assistant_scan_start(struct bt_conn *conn, bool start_scan)
{
	struct bt_bap_bass_cp_scan_start *cp;
	int err;

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

		return -EINVAL;
	} else if (broadcast_assistant.cp_handle == 0) {
		LOG_DBG("handle not set");

		return -EINVAL;
	} else if (broadcast_assistant.busy) {
		LOG_DBG("instance busy");

		return -EBUSY;
	}

	if (start_scan) {
		static bool cb_registered;

		if (!cb_registered) {
			bt_le_scan_cb_register(&scan_cb);
			cb_registered = true;
		}

		err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL);
		if (err != 0) {
			LOG_DBG("Could not start scan (%d)", err);

			return err;
		}

		broadcast_assistant.scanning = true;
	}

	/* Reset buffer before using */
	net_buf_simple_reset(&att_buf);
	cp = net_buf_simple_add(&att_buf, sizeof(*cp));

	cp->opcode = BT_BAP_BASS_OP_SCAN_START;

	return bt_bap_broadcast_assistant_common_cp(conn, &att_buf);
}

int bt_bap_broadcast_assistant_scan_stop(struct bt_conn *conn)
{
	struct bt_bap_bass_cp_scan_stop *cp;
	int err;

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

		return -EINVAL;
	} else if (broadcast_assistant.cp_handle == 0) {
		LOG_DBG("handle not set");

		return -EINVAL;
	} else if (broadcast_assistant.busy) {
		LOG_DBG("instance busy");

		return -EBUSY;
	}

	if (broadcast_assistant.scanning) {
		err = bt_le_scan_stop();
		if (err != 0) {
			LOG_DBG("Could not stop scan (%d)", err);

			return err;
		}

		broadcast_assistant.scanning = false;
	}

	/* Reset buffer before using */
	net_buf_simple_reset(&att_buf);
	cp = net_buf_simple_add(&att_buf, sizeof(*cp));

	cp->opcode = BT_BAP_BASS_OP_SCAN_STOP;

	return bt_bap_broadcast_assistant_common_cp(conn, &att_buf);
}

int bt_bap_broadcast_assistant_add_src(struct bt_conn *conn,
				       const struct bt_bap_broadcast_assistant_add_src_param *param)
{
	struct bt_bap_bass_cp_add_src *cp;

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

		return -EINVAL;
	} else if (broadcast_assistant.cp_handle == 0) {
		LOG_DBG("handle not set");

		return -EINVAL;
	} else if (broadcast_assistant.busy) {
		LOG_DBG("instance busy");

		return -EBUSY;
	}

	/* Reset buffer before using */
	net_buf_simple_reset(&att_buf);
	cp = net_buf_simple_add(&att_buf, sizeof(*cp));

	cp->opcode = BT_BAP_BASS_OP_ADD_SRC;
	cp->adv_sid = param->adv_sid;
	bt_addr_le_copy(&cp->addr, &param->addr);

	sys_put_le24(param->broadcast_id, cp->broadcast_id);

	if (param->pa_sync) {
		if (past_available(conn, &param->addr, param->adv_sid)) {
			cp->pa_sync = BT_BAP_BASS_PA_REQ_SYNC_PAST;
		} else {
			cp->pa_sync = BT_BAP_BASS_PA_REQ_SYNC;
		}
	} else {
		cp->pa_sync = BT_BAP_BASS_PA_REQ_NO_SYNC;
	}
	cp->pa_interval = sys_cpu_to_le16(param->pa_interval);

	cp->num_subgroups = param->num_subgroups;
	for (int i = 0; i < param->num_subgroups; i++) {
		struct bt_bap_bass_cp_subgroup *subgroup;
		const size_t subgroup_size = sizeof(subgroup->bis_sync) +
					     sizeof(subgroup->metadata_len) +
					     param->subgroups[i].metadata_len;

		if (att_buf.len + subgroup_size > att_buf.size) {
			LOG_DBG("MTU is too small to send %zu octets", att_buf.len + subgroup_size);

			return -EINVAL;
		}

		subgroup = net_buf_simple_add(&att_buf, subgroup_size);

		if (param->subgroups[i].bis_sync != BT_BAP_BIS_SYNC_NO_PREF) {
			/* The BIS Index bitfield to be sent must use BIT(0) for BIS Index 1 */
			subgroup->bis_sync = param->subgroups[i].bis_sync >> 1;
		} else {
			subgroup->bis_sync = BT_BAP_BIS_SYNC_NO_PREF;
		}

		CHECKIF(param->pa_sync == 0 && subgroup->bis_sync != 0) {
			LOG_DBG("Only syncing to BIS is not allowed");
			return -EINVAL;
		}

		if (param->subgroups[i].metadata_len != 0) {
			(void)memcpy(subgroup->metadata,
				     param->subgroups[i].metadata,
				     param->subgroups[i].metadata_len);
			subgroup->metadata_len = param->subgroups[i].metadata_len;
		} else {
			subgroup->metadata_len = 0;
		}

	}

	return bt_bap_broadcast_assistant_common_cp(conn, &att_buf);
}

int bt_bap_broadcast_assistant_mod_src(struct bt_conn *conn,
				       const struct bt_bap_broadcast_assistant_mod_src_param *param)
{
	struct bt_bap_bass_cp_mod_src *cp;
	bool known_recv_state;
	bool past_avail;

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

		return -EINVAL;
	} else if (broadcast_assistant.cp_handle == 0) {
		LOG_DBG("handle not set");

		return -EINVAL;
	} else if (broadcast_assistant.busy) {
		LOG_DBG("instance busy");

		return -EBUSY;
	}

	/* Reset buffer before using */
	net_buf_simple_reset(&att_buf);
	cp = net_buf_simple_add(&att_buf, sizeof(*cp));

	cp->opcode = BT_BAP_BASS_OP_MOD_SRC;
	cp->src_id = param->src_id;

	/* Since we do not have the address and SID in this function, we
	 * rely on cached PAST support information
	 */
	known_recv_state = false;
	past_avail = false;
	for (size_t i = 0; i < ARRAY_SIZE(broadcast_assistant.src_ids); i++) {
		if (broadcast_assistant.src_ids[i] == param->src_id) {
			known_recv_state = true;
			past_avail = broadcast_assistant.past_avail[i];
			break;
		}
	}

	if (!known_recv_state) {
		LOG_WRN("Attempting to modify unknown receive state: %u",
			param->src_id);
	}

	if (param->pa_sync) {
		if (known_recv_state && past_avail) {
			cp->pa_sync = BT_BAP_BASS_PA_REQ_SYNC_PAST;
		} else {
			cp->pa_sync = BT_BAP_BASS_PA_REQ_SYNC;
		}
	} else {
		cp->pa_sync = BT_BAP_BASS_PA_REQ_NO_SYNC;
	}

	cp->pa_interval = sys_cpu_to_le16(param->pa_interval);

	cp->num_subgroups = param->num_subgroups;
	for (int i = 0; i < param->num_subgroups; i++) {
		struct bt_bap_bass_cp_subgroup *subgroup;
		const size_t subgroup_size = sizeof(subgroup->bis_sync) +
					     sizeof(subgroup->metadata_len) +
					     param->subgroups[i].metadata_len;

		if (att_buf.len + subgroup_size > att_buf.size) {
			LOG_DBG("MTU is too small to send %zu octets", att_buf.len + subgroup_size);
			return -EINVAL;
		}
		subgroup = net_buf_simple_add(&att_buf, subgroup_size);

		if (param->subgroups[i].bis_sync != BT_BAP_BIS_SYNC_NO_PREF) {
			/* The BIS Index bitfield to be sent must use BIT(0) for BIS Index 1 */
			subgroup->bis_sync = param->subgroups[i].bis_sync >> 1;
		} else {
			subgroup->bis_sync = BT_BAP_BIS_SYNC_NO_PREF;
		}

		CHECKIF(param->pa_sync == 0 && subgroup->bis_sync != 0) {
			LOG_DBG("Only syncing to BIS is not allowed");
			return -EINVAL;
		}

		if (param->subgroups[i].metadata_len != 0) {
			(void)memcpy(subgroup->metadata,
				     param->subgroups[i].metadata,
				     param->subgroups[i].metadata_len);
			subgroup->metadata_len = param->subgroups[i].metadata_len;
		} else {
			subgroup->metadata_len = 0;
		}
	}

	return bt_bap_broadcast_assistant_common_cp(conn, &att_buf);
}

int bt_bap_broadcast_assistant_set_broadcast_code(
	struct bt_conn *conn, uint8_t src_id,
	const uint8_t broadcast_code[BT_AUDIO_BROADCAST_CODE_SIZE])
{
	struct bt_bap_bass_cp_broadcase_code *cp;

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

		return -EINVAL;
	} else if (broadcast_assistant.cp_handle == 0) {
		LOG_DBG("handle not set");

		return -EINVAL;
	} else if (broadcast_assistant.busy) {
		LOG_DBG("instance busy");

		return -EBUSY;
	}

	/* Reset buffer before using */
	net_buf_simple_reset(&att_buf);
	cp = net_buf_simple_add(&att_buf, sizeof(*cp));

	cp->opcode = BT_BAP_BASS_OP_BROADCAST_CODE;
	cp->src_id = src_id;

	(void)memcpy(cp->broadcast_code, broadcast_code,
		     BT_AUDIO_BROADCAST_CODE_SIZE);

	LOG_HEXDUMP_DBG(cp->broadcast_code, BT_AUDIO_BROADCAST_CODE_SIZE, "broadcast code:");

	return bt_bap_broadcast_assistant_common_cp(conn, &att_buf);
}

int bt_bap_broadcast_assistant_rem_src(struct bt_conn *conn, uint8_t src_id)
{
	struct bt_bap_bass_cp_rem_src *cp;

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

		return -EINVAL;
	} else if (broadcast_assistant.cp_handle == 0) {
		LOG_DBG("handle not set");

		return -EINVAL;
	} else if (broadcast_assistant.busy) {
		LOG_DBG("instance busy");

		return -EBUSY;
	}

	/* Reset buffer before using */
	net_buf_simple_reset(&att_buf);
	cp = net_buf_simple_add(&att_buf, sizeof(*cp));

	cp->opcode = BT_BAP_BASS_OP_REM_SRC;
	cp->src_id = src_id;

	return bt_bap_broadcast_assistant_common_cp(conn, &att_buf);
}

int bt_bap_broadcast_assistant_read_recv_state(struct bt_conn *conn,
					       uint8_t idx)
{
	int err;

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

		return -EINVAL;
	}

	CHECKIF(idx >= ARRAY_SIZE(broadcast_assistant.recv_state_handles)) {
		LOG_DBG("Invalid idx: %u", idx);

		return -EINVAL;
	}

	if (broadcast_assistant.recv_state_handles[idx] == 0) {
		LOG_DBG("handle not set");

		return -EINVAL;
	}

	broadcast_assistant.read_params.func = read_recv_state_cb;
	broadcast_assistant.read_params.handle_count = 1;
	broadcast_assistant.read_params.single.handle =
		broadcast_assistant.recv_state_handles[idx];

	err = bt_gatt_read(conn, &broadcast_assistant.read_params);
	if (err != 0) {
		(void)memset(&broadcast_assistant.read_params, 0,
			     sizeof(broadcast_assistant.read_params));
	}

	return err;
}
