/* main.c - Application main entry point */

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

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

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/iso.h>
#include <zephyr/bluetooth/hci.h>

#include "bs_types.h"
#include "bs_tracing.h"
#include "time_machine.h"
#include "bstests.h"

#define FAIL(...)					\
	do {						\
		bst_result = Failed;			\
		bs_trace_error_time_line(__VA_ARGS__);	\
	} while (0)

#define PASS(...)					\
	do {						\
		bst_result = Passed;			\
		bs_trace_info_time(1, __VA_ARGS__);	\
	} while (0)

extern enum bst_result_t bst_result;

static struct bt_iso_chan iso_chan[CONFIG_BT_ISO_MAX_CHAN];

static K_SEM_DEFINE(sem_peer_addr, 0, 1);
static K_SEM_DEFINE(sem_peer_conn, 0, 1);
static K_SEM_DEFINE(sem_peer_disc, 0, CONFIG_BT_MAX_CONN);
static K_SEM_DEFINE(sem_iso_conn, 0, 1);
static K_SEM_DEFINE(sem_iso_disc, 0, 1);
static K_SEM_DEFINE(sem_iso_data, CONFIG_BT_ISO_TX_BUF_COUNT,
				   CONFIG_BT_ISO_TX_BUF_COUNT);
static bt_addr_le_t peer_addr;

#define CREATE_CONN_INTERVAL 0x0010
#define CREATE_CONN_WINDOW   0x0010

#define ISO_INTERVAL_US      10000U
#define ISO_LATENCY_MS       DIV_ROUND_UP(ISO_INTERVAL_US, USEC_PER_MSEC)
#define ISO_LATENCY_FT_MS    20U

#define BT_CONN_US_TO_INTERVAL(t) ((uint16_t)((t) * 4U / 5U / USEC_PER_MSEC))

#if (CONFIG_BT_CTLR_CENTRAL_SPACING == 0)
#define CONN_INTERVAL_MIN    BT_CONN_US_TO_INTERVAL(ISO_INTERVAL_US)
#else /* CONFIG_BT_CTLR_CENTRAL_SPACING > 0 */
#define CONN_INTERVAL_MIN    BT_CONN_US_TO_INTERVAL(ISO_INTERVAL_US * CONFIG_BT_MAX_CONN)
#endif /* CONFIG_BT_CTLR_CENTRAL_SPACING > 0 */

#define CONN_INTERVAL_MAX    CONN_INTERVAL_MIN
#define CONN_TIMEOUT         MAX((BT_CONN_INTERVAL_TO_MS(CONN_INTERVAL_MAX) * 6U / 10U), 10U)

#define ADV_INTERVAL_MIN     0x0020
#define ADV_INTERVAL_MAX     0x0020

#define BT_CONN_LE_CREATE_CONN_CUSTOM  \
	BT_CONN_LE_CREATE_PARAM(BT_CONN_LE_OPT_NONE, \
				CREATE_CONN_INTERVAL, \
				CREATE_CONN_WINDOW)

#define BT_LE_CONN_PARAM_CUSTOM \
	BT_LE_CONN_PARAM(CONN_INTERVAL_MIN, CONN_INTERVAL_MAX, 0U, CONN_TIMEOUT)

#if defined(CONFIG_TEST_USE_LEGACY_ADVERTISING)
#define BT_LE_ADV_CONN_CUSTOM BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE | \
					      BT_LE_ADV_OPT_ONE_TIME | \
					      BT_LE_ADV_OPT_USE_NAME, \
					      ADV_INTERVAL_MIN, \
					      ADV_INTERVAL_MAX, \
					      NULL)
#else /* !CONFIG_TEST_USE_LEGACY_ADVERTISING */
#define BT_LE_ADV_CONN_CUSTOM BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE | \
					      BT_LE_ADV_OPT_EXT_ADV | \
					      BT_LE_ADV_OPT_ONE_TIME | \
					      BT_LE_ADV_OPT_USE_NAME, \
					      ADV_INTERVAL_MIN, \
					      ADV_INTERVAL_MAX, \
					      NULL)
#endif /* !CONFIG_TEST_USE_LEGACY_ADVERTISING */

#define SEQ_NUM_MAX 1000U

