tests: bluetooth: tester: Implement BAP/BSRC/SCC/BV-38-C

 - Make ext_adv and per_adv into arrays for multiple BIGs
 - Create bap_broadcast-source_setup_v2 command
  - Handles broadcast_id as an input

Signed-off-by: Graham Wacey <graham.wacey@nordicsemi.no>
Signed-off-by: Alexander Svensen <alexander.svensen@nordicsemi.no>
diff --git a/tests/bluetooth/tester/hci_ipc_cpunet.conf b/tests/bluetooth/tester/hci_ipc_cpunet.conf
index 58876f4..8823c19 100644
--- a/tests/bluetooth/tester/hci_ipc_cpunet.conf
+++ b/tests/bluetooth/tester/hci_ipc_cpunet.conf
@@ -6,3 +6,13 @@
 # PTS tests specific tweaks
 CONFIG_BT_CTLR_PERIPHERAL_ISO_EARLY_CIG_START=y
 CONFIG_BT_CTLR_ISOAL_PSN_IGNORE=y
+
+CONFIG_BT_ISO_MAX_BIG=2
+CONFIG_BT_EXT_ADV_MAX_ADV_SET=2
+
+CONFIG_BT_CTLR_ADV_ISO_SET=2
+CONFIG_BT_CTLR_ADV_ISO_STREAM_COUNT=4
+CONFIG_BT_CTLR_ADV_ISO_STREAM_MAX=4
+
+CONFIG_BT_CTLR_ISOAL_SOURCES=4
+CONFIG_BT_CTLR_ISO_TX_BUFFERS=8
diff --git a/tests/bluetooth/tester/overlay-le-audio.conf b/tests/bluetooth/tester/overlay-le-audio.conf
index e22151c..be5004d 100644
--- a/tests/bluetooth/tester/overlay-le-audio.conf
+++ b/tests/bluetooth/tester/overlay-le-audio.conf
@@ -11,6 +11,7 @@
 CONFIG_BT_PER_ADV_SYNC=y
 CONFIG_BT_ISO_SYNC_RECEIVER=y
 CONFIG_BT_EXT_ADV=y
+CONFIG_BT_EXT_ADV_MAX_ADV_SET=2
 CONFIG_BT_BAP_UNICAST_SERVER=y
 CONFIG_BT_BAP_UNICAST_CLIENT=y
 CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT=2
@@ -48,10 +49,12 @@
 
 # Broadcast Source
 CONFIG_BT_BAP_BROADCAST_SOURCE=y
+CONFIG_BT_BAP_BROADCAST_SRC_COUNT=2
 CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT=2
 CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT=2
 CONFIG_BT_ISO_TX_BUF_COUNT=4
 CONFIG_BT_BAP_BROADCAST_ASSISTANT=y
+CONFIG_BT_ISO_MAX_BIG=2
 
 # Broadcast Sink
 CONFIG_BT_BAP_SCAN_DELEGATOR=y
diff --git a/tests/bluetooth/tester/src/audio/btp/btp_bap.h b/tests/bluetooth/tester/src/audio/btp/btp_bap.h
index 002ef1d..cfce8eb 100644
--- a/tests/bluetooth/tester/src/audio/btp/btp_bap.h
+++ b/tests/bluetooth/tester/src/audio/btp/btp_bap.h
@@ -176,6 +176,27 @@
 	uint8_t src_id;
 } __packed;
 
+#define BTP_BAP_BROADCAST_SOURCE_SETUP_V2	0x19
+struct btp_bap_broadcast_source_setup_v2_cmd {
+	uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE];
+	uint8_t streams_per_subgroup;
+	uint8_t subgroups;
+	uint8_t sdu_interval[3];
+	uint8_t framing;
+	uint16_t max_sdu;
+	uint8_t retransmission_num;
+	uint16_t max_transport_latency;
+	uint8_t presentation_delay[3];
+	uint8_t coding_format;
+	uint16_t vid;
+	uint16_t cid;
+	uint8_t cc_ltvs_len;
+	uint8_t cc_ltvs[];
+} __packed;
+struct btp_bap_broadcast_source_setup_v2_rp {
+	uint32_t gap_settings;
+} __packed;
+
 /* BAP events */
 #define BTP_BAP_EV_DISCOVERY_COMPLETED		0x80
 struct btp_bap_discovery_completed_ev {
diff --git a/tests/bluetooth/tester/src/audio/btp_bap.c b/tests/bluetooth/tester/src/audio/btp_bap.c
index 1ad1e42..767eefa 100644
--- a/tests/bluetooth/tester/src/audio/btp_bap.c
+++ b/tests/bluetooth/tester/src/audio/btp_bap.c
@@ -332,6 +332,8 @@
 
 	/* octet 0 */
 	tester_set_bit(rp->data, BTP_BAP_READ_SUPPORTED_COMMANDS);
+	tester_set_bit(rp->data, BTP_BAP_DISCOVER);
+	tester_set_bit(rp->data, BTP_BAP_SEND);
 
 	*rsp_len = sizeof(*rp) + 1;
 
@@ -369,13 +371,18 @@
 		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
 		.func = btp_bap_audio_stream_send,
 	},
-#if defined(CONFIG_BT_BAP_BROADCAST_SINK) || defined(CONFIG_BT_BAP_BROADCAST_SINK)
+#if defined(CONFIG_BT_BAP_BROADCAST_SOURCE) || defined(CONFIG_BT_BAP_BROADCAST_SINK)
 	{
 		.opcode = BTP_BAP_BROADCAST_SOURCE_SETUP,
 		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
 		.func = btp_bap_broadcast_source_setup,
 	},
 	{
+		.opcode = BTP_BAP_BROADCAST_SOURCE_SETUP_V2,
+		.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
+		.func = btp_bap_broadcast_source_setup_v2,
+	},
+	{
 		.opcode = BTP_BAP_BROADCAST_SOURCE_RELEASE,
 		.expect_len = sizeof(struct btp_bap_broadcast_source_release_cmd),
 		.func = btp_bap_broadcast_source_release,
@@ -475,7 +482,7 @@
 		.expect_len = sizeof(struct btp_bap_send_past_cmd),
 		.func = btp_bap_broadcast_assistant_send_past,
 	},
-#endif /* CONFIG_BT_BAP_BROADCAST_SINK || CONFIG_BT_BAP_BROADCAST_SINK */
+#endif /* CONFIG_BT_BAP_BROADCAST_SOURCE || CONFIG_BT_BAP_BROADCAST_SINK */
 };
 
 uint8_t tester_init_pacs(void)
diff --git a/tests/bluetooth/tester/src/audio/btp_bap_broadcast.c b/tests/bluetooth/tester/src/audio/btp_bap_broadcast.c
index 29105d6..e0e942b 100644
--- a/tests/bluetooth/tester/src/audio/btp_bap_broadcast.c
+++ b/tests/bluetooth/tester/src/audio/btp_bap_broadcast.c
@@ -27,10 +27,11 @@
 #include "btp_bap_audio_stream.h"
 #include "btp_bap_broadcast.h"
 
-static K_SEM_DEFINE(sem_stream_stopped, 0U, CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT);
+static K_SEM_DEFINE(sem_stream_stopped, 0U,
+		    (CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT * CONFIG_BT_BAP_BROADCAST_SRC_COUNT));
 
 static struct btp_bap_broadcast_remote_source remote_broadcast_sources[1];
