A Broadcast Sink might scan an encrypted stream, but the user might not know the Broadacst Code to decrypt it. However, if the Broadcast Sink is acting as a Scan Delegator, it can request the Code from Broadcast Assistants. This adds support to ask for the Broadcast Code through BASS, if an empty Code was entered by the user at transport select. The bluetoothctl log below shows a Scan Delegator creating a media transport for an encrypted BIS added by a Broadcast Assistant through the Add Source operation. The user is asked to enter the Broadcast Code at transport.select, and the "no" option is chosen, since the Code is unknown. However, the Code is received from the Broadcast Assistant and the transport is successfully acquired. client/bluetoothctl [bluetooth]# endpoint.register 00001851-0000-1000-8000-00805f9b34fb 0x06 [/local/endpoint/ep0] Auto Accept (yes/no): y [/local/endpoint/ep0] Max Transports (auto/value): a [/local/endpoint/ep0] Locations: 1 [/local/endpoint/ep0] Supported Context (value): 1 [bluetooth]# Endpoint /local/endpoint/ep0 registered [bluetooth]# advertise on [bluetooth]# [NEW] Device 00:60:37:31:7E:3F 00-60-37-31-7E-3F [00-60-37-31-7E-3F]# [NEW] Device 23:E1:A6:85:D9:11 23-E1-A6-85-D9-11 [00-60-37-31-7E-3F]# [NEW] Transport /org/bluez/hci2/dev_23_E1_A6_85_D9_11/bis1/fd0 [00-60-37-31-7E-3F]# transport.select /org/bluez/hci2/dev_23_E1_A6_85_D9_11/bis1/fd0 [] Enter brocast code[value/no]: no [00-60-37-31-7E-3F]# Setting broadcast code succeeded [00-60-37-31-7E-3F]# [CHG] Transport /org/bluez/hci2/dev_23_E1_A6_85_D9_11/bis1/fd0 State: broadcasting [00-60-37-31-7E-3F]# transport.acquire /org/bluez/hci2/dev_23_E1_A6_85_D9_11/bis1/fd0 [00-60-37-31-7E-3F]# Transport /org/bluez/hci2/dev_23_E1_A6_85_D9_11/bis1/fd0 acquiring complete [00-60-37-31-7E-3F]# [CHG] Transport /org/bluez/hci2/dev_23_E1_A6_85_D9_11/bis1/fd0 State: active The btmon log shows the BASS GATT write commands and notifications exchanged between the Scan Delegator and the Broadcast Assistant: > ACL Data RX: Handle 0 flags 0x01 dlen 1 ATT: Write Command (0x52) len 23 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[21]: 020111d985a6e12300f9bb8502ffff010100000000 Opcode: Add Source (0x02) Source_Address_Type: 1 Source_Address: 23:E1:A6:85:D9:11 Source_Adv_SID: 0 Broadcast_ID: 0x85bbf9 PA_Sync_State: Synchronize to PA - PAST not available PA_Interval: 0xffff Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 < HCI Command: LE Periodic Advertising Create Sync (0x08|0x0044) plen 14 Options: 0x0000 Use advertising SID, Advertiser Address Type and address Reporting initially enabled SID: 0x00 Adv address type: Random (0x01) Adv address: 23:E1:A6:85:D9:11 (Non-Resolvable) Skip: 0x0000 Sync timeout: 20000 msec (0x07d0) Sync CTE type: 0x0000 > HCI Event: LE Meta Event (0x3e) plen 16 LE Periodic Advertising Sync Established (0x0e) Status: Success (0x00) Sync handle: 0 Advertising SID: 0x00 Advertiser address type: Random (0x01) Advertiser address: 23:E1:A6:85:D9:11 (Non-Resolvable) Advertiser PHY: LE 2M (0x02) Periodic advertising interval: 10.00 msec (0x0008) Advertiser clock accuracy: 0x07 > HCI Event: LE Meta Event (0x3e) plen 42 LE Periodic Advertising Report (0x0f) Sync handle: 0 TX power: 127 dbm (0x7f) RSSI: -57 dBm (0xc7) CTE Type: No Constant Tone Extension (0xff) Data status: Complete Data length: 0x22 Service Data: Basic Audio Announcement (0x1851) Presetation Delay: 40000 Number of Subgroups: 1 Subgroup #0: Number of BIS(s): 1 Codec: LC3 (0x06) Codec Specific Configuration: #0: len 0x02 type 0x01 Codec Specific Configuration: Sampling Frequency: 16 Khz (0x03) Codec Specific Configuration: #1: len 0x02 type 0x02 Codec Specific Configuration: Frame Duration: 10 ms (0x01) Codec Specific Configuration: #2: len 0x03 type 0x04 Codec Specific Configuration: Frame Length: 40 (0x0028) Codec Specific Configuration: #3: len 0x05 type 0x03 Codec Specific Configuration: Location: 0x00000001 Codec Specific Configuration: Location: Front Left (0x00000001) BIS #0: Index: 1 > HCI Event: LE Meta Event (0x3e) plen 20 LE Broadcast Isochronous Group Info Advertising Report (0x22) Sync Handle: 0x0000 Number BIS: 1 NSE: 3 ISO Interval: 10.00 msec (0x0008) BN: 1 PTO: 1 IRC: 3 Maximum PDU: 40 SDU Interval: 10000 us (0x002710) Maximum SDU: 40 PHY: LE 2M (0x02) Framing: Unframed (0x00) Encryption: 0x01 bluetoothd[5431]: < ACL Data TX: Handle 0 flags 0x00 dlen 29 ATT: Handle Multiple Value Notification (0x23) len 24 Length: 0x0014 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[20]: 010111d985a6e12300f9bb850200010000000000 Source_ID: 1 Source_Address_Type: 1 Source_Address: 23:E1:A6:85:D9:11 Source_Adv_SID: 0 Broadcast_ID: 0x85bbf9 PA_Sync_State: Synchronized to PA BIG_Encryption: Not encrypted Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000000 bluetoothd[5431]: < ACL Data TX: Handle 0 flags 0x00 dlen 29 ATT: Handle Multiple Value Notification (0x23) len 24 Length: 0x0014 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[20]: 010111d985a6e12300f9bb850201010000000000 Source_ID: 1 Source_Address_Type: 1 Source_Address: 23:E1:A6:85:D9:11 Source_Adv_SID: 0 Broadcast_ID: 0x85bbf9 PA_Sync_State: Synchronized to PA BIG_Encryption: Broadcast_Code required Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000000 > ACL Data RX: Handle 0 flags 0x02 dlen 25 ATT: Write Command (0x52) len 20 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[18]: 040161616100000000000000000000000000 Opcode: Set Broadcast_Code (0x04) Source_ID: 1 Broadcast_Code[16]: 61616100000000000000000000000000 < HCI Command: LE Broadcast Isochronous Group Create Sync (0x08|0x006b) BIG Handle: 0x00 BIG Sync Handle: 0x0000 Encryption: Encrypted (0x01) Broadcast Code[16]: 61616100000000000000000000000000 Maximum Number Subevents: 0x00 Timeout: 20000 ms (0x07d0) Number of BIS: 1 BIS ID: 0x01 > HCI Event: LE Meta Event (0x3e) plen 17 LE Broadcast Isochronous Group Sync Estabilished (0x1d) Status: Success (0x00) BIG Handle: 0x00 Transport Latency: 960 us (0x0003c0) NSE: 3 BN: 1 PTO: 1 IRC: 3 Maximum PDU: 40 ISO Interval: 10.00 msec (0x0008) Connection Handle #0: 10 < HCI Command: LE Setup Isochronous Data Path (0x08|0x006e) plen 13 Handle: 10 Data Path Direction: Output (Controller to Host) (0x01) Data Path: HCI (0x00) Coding Format: Transparent (0x03) Company Codec ID: Ericsson Technology Licensing (0) Vendor Codec ID: 0 Controller Delay: 0 us (0x000000) Codec Configuration Length: 0 Codec Configuration[0]: > HCI Event: Command Complete (0x0e) plen 6 LE Setup Isochronous Data Path (0x08|0x006e) ncmd 1 Status: Success (0x00) Handle: 10 bluetoothd[5431]: < ACL Data TX: Handle 0 flags 0x00 dlen 29 ATT: Handle Multiple Value Notification (0x23) len 24 Length: 0x0014 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[20]: 010111d985a6e12300f9bb850202010100000000 Source_ID: 1 Source_Address_Type: 1 Source_Address: 23:E1:A6:85:D9:11 Source_Adv_SID: 0 Broadcast_ID: 0x85bbf9 PA_Sync_State: Synchronized to PA BIG_Encryption: Decrypting Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 --- profiles/audio/transport.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/profiles/audio/transport.c b/profiles/audio/transport.c index caa7287db..6b6365289 100644 --- a/profiles/audio/transport.c +++ b/profiles/audio/transport.c @@ -35,6 +35,7 @@ #include "src/shared/util.h" #include "src/shared/queue.h" #include "src/shared/bap.h" +#include "src/shared/bass.h" #include "src/shared/io.h" #include "asha.h" @@ -45,6 +46,7 @@ #include "sink.h" #include "source.h" #include "avrcp.h" +#include "bass.h" #define MEDIA_TRANSPORT_INTERFACE "org.bluez.MediaTransport1" @@ -1208,6 +1210,18 @@ static gboolean qos_bcast_exists(const GDBusPropertyTable *property, void *data) return bap->qos.bcast.io_qos.phy != 0x00; } +static void bcast_qos_set(void *user_data, int err) +{ + GDBusPendingPropertySet id = GPOINTER_TO_UINT(user_data); + + if (!err) + g_dbus_pending_property_success(id); + else + g_dbus_pending_property_error(id, + ERROR_INTERFACE ".Failed", + "Failed to set Broadcast Code"); +} + static void set_bcast_qos(const GDBusPropertyTable *property, DBusMessageIter *dict, GDBusPendingPropertySet id, void *data) @@ -1230,10 +1244,28 @@ static void set_bcast_qos(const GDBusPropertyTable *property, uint8_t *val; int len; DBusMessageIter array; + uint8_t empty_bcode[BT_BASS_BCAST_CODE_SIZE] = {0}; dbus_message_iter_recurse(&value, &array); dbus_message_iter_get_fixed_array(&array, &val, &len); + if (len > BT_BASS_BCAST_CODE_SIZE) { + g_dbus_pending_property_error(id, + ERROR_INTERFACE ".InvalidArguments", + "Invalid arguments in method call"); + return; + } + + if (!memcmp(val, empty_bcode, len)) { + /* If the user did not provide a Broadcast Code + * for the encrypted stream, request the code from + * Broadcast Assistants, if any are available. + */ + bass_req_bcode(bap->stream, bcast_qos_set, + GUINT_TO_POINTER(id)); + return; + } + bap_qos->bcast.bcode = util_iov_new(val, len); } -- 2.43.0