#define NAME_LEN 30

#define BUF_ALLOC_TIMEOUT   (50) /* milliseconds */
NET_BUF_POOL_FIXED_DEFINE(tx_pool, CONFIG_BT_ISO_TX_BUF_COUNT,
			  BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU),
			  CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL);

static bool data_cb(struct bt_data *data, void *user_data)
{
	char *name = user_data;

	switch (data->type) {
	case BT_DATA_NAME_SHORTENED:
	case BT_DATA_NAME_COMPLETE:
		memcpy(name, data->data, MIN(data->data_len, NAME_LEN - 1));
		return false;
	default:
		return true;
	}
}

static const char *phy2str(uint8_t phy)
{
	switch (phy) {
	case 0: return "No packets";
	case BT_GAP_LE_PHY_1M: return "LE 1M";
	case BT_GAP_LE_PHY_2M: return "LE 2M";
	case BT_GAP_LE_PHY_CODED: return "LE Coded";
	default: return "Unknown";
	}
}

static void scan_recv(const struct bt_le_scan_recv_info *info,
		      struct net_buf_simple *buf)
{
	char le_addr[BT_ADDR_LE_STR_LEN];
	char name[NAME_LEN];

	(void)memset(name, 0, sizeof(name));

	bt_data_parse(buf, data_cb, name);

	bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));
	printk("[DEVICE]: %s, AD evt type %u, Tx Pwr: %i, RSSI %i %s "
	       "C:%u S:%u D:%u SR:%u E:%u Prim: %s, Secn: %s, "
	       "Interval: 0x%04x (%u ms), SID: %u\n",
	       le_addr, info->adv_type, info->tx_power, info->rssi, name,
	       (info->adv_props & BT_GAP_ADV_PROP_CONNECTABLE) != 0,
	       (info->adv_props & BT_GAP_ADV_PROP_SCANNABLE) != 0,
	       (info->adv_props & BT_GAP_ADV_PROP_DIRECTED) != 0,
	       (info->adv_props & BT_GAP_ADV_PROP_SCAN_RESPONSE) != 0,
	       (info->adv_props & BT_GAP_ADV_PROP_EXT_ADV) != 0,
	       phy2str(info->primary_phy), phy2str(info->secondary_phy),
	       info->interval, info->interval * 5 / 4, info->sid);

	bt_addr_le_copy(&peer_addr, info->addr);
	k_sem_give(&sem_peer_addr);
}

static struct bt_le_scan_cb scan_callbacks = {
	.recv = scan_recv,
};

static void connected(struct bt_conn *conn, uint8_t err)
{
	char addr[BT_ADDR_LE_STR_LEN];

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

	if (err) {
		struct bt_conn_info conn_info;

		printk("Failed to connect to %s (%u)\n", addr, err);

		err = bt_conn_get_info(conn, &conn_info);
		if (err) {
			FAIL("Failed to get connection info (%d).\n", err);
			return;
		}

		printk("%s: %s role %u\n", __func__, addr, conn_info.role);

		if (conn_info.role == BT_CONN_ROLE_CENTRAL) {
			bt_conn_unref(conn);
		}

		return;
	}

	printk("Connected: %s\n", addr);

	k_sem_give(&sem_peer_conn);
}

static void disconnected(struct bt_conn *conn, uint8_t reason)
{
	struct bt_conn_info conn_info;
	char addr[BT_ADDR_LE_STR_LEN];
	int err;

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

	printk("Disconnected: %s (reason 0x%02x)\n", addr, reason);

	err = bt_conn_get_info(conn, &conn_info);
	if (err) {
		FAIL("Failed to get connection info (%d).\n", err);
		return;
	}

	printk("%s: %s role %u\n", __func__, addr, conn_info.role);

	if (conn_info.role == BT_CONN_ROLE_CENTRAL) {
		bt_conn_unref(conn);
	}

	k_sem_give(&sem_peer_disc);
}

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

static void disconnect(struct bt_conn *conn, void *data)
{
	char addr[BT_ADDR_LE_STR_LEN];
	int err;

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

	printk("Disconnecting %s...\n", addr);
	err = bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
	if (err) {
		FAIL("Failed disconnection %s.\n", addr);
		return;
	}
	printk("success.\n");
}