-static struct btp_bap_broadcast_local_source local_source;
+static struct btp_bap_broadcast_local_source local_sources[CONFIG_BT_BAP_BROADCAST_SRC_COUNT];
 /* Only one PA sync supported for now. */
 static struct btp_bap_broadcast_remote_source *broadcast_source_to_sync;
 /* A mask for the maximum BIS we can sync to. +1 since the BIS indexes start from 1. */
@@ -52,12 +53,72 @@
 	return &stream->audio_stream.cap_stream.bap_stream;
 }
 
-struct btp_bap_broadcast_local_source *btp_bap_broadcast_local_source_get(uint8_t source_id)
+uint8_t btp_bap_broadcast_local_source_idx_get(struct btp_bap_broadcast_local_source *source)
 {
-	/* Only one local broadcast source supported for now */
-	(void) source_id;
+	return ARRAY_INDEX(local_sources, source);
+}
 
-	return &local_source;
+struct btp_bap_broadcast_local_source *btp_bap_broadcast_local_source_allocate(
+	uint32_t broadcast_id)
+{
+	for (size_t i = 0; i < ARRAY_SIZE(local_sources); i++) {
+		if (local_sources[i].broadcast_id == broadcast_id) {
+			LOG_ERR("Local source already allocated for broadcast id %d", broadcast_id);
+
+			return NULL;
+		}
+	}
+
+	for (size_t i = 0; i < ARRAY_SIZE(local_sources); i++) {
+		if (!local_sources[i].allocated) {
+			local_sources[i].allocated = true;
+			local_sources[i].source_id = i;
+			local_sources[i].broadcast_id = broadcast_id;
+
+			return &local_sources[i];
+		}
+	}
+
+	return NULL;
+}
+
+static int btp_bap_broadcast_local_source_free(struct btp_bap_broadcast_local_source *source)
+{
+	if (source == NULL) {
+		return -EINVAL;
+	}
+
+	memset(&source, 0, sizeof(*source));
+
+	return 0;
+}
+
+struct btp_bap_broadcast_local_source *btp_bap_broadcast_local_source_from_src_id_get(
+	uint32_t source_id)
+{
+	for (size_t i = 0; i < ARRAY_SIZE(local_sources); i++) {
+		if (local_sources[i].source_id == source_id) {
+			return &local_sources[i];
+		}
+	}
+
+	LOG_ERR("No local source found with source id %u", source_id);
+
+	return NULL;
+}
+
+static struct btp_bap_broadcast_local_source *btp_bap_broadcast_local_source_from_brcst_id_get(
+	uint32_t broadcast_id)
+{
+	for (size_t i = 0; i < ARRAY_SIZE(local_sources); i++) {
+		if (local_sources[i].broadcast_id == broadcast_id) {
+			return &local_sources[i];
+		}
+	}
+
+	LOG_ERR("No local source found with broadcast id 0x%06X", broadcast_id);
+
+	return NULL;
 }
 
 static struct btp_bap_broadcast_remote_source *remote_broadcaster_alloc(void)
@@ -282,15 +343,14 @@
 	create_param.encryption = false;
 	create_param.packing = BT_ISO_PACKING_SEQUENTIAL;
 
-	LOG_DBG("Creating broadcast source with %zu subgroups with %zu streams",
-		subgroups, subgroups * streams_per_subgroup);
+	LOG_DBG("Creating broadcast source (%u) with %zu subgroups with %zu streams",
+		source->source_id, subgroups, subgroups * streams_per_subgroup);
 
 	if (source->bap_broadcast == NULL) {
 		err = bt_bap_broadcast_source_create(&create_param,
 						     &source->bap_broadcast);
 		if (err != 0) {
 			LOG_DBG("Unable to create broadcast source: %d", err);
-
 			return err;
 		}
 	} else {
@@ -298,7 +358,6 @@
 						       &create_param);
 		if (err != 0) {
 			LOG_DBG("Unable to reconfig broadcast source: %d", err);
-
 			return err;
 		}
 	}
@@ -326,8 +385,13 @@
 	struct btp_bap_broadcast_source_setup_rp *rp = rsp;
 	uint32_t broadcast_id;
 
-	/* Only one local source/BIG supported for now */
-	struct btp_bap_broadcast_local_source *source = &local_source;
+	err = bt_rand(&broadcast_id, BT_AUDIO_BROADCAST_ID_SIZE);
+	if (err != 0) {
+		LOG_DBG("Failed to generate broadcast id: %d", err);
+		return BTP_STATUS_FAILED;
+	}
+
+	struct btp_bap_broadcast_local_source *source;
 
 	uint32_t gap_settings = BIT(BTP_GAP_SETTINGS_DISCOVERABLE) |
 				BIT(BTP_GAP_SETTINGS_EXTENDED_ADVERTISING);
@@ -337,7 +401,7 @@
 
 	/* Broadcast Audio Streaming Endpoint advertising data */
 	struct bt_data base_ad[2];
-	struct bt_data per_ad;
+	struct bt_data *per_ad;
 
 	LOG_DBG("");
 
@@ -348,6 +412,12 @@
 	codec_cfg.data_len = cp->cc_ltvs_len;
 	memcpy(codec_cfg.data, cp->cc_ltvs, cp->cc_ltvs_len);
 
+	source = btp_bap_broadcast_local_source_allocate(broadcast_id);
+	if (source == NULL) {
+		LOG_DBG("No more free local source items");
+		return BTP_STATUS_FAILED;
+	}
+
 	source->qos.phy = BT_BAP_QOS_CFG_2M;
 	source->qos.framing = cp->framing;
 	source->qos.rtn = cp->retransmission_num;
@@ -361,14 +431,6 @@
 	err = setup_broadcast_source(cp->streams_per_subgroup, cp->subgroups, source, &codec_cfg);
 	if (err != 0) {
 		LOG_DBG("Unable to setup broadcast source: %d", err);
-
-		return BTP_STATUS_FAILED;
-	}
-
-	err = bt_rand(&broadcast_id, BT_AUDIO_BROADCAST_ID_SIZE);
-	if (err) {
-		LOG_DBG("Unable to generate broadcast ID: %d\n", err);
-
 		return BTP_STATUS_FAILED;
 	}
 
@@ -381,32 +443,32 @@
 	base_ad[1].type = BT_DATA_NAME_COMPLETE;
 	base_ad[1].data_len = sizeof(CONFIG_BT_DEVICE_NAME) - 1;
 	base_ad[1].data = CONFIG_BT_DEVICE_NAME;
-	err = tester_gap_create_adv_instance(&ext_adv_param, BTP_GAP_ADDR_TYPE_IDENTITY, base_ad, 2,
-					     NULL, 0, &gap_settings);
+
+	err = tester_gap_create_adv_instance(&ext_adv_param, BTP_GAP_ADDR_TYPE_IDENTITY,
+					     base_ad, ARRAY_SIZE(base_ad), NULL, 0, &gap_settings,
+					     &source->ext_adv);
 	if (err != 0) {
 		LOG_DBG("Failed to create extended advertising instance: %d", err);
-
 		return BTP_STATUS_FAILED;
 	}
 
