From 17b39baa6168758c1fe32e3902676f550274a4e3 Mon Sep 17 00:00:00 2001 From: Magdalena Kasenberg Date: Fri, 15 Sep 2023 17:10:57 +0200 Subject: [PATCH] bluetooth: tester: Add support for BASS Support for BAP/BASS and BASS test cases. Signed-off-by: Magdalena Kasenberg --- tests/bluetooth/tester/overlay-le-audio.conf | 9 + tests/bluetooth/tester/src/btp/btp_ascs.h | 2 +- tests/bluetooth/tester/src/btp/btp_bap.h | 119 ++- tests/bluetooth/tester/src/btp/btp_gap.h | 3 +- tests/bluetooth/tester/src/btp/btp_pacs.h | 2 +- tests/bluetooth/tester/src/btp_bap.c | 761 +++++++++++++++++-- tests/bluetooth/tester/src/btp_core.c | 21 +- tests/bluetooth/tester/src/btp_gap.c | 20 +- 8 files changed, 858 insertions(+), 79 deletions(-) diff --git a/tests/bluetooth/tester/overlay-le-audio.conf b/tests/bluetooth/tester/overlay-le-audio.conf index 530558c1308..4a7fc4e606c 100644 --- a/tests/bluetooth/tester/overlay-le-audio.conf +++ b/tests/bluetooth/tester/overlay-le-audio.conf @@ -31,6 +31,7 @@ CONFIG_BT_BAP_BROADCAST_SOURCE=y 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 # Broadcast Sink CONFIG_BT_BAP_SCAN_DELEGATOR=y @@ -38,6 +39,14 @@ CONFIG_BT_BAP_BROADCAST_SINK=y CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT=2 CONFIG_BT_BAP_BROADCAST_SNK_SUBGROUP_COUNT=2 +# BASS +CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER=y +CONFIG_BT_BAP_SCAN_DELEGATOR_MAX_METADATA_LEN=255 +CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER=y +# BASS notifications need higher MTU +CONFIG_BT_L2CAP_TX_MTU=255 +CONFIG_BT_BUF_ACL_RX_SIZE=255 + # ASCS CONFIG_BT_ASCS_ASE_SNK_COUNT=2 CONFIG_BT_ASCS_ASE_SRC_COUNT=2 diff --git a/tests/bluetooth/tester/src/btp/btp_ascs.h b/tests/bluetooth/tester/src/btp/btp_ascs.h index f14cb5de3d4..739e8c7d824 100644 --- a/tests/bluetooth/tester/src/btp/btp_ascs.h +++ b/tests/bluetooth/tester/src/btp/btp_ascs.h @@ -1,4 +1,4 @@ -/* btp_bap.h - Bluetooth tester headers */ +/* btp_ascs.h - Bluetooth tester headers */ /* * Copyright (c) 2023 Codecoup diff --git a/tests/bluetooth/tester/src/btp/btp_bap.h b/tests/bluetooth/tester/src/btp/btp_bap.h index ede3448f2cf..d094d536390 100644 --- a/tests/bluetooth/tester/src/btp/btp_bap.h +++ b/tests/bluetooth/tester/src/btp/btp_bap.h @@ -6,6 +6,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + /* BAP commands */ #define BTP_BAP_READ_SUPPORTED_COMMANDS 0x01 struct btp_bap_read_supported_commands_rp { @@ -50,32 +52,32 @@ struct btp_bap_broadcast_source_setup_cmd { } __packed; struct btp_bap_broadcast_source_setup_rp { uint32_t gap_settings; - uint8_t broadcast_id[3]; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; } __packed; #define BTP_BAP_BROADCAST_SOURCE_RELEASE 0x05 struct btp_bap_broadcast_source_release_cmd { - uint8_t broadcast_id[3]; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; } __packed; #define BTP_BAP_BROADCAST_ADV_START 0x06 struct btp_bap_broadcast_adv_start_cmd { - uint8_t broadcast_id[3]; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; } __packed; #define BTP_BAP_BROADCAST_ADV_STOP 0x07 struct btp_bap_broadcast_adv_stop_cmd { - uint8_t broadcast_id[3]; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; } __packed; #define BTP_BAP_BROADCAST_SOURCE_START 0x08 struct btp_bap_broadcast_source_start_cmd { - uint8_t broadcast_id[3]; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; } __packed; #define BTP_BAP_BROADCAST_SOURCE_STOP 0x09 struct btp_bap_broadcast_source_stop_cmd { - uint8_t broadcast_id[3]; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; } __packed; #define BTP_BAP_BROADCAST_SINK_SETUP 0x0a @@ -97,16 +99,81 @@ struct btp_bap_broadcast_scan_stop_cmd { #define BTP_BAP_BROADCAST_SINK_SYNC 0x0e struct btp_bap_broadcast_sink_sync_cmd { bt_addr_le_t address; - uint8_t broadcast_id[3]; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; uint8_t advertiser_sid; uint16_t skip; uint16_t sync_timeout; + uint8_t past_avail; + uint8_t src_id; } __packed; #define BTP_BAP_BROADCAST_SINK_STOP 0x0f struct btp_bap_broadcast_sink_stop_cmd { bt_addr_le_t address; - uint8_t broadcast_id[3]; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; +} __packed; + +#define BTP_BAP_BROADCAST_SINK_BIS_SYNC 0x10 +struct btp_bap_broadcast_sink_bis_sync_cmd { + bt_addr_le_t address; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; + uint32_t requested_bis_sync; +} __packed; + +#define BTP_BAP_DISCOVER_SCAN_DELEGATORS 0x11 +struct btp_bap_discover_scan_delegators_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_BAP_BROADCAST_ASSISTANT_SCAN_START 0x12 +struct btp_bap_broadcast_assistant_scan_start_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_BAP_BROADCAST_ASSISTANT_SCAN_STOP 0x13 +struct btp_bap_broadcast_assistant_scan_stop_cmd { + bt_addr_le_t address; +} __packed; + +#define BTP_BAP_ADD_BROADCAST_SRC 0x14 +struct btp_bap_add_broadcast_src_cmd { + bt_addr_le_t address; + bt_addr_le_t broadcaster_address; + uint8_t advertiser_sid; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; + uint8_t padv_sync; + uint16_t padv_interval; + uint8_t num_subgroups; + uint8_t subgroups[0]; +} __packed; + +#define BTP_BAP_REMOVE_BROADCAST_SRC 0x15 +struct btp_bap_remove_broadcast_src_cmd { + bt_addr_le_t address; + uint8_t src_id; +} __packed; + +#define BTP_BAP_MODIFY_BROADCAST_SRC 0x16 +struct btp_bap_modify_broadcast_src_cmd { + bt_addr_le_t address; + uint8_t src_id; + uint8_t padv_sync; + uint16_t padv_interval; + uint8_t num_subgroups; + uint8_t subgroups[0]; +} __packed; + +#define BTP_BAP_SET_BROADCAST_CODE 0x17 +struct btp_bap_set_broadcast_code_cmd { + bt_addr_le_t address; + uint8_t src_id; + uint8_t broadcast_code[BT_AUDIO_BROADCAST_CODE_SIZE]; +} __packed; + +#define BTP_BAP_SEND_PAST 0x18 +struct btp_bap_send_past_cmd { + bt_addr_le_t address; + uint8_t src_id; } __packed; /* BAP events */ @@ -145,7 +212,7 @@ struct btp_bap_stream_received_ev { #define BTP_BAP_EV_BAA_FOUND 0x84 struct btp_bap_baa_found_ev { bt_addr_le_t address; - uint8_t broadcast_id[3]; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; uint8_t advertiser_sid; uint16_t padv_interval; } __packed; @@ -153,7 +220,7 @@ struct btp_bap_baa_found_ev { #define BTP_BAP_EV_BIS_FOUND 0x85 struct btp_bap_bis_found_ev { bt_addr_le_t address; - uint8_t broadcast_id[3]; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; uint8_t presentation_delay[3]; uint8_t subgroup_id; uint8_t bis_id; @@ -167,15 +234,43 @@ struct btp_bap_bis_found_ev { #define BTP_BAP_EV_BIS_SYNCED 0x86 struct btp_bap_bis_syned_ev { bt_addr_le_t address; - uint8_t broadcast_id[3]; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; uint8_t bis_id; } __packed; #define BTP_BAP_EV_BIS_STREAM_RECEIVED 0x87 struct btp_bap_bis_stream_received_ev { bt_addr_le_t address; - uint8_t broadcast_id[3]; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; uint8_t bis_id; uint8_t data_len; uint8_t data[]; } __packed; + +#define BTP_BAP_EV_SCAN_DELEGATOR_FOUND 0x88 +struct btp_bap_scan_delegator_found_ev { + bt_addr_le_t address; +} __packed; + +#define BTP_BAP_EV_BROADCAST_RECEIVE_STATE 0x89 +struct btp_bap_broadcast_receive_state_ev { + bt_addr_le_t address; + uint8_t src_id; + bt_addr_le_t broadcaster_address; + uint8_t advertiser_sid; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; + uint8_t pa_sync_state; + uint8_t big_encryption; + uint8_t num_subgroups; + uint8_t subgroups[0]; +} __packed; + +#define BTP_BAP_EV_PA_SYNC_REQ 0x8a +struct btp_bap_pa_sync_req_ev { + bt_addr_le_t address; + uint8_t src_id; + uint8_t advertiser_sid; + uint8_t broadcast_id[BT_AUDIO_BROADCAST_ID_SIZE]; + uint8_t past_avail; + uint16_t pa_interval; +} __packed; diff --git a/tests/bluetooth/tester/src/btp/btp_gap.h b/tests/bluetooth/tester/src/btp/btp_gap.h index 960d810e025..a727ffce4e4 100644 --- a/tests/bluetooth/tester/src/btp/btp_gap.h +++ b/tests/bluetooth/tester/src/btp/btp_gap.h @@ -456,5 +456,6 @@ 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); -int tester_padv_create_sync(struct bt_le_per_adv_sync_param *create_params); +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/btp_pacs.h b/tests/bluetooth/tester/src/btp/btp_pacs.h index 91f9596e869..7403feee762 100644 --- a/tests/bluetooth/tester/src/btp/btp_pacs.h +++ b/tests/bluetooth/tester/src/btp/btp_pacs.h @@ -1,4 +1,4 @@ -/* btp_bap.h - Bluetooth tester headers */ +/* btp_pacs.h - Bluetooth tester headers */ /* * Copyright (c) 2023 Codecoup diff --git a/tests/bluetooth/tester/src/btp_bap.c b/tests/bluetooth/tester/src/btp_bap.c index a35950b9cc5..d6149d2c3ac 100644 --- a/tests/bluetooth/tester/src/btp_bap.c +++ b/tests/bluetooth/tester/src/btp_bap.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "bap_endpoint.h" #include @@ -118,7 +119,15 @@ static struct bt_bap_stream *sink_streams[MAX_STREAMS_COUNT]; /* A mask for the maximum BIS we can sync to. +1 since the BIS indexes start from 1. */ static const uint32_t bis_index_mask = BIT_MASK(MAX_STREAMS_COUNT + 1); static uint32_t bis_index_bitfield; +static uint32_t requested_bis_sync; #define INVALID_BROADCAST_ID (BT_AUDIO_BROADCAST_ID_MAX + 1) +#define SYNC_RETRY_COUNT 6 /* similar to retries for connections */ +#define PA_SYNC_SKIP 5 +/* Sample assumes that we only have a single Scan Delegator receive state */ +static const struct bt_bap_scan_delegator_recv_state *sink_recv_state; +static const struct bt_bap_scan_delegator_recv_state *broadcast_recv_state; +static uint8_t sink_broadcast_code[BT_AUDIO_BROADCAST_CODE_SIZE]; +static struct bt_bap_scan_delegator_subgroup delegator_subgroups[BROADCAST_SNK_SUBGROUP_CNT]; static bool print_cb(struct bt_data *data, void *user_data) { @@ -237,10 +246,8 @@ static void btp_send_ascs_operation_completed_ev(struct bt_conn *conn, uint8_t a uint8_t opcode, uint8_t status) { struct btp_ascs_operation_completed_ev ev; - struct bt_conn_info info; - (void)bt_conn_get_info(conn, &info); - bt_addr_le_copy(&ev.address, info.le.dst); + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); ev.ase_id = ase_id; ev.opcode = opcode; ev.status = status; @@ -252,10 +259,8 @@ static void btp_send_ascs_operation_completed_ev(struct bt_conn *conn, uint8_t a static void btp_send_ascs_ase_state_changed_ev(struct bt_conn *conn, uint8_t ase_id, uint8_t state) { struct btp_ascs_ase_state_changed_ev ev; - struct bt_conn_info info; - (void)bt_conn_get_info(conn, &info); - bt_addr_le_copy(&ev.address, info.le.dst); + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); ev.ase_id = ase_id; ev.state = state; @@ -487,18 +492,15 @@ static void btp_send_stream_received_ev(struct bt_conn *conn, struct bt_bap_ep * uint8_t data_len, uint8_t *data) { struct btp_bap_stream_received_ev *ev; - struct bt_conn_info info; LOG_DBG("Stream received, ep %d, dir %d, len %d", ep->status.id, ep->dir, data_len); - (void)bt_conn_get_info(conn, &info); - net_buf_simple_init(rx_ev_buf, 0); ev = net_buf_simple_add(rx_ev_buf, sizeof(*ev)); - bt_addr_le_copy(&ev->address, info.le.dst); + bt_addr_le_copy(&ev->address, bt_conn_get_dst(conn)); ev->ase_id = ep->status.id; ev->data_len = data_len; @@ -680,6 +682,7 @@ static void stream_started(struct bt_bap_stream *stream) } if (a_stream->broadcast) { + a_stream->bis_synced = true; btp_send_bis_syced_ev(&broadcaster_addr, broadcaster_broadcast_id, a_stream->bis_id); } else { @@ -701,6 +704,8 @@ static void stream_stopped(struct bt_bap_stream *stream, uint8_t reason) if (!a_stream->broadcast) { btp_send_ascs_operation_completed_ev(stream->conn, a_stream->ase_id, BT_ASCS_STOP_OP, BTP_STATUS_SUCCESS); + } else { + a_stream->bis_synced = false; } } @@ -747,10 +752,8 @@ static struct bt_bap_stream_ops stream_ops = { static void btp_send_discovery_completed_ev(struct bt_conn *conn, uint8_t status) { struct btp_bap_discovery_completed_ev ev; - struct bt_conn_info info; - (void) bt_conn_get_info(conn, &info); - bt_addr_le_copy(&ev.address, info.le.dst); + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); ev.status = status; tester_event(BTP_SERVICE_ID_BAP, BTP_BAP_EV_DISCOVERY_COMPLETED, &ev, sizeof(ev)); @@ -807,11 +810,9 @@ static void btp_send_pac_codec_found_ev(struct bt_conn *conn, enum bt_audio_dir dir) { struct btp_bap_codec_cap_found_ev ev; - struct bt_conn_info info; const uint8_t *data; - (void)bt_conn_get_info(conn, &info); - bt_addr_le_copy(&ev.address, info.le.dst); + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); ev.dir = dir; ev.coding_format = codec_cap->id; @@ -838,10 +839,8 @@ static void btp_send_pac_codec_found_ev(struct bt_conn *conn, static void btp_send_ase_found_ev(struct bt_conn *conn, struct bt_bap_ep *ep) { struct btp_ascs_ase_found_ev ev; - struct bt_conn_info info; - (void)bt_conn_get_info(conn, &info); - bt_addr_le_copy(&ev.address, info.le.dst); + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); ev.ase_id = ep->status.id; ev.dir = ep->dir; @@ -1418,6 +1417,8 @@ static uint8_t broadcast_source_stop(const void *cmd, uint16_t cmd_len, static int broadcast_sink_reset(void) { bis_index_bitfield = 0U; + sink_recv_state = NULL; + (void)memset(sink_broadcast_code, 0, sizeof(sink_broadcast_code)); (void)memset(&broadcaster_addr, 0, sizeof(broadcaster_addr)); (void)memset(broadcaster, 0, sizeof(*broadcaster)); broadcaster_broadcast_id = INVALID_BROADCAST_ID; @@ -1433,18 +1434,20 @@ static void btp_send_baa_found_ev(const bt_addr_le_t *address, uint32_t broadcas bt_addr_le_copy(&ev.address, address); sys_put_le24(broadcast_id, ev.broadcast_id); ev.advertiser_sid = sid; - ev.padv_interval = interval; + ev.padv_interval = sys_cpu_to_le16(interval); tester_event(BTP_SERVICE_ID_BAP, BTP_BAP_EV_BAA_FOUND, &ev, sizeof(ev)); } -static bool scan_check_and_sync_broadcast(struct bt_data *data, void *user_data) +static bool baa_check(struct bt_data *data, void *user_data) { const struct bt_le_scan_recv_info *info = user_data; char le_addr[BT_ADDR_LE_STR_LEN]; struct bt_uuid_16 adv_uuid; uint32_t broadcast_id; + /* Parse the scanned Broadcast Audio Announcement */ + if (data->type != BT_DATA_SVC_DATA16) { return true; } @@ -1465,8 +1468,8 @@ static bool scan_check_and_sync_broadcast(struct bt_data *data, void *user_data) bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr)); - LOG_DBG("Found broadcaster with ID 0x%06X and addr %s and sid 0x%02X", broadcast_id, - le_addr, info->sid); + LOG_DBG("Found BAA with ID 0x%06X, addr %s, sid 0x%02X, interval 0x%04X", + broadcast_id, le_addr, info->sid, info->interval); btp_send_baa_found_ev(info->addr, broadcast_id, info->sid, info->interval); @@ -1478,7 +1481,7 @@ static void broadcast_scan_recv(const struct bt_le_scan_recv_info *info, struct { /* If 0 there is no periodic advertising. */ if (info->interval != 0U) { - bt_data_parse(ad, scan_check_and_sync_broadcast, (void *)info); + bt_data_parse(ad, baa_check, (void *)info); } } @@ -1526,8 +1529,7 @@ static void base_recv_cb(struct bt_bap_broadcast_sink *sink, const struct bt_bap return; } - LOG_DBG("Received BASE with %u subgroups from broadcast sink %p", base->subgroup_count, - sink); + LOG_DBG("Received BASE: broadcast sink %p subgroups %u", sink, base->subgroup_count); for (size_t i = 0U; i < base->subgroup_count; i++) { for (size_t j = 0U; j < base->subgroups[i].bis_count; j++) { @@ -1546,15 +1548,29 @@ static void base_recv_cb(struct bt_bap_broadcast_sink *sink, const struct bt_bap } bis_index_bitfield = base_bis_index_bitfield & bis_index_mask; + LOG_DBG("bis_index_bitfield 0x%08x", bis_index_bitfield); } static void syncable_cb(struct bt_bap_broadcast_sink *sink, bool encrypted) { int err; + uint32_t index_bitfield; - LOG_DBG(""); + LOG_DBG("PA found, encrypted %d, requested_bis_sync %d", encrypted, requested_bis_sync); - err = bt_bap_broadcast_sink_sync(broadcast_sink, bis_index_bitfield, sink_streams, NULL); + if (encrypted) { + /* Wait for Set Broadcast Code and start sync at broadcast_code_cb */ + return; + } + + if (!requested_bis_sync) { + /* No sync with any BIS was requested yet */ + return; + } + + index_bitfield = bis_index_bitfield & requested_bis_sync; + err = bt_bap_broadcast_sink_sync(broadcast_sink, index_bitfield, sink_streams, + sink_broadcast_code); if (err != 0) { LOG_DBG("Unable to sync to broadcast source: %d", err); } @@ -1565,21 +1581,36 @@ static struct bt_bap_broadcast_sink_cb broadcast_sink_cbs = { .syncable = syncable_cb, }; +static void pa_timer_handler(struct k_work *work) +{ + if (broadcast_recv_state != NULL) { + enum bt_bap_pa_state pa_state; + + if (broadcast_recv_state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ) { + pa_state = BT_BAP_PA_STATE_NO_PAST; + } else { + pa_state = BT_BAP_PA_STATE_FAILED; + } + + bt_bap_scan_delegator_set_pa_state(broadcast_recv_state->src_id, + pa_state); + } + + LOG_DBG("PA timeout"); +} + +static K_WORK_DELAYABLE_DEFINE(pa_timer, pa_timer_handler); + static void bap_pa_sync_synced_cb(struct bt_le_per_adv_sync *sync, struct bt_le_per_adv_sync_synced_info *info) { int err; - struct bt_le_per_adv_sync *pa_sync; - LOG_DBG(""); + LOG_DBG("Sync info: service_data 0x%04X", info->service_data); - pa_sync = tester_gap_padv_get(); + k_work_cancel_delayable(&pa_timer); - if (sync != pa_sync) { - return; - } - - err = bt_bap_broadcast_sink_create(pa_sync, broadcaster_broadcast_id, &broadcast_sink); + err = bt_bap_broadcast_sink_create(sync, broadcaster_broadcast_id, &broadcast_sink); if (err != 0) { LOG_DBG("Failed to create broadcast sink: ID 0x%06X, err %d", broadcaster_broadcast_id, err); @@ -1590,6 +1621,203 @@ static struct bt_le_per_adv_sync_cb bap_pa_sync_cb = { .synced = bap_pa_sync_synced_cb, }; +static void btp_send_pas_sync_req_ev(struct bt_conn *conn, uint8_t src_id, + uint8_t advertiser_sid, uint32_t broadcast_id, + bool past_avail, uint16_t pa_interval) +{ + struct btp_bap_pa_sync_req_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + ev.src_id = src_id; + ev.advertiser_sid = advertiser_sid; + sys_put_le24(broadcast_id, ev.broadcast_id); + ev.past_avail = past_avail; + ev.pa_interval = sys_cpu_to_le16(pa_interval); + + tester_event(BTP_SERVICE_ID_BAP, BTP_BAP_EV_PA_SYNC_REQ, &ev, sizeof(ev)); +} + +static void btp_send_scan_delegator_found_ev(struct bt_conn *conn) +{ + struct btp_bap_scan_delegator_found_ev ev; + + bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn)); + + tester_event(BTP_SERVICE_ID_BAP, BTP_BAP_EV_SCAN_DELEGATOR_FOUND, &ev, sizeof(ev)); +} + +static void btp_send_broadcast_receive_state_ev(struct bt_conn *conn, + const struct bt_bap_scan_delegator_recv_state *state) +{ + struct btp_bap_broadcast_receive_state_ev *ev; + size_t len; + uint8_t *ptr; + + tester_rsp_buffer_lock(); + tester_rsp_buffer_allocate(sizeof(*ev) + BT_BAP_SCAN_DELEGATOR_MAX_SUBGROUPS * + sizeof(struct bt_bap_scan_delegator_subgroup), (uint8_t **)&ev); + + if (conn) { + bt_addr_le_copy(&ev->address, bt_conn_get_dst(conn)); + } else { + (void)memset(&ev->address, 0, sizeof(ev->address)); + } + + ev->src_id = state->src_id; + bt_addr_le_copy(&ev->broadcaster_address, &state->addr); + ev->advertiser_sid = state->adv_sid; + sys_put_le24(state->broadcast_id, ev->broadcast_id); + ev->pa_sync_state = state->pa_sync_state; + ev->big_encryption = state->encrypt_state; + ev->num_subgroups = state->num_subgroups; + + ptr = ev->subgroups; + for (uint8_t i = 0; i < ev->num_subgroups; i++) { + const struct bt_bap_scan_delegator_subgroup *subgroup = &state->subgroups[i]; + + sys_put_le32(subgroup->bis_sync >> 1, ptr); + ptr += sizeof(subgroup->bis_sync); + *ptr = subgroup->metadata_len; + ptr += sizeof(subgroup->metadata_len); + memcpy(ptr, subgroup->metadata, subgroup->metadata_len); + ptr += subgroup->metadata_len; + } + + len = sizeof(*ev) + ptr - ev->subgroups; + tester_event(BTP_SERVICE_ID_BAP, BTP_BAP_EV_BROADCAST_RECEIVE_STATE, ev, len); + + tester_rsp_buffer_free(); + tester_rsp_buffer_unlock(); +} + +static int pa_sync_past(struct bt_conn *conn, uint16_t sync_timeout) +{ + struct bt_le_per_adv_sync_transfer_param param = { 0 }; + int err; + + param.skip = PA_SYNC_SKIP; + param.timeout = sync_timeout; + + err = bt_le_per_adv_sync_transfer_subscribe(conn, ¶m); + if (err != 0) { + LOG_DBG("Could not do PAST subscribe: %d", err); + } else { + LOG_DBG("Syncing with PAST: %d", err); + (void)k_work_reschedule(&pa_timer, K_MSEC(param.timeout * 10)); + } + + return err; +} + +static int pa_sync_req_cb(struct bt_conn *conn, + const struct bt_bap_scan_delegator_recv_state *recv_state, + bool past_avail, uint16_t pa_interval) +{ + LOG_DBG("sync state %d ", recv_state->pa_sync_state); + + sink_recv_state = recv_state; + broadcast_recv_state = recv_state; + + btp_send_pas_sync_req_ev(conn, recv_state->src_id, recv_state->adv_sid, + recv_state->broadcast_id, past_avail, pa_interval); + + return 0; +} + +static int pa_sync_term_req_cb(struct bt_conn *conn, + const struct bt_bap_scan_delegator_recv_state *recv_state) +{ + LOG_DBG(""); + + sink_recv_state = recv_state; + + tester_gap_padv_stop_sync(); + + return 0; +} + +static void broadcast_code_cb(struct bt_conn *conn, + const struct bt_bap_scan_delegator_recv_state *recv_state, + const uint8_t broadcast_code[BT_AUDIO_BROADCAST_CODE_SIZE]) +{ + int err; + uint32_t index_bitfield; + + LOG_DBG("Broadcast code received for %p", recv_state); + + sink_recv_state = recv_state; + + (void)memcpy(sink_broadcast_code, broadcast_code, BT_AUDIO_BROADCAST_CODE_SIZE); + + if (!requested_bis_sync) { + return; + } + + index_bitfield = bis_index_bitfield & requested_bis_sync; + err = bt_bap_broadcast_sink_sync(broadcast_sink, index_bitfield, sink_streams, + sink_broadcast_code); + if (err != 0) { + LOG_DBG("Unable to sync to broadcast source: %d", err); + } +} + +static int bis_sync_req_cb(struct bt_conn *conn, + const struct bt_bap_scan_delegator_recv_state *recv_state, + const uint32_t bis_sync_req[BT_BAP_SCAN_DELEGATOR_MAX_SUBGROUPS]) +{ + bool bis_synced = false; + + LOG_DBG("BIS sync request received for %p: 0x%08x", recv_state, bis_sync_req[0]); + + for (int i = 0; i < MAX_STREAMS_COUNT; i++) { + if (broadcaster->streams[i].bis_synced) { + bis_synced = true; + break; + } + } + + /* We only care about a single subgroup in this sample */ + if (bis_synced) { + /* If the BIS sync request is received while we are already + * synced, it means that the requested BIS sync has changed. + */ + int err; + + /* The stream stopped callback will be called as part of this, + * and we do not need to wait for any events from the + * controller. Thus, when this returns, the `bis_synced` + * is back to false. + */ + err = bt_bap_broadcast_sink_stop(broadcast_sink); + if (err != 0) { + LOG_DBG("Failed to stop Broadcast Sink: %d", err); + + return err; + } + } + + requested_bis_sync = bis_sync_req[0]; + broadcaster_broadcast_id = recv_state->broadcast_id; + + return 0; +} + +static void recv_state_updated_cb(struct bt_conn *conn, + const struct bt_bap_scan_delegator_recv_state *recv_state) +{ + LOG_DBG("Receive state with ID %u updated", recv_state->src_id); + + btp_send_broadcast_receive_state_ev(conn, recv_state); +} + +static struct bt_bap_scan_delegator_cb scan_delegator_cbs = { + .recv_state_updated = recv_state_updated_cb, + .pa_sync_req = pa_sync_req_cb, + .pa_sync_term_req = pa_sync_term_req_cb, + .broadcast_code = broadcast_code_cb, + .bis_sync_req = bis_sync_req_cb, +}; + static uint8_t broadcast_sink_setup(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { @@ -1608,8 +1836,14 @@ static uint8_t broadcast_sink_setup(const void *cmd, uint16_t cmd_len, sink_streams[i]->ops = &stream_ops; } + /* For Scan Delegator role */ + bt_bap_scan_delegator_register_cb(&scan_delegator_cbs); + + /* For Broadcast Sink role */ bt_bap_broadcast_sink_register_cb(&broadcast_sink_cbs); bt_le_per_adv_sync_cb_register(&bap_pa_sync_cb); + + /* For Broadcast Sink or Broadcast Assistant role */ bt_le_scan_cb_register(&bap_scan_cb); return BTP_STATUS_SUCCESS; @@ -1668,35 +1902,36 @@ static uint8_t broadcast_sink_sync(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { int err; + struct bt_conn *conn; const struct btp_bap_broadcast_sink_sync_cmd *cp = cmd; struct bt_le_per_adv_sync_param create_params = {0}; LOG_DBG(""); - /* Sink Sync steps: - * 1. bt_le_per_adv_sync_create() - * 2. bap_pa_sync_synced_cb() - * 3. bt_bap_broadcast_sink_create() - * 4. - base_recv_cb() - * - syncable_cb() - * - broadcast_code_cb() <- only with scan delegator - * - bis_sync_req_cb() <- only for scan delegator - * 5. bt_bap_broadcast_sink_sync() - * 6. stream_started() - * 7. stream_recv_cb() - * 8. bap_pa_sync_terminated_cb() - * 9. stream_stopped_cb() - */ - broadcaster_broadcast_id = sys_get_le24(cp->broadcast_id); bt_addr_le_copy(&broadcaster_addr, &cp->address); - bt_addr_le_copy(&create_params.addr, &cp->address); - create_params.options = BT_LE_PER_ADV_SYNC_OPT_FILTER_DUPLICATE; - create_params.sid = cp->advertiser_sid; - create_params.skip = cp->skip; - create_params.timeout = cp->sync_timeout; - err = tester_padv_create_sync(&create_params); + if (IS_ENABLED(CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER) && cp->past_avail) { + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + return BTP_STATUS_FAILED; + } + + err = bt_bap_scan_delegator_set_pa_state(cp->src_id, BT_BAP_PA_STATE_INFO_REQ); + if (err != 0) { + LOG_DBG("Failed to set INFO_REQ state: %d", err); + } + + err = pa_sync_past(conn, cp->sync_timeout); + } else { + bt_addr_le_copy(&create_params.addr, &cp->address); + create_params.options = 0; + create_params.sid = cp->advertiser_sid; + create_params.skip = cp->skip; + create_params.timeout = cp->sync_timeout; + err = tester_gap_padv_create_sync(&create_params); + } + if (err != 0) { return BTP_STATUS_FAILED; } @@ -1711,6 +1946,8 @@ static uint8_t broadcast_sink_stop(const void *cmd, uint16_t cmd_len, LOG_DBG(""); + requested_bis_sync = 0; + err = bt_bap_broadcast_sink_stop(broadcast_sink); if (err != 0) { LOG_DBG("Unable to sync to broadcast source: %d", err); @@ -1718,6 +1955,368 @@ static uint8_t broadcast_sink_stop(const void *cmd, uint16_t cmd_len, return BTP_STATUS_FAILED; } + err = tester_gap_padv_stop_sync(); + if (err != 0) { + LOG_DBG("Failed to stop PA sync, %d", err); + + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t broadcast_sink_bis_sync(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + const struct btp_bap_broadcast_sink_bis_sync_cmd *cp = cmd; + + LOG_DBG(""); + + if (cp->requested_bis_sync == BT_BAP_BIS_SYNC_NO_PREF) { + requested_bis_sync = sys_le32_to_cpu(cp->requested_bis_sync); + } else { + /* For semantic purposes Zephyr API uses BIS Index bitfield + * where BIT(1) means BIS Index 1 + */ + requested_bis_sync = sys_le32_to_cpu(cp->requested_bis_sync) << 1; + } + + err = bt_bap_broadcast_sink_sync(broadcast_sink, requested_bis_sync, sink_streams, + sink_broadcast_code); + if (err != 0) { + LOG_DBG("Unable to sync to BISes, req_bis_sync %d, err %d", requested_bis_sync, + err); + + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static void bap_broadcast_assistant_discover_cb(struct bt_conn *conn, int err, + uint8_t recv_state_count) +{ + LOG_DBG("err %d", err); + + if (err != 0) { + LOG_DBG("BASS discover failed (%d)", err); + } else { + LOG_DBG("BASS discover done with %u recv states", recv_state_count); + + btp_send_scan_delegator_found_ev(conn); + } +} + +static void bap_broadcast_assistant_scan_cb(const struct bt_le_scan_recv_info *info, + uint32_t broadcast_id) +{ + char le_addr[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr)); + LOG_DBG("[DEVICE]: %s, broadcast_id 0x%06X, interval (ms) %u), SID 0x%x, RSSI %i", le_addr, + broadcast_id, BT_GAP_PER_ADV_INTERVAL_TO_MS(info->interval), info->sid, info->rssi); +} + +static void bap_broadcast_assistant_recv_state_cb(struct bt_conn *conn, int err, + const struct bt_bap_scan_delegator_recv_state *state) +{ + LOG_DBG("err: %d", err); + + if (err != 0 || state == NULL) { + return; + } + + btp_send_broadcast_receive_state_ev(conn, state); +} + +static void bap_broadcast_assistant_recv_state_removed_cb(struct bt_conn *conn, int err, + uint8_t src_id) +{ + LOG_DBG("err: %d", err); +} + +static void bap_broadcast_assistant_scan_start_cb(struct bt_conn *conn, int err) +{ + LOG_DBG("err: %d", err); +} + +static void bap_broadcast_assistant_scan_stop_cb(struct bt_conn *conn, int err) +{ + LOG_DBG("err: %d", err); +} + +static void bap_broadcast_assistant_add_src_cb(struct bt_conn *conn, int err) +{ + LOG_DBG("err: %d", err); +} + +static void bap_broadcast_assistant_mod_src_cb(struct bt_conn *conn, int err) +{ + LOG_DBG("err: %d", err); +} + +static void bap_broadcast_assistant_broadcast_code_cb(struct bt_conn *conn, int err) +{ + LOG_DBG("err: %d", err); +} + +static void bap_broadcast_assistant_rem_src_cb(struct bt_conn *conn, int err) +{ + LOG_DBG("err: %d", err); +} + +static struct bt_bap_broadcast_assistant_cb broadcast_assistant_cb = { + .discover = bap_broadcast_assistant_discover_cb, + .scan = bap_broadcast_assistant_scan_cb, + .recv_state = bap_broadcast_assistant_recv_state_cb, + .recv_state_removed = bap_broadcast_assistant_recv_state_removed_cb, + .scan_start = bap_broadcast_assistant_scan_start_cb, + .scan_stop = bap_broadcast_assistant_scan_stop_cb, + .add_src = bap_broadcast_assistant_add_src_cb, + .mod_src = bap_broadcast_assistant_mod_src_cb, + .broadcast_code = bap_broadcast_assistant_broadcast_code_cb, + .rem_src = bap_broadcast_assistant_rem_src_cb, +}; + +static uint8_t broadcast_discover_scan_delegators(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + struct bt_conn *conn; + const struct btp_bap_discover_scan_delegators_cmd *cp = cmd; + + LOG_DBG(""); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + return BTP_STATUS_FAILED; + } + + err = bt_bap_broadcast_assistant_discover(conn); + if (err != 0) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t broadcast_assistant_scan_start(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + struct bt_conn *conn; + const struct btp_bap_broadcast_assistant_scan_start_cmd *cp = cmd; + + LOG_DBG(""); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + return BTP_STATUS_FAILED; + } + + err = bt_bap_broadcast_assistant_scan_start(conn, true); + if (err != 0) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t broadcast_assistant_scan_stop(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + struct bt_conn *conn; + const struct btp_bap_broadcast_assistant_scan_stop_cmd *cp = cmd; + + LOG_DBG(""); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + return BTP_STATUS_FAILED; + } + + err = bt_bap_broadcast_assistant_scan_stop(conn); + if (err != 0) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t broadcast_assistant_add_src(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + const uint8_t *ptr; + struct bt_conn *conn; + const struct btp_bap_add_broadcast_src_cmd *cp = cmd; + struct bt_bap_broadcast_assistant_add_src_param param = { 0 }; + + LOG_DBG(""); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + return BTP_STATUS_FAILED; + } + + memset(delegator_subgroups, 0, sizeof(delegator_subgroups)); + bt_addr_le_copy(¶m.addr, &cp->broadcaster_address); + param.adv_sid = cp->advertiser_sid; + param.pa_sync = cp->padv_sync > 0 ? true : false; + param.broadcast_id = sys_get_le24(cp->broadcast_id); + param.pa_interval = sys_le16_to_cpu(cp->padv_interval); + param.num_subgroups = MIN(cp->num_subgroups, BROADCAST_SNK_SUBGROUP_CNT); + param.subgroups = delegator_subgroups; + + ptr = cp->subgroups; + for (uint8_t i = 0; i < param.num_subgroups; i++) { + struct bt_bap_scan_delegator_subgroup *subgroup = &delegator_subgroups[i]; + + subgroup->bis_sync = sys_get_le32(ptr); + ptr += sizeof(subgroup->bis_sync); + subgroup->metadata_len = *ptr; + ptr += sizeof(subgroup->metadata_len); + memcpy(subgroup->metadata, ptr, subgroup->metadata_len); + ptr += subgroup->metadata_len; + } + + err = bt_bap_broadcast_assistant_add_src(conn, ¶m); + if (err != 0) { + LOG_DBG("err %d", err); + + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t broadcast_assistant_remove_src(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + struct bt_conn *conn; + const struct btp_bap_remove_broadcast_src_cmd *cp = cmd; + + LOG_DBG(""); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + return BTP_STATUS_FAILED; + } + + err = bt_bap_broadcast_assistant_rem_src(conn, cp->src_id); + if (err != 0) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t broadcast_assistant_modify_src(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + const uint8_t *ptr; + struct bt_conn *conn; + const struct btp_bap_modify_broadcast_src_cmd *cp = cmd; + struct bt_bap_broadcast_assistant_mod_src_param param = { 0 }; + + LOG_DBG(""); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + return BTP_STATUS_FAILED; + } + + memset(delegator_subgroups, 0, sizeof(delegator_subgroups)); + param.src_id = cp->src_id; + param.pa_sync = cp->padv_sync > 0 ? true : false; + param.pa_interval = sys_le16_to_cpu(cp->padv_interval); + param.num_subgroups = MIN(cp->num_subgroups, BROADCAST_SNK_SUBGROUP_CNT); + param.subgroups = delegator_subgroups; + + ptr = cp->subgroups; + for (uint8_t i = 0; i < param.num_subgroups; i++) { + struct bt_bap_scan_delegator_subgroup *subgroup = &delegator_subgroups[i]; + + subgroup->bis_sync = sys_get_le32(ptr); + ptr += sizeof(subgroup->bis_sync); + subgroup->metadata_len = *ptr; + ptr += sizeof(subgroup->metadata_len); + memcpy(subgroup->metadata, ptr, subgroup->metadata_len); + ptr += subgroup->metadata_len; + } + + err = bt_bap_broadcast_assistant_mod_src(conn, ¶m); + if (err != 0) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t broadcast_assistant_set_broadcast_code(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + struct bt_conn *conn; + const struct btp_bap_set_broadcast_code_cmd *cp = cmd; + + LOG_DBG(""); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + return BTP_STATUS_FAILED; + } + + err = bt_bap_broadcast_assistant_set_broadcast_code(conn, cp->src_id, cp->broadcast_code); + if (err != 0) { + LOG_DBG("err %d", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t broadcast_assistant_send_past(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + uint16_t service_data; + struct bt_conn *conn; + struct bt_le_per_adv_sync *pa_sync; + const struct btp_bap_send_past_cmd *cp = cmd; + + LOG_DBG(""); + + conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); + if (!conn) { + return BTP_STATUS_FAILED; + } + + pa_sync = tester_gap_padv_get(); + if (!pa_sync) { + LOG_DBG("Could not send PAST to Scan Delegator"); + + return BTP_STATUS_FAILED; + } + + LOG_DBG("Sending PAST"); + + /* If octet 0 is set to 0, it means AdvA in PAST matches AdvA in ADV_EXT_IND. + * Octet 1 shall be set to Source_ID. + */ + service_data = cp->src_id << 8; + + err = bt_le_per_adv_sync_transfer(pa_sync, conn, service_data); + if (err != 0) { + LOG_DBG("Could not transfer periodic adv sync: %d", err); + + return BTP_STATUS_FAILED; + } + return BTP_STATUS_SUCCESS; } @@ -2698,6 +3297,51 @@ static const struct btp_handler bap_handlers[] = { .expect_len = sizeof(struct btp_bap_broadcast_sink_stop_cmd), .func = broadcast_sink_stop, }, + { + .opcode = BTP_BAP_BROADCAST_SINK_BIS_SYNC, + .expect_len = sizeof(struct btp_bap_broadcast_sink_bis_sync_cmd), + .func = broadcast_sink_bis_sync, + }, + { + .opcode = BTP_BAP_DISCOVER_SCAN_DELEGATORS, + .expect_len = sizeof(struct btp_bap_discover_scan_delegators_cmd), + .func = broadcast_discover_scan_delegators, + }, + { + .opcode = BTP_BAP_BROADCAST_ASSISTANT_SCAN_START, + .expect_len = sizeof(struct btp_bap_broadcast_assistant_scan_start_cmd), + .func = broadcast_assistant_scan_start, + }, + { + .opcode = BTP_BAP_BROADCAST_ASSISTANT_SCAN_STOP, + .expect_len = sizeof(struct btp_bap_broadcast_assistant_scan_stop_cmd), + .func = broadcast_assistant_scan_stop, + }, + { + .opcode = BTP_BAP_ADD_BROADCAST_SRC, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = broadcast_assistant_add_src, + }, + { + .opcode = BTP_BAP_REMOVE_BROADCAST_SRC, + .expect_len = sizeof(struct btp_bap_remove_broadcast_src_cmd), + .func = broadcast_assistant_remove_src, + }, + { + .opcode = BTP_BAP_MODIFY_BROADCAST_SRC, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = broadcast_assistant_modify_src, + }, + { + .opcode = BTP_BAP_SET_BROADCAST_CODE, + .expect_len = sizeof(struct btp_bap_set_broadcast_code_cmd), + .func = broadcast_assistant_set_broadcast_code, + }, + { + .opcode = BTP_BAP_SEND_PAST, + .expect_len = sizeof(struct btp_bap_send_past_cmd), + .func = broadcast_assistant_send_past, + }, }; uint8_t tester_init_pacs(void) @@ -2767,6 +3411,9 @@ uint8_t tester_init_bap(void) return BTP_STATUS_FAILED; } + /* For Broadcast Assistant role */ + bt_bap_broadcast_assistant_register_cb(&broadcast_assistant_cb); + k_work_queue_init(&iso_data_work_q); k_work_queue_start(&iso_data_work_q, iso_data_thread_stack_area, K_THREAD_STACK_SIZEOF(iso_data_thread_stack_area), diff --git a/tests/bluetooth/tester/src/btp_core.c b/tests/bluetooth/tester/src/btp_core.c index 1840d2d5d0b..8c157a5eccb 100644 --- a/tests/bluetooth/tester/src/btp_core.c +++ b/tests/bluetooth/tester/src/btp_core.c @@ -156,7 +156,8 @@ static uint8_t register_service(const void *cmd, uint16_t cmd_len, status = tester_init_ias(); break; #endif /* CONFIG_BT_IAS */ -#if defined(CONFIG_BT_BAP_UNICAST_CLIENT) || defined(CONFIG_BT_BAP_UNICAST_SERVER) +#if defined(CONFIG_BT_BAP_UNICAST_CLIENT) || defined(CONFIG_BT_BAP_UNICAST_SERVER) || \ + defined(CONFIG_BT_BAP_BROADCAST_SOURCE) || defined(CONFIG_BT_BAP_BROADCAST_SINK) case BTP_SERVICE_ID_PACS: status = tester_init_pacs(); break; @@ -166,7 +167,9 @@ static uint8_t register_service(const void *cmd, uint16_t cmd_len, case BTP_SERVICE_ID_BAP: status = tester_init_bap(); break; -#endif /* CONFIG_BT_BAP_UNICAST_CLIENT or CONFIG_BT_BAP_UNICAST_SERVER */ +#endif /* CONFIG_BT_BAP_UNICAST_CLIENT || CONFIG_BT_BAP_UNICAST_SERVER || \ + * CONFIG_BT_BAP_BROADCAST_SOURCE || CONFIG_BT_BAP_BROADCAST_SINK + */ #if defined(CONFIG_BT_MICP_MIC_DEV) || defined(CONFIG_BT_MICP_MIC_CTLR) case BTP_SERVICE_ID_MICP: status = tester_init_micp(); @@ -265,7 +268,8 @@ static uint8_t unregister_service(const void *cmd, uint16_t cmd_len, status = tester_unregister_ias(); break; #endif /* CONFIG_BT_IAS */ -#if defined(CONFIG_BT_BAP_UNICAST_CLIENT) || defined(CONFIG_BT_BAP_UNICAST_SERVER) +#if defined(CONFIG_BT_BAP_UNICAST_CLIENT) || defined(CONFIG_BT_BAP_UNICAST_SERVER) || \ + defined(CONFIG_BT_BAP_BROADCAST_SOURCE) || defined(CONFIG_BT_BAP_BROADCAST_SINK) case BTP_SERVICE_ID_PACS: status = tester_unregister_pacs(); break; @@ -275,10 +279,17 @@ static uint8_t unregister_service(const void *cmd, uint16_t cmd_len, case BTP_SERVICE_ID_BAP: status = tester_unregister_bap(); break; - case BTP_SERVICE_ID_MICP: +#endif /* CONFIG_BT_BAP_UNICAST_CLIENT || CONFIG_BT_BAP_UNICAST_SERVER || \ + * CONFIG_BT_BAP_BROADCAST_SOURCE || CONFIG_BT_BAP_BROADCAST_SINK + */ +#if defined(CONFIG_BT_MICP_MIC_DEV) || defined(CONFIG_BT_MICP_MIC_CTLR) + case BTP_SERVICE_ID_MICP: status = tester_unregister_micp(); break; -#endif /* CONFIG_BT_BAP_UNICAST_CLIENT or CONFIG_BT_BAP_UNICAST_SERVER */ + case BTP_SERVICE_ID_MICS: + status = tester_unregister_mics(); + break; +#endif /* CONFIG_BT_MICP_MIC_DEV or CONFIG_BT_MICP_MIC_CTLR */ #if defined(CONFIG_BT_HAS) case BTP_SERVICE_ID_HAS: status = tester_unregister_has(); diff --git a/tests/bluetooth/tester/src/btp_gap.c b/tests/bluetooth/tester/src/btp_gap.c index 2191da79534..e09e90a06e1 100644 --- a/tests/bluetooth/tester/src/btp_gap.c +++ b/tests/bluetooth/tester/src/btp_gap.c @@ -1539,7 +1539,7 @@ static uint8_t padv_set_data(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } -int tester_padv_create_sync(struct bt_le_per_adv_sync_param *create_params) +int tester_gap_padv_create_sync(struct bt_le_per_adv_sync_param *create_params) { int err; @@ -1556,6 +1556,22 @@ int tester_padv_create_sync(struct bt_le_per_adv_sync_param *create_params) return err; } +int tester_gap_padv_stop_sync(void) +{ + int err; + + if (pa_sync == NULL) { + return -EALREADY; + } + + err = bt_le_per_adv_sync_delete(pa_sync); + if (err != 0) { + LOG_DBG("Unable to stop sync to PA: %d", err); + } + + return err; +} + static uint8_t padv_create_sync(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { @@ -1569,7 +1585,7 @@ static uint8_t padv_create_sync(const void *cmd, uint16_t cmd_len, create_params.skip = cp->skip; create_params.timeout = cp->sync_timeout; - err = tester_padv_create_sync(&create_params); + err = tester_gap_padv_create_sync(&create_params); if (err != 0) { return BTP_STATUS_FAILED; }