/** Print data as d_0 d_1 d_2 ... d_(n-2) d_(n-1) d_(n) to show the 3 first and 3 last octets
 *
 * Examples:
 * 01
 * 0102
 * 010203
 * 01020304
 * 0102030405
 * 010203040506
 * 010203...050607
 * 010203...060708
 * etc.
 */
static void iso_print_data(uint8_t *data, size_t data_len)
{
	/* Maximum number of octets from each end of the data */
	const uint8_t max_octets = 3;
	char data_str[35];
	size_t str_len;

	str_len = bin2hex(data, MIN(max_octets, data_len), data_str, sizeof(data_str));
	if (data_len > max_octets) {
		if (data_len > (max_octets * 2)) {
			static const char dots[] = "...";

			strcat(&data_str[str_len], dots);
			str_len += strlen(dots);
		}

		str_len += bin2hex(data + (data_len - MIN(max_octets, data_len - max_octets)),
				   MIN(max_octets, data_len - max_octets),
				   data_str + str_len,
				   sizeof(data_str) - str_len);
	}

	printk("\t %s\n", data_str);
}

static uint16_t expected_seq_num[CONFIG_BT_ISO_MAX_CHAN];

static void iso_recv(struct bt_iso_chan *chan, const struct bt_iso_recv_info *info,
		struct net_buf *buf)
{
	uint16_t seq_num;
	uint8_t index;

	index = bt_conn_index(chan->iso);

	printk("Incoming data channel %p (%u) flags 0x%x seq_num %u ts %u len %u:\n",
	       chan, index, info->flags, info->seq_num, info->ts, buf->len);
	iso_print_data(buf->data, buf->len);

	seq_num = sys_get_le32(buf->data);
	if (info->flags & BT_ISO_FLAGS_VALID) {
		if (seq_num != expected_seq_num[index]) {
			if (expected_seq_num[index]) {
				FAIL("ISO data miss match, expected %u actual %u\n",
				     expected_seq_num[index], seq_num);
			}
			expected_seq_num[index] = seq_num;
		}

		expected_seq_num[index] += 1U;

#if defined(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS)
		expected_seq_num[index] += ((CONFIG_TEST_FT_PER_SKIP_EVENTS_COUNT - 1U) * 2U);
#elif defined(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS)
		expected_seq_num[index] += ((CONFIG_TEST_FT_CEN_SKIP_EVENTS_COUNT - 1U) * 2U);
#endif
	} else if (expected_seq_num[index] &&
		   expected_seq_num[index] < SEQ_NUM_MAX) {
		FAIL("%s: Invalid ISO data after valid ISO data reception.\n"
		     "Expected %u\n", __func__, expected_seq_num[index]);
	}
}

void iso_sent(struct bt_iso_chan *chan)
{
	k_sem_give(&sem_iso_data);
}

static void iso_connected(struct bt_iso_chan *chan)
{
	printk("ISO Channel %p connected\n", chan);

	k_sem_give(&sem_iso_conn);
}

static void iso_disconnected(struct bt_iso_chan *chan, uint8_t reason)
{
	printk("ISO Channel %p disconnected (reason 0x%02x)\n", chan, reason);

	k_sem_give(&sem_iso_disc);
}

static struct bt_iso_chan_ops iso_ops = {
	.connected    = iso_connected,
	.disconnected = iso_disconnected,
	.recv         = iso_recv,
	.sent         = iso_sent,
};