-	err = tester_gap_padv_configure(&per_adv_param);
+	err = tester_gap_padv_configure(source->ext_adv, &per_adv_param);
 	if (err != 0) {
 		LOG_DBG("Failed to configure periodic advertising: %d", err);
-
 		return BTP_STATUS_FAILED;
 	}
 
 	err = bt_bap_broadcast_source_get_base(source->bap_broadcast, &base_buf);
 	if (err != 0) {
 		LOG_DBG("Failed to get encoded BASE: %d\n", err);
-
 		return BTP_STATUS_FAILED;
 	}
 
-	per_ad.type = BT_DATA_SVC_DATA16;
-	per_ad.data_len = base_buf.len;
-	per_ad.data = base_buf.data;
-	err = tester_gap_padv_set_data(&per_ad, 1);
+	per_ad = &source->per_adv_local;
+	per_ad->type = BT_DATA_SVC_DATA16;
+	per_ad->data_len = base_buf.len;
+	per_ad->data = base_buf.data;
+	err = tester_gap_padv_set_data(source->ext_adv, per_ad, 1);
 	if (err != 0) {
 		return BTP_STATUS_FAILED;
 	}
@@ -418,11 +480,133 @@
 	return BTP_STATUS_SUCCESS;
 }
 
+uint8_t btp_bap_broadcast_source_setup_v2(const void *cmd, uint16_t cmd_len,
+					  void *rsp, uint16_t *rsp_len)
+{
+	struct bt_le_per_adv_param per_adv_param =
+		*BT_LE_PER_ADV_PARAM(BT_GAP_MS_TO_PER_ADV_INTERVAL(150),
+				     BT_GAP_MS_TO_PER_ADV_INTERVAL(150), BT_LE_PER_ADV_OPT_NONE);
+	/* Zephyr Controller works best while Extended Advertising interval is a multiple
+	 * of the ISO Interval minus 10 ms (max. advertising random delay). This is
+	 * required to place the AUX_ADV_IND PDUs in a non-overlapping interval with the
+	 * Broadcast ISO radio events.
+	 */
+	struct bt_le_adv_param ext_adv_param =
+		*BT_LE_ADV_PARAM(BT_LE_ADV_OPT_EXT_ADV, BT_GAP_MS_TO_ADV_INTERVAL(140),
+				 BT_GAP_MS_TO_ADV_INTERVAL(140), NULL);
+	int err;
+	struct bt_audio_codec_cfg codec_cfg;
+	const struct btp_bap_broadcast_source_setup_v2_cmd *cp = cmd;
+	struct btp_bap_broadcast_source_setup_v2_rp *rp = rsp;
+
+	if ((cmd_len < sizeof(*cp)) ||
+	    (cmd_len != sizeof(*cp) + cp->cc_ltvs_len)) {
+		return BTP_STATUS_FAILED;
+	}
+
+	uint32_t broadcast_id = sys_get_le24(cp->broadcast_id);
+
+	struct btp_bap_broadcast_local_source *source;
+
+	uint32_t gap_settings = BIT(BTP_GAP_SETTINGS_DISCOVERABLE) |
+				BIT(BTP_GAP_SETTINGS_EXTENDED_ADVERTISING);
+
+	NET_BUF_SIMPLE_DEFINE(ad_buf, BT_UUID_SIZE_16 + BT_AUDIO_BROADCAST_ID_SIZE);
+	NET_BUF_SIMPLE_DEFINE(base_buf, 128);
+
+	/* Broadcast Audio Streaming Endpoint advertising data */
+	struct bt_data base_ad[2];
+	struct bt_data *per_ad;
+
+	LOG_DBG("");
+
+	memset(&codec_cfg, 0, sizeof(codec_cfg));
+	codec_cfg.id = cp->coding_format;
+	codec_cfg.vid = cp->vid;
+	codec_cfg.cid = cp->cid;
+	codec_cfg.data_len = cp->cc_ltvs_len;
+	memcpy(codec_cfg.data, cp->cc_ltvs, cp->cc_ltvs_len);
+
+	source = btp_bap_broadcast_local_source_allocate(broadcast_id);
+	if (source == NULL) {
+		LOG_DBG("No more free local source items");
+		return BTP_STATUS_FAILED;
+	}
+
+	source->qos.phy = BT_BAP_QOS_CFG_2M;
+	source->qos.framing = cp->framing;
+	source->qos.rtn = cp->retransmission_num;
+	source->qos.latency = sys_le16_to_cpu(cp->max_transport_latency);
+	source->qos.interval = sys_get_le24(cp->sdu_interval);
+	source->qos.pd = sys_get_le24(cp->presentation_delay);
+	source->qos.sdu = sys_le16_to_cpu(cp->max_sdu);
+
+	source->stream_count = cp->subgroups * cp->streams_per_subgroup;
+
+	err = setup_broadcast_source(cp->streams_per_subgroup, cp->subgroups, source, &codec_cfg);
+	if (err != 0) {
+		LOG_DBG("Unable to setup broadcast source: %d", err);
+		return BTP_STATUS_FAILED;
+	}
+
+	/* Setup extended advertising data */
+	net_buf_simple_add_le16(&ad_buf, BT_UUID_BROADCAST_AUDIO_VAL);
+	net_buf_simple_add_le24(&ad_buf, broadcast_id);
+	base_ad[0].type = BT_DATA_SVC_DATA16;
+	base_ad[0].data_len = ad_buf.len;
+	base_ad[0].data = ad_buf.data;
+	base_ad[1].type = BT_DATA_NAME_COMPLETE;
+	base_ad[1].data_len = sizeof(CONFIG_BT_DEVICE_NAME) - 1;
+	base_ad[1].data = CONFIG_BT_DEVICE_NAME;
+
+	err = tester_gap_create_adv_instance(&ext_adv_param, BTP_GAP_ADDR_TYPE_IDENTITY,
+					     base_ad, ARRAY_SIZE(base_ad), NULL, 0, &gap_settings,
+					     &source->ext_adv);
+	if (err != 0) {
+		LOG_DBG("Failed to create extended advertising instance: %d", err);
+		return BTP_STATUS_FAILED;
+	}
+
+	err = tester_gap_padv_configure(source->ext_adv, &per_adv_param);
+	if (err != 0) {
+		LOG_DBG("Failed to configure periodic advertising: %d", err);
+		return BTP_STATUS_FAILED;
+	}
+
+	err = bt_bap_broadcast_source_get_base(source->bap_broadcast, &base_buf);
+	if (err != 0) {
+		LOG_DBG("Failed to get encoded BASE: %d", err);
+		return BTP_STATUS_FAILED;
+	}
+
+	per_ad = &source->per_adv_local;
+	per_ad->type = BT_DATA_SVC_DATA16;
+	per_ad->data_len = base_buf.len;
+	per_ad->data = base_buf.data;
+	err = tester_gap_padv_set_data(source->ext_adv, per_ad, 1);
+	if (err != 0) {
+		LOG_DBG("Failed to set periodic advertising data: %d", err);
+		return BTP_STATUS_FAILED;
+	}
+
+	rp->gap_settings = gap_settings;
+	*rsp_len = sizeof(*rp) + 1;
+
+	return BTP_STATUS_SUCCESS;
+}
+
 uint8_t btp_bap_broadcast_source_release(const void *cmd, uint16_t cmd_len,
 					 void *rsp, uint16_t *rsp_len)
 {
 	int err;
-	struct btp_bap_broadcast_local_source *source = &local_source;
+	const struct btp_bap_broadcast_source_release_cmd *cp = cmd;
+	uint32_t broadcast_id = sys_get_le24(cp->broadcast_id);
+	struct btp_bap_broadcast_local_source *source =
+		btp_bap_broadcast_local_source_from_brcst_id_get(broadcast_id);
+
+	if (source == NULL) {
+		return BTP_STATUS_FAILED;
+	}
 
 	LOG_DBG("");
 
@@ -433,7 +617,7 @@
 		return BTP_STATUS_FAILED;
 	}
 