static void test_cis_central(void)
{
	struct bt_iso_chan_io_qos iso_tx[CONFIG_BT_ISO_MAX_CHAN];
	struct bt_iso_chan_io_qos iso_rx[CONFIG_BT_ISO_MAX_CHAN];
	struct bt_iso_chan_qos iso_qos[CONFIG_BT_ISO_MAX_CHAN];
	struct bt_iso_chan *channels[CONFIG_BT_ISO_MAX_CHAN];
	struct bt_conn *conn_list[CONFIG_BT_MAX_CONN];
	struct bt_iso_cig_param cig_param;
	struct bt_iso_cig *cig;
	int conn_count;
	int err;

	printk("Bluetooth initializing...");
	err = bt_enable(NULL);
	if (err) {
		FAIL("Could not init BT: %d\n", err);
		return;
	}
	printk("success.\n");

	printk("Scan callbacks register...");
	bt_le_scan_cb_register(&scan_callbacks);
	printk("success.\n");

	for (int i = 0; i < CONFIG_BT_ISO_MAX_CHAN; i++) {
		iso_tx[i].sdu = CONFIG_BT_ISO_TX_MTU;
		iso_tx[i].phy = BT_GAP_LE_PHY_2M;
		iso_tx[i].path = NULL;
		if (IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS)) {
			iso_tx[i].rtn = 2U;
		} else {
			iso_tx[i].rtn = 0U;
		}

		if (!IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS) ||
		    IS_ENABLED(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS)) {
			iso_qos[i].tx = &iso_tx[i];
		} else {
			iso_qos[i].tx = NULL;
		}

		iso_rx[i].sdu = CONFIG_BT_ISO_RX_MTU;
		iso_rx[i].phy = BT_GAP_LE_PHY_2M;
		iso_rx[i].path = NULL;
		if (IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS)) {
			iso_rx[i].rtn = 2U;
		} else {
			iso_rx[i].rtn = 0U;
		}

		if (IS_ENABLED(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS)) {
			iso_qos[i].rx = &iso_rx[i];
		} else {
			iso_qos[i].rx = NULL;
		}

		iso_chan[i].ops = &iso_ops;
		iso_chan[i].qos = &iso_qos[i];
#if defined(CONFIG_BT_SMP)
		iso_chan[i].required_sec_level = BT_SECURITY_L2,
#endif /* CONFIG_BT_SMP */

		channels[i] = &iso_chan[i];
	}

	cig_param.cis_channels = channels;
	cig_param.num_cis = ARRAY_SIZE(channels);
	cig_param.sca = BT_GAP_SCA_UNKNOWN;
	cig_param.packing = 0U;
	cig_param.framing = 0U;
	cig_param.c_to_p_interval = ISO_INTERVAL_US;
	cig_param.p_to_c_interval = ISO_INTERVAL_US;
	if (IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS)) {
		cig_param.c_to_p_latency = ISO_LATENCY_FT_MS;
		cig_param.p_to_c_latency = ISO_LATENCY_FT_MS;
	} else {
		cig_param.c_to_p_latency = ISO_LATENCY_MS;
		cig_param.p_to_c_latency = ISO_LATENCY_MS;
	}

	printk("Create CIG...");
	err = bt_iso_cig_create(&cig_param, &cig);
	if (err) {
		FAIL("Failed to create CIG (%d)\n", err);
		return;
	}
	printk("success.\n");

	conn_count = 0;

#if defined(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS)
	for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) {
		expected_seq_num[chan] = (CONFIG_TEST_FT_CEN_SKIP_EVENTS_COUNT - 1U) * 2U;
	}
#endif

#if !defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS)
	for (int i = 0; i < CONFIG_BT_MAX_CONN; i++) {
#else
		int i = 0;
#endif

		struct bt_conn *conn;
		int conn_index;
		int chan;

		printk("Start scanning (%d)...", i);
		err = bt_le_scan_start(BT_LE_SCAN_PASSIVE_CONTINUOUS, NULL);
		if (err) {
			FAIL("Could not start scan: %d\n", err);
			return;
		}
		printk("success.\n");

		printk("Waiting for advertising report...\n");
		err = k_sem_take(&sem_peer_addr, K_FOREVER);
		if (err) {
			FAIL("failed (err %d)\n", err);
			return;
		}
		printk("Found peer advertising.\n");

		printk("Stop scanning... ");
		err = bt_le_scan_stop();
		if (err) {
			FAIL("Could not stop scan: %d\n", err);
			return;
		}
		printk("success.\n");

		printk("Create connection...");
		err = bt_conn_le_create(&peer_addr, BT_CONN_LE_CREATE_CONN_CUSTOM,
					BT_LE_CONN_PARAM_CUSTOM, &conn);
		if (err) {
			FAIL("Create connection failed (0x%x)\n", err);
			return;
		}
		printk("success.\n");

		printk("Waiting for connection %d...", i);
		err = k_sem_take(&sem_peer_conn, K_FOREVER);
		if (err) {
			FAIL("failed (err %d)\n", err);
			return;
		}
		printk("connected to peer device %d.\n", i);

		conn_list[conn_count] = conn;
		conn_index = chan = conn_count;
		conn_count++;

#if defined(CONFIG_TEST_CONNECT_ACL_FIRST)
	}

	for (int chan = 0, conn_index = 0;
	     (conn_index < conn_count) && (chan < CONFIG_BT_ISO_MAX_CHAN);
	     conn_index++, chan++) {

#elif defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS)
	for (int chan = 0, conn_index = 0;
	     (chan < CONFIG_BT_ISO_MAX_CHAN); chan++) {
#endif

		struct bt_iso_connect_param iso_connect_param;

		printk("Connect ISO Channel %d...", chan);
		iso_connect_param.acl = conn_list[conn_index];
		iso_connect_param.iso_chan = &iso_chan[chan];
		err = bt_iso_chan_connect(&iso_connect_param, 1);
		if (err) {
			FAIL("Failed to connect iso (%d)\n", err);
			return;
		}

		printk("Waiting for ISO channel connection %d...", chan);
		err = k_sem_take(&sem_iso_conn, K_FOREVER);
		if (err) {
			FAIL("failed (err %d)\n", err);
			return;
		}
		printk("connected to peer %d ISO channel.\n", chan);
	}

	if (!IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS) ||
	    IS_ENABLED(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS)) {
		for (uint16_t seq_num = 0U; seq_num < SEQ_NUM_MAX; seq_num++) {

			for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) {
				uint8_t iso_data[CONFIG_BT_ISO_TX_MTU] = { 0, };
				struct net_buf *buf;
				int ret;

				buf = net_buf_alloc(&tx_pool, K_MSEC(BUF_ALLOC_TIMEOUT));
				if (!buf) {
					FAIL("Data buffer allocate timeout on channel %d\n", chan);
					return;
				}

				net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE);
				sys_put_le16(seq_num, iso_data);
				net_buf_add_mem(buf, iso_data, sizeof(iso_data));

				ret = k_sem_take(&sem_iso_data, K_MSEC(BUF_ALLOC_TIMEOUT));
				if (ret) {
					FAIL("k_sem_take for ISO data sent failed.\n");
					return;
				}

				printk("ISO send: seq_num %u, chan %d\n", seq_num, chan);
				ret = bt_iso_chan_send(&iso_chan[chan], buf, seq_num);
				if (ret < 0) {
					FAIL("Unable to send data on channel %d : %d\n", chan, ret);
					net_buf_unref(buf);
					return;
				}
			}

			if ((seq_num % 100) == 0) {
				printk("Sending value %u\n", seq_num);
			}
		}

		k_sleep(K_MSEC(1000));
	} else {
		k_sleep(K_SECONDS(11));
	}

	for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) {
		printk("ISO disconnect channel %d...", chan);
		err = bt_iso_chan_disconnect(&iso_chan[chan]);
		if (err) {
			FAIL("Failed to disconnect channel %d (%d)\n", chan, err);
			return;
		}
		printk("success\n");

		printk("Waiting for ISO channel disconnect %d...", chan);
		err = k_sem_take(&sem_iso_disc, K_FOREVER);
		if (err) {
			FAIL("failed (err %d)\n", err);
			return;
		}
		printk("disconnected to peer %d ISO channel.\n", chan);
	}

	bt_conn_foreach(BT_CONN_TYPE_LE, disconnect, NULL);

#if !defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS)
	for (int i = 0; i < CONFIG_BT_MAX_CONN; i++) {
#endif

		printk("Waiting for disconnection %d...", i);
		err = k_sem_take(&sem_peer_disc, K_FOREVER);
		if (err) {
			FAIL("failed (err %d)\n", err);
			return;
		}
		printk("Disconnected from peer device %d.\n", i);

#if !defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS)
	}
#endif

	if (IS_ENABLED(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS)) {
		for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) {
			if (expected_seq_num[chan] < SEQ_NUM_MAX) {
				FAIL("ISO Data reception incomplete %u (%u).\n",
				     expected_seq_num[chan], SEQ_NUM_MAX);
				return;
			}
		}
	}

	PASS("Central ISO tests Passed\n");
}