-	memset(source, 0, sizeof(*source));
+	btp_bap_broadcast_local_source_free(source);
 
 	return BTP_STATUS_SUCCESS;
 }
@@ -442,20 +626,27 @@
 				    void *rsp, uint16_t *rsp_len)
 {
 	int err;
-	struct bt_le_ext_adv *ext_adv = tester_gap_ext_adv_get();
+	const struct btp_bap_broadcast_adv_start_cmd *cp = cmd;
+	uint32_t broadcast_id = sys_get_le24(cp->broadcast_id);
+	struct btp_bap_broadcast_local_source *source =
+		btp_bap_broadcast_local_source_from_brcst_id_get(broadcast_id);
 
-	LOG_DBG("");
-
-	if (ext_adv == NULL) {
+	if (source == NULL) {
 		return BTP_STATUS_FAILED;
 	}
 
-	err = tester_gap_start_ext_adv();
+	LOG_DBG("");
+
+	if (source->ext_adv == NULL) {
+		return BTP_STATUS_FAILED;
+	}
+
+	err = tester_gap_start_ext_adv(source->ext_adv);
 	if (err != 0) {
 		return BTP_STATUS_FAILED;
 	}
 
-	err = tester_gap_padv_start();
+	err = tester_gap_padv_start(source->ext_adv);
 	if (err != 0) {
 		LOG_DBG("Unable to start periodic advertising: %d", err);
 
@@ -469,15 +660,23 @@
 				   void *rsp, uint16_t *rsp_len)
 {
 	int err;
+	const struct btp_bap_broadcast_adv_stop_cmd *cp = cmd;
+	uint32_t broadcast_id = sys_get_le24(cp->broadcast_id);
+	struct btp_bap_broadcast_local_source *source =
+		btp_bap_broadcast_local_source_from_brcst_id_get(broadcast_id);
+
+	if (source == NULL) {
+		return BTP_STATUS_FAILED;
+	}
 
 	LOG_DBG("");
 
-	err = tester_gap_padv_stop();
+	err = tester_gap_padv_stop(source->ext_adv);
 	if (err != 0) {
 		return BTP_STATUS_FAILED;
 	}
 
-	err = tester_gap_stop_ext_adv();
+	err = tester_gap_stop_ext_adv(source->ext_adv);
 
 	return BTP_STATUS_VAL(err);
 }
@@ -486,16 +685,22 @@
 				       void *rsp, uint16_t *rsp_len)
 {
 	int err;
-	struct btp_bap_broadcast_local_source *source = &local_source;
-	struct bt_le_ext_adv *ext_adv = tester_gap_ext_adv_get();
+	const struct btp_bap_broadcast_source_start_cmd *cp = cmd;
+	uint32_t broadcast_id = sys_get_le24(cp->broadcast_id);
+	struct btp_bap_broadcast_local_source *source =
+		btp_bap_broadcast_local_source_from_brcst_id_get(broadcast_id);
 
-	LOG_DBG("");
-
-	if (ext_adv == NULL) {
+	if (source == NULL) {
 		return BTP_STATUS_FAILED;
 	}
 
-	err = bt_bap_broadcast_source_start(source->bap_broadcast, ext_adv);
+	LOG_DBG("");
+
+	if (source->ext_adv == NULL) {
+		return BTP_STATUS_FAILED;
+	}
+
+	err = bt_bap_broadcast_source_start(source->bap_broadcast, source->ext_adv);
 	if (err != 0) {
 		LOG_DBG("Unable to start broadcast source: %d", err);
 
@@ -509,7 +714,14 @@
 				      void *rsp, uint16_t *rsp_len)
 {
 	int err;
-	struct btp_bap_broadcast_local_source *source = &local_source;
+	const struct btp_bap_broadcast_source_stop_cmd *cp = cmd;
+	uint32_t broadcast_id = sys_get_le24(cp->broadcast_id);
+	struct btp_bap_broadcast_local_source *source =
+		btp_bap_broadcast_local_source_from_brcst_id_get(broadcast_id);
+
+	if (source == NULL) {
+		return BTP_STATUS_FAILED;
+	}
 
 	LOG_DBG("");
 
diff --git a/tests/bluetooth/tester/src/audio/btp_bap_broadcast.h b/tests/bluetooth/tester/src/audio/btp_bap_broadcast.h
index acb49be..a10198c 100644
--- a/tests/bluetooth/tester/src/audio/btp_bap_broadcast.h
+++ b/tests/bluetooth/tester/src/audio/btp_bap_broadcast.h
@@ -41,11 +41,15 @@
 };
 
 struct btp_bap_broadcast_local_source {
+	bool allocated;
+	uint8_t source_id;
+	struct bt_le_ext_adv *ext_adv;
 	uint32_t broadcast_id;
 	struct bt_bap_qos_cfg qos;
 	struct btp_bap_broadcast_stream streams[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT];
 	struct bt_audio_codec_cfg subgroup_codec_cfg[CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT];
 	uint8_t stream_count;
+	struct bt_data per_adv_local;
 	/* Only for BTP BAP commands */
 	struct bt_bap_broadcast_source *bap_broadcast;
 	/* Only for BTP CAP commands */
@@ -53,12 +57,16 @@
 };
 
 int btp_bap_broadcast_init(void);
-struct btp_bap_broadcast_local_source *btp_bap_broadcast_local_source_get(uint8_t source_id);
+struct btp_bap_broadcast_local_source *btp_bap_broadcast_local_source_from_src_id_get(
+	uint32_t source_id);
+uint8_t btp_bap_broadcast_local_source_idx_get(struct btp_bap_broadcast_local_source *source);
 struct btp_bap_broadcast_stream *btp_bap_broadcast_stream_alloc(
 	struct btp_bap_broadcast_local_source *source);
 
 uint8_t btp_bap_broadcast_source_setup(const void *cmd, uint16_t cmd_len,
 				       void *rsp, uint16_t *rsp_len);
+uint8_t btp_bap_broadcast_source_setup_v2(const void *cmd, uint16_t cmd_len,
+					  void *rsp, uint16_t *rsp_len);
 uint8_t btp_bap_broadcast_source_release(const void *cmd, uint16_t cmd_len,
 					 void *rsp, uint16_t *rsp_len);
 uint8_t btp_bap_broadcast_adv_start(const void *cmd, uint16_t cmd_len,
diff --git a/tests/bluetooth/tester/src/audio/btp_cap.c b/tests/bluetooth/tester/src/audio/btp_cap.c
index c8e8e22..a847e8e 100644
--- a/tests/bluetooth/tester/src/audio/btp_cap.c
+++ b/tests/bluetooth/tester/src/audio/btp_cap.c
@@ -24,6 +24,18 @@
 
 static K_SEM_DEFINE(source_stopped_sem, 0U, CONFIG_BT_BAP_BROADCAST_SRC_COUNT);
 
+struct cap_initiator_broadcast_params {
+	struct bt_cap_initiator_broadcast_subgroup_param
+		cap_subgroup_params[CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT];
+	struct bt_cap_initiator_broadcast_stream_param
+		cap_stream_params[CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT]
+				 [CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT];
+};
+
+static struct cap_initiator_broadcast_params
+	cap_broadcast_params[CONFIG_BT_BAP_BROADCAST_SRC_COUNT];
+
+
 extern struct bt_csip_set_coordinator_set_member *btp_csip_set_members[CONFIG_BT_MAX_CONN];
 
 static struct bt_bap_stream *stream_unicast_to_bap(struct btp_bap_unicast_stream *stream)
@@ -460,12 +472,6 @@
 	return BTP_STATUS_SUCCESS;
 }
 
-static struct bt_cap_initiator_broadcast_subgroup_param
-	cap_subgroup_params[CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT];
-static struct bt_cap_initiator_broadcast_stream_param
-	cap_stream_params[CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT]
-		     [CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT];
-
 static uint8_t btp_cap_broadcast_source_setup_stream(const void *cmd, uint16_t cmd_len,
 						     void *rsp, uint16_t *rsp_len)
 {
@@ -473,7 +479,12 @@
 	struct btp_bap_broadcast_stream *stream;
 	const struct btp_cap_broadcast_source_setup_stream_cmd *cp = cmd;
 	struct btp_bap_broadcast_local_source *source =
-		btp_bap_broadcast_local_source_get(cp->source_id);
+		btp_bap_broadcast_local_source_from_src_id_get(cp->source_id);
+
+	if (source == NULL) {
+		return BTP_STATUS_FAILED;
+	}
+
 	struct bt_audio_codec_cfg *codec_cfg;
 
 	stream = btp_bap_broadcast_stream_alloc(source);
@@ -510,15 +521,29 @@
 	struct bt_audio_codec_cfg *codec_cfg;
 	const struct btp_cap_broadcast_source_setup_subgroup_cmd *cp = cmd;
 	struct btp_bap_broadcast_local_source *source =
-		btp_bap_broadcast_local_source_get(cp->source_id);
+		btp_bap_broadcast_local_source_from_src_id_get(cp->source_id);
 
-	if (cp->subgroup_id >= sizeof(cap_subgroup_params)) {
+	if (source == NULL) {
 		return BTP_STATUS_FAILED;
 	}
 
-	cap_subgroup_params[cp->subgroup_id].codec_cfg =
-		&source->subgroup_codec_cfg[cp->subgroup_id];
-	codec_cfg = cap_subgroup_params[cp->subgroup_id].codec_cfg;
+	if (cp->subgroup_id >= ARRAY_SIZE(cap_broadcast_params[0].cap_subgroup_params)) {
+		return BTP_STATUS_FAILED;
+	}
+
+	uint8_t idx = btp_bap_broadcast_local_source_idx_get(source);
+
+	if (idx >= ARRAY_SIZE(cap_broadcast_params)) {
+		return BTP_STATUS_FAILED;
+	}
+
+	struct bt_cap_initiator_broadcast_subgroup_param *subgroup_param =
+		&cap_broadcast_params[idx].cap_subgroup_params[cp->subgroup_id];
+
+	subgroup_param->codec_cfg = &source->subgroup_codec_cfg[cp->subgroup_id];
+
+	codec_cfg = subgroup_param->codec_cfg;
+
 	memset(codec_cfg, 0, sizeof(*codec_cfg));
 	codec_cfg->id = cp->coding_format;
 	codec_cfg->vid = cp->vid;
@@ -550,7 +575,7 @@
 	struct bt_data per_ad;
 
 	/* A more specialized adv instance may already have been created by another btp module */
-	if (tester_gap_ext_adv_get() == NULL) {
+	if (source->ext_adv == NULL) {
 		struct bt_le_adv_param param = *BT_LE_EXT_ADV_NCONN;
 		struct bt_data base_ad[2];
 
@@ -567,16 +592,17 @@
 		base_ad[1].data_len = sizeof(CONFIG_BT_DEVICE_NAME) - 1;
 		base_ad[1].data = CONFIG_BT_DEVICE_NAME;
 
-		err = tester_gap_create_adv_instance(&param, BTP_GAP_ADDR_TYPE_IDENTITY, base_ad,
-						     2, NULL, 0, gap_settings);
+		err = tester_gap_create_adv_instance(&param, BTP_GAP_ADDR_TYPE_IDENTITY,
+						     base_ad, 2, NULL, 0, gap_settings,
+						     &source->ext_adv);
 		if (err != 0) {
 			LOG_DBG("Failed to create extended advertising instance: %d", err);
-
 			return -EINVAL;
 		}
 	}
 
-	err = tester_gap_padv_configure(BT_LE_PER_ADV_PARAM(BT_GAP_PER_ADV_FAST_INT_MIN_2,
+	err = tester_gap_padv_configure(source->ext_adv,
+					BT_LE_PER_ADV_PARAM(BT_GAP_PER_ADV_FAST_INT_MIN_2,
 							    BT_GAP_PER_ADV_FAST_INT_MAX_2,
 							    BT_LE_PER_ADV_OPT_NONE));
 	if (err != 0) {
@@ -595,7 +621,7 @@
 	per_ad.type = BT_DATA_SVC_DATA16;
 	per_ad.data_len = base_buf.len;
 	per_ad.data = base_buf.data;
-	err = tester_gap_padv_set_data(&per_ad, 1);
+	err = tester_gap_padv_set_data(source->ext_adv, &per_ad, 1);
 	if (err != 0) {
 		return -EINVAL;
 	}
@@ -612,7 +638,15 @@
 	const struct btp_cap_broadcast_source_setup_cmd *cp = cmd;
 	struct btp_cap_broadcast_source_setup_rp *rp = rsp;
 	struct btp_bap_broadcast_local_source *source =
-		btp_bap_broadcast_local_source_get(cp->source_id);
+		btp_bap_broadcast_local_source_from_src_id_get(cp->source_id);
+
+	if (source == NULL) {
+		return BTP_STATUS_FAILED;
+	}
+
+	struct cap_initiator_broadcast_params *cap_params =
+		&cap_broadcast_params[cp->source_id];
+
 	struct bt_bap_qos_cfg *qos = &source->qos;
 
 	LOG_DBG("");
@@ -622,7 +656,6 @@
 	for (size_t i = 0; i < ARRAY_SIZE(source->streams); i++) {
 		struct btp_bap_broadcast_stream *stream = &source->streams[i];
 		struct bt_cap_initiator_broadcast_stream_param *stream_param;
-		struct bt_cap_initiator_broadcast_subgroup_param *subgroup_param;
 		uint8_t bis_id;
 
 		if (!stream->in_use) {
@@ -630,9 +663,9 @@
 			break;
 		}
 
-		subgroup_param = &cap_subgroup_params[stream->subgroup_id];
-		bis_id = subgroup_param->stream_count++;
-		stream_param = &cap_stream_params[stream->subgroup_id][bis_id];
+		bis_id = cap_params->cap_subgroup_params[stream->subgroup_id].stream_count++;
+		stream_param = &cap_params->cap_stream_params[stream->subgroup_id][bis_id];
+
 		stream_param->stream = stream_broadcast_to_cap(stream);
 
 		if (cp->flags & BTP_CAP_BROADCAST_SOURCE_SETUP_FLAG_SUBGROUP_CODEC) {
@@ -644,13 +677,13 @@
 		}
 	}
 
-	for (size_t i = 0; i < ARRAY_SIZE(cap_subgroup_params); i++) {
-		if (cap_subgroup_params[i].stream_count == 0) {
+	for (size_t i = 0; i < ARRAY_SIZE(cap_params->cap_subgroup_params); i++) {
+		if (cap_params->cap_subgroup_params[i].stream_count == 0) {
 			/* No gaps allowed */
 			break;
 		}
 
-		cap_subgroup_params[i].stream_params = cap_stream_params[i];
+		cap_params->cap_subgroup_params[i].stream_params = cap_params->cap_stream_params[i];
 		create_param.subgroup_count++;
 	}
 
@@ -667,14 +700,14 @@
 	qos->interval = sys_get_le24(cp->sdu_interval);
 	qos->pd = sys_get_le24(cp->presentation_delay);
 
-	create_param.subgroup_params = cap_subgroup_params;
+	create_param.subgroup_params = cap_params->cap_subgroup_params;
 	create_param.qos = qos;
 	create_param.packing = BT_ISO_PACKING_SEQUENTIAL;
 	create_param.encryption = cp->flags & BTP_CAP_BROADCAST_SOURCE_SETUP_FLAG_ENCRYPTION;
 	memcpy(create_param.broadcast_code, cp->broadcast_code, sizeof(cp->broadcast_code));
 
 	err = bt_cap_initiator_broadcast_audio_create(&create_param, &source->cap_broadcast);
-	memset(cap_subgroup_params, 0, sizeof(cap_subgroup_params));
+	memset(&cap_params->cap_subgroup_params, 0, sizeof(cap_params->cap_subgroup_params));
 	memset(&create_param, 0, sizeof(create_param));
 	if (err != 0) {
 		LOG_ERR("Failed to create audio source: %d", err);
@@ -700,7 +733,7 @@
 	int err;
 	const struct btp_cap_broadcast_source_release_cmd *cp = cmd;
 	struct btp_bap_broadcast_local_source *source =
-		btp_bap_broadcast_local_source_get(cp->source_id);
+		btp_bap_broadcast_local_source_from_src_id_get(cp->source_id);
 
 	LOG_DBG("");
 
@@ -725,20 +758,24 @@
 					   void *rsp, uint16_t *rsp_len)
 {
 	int err;
-	struct bt_le_ext_adv *ext_adv = tester_gap_ext_adv_get();
+	const struct btp_cap_broadcast_adv_start_cmd *cp = cmd;
+	struct btp_bap_broadcast_local_source *source =
+		btp_bap_broadcast_local_source_from_src_id_get(cp->source_id);
 
-	LOG_DBG("");
-
-	if (ext_adv == NULL) {
+	if (source == NULL) {
 		return BTP_STATUS_FAILED;
 	}
 
-	err = tester_gap_start_ext_adv();
+	if (source->ext_adv == NULL) {
+		return BTP_STATUS_FAILED;
+	}
+
+	err = tester_gap_start_ext_adv(source->ext_adv);
 	if (err != 0) {
 		return BTP_STATUS_FAILED;
 	}
 
-	err = tester_gap_padv_start();
+	err = tester_gap_padv_start(source->ext_adv);
 	if (err != 0) {
 		LOG_DBG("Unable to start periodic advertising: %d", err);
 
@@ -752,10 +789,18 @@
 					  void *rsp, uint16_t *rsp_len)
 {
 	int err;
+	const struct btp_cap_broadcast_adv_stop_cmd *cp = cmd;
 
 	LOG_DBG("");
 
-	err = tester_gap_padv_stop();
+	struct btp_bap_broadcast_local_source *source =
+		btp_bap_broadcast_local_source_from_src_id_get(cp->source_id);
+
+	if (source == NULL) {
+		return BTP_STATUS_FAILED;
+	}
+
+	err = tester_gap_padv_stop(source->ext_adv);
 	if (err == -ESRCH) {
 		/* Ext adv hasn't been created yet */
 		return BTP_STATUS_SUCCESS;
@@ -764,7 +809,7 @@
 		return BTP_STATUS_FAILED;
 	}
 
-	err = tester_gap_stop_ext_adv();
+	err = tester_gap_stop_ext_adv(source->ext_adv);
 
 	return BTP_STATUS_VAL(err);
 }
@@ -775,16 +820,19 @@
 	int err;
 	const struct btp_cap_broadcast_source_start_cmd *cp = cmd;
 	struct btp_bap_broadcast_local_source *source =
-		btp_bap_broadcast_local_source_get(cp->source_id);
-	struct bt_le_ext_adv *ext_adv = tester_gap_ext_adv_get();
+		btp_bap_broadcast_local_source_from_src_id_get(cp->source_id);
 
-	LOG_DBG("");
-
-	if (ext_adv == NULL) {
+	if (source == NULL) {
 		return BTP_STATUS_FAILED;
 	}
 
-	err = bt_cap_initiator_broadcast_audio_start(source->cap_broadcast, ext_adv);
+	LOG_DBG("");
+
+	if (source->ext_adv == NULL) {
+		return BTP_STATUS_FAILED;
+	}
+
+	err = bt_cap_initiator_broadcast_audio_start(source->cap_broadcast, source->ext_adv);
 	if (err != 0) {
 		LOG_ERR("Failed to start audio source: %d", err);
 
@@ -800,7 +848,7 @@
 	int err;
 	const struct btp_cap_broadcast_source_stop_cmd *cp = cmd;
 	struct btp_bap_broadcast_local_source *source =
-		btp_bap_broadcast_local_source_get(cp->source_id);
+		btp_bap_broadcast_local_source_from_src_id_get(cp->source_id);
 
 	/* If no source has been started yet, there is nothing to stop */
 	if (source == NULL || source->cap_broadcast == NULL) {
@@ -832,7 +880,12 @@
 	struct bt_data per_ad;
 	const struct btp_cap_broadcast_source_update_cmd *cp = cmd;
 	struct btp_bap_broadcast_local_source *source =
-		btp_bap_broadcast_local_source_get(cp->source_id);
+		btp_bap_broadcast_local_source_from_src_id_get(cp->source_id);
+
+	if (source == NULL) {
+		return BTP_STATUS_FAILED;
+	}
+
 	NET_BUF_SIMPLE_DEFINE(base_buf, 128);
 
 	LOG_DBG("");
@@ -859,7 +912,7 @@
 	per_ad.type = BT_DATA_SVC_DATA16;
 	per_ad.data_len = base_buf.len;
 	per_ad.data = base_buf.data;
-	err = tester_gap_padv_set_data(&per_ad, 1);
+	err = tester_gap_padv_set_data(source->ext_adv, &per_ad, 1);
 	if (err != 0) {
 		return -EINVAL;
 	}
diff --git a/tests/bluetooth/tester/src/audio/btp_pbp.c b/tests/bluetooth/tester/src/audio/btp_pbp.c
index d3acfcb..b3a5d8b 100644
--- a/tests/bluetooth/tester/src/audio/btp_pbp.c
+++ b/tests/bluetooth/tester/src/audio/btp_pbp.c
@@ -143,6 +143,7 @@
 
 	int err = bt_rand(&broadcast_id, BT_AUDIO_BROADCAST_ID_SIZE);
 	struct bt_data ext_ad[3];
+	struct bt_le_ext_adv *ext_adv = NULL;
 
 	if (err) {
 		LOG_ERR("Unable to generate broadcast ID: %d\n", err);
@@ -166,7 +167,7 @@
 	ext_ad[2].data = pba_buf.data;
 
 	err = tester_gap_create_adv_instance(&param, BTP_GAP_ADDR_TYPE_IDENTITY, ext_ad,
-					     ARRAY_SIZE(ext_ad), NULL, 0, &gap_settings);
+					     ARRAY_SIZE(ext_ad), NULL, 0, &gap_settings, &ext_adv);
 	if (err) {
 		LOG_ERR("Could not set up extended advertisement: %d", err);
 		return -EINVAL;
diff --git a/tests/bluetooth/tester/src/btp/btp_gap.h b/tests/bluetooth/tester/src/btp/btp_gap.h
index fd7826a..4ae2e53 100644
--- a/tests/bluetooth/tester/src/btp/btp_gap.h
+++ b/tests/bluetooth/tester/src/btp/btp_gap.h
@@ -448,17 +448,19 @@
 struct bt_le_per_adv_sync_param;
 struct bt_le_adv_param;
 struct bt_data;
-struct bt_le_ext_adv *tester_gap_ext_adv_get(void);
+struct bt_le_ext_adv *tester_gap_ext_adv_get(uint8_t ext_adv_idx);
 struct bt_le_per_adv_sync *tester_gap_padv_get(void);
 int tester_gap_create_adv_instance(struct bt_le_adv_param *param, uint8_t own_addr_type,
 				   const struct bt_data *ad, size_t ad_len,
-				   const struct bt_data *sd, size_t sd_len, uint32_t *settings);
-int tester_gap_stop_ext_adv(void);
-int tester_gap_start_ext_adv(void);
-int tester_gap_padv_configure(const struct bt_le_per_adv_param *param);
-int tester_gap_padv_set_data(struct bt_data *per_ad, uint8_t ad_len);
-int tester_gap_padv_start(void);
-int tester_gap_padv_stop(void);
+				   const struct bt_data *sd, size_t sd_len,
+				   uint32_t *settings, struct bt_le_ext_adv **ext_adv);
+int tester_gap_stop_ext_adv(struct bt_le_ext_adv *ext_adv);
+int tester_gap_start_ext_adv(struct bt_le_ext_adv *ext_adv);
+int tester_gap_padv_configure(struct bt_le_ext_adv *ext_adv,
+			      const struct bt_le_per_adv_param *param);
+int tester_gap_padv_set_data(struct bt_le_ext_adv *ext_adv, struct bt_data *per_ad, uint8_t ad_len);
+int tester_gap_padv_start(struct bt_le_ext_adv *ext_adv);
+int tester_gap_padv_stop(struct bt_le_ext_adv *ext_adv);
 int tester_gap_padv_create_sync(struct bt_le_per_adv_sync_param *create_params);
 int tester_gap_padv_stop_sync(void);
 #endif /* defined(CONFIG_BT_EXT_ADV) */
diff --git a/tests/bluetooth/tester/src/btp_gap.c b/tests/bluetooth/tester/src/btp_gap.c
index 350988f..547400d 100644
--- a/tests/bluetooth/tester/src/btp_gap.c
+++ b/tests/bluetooth/tester/src/btp_gap.c
@@ -522,18 +522,42 @@
 };
 static struct bt_data sd[10];
 
-static struct bt_le_ext_adv *ext_adv;
+#if CONFIG_BT_EXT_ADV
+static struct bt_le_ext_adv *ext_adv_sets[CONFIG_BT_EXT_ADV_MAX_ADV_SET];
+#else
+static struct bt_le_ext_adv *ext_adv_sets[1];
+#endif
 
-struct bt_le_ext_adv *tester_gap_ext_adv_get(void)
+struct bt_le_ext_adv *tester_gap_ext_adv_get(uint8_t ext_adv_idx)
 {
 	if (!IS_ENABLED(CONFIG_BT_EXT_ADV)) {
 		return NULL;
 	}
 
-	return ext_adv;
+	if (ext_adv_idx >= ARRAY_SIZE(ext_adv_sets)) {
+		LOG_ERR("Invalid ext_adv_id: %d", ext_adv_idx);
+		return NULL;
+	}
+
+	return ext_adv_sets[ext_adv_idx];
 }
 
-int tester_gap_start_ext_adv(void)
+static int tester_gap_ext_adv_idx_free_get(void)
+{
+	if (!IS_ENABLED(CONFIG_BT_EXT_ADV)) {
+		return -ENOTSUP;
+	}
+
+	for (int i = 0; i < ARRAY_SIZE(ext_adv_sets); i++) {
+		if (ext_adv_sets[i] == NULL) {
+			return i;
+		}
+	}
+
+	return -ENOMEM;
+}
+
+int tester_gap_start_ext_adv(struct bt_le_ext_adv *ext_adv)
 {
 	if (!IS_ENABLED(CONFIG_BT_EXT_ADV)) {
 		return -ENOTSUP;
@@ -541,10 +565,14 @@
 
 	int err;
 
+	if (ext_adv == NULL) {
+		LOG_ERR("Invalid ext_adv");
+		return -EINVAL;
+	}
+
 	err = bt_le_ext_adv_start(ext_adv, BT_LE_EXT_ADV_START_DEFAULT);
 	if (err != 0) {
 		LOG_ERR("Failed to start advertising");
-
 		return -EINVAL;
 	}
 
@@ -553,7 +581,7 @@
 	return 0;
 }
 
-int tester_gap_stop_ext_adv(void)
+int tester_gap_stop_ext_adv(struct bt_le_ext_adv *ext_adv)
 {
 	if (!IS_ENABLED(CONFIG_BT_EXT_ADV)) {
 		return -ENOTSUP;
@@ -561,6 +589,11 @@
 
 	int err;
 
+	if (ext_adv == NULL) {
+		LOG_ERR("Invalid ext_adv");
+		return -EINVAL;
+	}
+
 	err = bt_le_ext_adv_stop(ext_adv);
 	if (err != 0) {
 		LOG_ERR("Failed to stop advertising");
@@ -625,10 +658,10 @@
 	return BTP_STATUS_SUCCESS;
 }
 
-int tester_gap_create_adv_instance(struct bt_le_adv_param *param, uint8_t own_addr_type,
-				   const struct bt_data *ad, size_t ad_len,
-				   const struct bt_data *sd, size_t sd_len,
-				   uint32_t *settings)
+int tester_gap_create_adv_instance(struct bt_le_adv_param *param,
+				   uint8_t own_addr_type, const struct bt_data *ad, size_t ad_len,
+				   const struct bt_data *sd, size_t sd_len, uint32_t *settings,
+				   struct bt_le_ext_adv **ext_adv)
 {
 	int err = 0;
 
@@ -678,27 +711,41 @@
 
 	if (IS_ENABLED(CONFIG_BT_EXT_ADV) && atomic_test_bit(&current_settings,
 	    BTP_GAP_SETTINGS_EXTENDED_ADVERTISING)) {
+
 		param->options |= BT_LE_ADV_OPT_EXT_ADV;
-		if (ext_adv != NULL) {
-			err = bt_le_ext_adv_stop(ext_adv);
+		if (*ext_adv) {
+			err = bt_le_ext_adv_stop(*ext_adv);
 			if (err != 0) {
 				return err;
 			}
 
-			err = bt_le_ext_adv_delete(ext_adv);
+			err = bt_le_ext_adv_delete(*ext_adv);
 			if (err != 0) {
 				return err;
 			}
 
-			ext_adv = NULL;
+			*ext_adv = NULL;
 		}
 
-		err = bt_le_ext_adv_create(param, NULL, &ext_adv);
+		int index = tester_gap_ext_adv_idx_free_get();
+
+		if (index < 0) {
+			LOG_ERR("No free ext_adv index");
+			return -ENOMEM;
+		}
+
+		/* Set the set_id to be matching the index of the ext_adv set */
+		param->sid = index;
+
+		err = bt_le_ext_adv_create(param, NULL, &ext_adv_sets[index]);
 		if (err != 0) {
 			return BTP_STATUS_FAILED;
 		}
 
-		err = bt_le_ext_adv_set_data(ext_adv, ad, ad_len, sd_len ? sd : NULL, sd_len);
+		err = bt_le_ext_adv_set_data(ext_adv_sets[index], ad, ad_len, sd_len ?
+					     sd : NULL, sd_len);
+
+		*ext_adv = ext_adv_sets[index];
 	}
 
 	return err;
@@ -757,7 +804,10 @@
 		i += sd[sd_len].data_len;
 	}
 
-	err = tester_gap_create_adv_instance(&param, own_addr_type, ad, adv_len, sd, sd_len, NULL);
+	struct bt_le_ext_adv *ext_adv = NULL;
+
+	err = tester_gap_create_adv_instance(&param, own_addr_type, ad, adv_len, sd,
+					     sd_len, NULL, &ext_adv);
 	if (err != 0) {
 		return BTP_STATUS_FAILED;
 	}
@@ -1462,7 +1512,8 @@
 #if defined(CONFIG_BT_PER_ADV)
 static struct bt_data padv[10];
 
-int tester_gap_padv_configure(const struct bt_le_per_adv_param *param)
+int tester_gap_padv_configure(struct bt_le_ext_adv *ext_adv,
+			      const struct bt_le_per_adv_param *param)
 {
 	int err;
 	struct bt_le_adv_param ext_adv_param =
@@ -1471,8 +1522,9 @@
 	if (ext_adv == NULL) {
 		current_settings = BIT(BTP_GAP_SETTINGS_DISCOVERABLE) |
 				   BIT(BTP_GAP_SETTINGS_EXTENDED_ADVERTISING);
-		err = tester_gap_create_adv_instance(&ext_adv_param, BTP_GAP_ADDR_TYPE_IDENTITY, ad,
-						     1, NULL, 0, NULL);
+		err = tester_gap_create_adv_instance(&ext_adv_param,
+						     BTP_GAP_ADDR_TYPE_IDENTITY, ad, 1, NULL, 0,
+						     NULL, &ext_adv);
 		if (err != 0) {
 			return -EINVAL;
 		}
@@ -1501,9 +1553,11 @@
 		options |= BT_LE_PER_ADV_OPT_USE_TX_POWER;
 	}
 
-	err = tester_gap_padv_configure(BT_LE_PER_ADV_PARAM(sys_le16_to_cpu(cp->interval_min),
-							    sys_le16_to_cpu(cp->interval_max),
-							    options));
+	struct bt_le_ext_adv *ext_adv = tester_gap_ext_adv_get(0);
+
+	err = tester_gap_padv_configure(ext_adv,
+					BT_LE_PER_ADV_PARAM(sys_le16_to_cpu(cp->interval_min),
+					sys_le16_to_cpu(cp->interval_max), options));
 	if (err) {
 		return BTP_STATUS_FAILED;
 	}
@@ -1515,7 +1569,7 @@
 	return BTP_STATUS_SUCCESS;
 }
 
-int tester_gap_padv_start(void)
+int tester_gap_padv_start(struct bt_le_ext_adv *ext_adv)
 {
 	int err;
 
@@ -1524,7 +1578,7 @@
 	}
 
 	if (!atomic_test_bit(&current_settings, BTP_GAP_SETTINGS_ADVERTISING)) {
-		err = tester_gap_start_ext_adv();
+		err = tester_gap_start_ext_adv(ext_adv);
 		if (err != 0) {
 			return -EINVAL;
 		}
@@ -1545,7 +1599,9 @@
 	int err;
 	struct btp_gap_padv_start_rp *rp = rsp;
 
-	err = tester_gap_padv_start();
+	struct bt_le_ext_adv *ext_adv = tester_gap_ext_adv_get(0);
+
+	err = tester_gap_padv_start(ext_adv);
 
 	if (err) {
 		return BTP_STATUS_FAILED;
@@ -1558,7 +1614,7 @@
 	return BTP_STATUS_SUCCESS;
 }
 
-int tester_gap_padv_stop(void)
+int tester_gap_padv_stop(struct bt_le_ext_adv *ext_adv)
 {
 	int err;
 
@@ -1581,8 +1637,9 @@
 {
 	int err;
 	struct btp_gap_padv_stop_rp *rp = rsp;
+	struct bt_le_ext_adv *ext_adv = tester_gap_ext_adv_get(0);
 
-	err = tester_gap_padv_stop();
+	err = tester_gap_padv_stop(ext_adv);
 
 	if (err) {
 		return BTP_STATUS_FAILED;
@@ -1595,7 +1652,7 @@
 	return BTP_STATUS_SUCCESS;
 }
 
-int tester_gap_padv_set_data(struct bt_data *per_ad, uint8_t ad_len)
+int tester_gap_padv_set_data(struct bt_le_ext_adv *ext_adv, struct bt_data *per_ad, uint8_t ad_len)
 {
 	int err;
 
@@ -1616,9 +1673,10 @@
 			     void *rsp, uint16_t *rsp_len)
 {
 	int err;
-	uint8_t padv_len = 0U;
 	const struct btp_gap_padv_set_data_cmd *cp = cmd;
 
+	uint8_t padv_len = 0U;
+
 	for (uint8_t i = 0; i < cp->data_len; padv_len++) {
 		if (padv_len >= ARRAY_SIZE(padv)) {
 			LOG_ERR("padv[] Out of memory");
@@ -1631,7 +1689,9 @@
 		i += padv[padv_len].data_len;
 	}
 
-	err = tester_gap_padv_set_data(padv, padv_len);
+	struct bt_le_ext_adv *ext_adv = tester_gap_ext_adv_get(0);
+
+	err = tester_gap_padv_set_data(ext_adv, padv, padv_len);
 
 	return BTP_STATUS_VAL(err);
 }