static const struct bt_data ad[] = {
	BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
};

static struct bt_iso_chan_io_qos iso_rx_p[CONFIG_BT_ISO_MAX_CHAN];
static struct bt_iso_chan_qos iso_qos_p[CONFIG_BT_ISO_MAX_CHAN];
static struct bt_iso_chan iso_chan_p[CONFIG_BT_ISO_MAX_CHAN];
static uint8_t chan_count;

static int iso_accept(const struct bt_iso_accept_info *info,
		      struct bt_iso_chan **chan)
{
	printk("Incoming request from %p\n", (void *)info->acl);

	if ((chan_count >= CONFIG_BT_ISO_MAX_CHAN) ||
	    iso_chan_p[chan_count].iso) {
		FAIL("No channels available\n");
		return -ENOMEM;
	}

	*chan = &iso_chan_p[chan_count];
	chan_count++;

	printk("Accepted on channel %p\n", *chan);

	return 0;
}

static struct bt_iso_server iso_server = {
#if defined(CONFIG_BT_SMP)
	.sec_level = BT_SECURITY_L1,
#endif /* CONFIG_BT_SMP */
	.accept = iso_accept,
};

static void test_cis_peripheral(void)
{
	struct bt_iso_chan_io_qos iso_tx_p[CONFIG_BT_ISO_MAX_CHAN];
	int err;

	printk("Bluetooth initializing...");
	err = bt_enable(NULL);
	if (err) {
		FAIL("Bluetooth init failed (err %d)\n", err);
		return;
	}
	printk("success.\n");

	for (int i = 0; i < CONFIG_BT_ISO_MAX_CHAN; i++) {
		iso_tx_p[i].sdu = CONFIG_BT_ISO_TX_MTU;
		iso_tx_p[i].phy = BT_GAP_LE_PHY_2M;
		iso_tx_p[i].path = NULL;
		if (IS_ENABLED(CONFIG_TEST_FT_SKIP_SUBEVENTS)) {
			iso_tx_p[i].rtn = 2U;
		} else {
			iso_tx_p[i].rtn = 0U;
		}

		iso_qos_p[i].tx = &iso_tx_p[i];

		iso_rx_p[i].sdu = CONFIG_BT_ISO_RX_MTU;

		iso_qos_p[i].rx = &iso_rx_p[i];

		iso_chan_p[i].ops = &iso_ops;
		iso_chan_p[i].qos = &iso_qos_p[i];
	}

	printk("ISO Server Register...");
	err = bt_iso_server_register(&iso_server);
	if (err) {
		FAIL("Unable to register ISO server (err %d)\n", err);
		return;
	}
	printk("success.\n");

#if defined(CONFIG_TEST_USE_LEGACY_ADVERTISING)
	printk("Start Advertising...");
	err = bt_le_adv_start(BT_LE_ADV_CONN_CUSTOM, ad, ARRAY_SIZE(ad), NULL, 0);
	if (err) {
		FAIL("Advertising failed to start (err %d)\n", err);
		return;
	}
	printk("success.\n");

#else /* !CONFIG_TEST_USE_LEGACY_ADVERTISING */
	struct bt_le_ext_adv *adv;

	printk("Creating connectable extended advertising set...\n");
	err = bt_le_ext_adv_create(BT_LE_ADV_CONN_CUSTOM, NULL, &adv);
	if (err) {
		FAIL("Failed to create advertising set (err %d)\n", err);
		return;
	}
	printk("success.\n");

	/* Set extended advertising data */
	err = bt_le_ext_adv_set_data(adv, ad, ARRAY_SIZE(ad), NULL, 0);
	if (err) {
		FAIL("Failed to set advertising data (err %d)\n", err);
		return;
	}

	printk("Start Advertising...");
	err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT);
	if (err) {
		FAIL("Failed to start extended advertising (err %d)\n", err);
		return;
	}
	printk("success.\n");
#endif /* !CONFIG_TEST_USE_LEGACY_ADVERTISING */

	printk("Waiting for connection from central...\n");
	err = k_sem_take(&sem_peer_conn, K_FOREVER);
	if (err) {
		FAIL("failed (err %d)\n", err);
		return;
	}
	printk("connected to peer central.\n");

#if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS)
	for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) {
#endif

		printk("Waiting for ISO channel connection...");
		err = k_sem_take(&sem_iso_conn, K_FOREVER);
		if (err) {
			FAIL("failed (err %d)\n", err);
			return;
		}
		printk("connected to peer ISO channel.\n");

#if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS)
	}
#endif

	if (IS_ENABLED(CONFIG_TEST_FT_CEN_SKIP_SUBEVENTS)) {
		for (uint16_t seq_num = 0U; seq_num < SEQ_NUM_MAX; seq_num++) {
			for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) {
				uint8_t iso_data[CONFIG_BT_ISO_TX_MTU] = { 0, };
				struct net_buf *buf;
				int ret;

				buf = net_buf_alloc(&tx_pool, K_MSEC(BUF_ALLOC_TIMEOUT));
				if (!buf) {
					FAIL("Data buffer allocate timeout on channel %d\n", chan);
					return;
				}

				net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE);
				sys_put_le16(seq_num, iso_data);
				net_buf_add_mem(buf, iso_data, sizeof(iso_data));

				ret = k_sem_take(&sem_iso_data, K_MSEC(BUF_ALLOC_TIMEOUT));
				if (ret) {
					FAIL("k_sem_take for ISO data sent failed.\n");
					return;
				}

				printk("ISO send: seq_num %u, chan %d\n", seq_num, chan);
				ret = bt_iso_chan_send(&iso_chan_p[chan], buf, seq_num);
				if (ret < 0) {
					FAIL("Unable to send data on channel %d : %d\n", chan, ret);
					net_buf_unref(buf);
					return;
				}
			}

			if ((seq_num % 100) == 0) {
				printk("Sending value %u\n", seq_num);
			}
		}
	}

#if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS)
	for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) {
#endif

		printk("Waiting for ISO channel disconnect...");
		err = k_sem_take(&sem_iso_disc, K_FOREVER);
		if (err) {
			FAIL("failed (err %d)\n", err);
			return;
		}
		printk("disconnected to peer ISO channel.\n");

#if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS)
	}
#endif

	printk("Waiting for disconnection...");
	err = k_sem_take(&sem_peer_disc, K_FOREVER);
	if (err) {
		FAIL("failed (err %d)\n", err);
		return;
	}
	printk("disconnected from peer device.\n");

#if !defined(CONFIG_TEST_FT_SKIP_SUBEVENTS) || defined(CONFIG_TEST_FT_PER_SKIP_SUBEVENTS)
#if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS)
	for (int chan = 0; chan < CONFIG_BT_ISO_MAX_CHAN; chan++) {
#else
		int  chan = 0;
#endif
		if (expected_seq_num[chan] < SEQ_NUM_MAX) {
			FAIL("ISO Data reception incomplete %u (%u).\n", expected_seq_num[chan],
			     SEQ_NUM_MAX);
			return;
		}
#if defined(CONFIG_TEST_MULTIPLE_PERIPERAL_CIS)
	}
#endif
#endif

	PASS("Peripheral ISO tests Passed\n");
}

static void test_cis_init(void)
{
	bst_ticker_set_next_tick_absolute(60e6);
	bst_result = In_progress;
}

static void test_cis_tick(bs_time_t HW_device_time)
{
	if (bst_result != Passed) {
		FAIL("test failed (not passed after seconds)\n");
	}
}

static const struct bst_test_instance test_def[] = {
	{
		.test_id = "central",
		.test_descr = "Central ISO",
		.test_post_init_f = test_cis_init,
		.test_tick_f = test_cis_tick,
		.test_main_f = test_cis_central,
	},
	{
		.test_id = "peripheral",
		.test_descr = "Peripheral ISO",
		.test_post_init_f = test_cis_init,
		.test_tick_f = test_cis_tick,
		.test_main_f = test_cis_peripheral,
	},
	BSTEST_END_MARKER
};

struct bst_test_list *test_cis_install(struct bst_test_list *tests)
{
	return bst_add_tests(tests, test_def);
}

bst_test_install_t test_installers[] = {
	test_cis_install,
	NULL
};

int main(void)
{
	bst_main();
	return 0;
}
