bluez/client/assistant.c

416 lines
9.1 KiB
C
Raw Normal View History

client: Add assistant submenu This adds the initial implementation for the assistant menu in bluetoothctl, to detect and print MediaAssistant objects. The current BAP Broadcast Assistant implementation can be tested by running bluetoothctl, connecting to a BASS Server, scanning a Broadcast Source that is streaming a number of BISes with audio capabilities matching the capabilities of the peer device, and noticing the MediaAssistant objects being created: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:94:A6:A3 00-60-37-94-A6-A3 [bluetooth]# connect 00:60:37:94:A6:A3 Attempting to connect to 00:60:37:94:A6:A3 [CHG] Device 00:60:37:94:A6:A3 Connected: yes [00-60-37-94-A6-A3]# Connection successful [00-60-37-94-A6-A3]# [NEW] Device 15:65:78:B6:52:F6 15-65-78-B6-52-F6 [00-60-37-94-A6-A3]# [NEW] Assistant /org/bluez/hci0/src_15_65_78_B6_52_F6/dev_00_60_37_94_A6_A3/bis1 [00-60-37-94-A6-A3]# [NEW] Assistant /org/bluez/hci0/src_15_65_78_B6_52_F6/dev_00_60_37_94_A6_A3/bis2 [00-60-37-94-A6-A3]# scan off [00-60-37-94-A6-A3]# Diovery stopped [00-60-37-94-A6-A3]# disconnect Attempting to disconnect from 00:60:37:94:A6:A3 [00-60-37-94-A6-A3]# Successful disconnected [CHG] Device 00:60:37:94:A6:A3 Connected: no [bluetooth]# [DEL] Assistant /org/bluez/hci0/src_15_65_78_B6_52_F6/dev_00_60_37_94_A6_A3/bis1 [bluetooth]# [DEL] Assistant /org/bluez/hci0/src_15_65_78_B6_52_F6/dev_00_60_37_94_A6_A3/bis2
2024-07-16 22:22:07 +08:00
// SPDX-License-Identifier: GPL-2.0-or-later
/*
*
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright 2024 NXP
*
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#define _GNU_SOURCE
#include <stdio.h>
#include <stdbool.h>
#include <inttypes.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <glib.h>
#include "gdbus/gdbus.h"
#include "lib/bluetooth.h"
#include "lib/uuid.h"
#include "src/shared/util.h"
#include "src/shared/shell.h"
#include "src/shared/io.h"
#include "src/shared/queue.h"
#include "print.h"
#include "assistant.h"
/* String display constants */
#define COLORED_NEW COLOR_GREEN "NEW" COLOR_OFF
#define COLORED_CHG COLOR_YELLOW "CHG" COLOR_OFF
#define COLORED_DEL COLOR_RED "DEL" COLOR_OFF
#define MEDIA_ASSISTANT_INTERFACE "org.bluez.MediaAssistant1"
assistant: Implement MediaAssistant Push command This implements the MediaAssistant "Push" command, to trigger the BlueZ Broadcast Assistant to send stream information to the peer. After issuing the "Push" command, the user is prompted to enter any stream metadata to be sent to the peer. If the "auto" value is chosen, the default metadata found in the BASE will be sent. Otherwise, the LTVs found in the BASE will be overwritten by the user input. If the stream is encrypted, the user is also prompted to enter the Broadcast Code for decrypting. If the "auto" value is chosen, a zero filled array will be provided over DBus. Below is a bluetoothctl log to exercise the "Push" command for an unencrypted stream: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:31:7E:3F 00-60-37-31-7E-3F [bluetooth]# connect 00:60:37:31:7E:3F Attempting to connect to 00:60:37:31:7E:3F [CHG] Device 00:60:37:31:7E:3F Connected: yes [00-60-37-31-7E-3F]# Connection successful [00-60-37-31-7E-3F]# [NEW] Device 15:19:44:63:76:7A 15-19-44-63-76-7A [00-60-37-31-7E-3F]# [NEW] Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 [00-60-37-31-7E-3F]# assistant.push /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 [Assistant] Enter Metadata (auto/value): 0x03 0x02 0x04 0x00 [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 State: pending [00-60-37-31-7E-3F]# Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 pushed [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 State: active The btmon log below shows the GATT write command sent by the Assistant and the GATT notification received from the peer: < ACL Data TX: Handle 0 flags 0x00 dlen 32 ATT: Write Command (0x52) len 27 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[25]: 02017a766344191500c21a3702ffff01010000000403020400 Opcode: Add Source (0x02) Source_Address_Type: 1 Source_Address: 15:19:44:63:76:7A Source_Adv_SID: 0 Broadcast_ID: 0x371ac2 PA_Sync_State: Synchronize to PA - PAST not available PA_Interval: 0xffff Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 > ACL Data RX: Handle 0 flags 0x01 dlen 6 ATT: Handle Multiple Value Notification (0x23) len 28 Length: 0x0018 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[24]: 01017a766344191500c21a37020001010000000403020400 Source_ID: 1 Source_Address_Type: 1 Source_Address: 15:19:44:63:76:7A Source_Adv_SID: 0 Broadcast_ID: 0x371ac2 PA_Sync_State: Synchronized to PA BIG_Encryption: Not encrypted Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 The bluetoothctl log below shows the "Push" command flow for an encrypted stream: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:31:7E:3F 00-60-37-31-7E-3F [bluetooth]# connect 00:60:37:31:7E:3F Attempting to connect to 00:60:37:31:7E:3F [CHG] Device 00:60:37:31:7E:3F Connected: yes [00-60-37-31-7E-3F]# Connection successful [00-60-37-31-7E-3F]# [NEW] Device 05:1F:EE:F3:F8:7D 05-1F-EE-F3-F8-7D [00-60-37-31-7E-3F]# [NEW] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 [00-60-37-31-7E-3F]# assistant.push /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 [Assistant] Enter Metadata (auto/value): 0x03 0x02 0x04 0x00 [Assistant] Enter Broadcast Code (auto/value): 0x01 0x02 0x68 0x05 0x53 0xf1 0x41 0x5a 0xa2 0x65 0xbb 0xaf 0xc6 0xea 0x03 0xb8 [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 State: pending [00-60-37-31-7E-3F]# Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 pushed [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 State: requesting [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 State: active The GATT write commands and notifications for this scenario are shown in the btmon log below: < ACL Data TX: Handle 0 flags 0x00 dlen 32 ATT: Write Command (0x52) len 27 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[25]: 02017df8f3ee1f0500f4015d02ffff01010000000403020400 Opcode: Add Source (0x02) Source_Address_Type: 1 Source_Address: 05:1F:EE:F3:F8:7D Source_Adv_SID: 0 Broadcast_ID: 0x5d01f4 PA_Sync_State: Synchronize to PA - PAST not available PA_Interval: 0xffff Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 > ACL Data RX: Handle 0 flags 0x01 dlen 6 ATT: Handle Multiple Value Notification (0x23) len 28 Length: 0x0018 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[24]: 01017df8f3ee1f0500f4015d020101000000000403020400 Source_ID: 1 Source_Address_Type: 1 Source_Address: 05:1F:EE:F3:F8:7D Source_Adv_SID: 0 Broadcast_ID: 0x5d01f4 PA_Sync_State: Synchronized to PA BIG_Encryption: Broadcast_Code required Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000000 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 < ACL Data TX: Handle 0 flags 0x00 dlen 25 ATT: Write Command (0x52) len 20 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[18]: 04010102680553f1415aa265bbafc6ea03b8 Opcode: Set Broadcast_Code (0x04) Source_ID: 1 Broadcast_Code[16]: 0102680553f1415aa265bbafc6ea03b8 > ACL Data RX: Handle 0 flags 0x01 dlen 6 ATT: Handle Multiple Value Notification (0x23) len 28 Length: 0x0018 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[24]: 01017df8f3ee1f0500f4015d020201010000000403020400 Source_ID: 1 Source_Address_Type: 1 Source_Address: 05:1F:EE:F3:F8:7D Source_Adv_SID: 0 Broadcast_ID: 0x5d01f4 PA_Sync_State: Synchronized to PA BIG_Encryption: Decrypting Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00
2024-08-05 20:04:29 +08:00
#define BCODE_LEN 16
struct assistant_config {
GDBusProxy *proxy; /* DBus object reference */
struct iovec *meta; /* Stream metadata LTVs */
struct bt_iso_qos qos; /* Stream QoS parameters */
};
client: Add assistant submenu This adds the initial implementation for the assistant menu in bluetoothctl, to detect and print MediaAssistant objects. The current BAP Broadcast Assistant implementation can be tested by running bluetoothctl, connecting to a BASS Server, scanning a Broadcast Source that is streaming a number of BISes with audio capabilities matching the capabilities of the peer device, and noticing the MediaAssistant objects being created: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:94:A6:A3 00-60-37-94-A6-A3 [bluetooth]# connect 00:60:37:94:A6:A3 Attempting to connect to 00:60:37:94:A6:A3 [CHG] Device 00:60:37:94:A6:A3 Connected: yes [00-60-37-94-A6-A3]# Connection successful [00-60-37-94-A6-A3]# [NEW] Device 15:65:78:B6:52:F6 15-65-78-B6-52-F6 [00-60-37-94-A6-A3]# [NEW] Assistant /org/bluez/hci0/src_15_65_78_B6_52_F6/dev_00_60_37_94_A6_A3/bis1 [00-60-37-94-A6-A3]# [NEW] Assistant /org/bluez/hci0/src_15_65_78_B6_52_F6/dev_00_60_37_94_A6_A3/bis2 [00-60-37-94-A6-A3]# scan off [00-60-37-94-A6-A3]# Diovery stopped [00-60-37-94-A6-A3]# disconnect Attempting to disconnect from 00:60:37:94:A6:A3 [00-60-37-94-A6-A3]# Successful disconnected [CHG] Device 00:60:37:94:A6:A3 Connected: no [bluetooth]# [DEL] Assistant /org/bluez/hci0/src_15_65_78_B6_52_F6/dev_00_60_37_94_A6_A3/bis1 [bluetooth]# [DEL] Assistant /org/bluez/hci0/src_15_65_78_B6_52_F6/dev_00_60_37_94_A6_A3/bis2
2024-07-16 22:22:07 +08:00
static DBusConnection *dbus_conn;
static GList *assistants;
static char *proxy_description(GDBusProxy *proxy, const char *title,
const char *description)
{
const char *path;
path = g_dbus_proxy_get_path(proxy);
return g_strdup_printf("%s%s%s%s %s ",
description ? "[" : "",
description ? : "",
description ? "] " : "",
title, path);
}
static void print_assistant(GDBusProxy *proxy, const char *description)
{
char *str;
str = proxy_description(proxy, "Assistant", description);
bt_shell_printf("%s\n", str);
g_free(str);
}
static void assistant_added(GDBusProxy *proxy)
{
assistants = g_list_append(assistants, proxy);
print_assistant(proxy, COLORED_NEW);
}
static void proxy_added(GDBusProxy *proxy, void *user_data)
{
const char *interface;
interface = g_dbus_proxy_get_interface(proxy);
if (!strcmp(interface, MEDIA_ASSISTANT_INTERFACE))
assistant_added(proxy);
}
static void assistant_removed(GDBusProxy *proxy)
{
assistants = g_list_remove(assistants, proxy);
print_assistant(proxy, COLORED_DEL);
}
static void proxy_removed(GDBusProxy *proxy, void *user_data)
{
const char *interface;
interface = g_dbus_proxy_get_interface(proxy);
if (!strcmp(interface, MEDIA_ASSISTANT_INTERFACE))
assistant_removed(proxy);
}
static void assistant_property_changed(GDBusProxy *proxy, const char *name,
DBusMessageIter *iter)
{
char *str;
str = proxy_description(proxy, "Assistant", COLORED_CHG);
print_iter(str, name, iter);
g_free(str);
}
static void property_changed(GDBusProxy *proxy, const char *name,
DBusMessageIter *iter, void *user_data)
{
const char *interface;
interface = g_dbus_proxy_get_interface(proxy);
if (!strcmp(interface, MEDIA_ASSISTANT_INTERFACE))
assistant_property_changed(proxy, name, iter);
}
static void assistant_unregister(void *data)
{
GDBusProxy *proxy = data;
bt_shell_printf("Assistant %s unregistered\n",
g_dbus_proxy_get_path(proxy));
}
static void disconnect_handler(DBusConnection *connection, void *user_data)
{
g_list_free_full(assistants, assistant_unregister);
assistants = NULL;
}
assistant: Implement MediaAssistant Push command This implements the MediaAssistant "Push" command, to trigger the BlueZ Broadcast Assistant to send stream information to the peer. After issuing the "Push" command, the user is prompted to enter any stream metadata to be sent to the peer. If the "auto" value is chosen, the default metadata found in the BASE will be sent. Otherwise, the LTVs found in the BASE will be overwritten by the user input. If the stream is encrypted, the user is also prompted to enter the Broadcast Code for decrypting. If the "auto" value is chosen, a zero filled array will be provided over DBus. Below is a bluetoothctl log to exercise the "Push" command for an unencrypted stream: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:31:7E:3F 00-60-37-31-7E-3F [bluetooth]# connect 00:60:37:31:7E:3F Attempting to connect to 00:60:37:31:7E:3F [CHG] Device 00:60:37:31:7E:3F Connected: yes [00-60-37-31-7E-3F]# Connection successful [00-60-37-31-7E-3F]# [NEW] Device 15:19:44:63:76:7A 15-19-44-63-76-7A [00-60-37-31-7E-3F]# [NEW] Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 [00-60-37-31-7E-3F]# assistant.push /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 [Assistant] Enter Metadata (auto/value): 0x03 0x02 0x04 0x00 [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 State: pending [00-60-37-31-7E-3F]# Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 pushed [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 State: active The btmon log below shows the GATT write command sent by the Assistant and the GATT notification received from the peer: < ACL Data TX: Handle 0 flags 0x00 dlen 32 ATT: Write Command (0x52) len 27 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[25]: 02017a766344191500c21a3702ffff01010000000403020400 Opcode: Add Source (0x02) Source_Address_Type: 1 Source_Address: 15:19:44:63:76:7A Source_Adv_SID: 0 Broadcast_ID: 0x371ac2 PA_Sync_State: Synchronize to PA - PAST not available PA_Interval: 0xffff Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 > ACL Data RX: Handle 0 flags 0x01 dlen 6 ATT: Handle Multiple Value Notification (0x23) len 28 Length: 0x0018 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[24]: 01017a766344191500c21a37020001010000000403020400 Source_ID: 1 Source_Address_Type: 1 Source_Address: 15:19:44:63:76:7A Source_Adv_SID: 0 Broadcast_ID: 0x371ac2 PA_Sync_State: Synchronized to PA BIG_Encryption: Not encrypted Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 The bluetoothctl log below shows the "Push" command flow for an encrypted stream: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:31:7E:3F 00-60-37-31-7E-3F [bluetooth]# connect 00:60:37:31:7E:3F Attempting to connect to 00:60:37:31:7E:3F [CHG] Device 00:60:37:31:7E:3F Connected: yes [00-60-37-31-7E-3F]# Connection successful [00-60-37-31-7E-3F]# [NEW] Device 05:1F:EE:F3:F8:7D 05-1F-EE-F3-F8-7D [00-60-37-31-7E-3F]# [NEW] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 [00-60-37-31-7E-3F]# assistant.push /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 [Assistant] Enter Metadata (auto/value): 0x03 0x02 0x04 0x00 [Assistant] Enter Broadcast Code (auto/value): 0x01 0x02 0x68 0x05 0x53 0xf1 0x41 0x5a 0xa2 0x65 0xbb 0xaf 0xc6 0xea 0x03 0xb8 [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 State: pending [00-60-37-31-7E-3F]# Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 pushed [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 State: requesting [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 State: active The GATT write commands and notifications for this scenario are shown in the btmon log below: < ACL Data TX: Handle 0 flags 0x00 dlen 32 ATT: Write Command (0x52) len 27 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[25]: 02017df8f3ee1f0500f4015d02ffff01010000000403020400 Opcode: Add Source (0x02) Source_Address_Type: 1 Source_Address: 05:1F:EE:F3:F8:7D Source_Adv_SID: 0 Broadcast_ID: 0x5d01f4 PA_Sync_State: Synchronize to PA - PAST not available PA_Interval: 0xffff Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 > ACL Data RX: Handle 0 flags 0x01 dlen 6 ATT: Handle Multiple Value Notification (0x23) len 28 Length: 0x0018 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[24]: 01017df8f3ee1f0500f4015d020101000000000403020400 Source_ID: 1 Source_Address_Type: 1 Source_Address: 05:1F:EE:F3:F8:7D Source_Adv_SID: 0 Broadcast_ID: 0x5d01f4 PA_Sync_State: Synchronized to PA BIG_Encryption: Broadcast_Code required Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000000 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 < ACL Data TX: Handle 0 flags 0x00 dlen 25 ATT: Write Command (0x52) len 20 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[18]: 04010102680553f1415aa265bbafc6ea03b8 Opcode: Set Broadcast_Code (0x04) Source_ID: 1 Broadcast_Code[16]: 0102680553f1415aa265bbafc6ea03b8 > ACL Data RX: Handle 0 flags 0x01 dlen 6 ATT: Handle Multiple Value Notification (0x23) len 28 Length: 0x0018 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[24]: 01017df8f3ee1f0500f4015d020201010000000403020400 Source_ID: 1 Source_Address_Type: 1 Source_Address: 05:1F:EE:F3:F8:7D Source_Adv_SID: 0 Broadcast_ID: 0x5d01f4 PA_Sync_State: Synchronized to PA BIG_Encryption: Decrypting Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00
2024-08-05 20:04:29 +08:00
static uint8_t *str2bytearray(char *arg, size_t *val_len)
{
uint8_t value[UINT8_MAX];
char *entry;
unsigned int i;
for (i = 0; (entry = strsep(&arg, " \t")) != NULL; i++) {
long val;
char *endptr = NULL;
if (*entry == '\0')
continue;
if (i >= G_N_ELEMENTS(value)) {
bt_shell_printf("Too much data\n");
return NULL;
}
val = strtol(entry, &endptr, 0);
if (!endptr || *endptr != '\0' || val > UINT8_MAX) {
bt_shell_printf("Invalid value at index %d\n", i);
return NULL;
}
value[i] = val;
}
*val_len = i;
return util_memdup(value, i);
}
static void append_qos(DBusMessageIter *iter, struct assistant_config *cfg)
{
DBusMessageIter entry, var, dict;
const char *key = "QoS";
const char *bcode_key = "BCode";
uint8_t *bcode = cfg->qos.bcast.bcode;
dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY,
NULL, &entry);
dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
"a{sv}", &var);
dbus_message_iter_open_container(&var, DBUS_TYPE_ARRAY, "{sv}",
&dict);
g_dbus_dict_append_basic_array(&dict, DBUS_TYPE_STRING,
&bcode_key, DBUS_TYPE_BYTE,
&bcode, BCODE_LEN);
dbus_message_iter_close_container(&var, &dict);
dbus_message_iter_close_container(&entry, &var);
dbus_message_iter_close_container(iter, &entry);
}
static void push_setup(DBusMessageIter *iter, void *user_data)
{
struct assistant_config *cfg = user_data;
DBusMessageIter dict;
const char *meta = "Metadata";
dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "{sv}", &dict);
if (cfg->meta)
g_dbus_dict_append_basic_array(&dict, DBUS_TYPE_STRING, &meta,
DBUS_TYPE_BYTE, &cfg->meta->iov_base,
cfg->meta->iov_len);
if (cfg->qos.bcast.encryption)
append_qos(&dict, cfg);
dbus_message_iter_close_container(iter, &dict);
}
static void push_reply(DBusMessage *message, void *user_data)
{
struct assistant_config *cfg = user_data;
DBusError error;
dbus_error_init(&error);
if (dbus_set_error_from_message(&error, message)) {
bt_shell_printf("Failed to push assistant: %s\n",
error.name);
dbus_error_free(&error);
return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
bt_shell_printf("Assistant %s pushed\n",
g_dbus_proxy_get_path(cfg->proxy));
free(cfg->meta);
g_free(cfg);
return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void assistant_set_bcode_cfg(const char *input, void *user_data)
{
struct assistant_config *cfg = user_data;
if (!strcasecmp(input, "a") || !strcasecmp(input, "auto")) {
client/assistant: Enter Broadcast Code as string Currently, the user sets the Broadcast Code as an array of bytes when prompted from the assistant submenu. However, the Bluetooth Core Specification requires that, on the UI level, the Broadcast Code shall be represented as a string (Vol 3, Part C, 3.2.6). This commit makes the Broadcast Code be parsed as a string from the assistant prompt. The bluetoothctl log below shows a Broadcast Assistant pushing an encrypted stream to a peer: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:31:7E:3F 00-60-37-31-7E-3F [bluetooth]# connect 00:60:37:31:7E:3F Attempting to connect to 00:60:37:31:7E:3F [CHG] Device 00:60:37:31:7E:3F Connected: yes [00-60-37-31-7E-3F]# Connection successful [00-60-37-31-7E-3F]# [NEW] Device 19:9A:7A:71:E5:8B 19-9A-7A-71-E5-8B [00-60-37-31-7E-3F]# [NEW] Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 [00-60-37-31-7E-3F]# assistant.push /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 [Assistant] Enter Metadata (auto/value): a [Assistant] Enter Broadcast Code (auto/value): Borne House [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 State: pending [00-60-37-31-7E-3F]# Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 pushed [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 State: requesting [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 State: active The btmon log below shows the way the Broadcast Code string is converted into a byte array and sent to the peer via GATT: bluetoothd[6013]: < ACL Data TX: Handle 0 flags 0x00 dlen 28 ATT: Write Command (0x52) len 23 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[21]: 02018be5717a9a1900db5e3a02ffff010100000000 Opcode: Add Source (0x02) Source_Address_Type: 1 Source_Address: 19:9A:7A:71:E5:8B Source_Adv_SID: 0 Broadcast_ID: 0x3a5edb PA_Sync_State: Synchronize to PA - PAST not available PA_Interval: 0xffff Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 > ACL Data RX: Handle 0 flags 0x01 dlen 2 ATT: Handle Multiple Value Notification (0x23) len 24 Length: 0x0014 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[20]: 01018be5717a9a1900db5e3a0201010000000000 Source_ID: 1 Source_Address_Type: 1 Source_Address: 19:9A:7A:71:E5:8B Source_Adv_SID: 0 Broadcast_ID: 0x3a5edb PA_Sync_State: Synchronized to PA BIG_Encryption: Broadcast_Code required Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000000 bluetoothd[6013]: < ACL Data TX: Handle 0 flags 0x00 dlen 25 ATT: Write Command (0x52) len 20 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[18]: 040142c3b8726e6520486f75736500000000 Opcode: Set Broadcast_Code (0x04) Source_ID: 1 Broadcast_Code[16]: 426f726e6520486f7573650000000000 > ACL Data RX: Handle 0 flags 0x01 dlen 2 ATT: Handle Multiple Value Notification (0x23) len 24 Length: 0x0014 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[20]: 01018be5717a9a1900db5e3a0202010100000000 Source_ID: 1 Source_Address_Type: 1 Source_Address: 19:9A:7A:71:E5:8B Source_Adv_SID: 0 Broadcast_ID: 0x3a5edb PA_Sync_State: Synchronized to PA BIG_Encryption: Decrypting Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001
2024-08-29 21:25:06 +08:00
memset(cfg->qos.bcast.bcode, 0, BCODE_LEN);
assistant: Implement MediaAssistant Push command This implements the MediaAssistant "Push" command, to trigger the BlueZ Broadcast Assistant to send stream information to the peer. After issuing the "Push" command, the user is prompted to enter any stream metadata to be sent to the peer. If the "auto" value is chosen, the default metadata found in the BASE will be sent. Otherwise, the LTVs found in the BASE will be overwritten by the user input. If the stream is encrypted, the user is also prompted to enter the Broadcast Code for decrypting. If the "auto" value is chosen, a zero filled array will be provided over DBus. Below is a bluetoothctl log to exercise the "Push" command for an unencrypted stream: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:31:7E:3F 00-60-37-31-7E-3F [bluetooth]# connect 00:60:37:31:7E:3F Attempting to connect to 00:60:37:31:7E:3F [CHG] Device 00:60:37:31:7E:3F Connected: yes [00-60-37-31-7E-3F]# Connection successful [00-60-37-31-7E-3F]# [NEW] Device 15:19:44:63:76:7A 15-19-44-63-76-7A [00-60-37-31-7E-3F]# [NEW] Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 [00-60-37-31-7E-3F]# assistant.push /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 [Assistant] Enter Metadata (auto/value): 0x03 0x02 0x04 0x00 [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 State: pending [00-60-37-31-7E-3F]# Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 pushed [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 State: active The btmon log below shows the GATT write command sent by the Assistant and the GATT notification received from the peer: < ACL Data TX: Handle 0 flags 0x00 dlen 32 ATT: Write Command (0x52) len 27 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[25]: 02017a766344191500c21a3702ffff01010000000403020400 Opcode: Add Source (0x02) Source_Address_Type: 1 Source_Address: 15:19:44:63:76:7A Source_Adv_SID: 0 Broadcast_ID: 0x371ac2 PA_Sync_State: Synchronize to PA - PAST not available PA_Interval: 0xffff Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 > ACL Data RX: Handle 0 flags 0x01 dlen 6 ATT: Handle Multiple Value Notification (0x23) len 28 Length: 0x0018 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[24]: 01017a766344191500c21a37020001010000000403020400 Source_ID: 1 Source_Address_Type: 1 Source_Address: 15:19:44:63:76:7A Source_Adv_SID: 0 Broadcast_ID: 0x371ac2 PA_Sync_State: Synchronized to PA BIG_Encryption: Not encrypted Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 The bluetoothctl log below shows the "Push" command flow for an encrypted stream: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:31:7E:3F 00-60-37-31-7E-3F [bluetooth]# connect 00:60:37:31:7E:3F Attempting to connect to 00:60:37:31:7E:3F [CHG] Device 00:60:37:31:7E:3F Connected: yes [00-60-37-31-7E-3F]# Connection successful [00-60-37-31-7E-3F]# [NEW] Device 05:1F:EE:F3:F8:7D 05-1F-EE-F3-F8-7D [00-60-37-31-7E-3F]# [NEW] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 [00-60-37-31-7E-3F]# assistant.push /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 [Assistant] Enter Metadata (auto/value): 0x03 0x02 0x04 0x00 [Assistant] Enter Broadcast Code (auto/value): 0x01 0x02 0x68 0x05 0x53 0xf1 0x41 0x5a 0xa2 0x65 0xbb 0xaf 0xc6 0xea 0x03 0xb8 [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 State: pending [00-60-37-31-7E-3F]# Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 pushed [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 State: requesting [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 State: active The GATT write commands and notifications for this scenario are shown in the btmon log below: < ACL Data TX: Handle 0 flags 0x00 dlen 32 ATT: Write Command (0x52) len 27 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[25]: 02017df8f3ee1f0500f4015d02ffff01010000000403020400 Opcode: Add Source (0x02) Source_Address_Type: 1 Source_Address: 05:1F:EE:F3:F8:7D Source_Adv_SID: 0 Broadcast_ID: 0x5d01f4 PA_Sync_State: Synchronize to PA - PAST not available PA_Interval: 0xffff Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 > ACL Data RX: Handle 0 flags 0x01 dlen 6 ATT: Handle Multiple Value Notification (0x23) len 28 Length: 0x0018 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[24]: 01017df8f3ee1f0500f4015d020101000000000403020400 Source_ID: 1 Source_Address_Type: 1 Source_Address: 05:1F:EE:F3:F8:7D Source_Adv_SID: 0 Broadcast_ID: 0x5d01f4 PA_Sync_State: Synchronized to PA BIG_Encryption: Broadcast_Code required Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000000 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 < ACL Data TX: Handle 0 flags 0x00 dlen 25 ATT: Write Command (0x52) len 20 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[18]: 04010102680553f1415aa265bbafc6ea03b8 Opcode: Set Broadcast_Code (0x04) Source_ID: 1 Broadcast_Code[16]: 0102680553f1415aa265bbafc6ea03b8 > ACL Data RX: Handle 0 flags 0x01 dlen 6 ATT: Handle Multiple Value Notification (0x23) len 28 Length: 0x0018 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[24]: 01017df8f3ee1f0500f4015d020201010000000403020400 Source_ID: 1 Source_Address_Type: 1 Source_Address: 05:1F:EE:F3:F8:7D Source_Adv_SID: 0 Broadcast_ID: 0x5d01f4 PA_Sync_State: Synchronized to PA BIG_Encryption: Decrypting Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00
2024-08-05 20:04:29 +08:00
} else {
client/assistant: Enter Broadcast Code as string Currently, the user sets the Broadcast Code as an array of bytes when prompted from the assistant submenu. However, the Bluetooth Core Specification requires that, on the UI level, the Broadcast Code shall be represented as a string (Vol 3, Part C, 3.2.6). This commit makes the Broadcast Code be parsed as a string from the assistant prompt. The bluetoothctl log below shows a Broadcast Assistant pushing an encrypted stream to a peer: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:31:7E:3F 00-60-37-31-7E-3F [bluetooth]# connect 00:60:37:31:7E:3F Attempting to connect to 00:60:37:31:7E:3F [CHG] Device 00:60:37:31:7E:3F Connected: yes [00-60-37-31-7E-3F]# Connection successful [00-60-37-31-7E-3F]# [NEW] Device 19:9A:7A:71:E5:8B 19-9A-7A-71-E5-8B [00-60-37-31-7E-3F]# [NEW] Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 [00-60-37-31-7E-3F]# assistant.push /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 [Assistant] Enter Metadata (auto/value): a [Assistant] Enter Broadcast Code (auto/value): Borne House [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 State: pending [00-60-37-31-7E-3F]# Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 pushed [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 State: requesting [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 State: active The btmon log below shows the way the Broadcast Code string is converted into a byte array and sent to the peer via GATT: bluetoothd[6013]: < ACL Data TX: Handle 0 flags 0x00 dlen 28 ATT: Write Command (0x52) len 23 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[21]: 02018be5717a9a1900db5e3a02ffff010100000000 Opcode: Add Source (0x02) Source_Address_Type: 1 Source_Address: 19:9A:7A:71:E5:8B Source_Adv_SID: 0 Broadcast_ID: 0x3a5edb PA_Sync_State: Synchronize to PA - PAST not available PA_Interval: 0xffff Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 > ACL Data RX: Handle 0 flags 0x01 dlen 2 ATT: Handle Multiple Value Notification (0x23) len 24 Length: 0x0014 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[20]: 01018be5717a9a1900db5e3a0201010000000000 Source_ID: 1 Source_Address_Type: 1 Source_Address: 19:9A:7A:71:E5:8B Source_Adv_SID: 0 Broadcast_ID: 0x3a5edb PA_Sync_State: Synchronized to PA BIG_Encryption: Broadcast_Code required Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000000 bluetoothd[6013]: < ACL Data TX: Handle 0 flags 0x00 dlen 25 ATT: Write Command (0x52) len 20 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[18]: 040142c3b8726e6520486f75736500000000 Opcode: Set Broadcast_Code (0x04) Source_ID: 1 Broadcast_Code[16]: 426f726e6520486f7573650000000000 > ACL Data RX: Handle 0 flags 0x01 dlen 2 ATT: Handle Multiple Value Notification (0x23) len 24 Length: 0x0014 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[20]: 01018be5717a9a1900db5e3a0202010100000000 Source_ID: 1 Source_Address_Type: 1 Source_Address: 19:9A:7A:71:E5:8B Source_Adv_SID: 0 Broadcast_ID: 0x3a5edb PA_Sync_State: Synchronized to PA BIG_Encryption: Decrypting Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001
2024-08-29 21:25:06 +08:00
if (strlen(input) > BCODE_LEN) {
bt_shell_printf("Input string too long %s\n", input);
goto fail;
}
assistant: Implement MediaAssistant Push command This implements the MediaAssistant "Push" command, to trigger the BlueZ Broadcast Assistant to send stream information to the peer. After issuing the "Push" command, the user is prompted to enter any stream metadata to be sent to the peer. If the "auto" value is chosen, the default metadata found in the BASE will be sent. Otherwise, the LTVs found in the BASE will be overwritten by the user input. If the stream is encrypted, the user is also prompted to enter the Broadcast Code for decrypting. If the "auto" value is chosen, a zero filled array will be provided over DBus. Below is a bluetoothctl log to exercise the "Push" command for an unencrypted stream: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:31:7E:3F 00-60-37-31-7E-3F [bluetooth]# connect 00:60:37:31:7E:3F Attempting to connect to 00:60:37:31:7E:3F [CHG] Device 00:60:37:31:7E:3F Connected: yes [00-60-37-31-7E-3F]# Connection successful [00-60-37-31-7E-3F]# [NEW] Device 15:19:44:63:76:7A 15-19-44-63-76-7A [00-60-37-31-7E-3F]# [NEW] Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 [00-60-37-31-7E-3F]# assistant.push /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 [Assistant] Enter Metadata (auto/value): 0x03 0x02 0x04 0x00 [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 State: pending [00-60-37-31-7E-3F]# Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 pushed [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 State: active The btmon log below shows the GATT write command sent by the Assistant and the GATT notification received from the peer: < ACL Data TX: Handle 0 flags 0x00 dlen 32 ATT: Write Command (0x52) len 27 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[25]: 02017a766344191500c21a3702ffff01010000000403020400 Opcode: Add Source (0x02) Source_Address_Type: 1 Source_Address: 15:19:44:63:76:7A Source_Adv_SID: 0 Broadcast_ID: 0x371ac2 PA_Sync_State: Synchronize to PA - PAST not available PA_Interval: 0xffff Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 > ACL Data RX: Handle 0 flags 0x01 dlen 6 ATT: Handle Multiple Value Notification (0x23) len 28 Length: 0x0018 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[24]: 01017a766344191500c21a37020001010000000403020400 Source_ID: 1 Source_Address_Type: 1 Source_Address: 15:19:44:63:76:7A Source_Adv_SID: 0 Broadcast_ID: 0x371ac2 PA_Sync_State: Synchronized to PA BIG_Encryption: Not encrypted Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 The bluetoothctl log below shows the "Push" command flow for an encrypted stream: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:31:7E:3F 00-60-37-31-7E-3F [bluetooth]# connect 00:60:37:31:7E:3F Attempting to connect to 00:60:37:31:7E:3F [CHG] Device 00:60:37:31:7E:3F Connected: yes [00-60-37-31-7E-3F]# Connection successful [00-60-37-31-7E-3F]# [NEW] Device 05:1F:EE:F3:F8:7D 05-1F-EE-F3-F8-7D [00-60-37-31-7E-3F]# [NEW] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 [00-60-37-31-7E-3F]# assistant.push /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 [Assistant] Enter Metadata (auto/value): 0x03 0x02 0x04 0x00 [Assistant] Enter Broadcast Code (auto/value): 0x01 0x02 0x68 0x05 0x53 0xf1 0x41 0x5a 0xa2 0x65 0xbb 0xaf 0xc6 0xea 0x03 0xb8 [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 State: pending [00-60-37-31-7E-3F]# Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 pushed [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 State: requesting [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 State: active The GATT write commands and notifications for this scenario are shown in the btmon log below: < ACL Data TX: Handle 0 flags 0x00 dlen 32 ATT: Write Command (0x52) len 27 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[25]: 02017df8f3ee1f0500f4015d02ffff01010000000403020400 Opcode: Add Source (0x02) Source_Address_Type: 1 Source_Address: 05:1F:EE:F3:F8:7D Source_Adv_SID: 0 Broadcast_ID: 0x5d01f4 PA_Sync_State: Synchronize to PA - PAST not available PA_Interval: 0xffff Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 > ACL Data RX: Handle 0 flags 0x01 dlen 6 ATT: Handle Multiple Value Notification (0x23) len 28 Length: 0x0018 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[24]: 01017df8f3ee1f0500f4015d020101000000000403020400 Source_ID: 1 Source_Address_Type: 1 Source_Address: 05:1F:EE:F3:F8:7D Source_Adv_SID: 0 Broadcast_ID: 0x5d01f4 PA_Sync_State: Synchronized to PA BIG_Encryption: Broadcast_Code required Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000000 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 < ACL Data TX: Handle 0 flags 0x00 dlen 25 ATT: Write Command (0x52) len 20 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[18]: 04010102680553f1415aa265bbafc6ea03b8 Opcode: Set Broadcast_Code (0x04) Source_ID: 1 Broadcast_Code[16]: 0102680553f1415aa265bbafc6ea03b8 > ACL Data RX: Handle 0 flags 0x01 dlen 6 ATT: Handle Multiple Value Notification (0x23) len 28 Length: 0x0018 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[24]: 01017df8f3ee1f0500f4015d020201010000000403020400 Source_ID: 1 Source_Address_Type: 1 Source_Address: 05:1F:EE:F3:F8:7D Source_Adv_SID: 0 Broadcast_ID: 0x5d01f4 PA_Sync_State: Synchronized to PA BIG_Encryption: Decrypting Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00
2024-08-05 20:04:29 +08:00
client/assistant: Enter Broadcast Code as string Currently, the user sets the Broadcast Code as an array of bytes when prompted from the assistant submenu. However, the Bluetooth Core Specification requires that, on the UI level, the Broadcast Code shall be represented as a string (Vol 3, Part C, 3.2.6). This commit makes the Broadcast Code be parsed as a string from the assistant prompt. The bluetoothctl log below shows a Broadcast Assistant pushing an encrypted stream to a peer: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:31:7E:3F 00-60-37-31-7E-3F [bluetooth]# connect 00:60:37:31:7E:3F Attempting to connect to 00:60:37:31:7E:3F [CHG] Device 00:60:37:31:7E:3F Connected: yes [00-60-37-31-7E-3F]# Connection successful [00-60-37-31-7E-3F]# [NEW] Device 19:9A:7A:71:E5:8B 19-9A-7A-71-E5-8B [00-60-37-31-7E-3F]# [NEW] Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 [00-60-37-31-7E-3F]# assistant.push /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 [Assistant] Enter Metadata (auto/value): a [Assistant] Enter Broadcast Code (auto/value): Borne House [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 State: pending [00-60-37-31-7E-3F]# Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 pushed [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 State: requesting [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 State: active The btmon log below shows the way the Broadcast Code string is converted into a byte array and sent to the peer via GATT: bluetoothd[6013]: < ACL Data TX: Handle 0 flags 0x00 dlen 28 ATT: Write Command (0x52) len 23 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[21]: 02018be5717a9a1900db5e3a02ffff010100000000 Opcode: Add Source (0x02) Source_Address_Type: 1 Source_Address: 19:9A:7A:71:E5:8B Source_Adv_SID: 0 Broadcast_ID: 0x3a5edb PA_Sync_State: Synchronize to PA - PAST not available PA_Interval: 0xffff Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 > ACL Data RX: Handle 0 flags 0x01 dlen 2 ATT: Handle Multiple Value Notification (0x23) len 24 Length: 0x0014 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[20]: 01018be5717a9a1900db5e3a0201010000000000 Source_ID: 1 Source_Address_Type: 1 Source_Address: 19:9A:7A:71:E5:8B Source_Adv_SID: 0 Broadcast_ID: 0x3a5edb PA_Sync_State: Synchronized to PA BIG_Encryption: Broadcast_Code required Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000000 bluetoothd[6013]: < ACL Data TX: Handle 0 flags 0x00 dlen 25 ATT: Write Command (0x52) len 20 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[18]: 040142c3b8726e6520486f75736500000000 Opcode: Set Broadcast_Code (0x04) Source_ID: 1 Broadcast_Code[16]: 426f726e6520486f7573650000000000 > ACL Data RX: Handle 0 flags 0x01 dlen 2 ATT: Handle Multiple Value Notification (0x23) len 24 Length: 0x0014 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[20]: 01018be5717a9a1900db5e3a0202010100000000 Source_ID: 1 Source_Address_Type: 1 Source_Address: 19:9A:7A:71:E5:8B Source_Adv_SID: 0 Broadcast_ID: 0x3a5edb PA_Sync_State: Synchronized to PA BIG_Encryption: Decrypting Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001
2024-08-29 21:25:06 +08:00
memcpy(cfg->qos.bcast.bcode, input, strlen(input));
assistant: Implement MediaAssistant Push command This implements the MediaAssistant "Push" command, to trigger the BlueZ Broadcast Assistant to send stream information to the peer. After issuing the "Push" command, the user is prompted to enter any stream metadata to be sent to the peer. If the "auto" value is chosen, the default metadata found in the BASE will be sent. Otherwise, the LTVs found in the BASE will be overwritten by the user input. If the stream is encrypted, the user is also prompted to enter the Broadcast Code for decrypting. If the "auto" value is chosen, a zero filled array will be provided over DBus. Below is a bluetoothctl log to exercise the "Push" command for an unencrypted stream: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:31:7E:3F 00-60-37-31-7E-3F [bluetooth]# connect 00:60:37:31:7E:3F Attempting to connect to 00:60:37:31:7E:3F [CHG] Device 00:60:37:31:7E:3F Connected: yes [00-60-37-31-7E-3F]# Connection successful [00-60-37-31-7E-3F]# [NEW] Device 15:19:44:63:76:7A 15-19-44-63-76-7A [00-60-37-31-7E-3F]# [NEW] Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 [00-60-37-31-7E-3F]# assistant.push /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 [Assistant] Enter Metadata (auto/value): 0x03 0x02 0x04 0x00 [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 State: pending [00-60-37-31-7E-3F]# Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 pushed [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 State: active The btmon log below shows the GATT write command sent by the Assistant and the GATT notification received from the peer: < ACL Data TX: Handle 0 flags 0x00 dlen 32 ATT: Write Command (0x52) len 27 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[25]: 02017a766344191500c21a3702ffff01010000000403020400 Opcode: Add Source (0x02) Source_Address_Type: 1 Source_Address: 15:19:44:63:76:7A Source_Adv_SID: 0 Broadcast_ID: 0x371ac2 PA_Sync_State: Synchronize to PA - PAST not available PA_Interval: 0xffff Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 > ACL Data RX: Handle 0 flags 0x01 dlen 6 ATT: Handle Multiple Value Notification (0x23) len 28 Length: 0x0018 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[24]: 01017a766344191500c21a37020001010000000403020400 Source_ID: 1 Source_Address_Type: 1 Source_Address: 15:19:44:63:76:7A Source_Adv_SID: 0 Broadcast_ID: 0x371ac2 PA_Sync_State: Synchronized to PA BIG_Encryption: Not encrypted Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 The bluetoothctl log below shows the "Push" command flow for an encrypted stream: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:31:7E:3F 00-60-37-31-7E-3F [bluetooth]# connect 00:60:37:31:7E:3F Attempting to connect to 00:60:37:31:7E:3F [CHG] Device 00:60:37:31:7E:3F Connected: yes [00-60-37-31-7E-3F]# Connection successful [00-60-37-31-7E-3F]# [NEW] Device 05:1F:EE:F3:F8:7D 05-1F-EE-F3-F8-7D [00-60-37-31-7E-3F]# [NEW] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 [00-60-37-31-7E-3F]# assistant.push /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 [Assistant] Enter Metadata (auto/value): 0x03 0x02 0x04 0x00 [Assistant] Enter Broadcast Code (auto/value): 0x01 0x02 0x68 0x05 0x53 0xf1 0x41 0x5a 0xa2 0x65 0xbb 0xaf 0xc6 0xea 0x03 0xb8 [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 State: pending [00-60-37-31-7E-3F]# Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 pushed [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 State: requesting [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 State: active The GATT write commands and notifications for this scenario are shown in the btmon log below: < ACL Data TX: Handle 0 flags 0x00 dlen 32 ATT: Write Command (0x52) len 27 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[25]: 02017df8f3ee1f0500f4015d02ffff01010000000403020400 Opcode: Add Source (0x02) Source_Address_Type: 1 Source_Address: 05:1F:EE:F3:F8:7D Source_Adv_SID: 0 Broadcast_ID: 0x5d01f4 PA_Sync_State: Synchronize to PA - PAST not available PA_Interval: 0xffff Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 > ACL Data RX: Handle 0 flags 0x01 dlen 6 ATT: Handle Multiple Value Notification (0x23) len 28 Length: 0x0018 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[24]: 01017df8f3ee1f0500f4015d020101000000000403020400 Source_ID: 1 Source_Address_Type: 1 Source_Address: 05:1F:EE:F3:F8:7D Source_Adv_SID: 0 Broadcast_ID: 0x5d01f4 PA_Sync_State: Synchronized to PA BIG_Encryption: Broadcast_Code required Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000000 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 < ACL Data TX: Handle 0 flags 0x00 dlen 25 ATT: Write Command (0x52) len 20 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[18]: 04010102680553f1415aa265bbafc6ea03b8 Opcode: Set Broadcast_Code (0x04) Source_ID: 1 Broadcast_Code[16]: 0102680553f1415aa265bbafc6ea03b8 > ACL Data RX: Handle 0 flags 0x01 dlen 6 ATT: Handle Multiple Value Notification (0x23) len 28 Length: 0x0018 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[24]: 01017df8f3ee1f0500f4015d020201010000000403020400 Source_ID: 1 Source_Address_Type: 1 Source_Address: 05:1F:EE:F3:F8:7D Source_Adv_SID: 0 Broadcast_ID: 0x5d01f4 PA_Sync_State: Synchronized to PA BIG_Encryption: Decrypting Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00
2024-08-05 20:04:29 +08:00
}
if (!g_dbus_proxy_method_call(cfg->proxy, "Push",
push_setup, push_reply,
cfg, NULL)) {
bt_shell_printf("Failed to push assistant\n");
client/assistant: Enter Broadcast Code as string Currently, the user sets the Broadcast Code as an array of bytes when prompted from the assistant submenu. However, the Bluetooth Core Specification requires that, on the UI level, the Broadcast Code shall be represented as a string (Vol 3, Part C, 3.2.6). This commit makes the Broadcast Code be parsed as a string from the assistant prompt. The bluetoothctl log below shows a Broadcast Assistant pushing an encrypted stream to a peer: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:31:7E:3F 00-60-37-31-7E-3F [bluetooth]# connect 00:60:37:31:7E:3F Attempting to connect to 00:60:37:31:7E:3F [CHG] Device 00:60:37:31:7E:3F Connected: yes [00-60-37-31-7E-3F]# Connection successful [00-60-37-31-7E-3F]# [NEW] Device 19:9A:7A:71:E5:8B 19-9A-7A-71-E5-8B [00-60-37-31-7E-3F]# [NEW] Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 [00-60-37-31-7E-3F]# assistant.push /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 [Assistant] Enter Metadata (auto/value): a [Assistant] Enter Broadcast Code (auto/value): Borne House [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 State: pending [00-60-37-31-7E-3F]# Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 pushed [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 State: requesting [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 State: active The btmon log below shows the way the Broadcast Code string is converted into a byte array and sent to the peer via GATT: bluetoothd[6013]: < ACL Data TX: Handle 0 flags 0x00 dlen 28 ATT: Write Command (0x52) len 23 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[21]: 02018be5717a9a1900db5e3a02ffff010100000000 Opcode: Add Source (0x02) Source_Address_Type: 1 Source_Address: 19:9A:7A:71:E5:8B Source_Adv_SID: 0 Broadcast_ID: 0x3a5edb PA_Sync_State: Synchronize to PA - PAST not available PA_Interval: 0xffff Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 > ACL Data RX: Handle 0 flags 0x01 dlen 2 ATT: Handle Multiple Value Notification (0x23) len 24 Length: 0x0014 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[20]: 01018be5717a9a1900db5e3a0201010000000000 Source_ID: 1 Source_Address_Type: 1 Source_Address: 19:9A:7A:71:E5:8B Source_Adv_SID: 0 Broadcast_ID: 0x3a5edb PA_Sync_State: Synchronized to PA BIG_Encryption: Broadcast_Code required Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000000 bluetoothd[6013]: < ACL Data TX: Handle 0 flags 0x00 dlen 25 ATT: Write Command (0x52) len 20 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[18]: 040142c3b8726e6520486f75736500000000 Opcode: Set Broadcast_Code (0x04) Source_ID: 1 Broadcast_Code[16]: 426f726e6520486f7573650000000000 > ACL Data RX: Handle 0 flags 0x01 dlen 2 ATT: Handle Multiple Value Notification (0x23) len 24 Length: 0x0014 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[20]: 01018be5717a9a1900db5e3a0202010100000000 Source_ID: 1 Source_Address_Type: 1 Source_Address: 19:9A:7A:71:E5:8B Source_Adv_SID: 0 Broadcast_ID: 0x3a5edb PA_Sync_State: Synchronized to PA BIG_Encryption: Decrypting Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001
2024-08-29 21:25:06 +08:00
goto fail;
}
assistant: Implement MediaAssistant Push command This implements the MediaAssistant "Push" command, to trigger the BlueZ Broadcast Assistant to send stream information to the peer. After issuing the "Push" command, the user is prompted to enter any stream metadata to be sent to the peer. If the "auto" value is chosen, the default metadata found in the BASE will be sent. Otherwise, the LTVs found in the BASE will be overwritten by the user input. If the stream is encrypted, the user is also prompted to enter the Broadcast Code for decrypting. If the "auto" value is chosen, a zero filled array will be provided over DBus. Below is a bluetoothctl log to exercise the "Push" command for an unencrypted stream: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:31:7E:3F 00-60-37-31-7E-3F [bluetooth]# connect 00:60:37:31:7E:3F Attempting to connect to 00:60:37:31:7E:3F [CHG] Device 00:60:37:31:7E:3F Connected: yes [00-60-37-31-7E-3F]# Connection successful [00-60-37-31-7E-3F]# [NEW] Device 15:19:44:63:76:7A 15-19-44-63-76-7A [00-60-37-31-7E-3F]# [NEW] Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 [00-60-37-31-7E-3F]# assistant.push /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 [Assistant] Enter Metadata (auto/value): 0x03 0x02 0x04 0x00 [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 State: pending [00-60-37-31-7E-3F]# Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 pushed [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 State: active The btmon log below shows the GATT write command sent by the Assistant and the GATT notification received from the peer: < ACL Data TX: Handle 0 flags 0x00 dlen 32 ATT: Write Command (0x52) len 27 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[25]: 02017a766344191500c21a3702ffff01010000000403020400 Opcode: Add Source (0x02) Source_Address_Type: 1 Source_Address: 15:19:44:63:76:7A Source_Adv_SID: 0 Broadcast_ID: 0x371ac2 PA_Sync_State: Synchronize to PA - PAST not available PA_Interval: 0xffff Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 > ACL Data RX: Handle 0 flags 0x01 dlen 6 ATT: Handle Multiple Value Notification (0x23) len 28 Length: 0x0018 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[24]: 01017a766344191500c21a37020001010000000403020400 Source_ID: 1 Source_Address_Type: 1 Source_Address: 15:19:44:63:76:7A Source_Adv_SID: 0 Broadcast_ID: 0x371ac2 PA_Sync_State: Synchronized to PA BIG_Encryption: Not encrypted Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 The bluetoothctl log below shows the "Push" command flow for an encrypted stream: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:31:7E:3F 00-60-37-31-7E-3F [bluetooth]# connect 00:60:37:31:7E:3F Attempting to connect to 00:60:37:31:7E:3F [CHG] Device 00:60:37:31:7E:3F Connected: yes [00-60-37-31-7E-3F]# Connection successful [00-60-37-31-7E-3F]# [NEW] Device 05:1F:EE:F3:F8:7D 05-1F-EE-F3-F8-7D [00-60-37-31-7E-3F]# [NEW] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 [00-60-37-31-7E-3F]# assistant.push /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 [Assistant] Enter Metadata (auto/value): 0x03 0x02 0x04 0x00 [Assistant] Enter Broadcast Code (auto/value): 0x01 0x02 0x68 0x05 0x53 0xf1 0x41 0x5a 0xa2 0x65 0xbb 0xaf 0xc6 0xea 0x03 0xb8 [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 State: pending [00-60-37-31-7E-3F]# Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 pushed [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 State: requesting [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 State: active The GATT write commands and notifications for this scenario are shown in the btmon log below: < ACL Data TX: Handle 0 flags 0x00 dlen 32 ATT: Write Command (0x52) len 27 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[25]: 02017df8f3ee1f0500f4015d02ffff01010000000403020400 Opcode: Add Source (0x02) Source_Address_Type: 1 Source_Address: 05:1F:EE:F3:F8:7D Source_Adv_SID: 0 Broadcast_ID: 0x5d01f4 PA_Sync_State: Synchronize to PA - PAST not available PA_Interval: 0xffff Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 > ACL Data RX: Handle 0 flags 0x01 dlen 6 ATT: Handle Multiple Value Notification (0x23) len 28 Length: 0x0018 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[24]: 01017df8f3ee1f0500f4015d020101000000000403020400 Source_ID: 1 Source_Address_Type: 1 Source_Address: 05:1F:EE:F3:F8:7D Source_Adv_SID: 0 Broadcast_ID: 0x5d01f4 PA_Sync_State: Synchronized to PA BIG_Encryption: Broadcast_Code required Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000000 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 < ACL Data TX: Handle 0 flags 0x00 dlen 25 ATT: Write Command (0x52) len 20 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[18]: 04010102680553f1415aa265bbafc6ea03b8 Opcode: Set Broadcast_Code (0x04) Source_ID: 1 Broadcast_Code[16]: 0102680553f1415aa265bbafc6ea03b8 > ACL Data RX: Handle 0 flags 0x01 dlen 6 ATT: Handle Multiple Value Notification (0x23) len 28 Length: 0x0018 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[24]: 01017df8f3ee1f0500f4015d020201010000000403020400 Source_ID: 1 Source_Address_Type: 1 Source_Address: 05:1F:EE:F3:F8:7D Source_Adv_SID: 0 Broadcast_ID: 0x5d01f4 PA_Sync_State: Synchronized to PA BIG_Encryption: Decrypting Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00
2024-08-05 20:04:29 +08:00
client/assistant: Enter Broadcast Code as string Currently, the user sets the Broadcast Code as an array of bytes when prompted from the assistant submenu. However, the Bluetooth Core Specification requires that, on the UI level, the Broadcast Code shall be represented as a string (Vol 3, Part C, 3.2.6). This commit makes the Broadcast Code be parsed as a string from the assistant prompt. The bluetoothctl log below shows a Broadcast Assistant pushing an encrypted stream to a peer: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:31:7E:3F 00-60-37-31-7E-3F [bluetooth]# connect 00:60:37:31:7E:3F Attempting to connect to 00:60:37:31:7E:3F [CHG] Device 00:60:37:31:7E:3F Connected: yes [00-60-37-31-7E-3F]# Connection successful [00-60-37-31-7E-3F]# [NEW] Device 19:9A:7A:71:E5:8B 19-9A-7A-71-E5-8B [00-60-37-31-7E-3F]# [NEW] Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 [00-60-37-31-7E-3F]# assistant.push /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 [Assistant] Enter Metadata (auto/value): a [Assistant] Enter Broadcast Code (auto/value): Borne House [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 State: pending [00-60-37-31-7E-3F]# Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 pushed [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 State: requesting [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 State: active The btmon log below shows the way the Broadcast Code string is converted into a byte array and sent to the peer via GATT: bluetoothd[6013]: < ACL Data TX: Handle 0 flags 0x00 dlen 28 ATT: Write Command (0x52) len 23 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[21]: 02018be5717a9a1900db5e3a02ffff010100000000 Opcode: Add Source (0x02) Source_Address_Type: 1 Source_Address: 19:9A:7A:71:E5:8B Source_Adv_SID: 0 Broadcast_ID: 0x3a5edb PA_Sync_State: Synchronize to PA - PAST not available PA_Interval: 0xffff Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 > ACL Data RX: Handle 0 flags 0x01 dlen 2 ATT: Handle Multiple Value Notification (0x23) len 24 Length: 0x0014 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[20]: 01018be5717a9a1900db5e3a0201010000000000 Source_ID: 1 Source_Address_Type: 1 Source_Address: 19:9A:7A:71:E5:8B Source_Adv_SID: 0 Broadcast_ID: 0x3a5edb PA_Sync_State: Synchronized to PA BIG_Encryption: Broadcast_Code required Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000000 bluetoothd[6013]: < ACL Data TX: Handle 0 flags 0x00 dlen 25 ATT: Write Command (0x52) len 20 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[18]: 040142c3b8726e6520486f75736500000000 Opcode: Set Broadcast_Code (0x04) Source_ID: 1 Broadcast_Code[16]: 426f726e6520486f7573650000000000 > ACL Data RX: Handle 0 flags 0x01 dlen 2 ATT: Handle Multiple Value Notification (0x23) len 24 Length: 0x0014 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[20]: 01018be5717a9a1900db5e3a0202010100000000 Source_ID: 1 Source_Address_Type: 1 Source_Address: 19:9A:7A:71:E5:8B Source_Adv_SID: 0 Broadcast_ID: 0x3a5edb PA_Sync_State: Synchronized to PA BIG_Encryption: Decrypting Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001
2024-08-29 21:25:06 +08:00
return;
assistant: Implement MediaAssistant Push command This implements the MediaAssistant "Push" command, to trigger the BlueZ Broadcast Assistant to send stream information to the peer. After issuing the "Push" command, the user is prompted to enter any stream metadata to be sent to the peer. If the "auto" value is chosen, the default metadata found in the BASE will be sent. Otherwise, the LTVs found in the BASE will be overwritten by the user input. If the stream is encrypted, the user is also prompted to enter the Broadcast Code for decrypting. If the "auto" value is chosen, a zero filled array will be provided over DBus. Below is a bluetoothctl log to exercise the "Push" command for an unencrypted stream: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:31:7E:3F 00-60-37-31-7E-3F [bluetooth]# connect 00:60:37:31:7E:3F Attempting to connect to 00:60:37:31:7E:3F [CHG] Device 00:60:37:31:7E:3F Connected: yes [00-60-37-31-7E-3F]# Connection successful [00-60-37-31-7E-3F]# [NEW] Device 15:19:44:63:76:7A 15-19-44-63-76-7A [00-60-37-31-7E-3F]# [NEW] Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 [00-60-37-31-7E-3F]# assistant.push /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 [Assistant] Enter Metadata (auto/value): 0x03 0x02 0x04 0x00 [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 State: pending [00-60-37-31-7E-3F]# Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 pushed [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 State: active The btmon log below shows the GATT write command sent by the Assistant and the GATT notification received from the peer: < ACL Data TX: Handle 0 flags 0x00 dlen 32 ATT: Write Command (0x52) len 27 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[25]: 02017a766344191500c21a3702ffff01010000000403020400 Opcode: Add Source (0x02) Source_Address_Type: 1 Source_Address: 15:19:44:63:76:7A Source_Adv_SID: 0 Broadcast_ID: 0x371ac2 PA_Sync_State: Synchronize to PA - PAST not available PA_Interval: 0xffff Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 > ACL Data RX: Handle 0 flags 0x01 dlen 6 ATT: Handle Multiple Value Notification (0x23) len 28 Length: 0x0018 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[24]: 01017a766344191500c21a37020001010000000403020400 Source_ID: 1 Source_Address_Type: 1 Source_Address: 15:19:44:63:76:7A Source_Adv_SID: 0 Broadcast_ID: 0x371ac2 PA_Sync_State: Synchronized to PA BIG_Encryption: Not encrypted Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 The bluetoothctl log below shows the "Push" command flow for an encrypted stream: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:31:7E:3F 00-60-37-31-7E-3F [bluetooth]# connect 00:60:37:31:7E:3F Attempting to connect to 00:60:37:31:7E:3F [CHG] Device 00:60:37:31:7E:3F Connected: yes [00-60-37-31-7E-3F]# Connection successful [00-60-37-31-7E-3F]# [NEW] Device 05:1F:EE:F3:F8:7D 05-1F-EE-F3-F8-7D [00-60-37-31-7E-3F]# [NEW] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 [00-60-37-31-7E-3F]# assistant.push /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 [Assistant] Enter Metadata (auto/value): 0x03 0x02 0x04 0x00 [Assistant] Enter Broadcast Code (auto/value): 0x01 0x02 0x68 0x05 0x53 0xf1 0x41 0x5a 0xa2 0x65 0xbb 0xaf 0xc6 0xea 0x03 0xb8 [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 State: pending [00-60-37-31-7E-3F]# Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 pushed [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 State: requesting [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 State: active The GATT write commands and notifications for this scenario are shown in the btmon log below: < ACL Data TX: Handle 0 flags 0x00 dlen 32 ATT: Write Command (0x52) len 27 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[25]: 02017df8f3ee1f0500f4015d02ffff01010000000403020400 Opcode: Add Source (0x02) Source_Address_Type: 1 Source_Address: 05:1F:EE:F3:F8:7D Source_Adv_SID: 0 Broadcast_ID: 0x5d01f4 PA_Sync_State: Synchronize to PA - PAST not available PA_Interval: 0xffff Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 > ACL Data RX: Handle 0 flags 0x01 dlen 6 ATT: Handle Multiple Value Notification (0x23) len 28 Length: 0x0018 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[24]: 01017df8f3ee1f0500f4015d020101000000000403020400 Source_ID: 1 Source_Address_Type: 1 Source_Address: 05:1F:EE:F3:F8:7D Source_Adv_SID: 0 Broadcast_ID: 0x5d01f4 PA_Sync_State: Synchronized to PA BIG_Encryption: Broadcast_Code required Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000000 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 < ACL Data TX: Handle 0 flags 0x00 dlen 25 ATT: Write Command (0x52) len 20 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[18]: 04010102680553f1415aa265bbafc6ea03b8 Opcode: Set Broadcast_Code (0x04) Source_ID: 1 Broadcast_Code[16]: 0102680553f1415aa265bbafc6ea03b8 > ACL Data RX: Handle 0 flags 0x01 dlen 6 ATT: Handle Multiple Value Notification (0x23) len 28 Length: 0x0018 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[24]: 01017df8f3ee1f0500f4015d020201010000000403020400 Source_ID: 1 Source_Address_Type: 1 Source_Address: 05:1F:EE:F3:F8:7D Source_Adv_SID: 0 Broadcast_ID: 0x5d01f4 PA_Sync_State: Synchronized to PA BIG_Encryption: Decrypting Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00
2024-08-05 20:04:29 +08:00
client/assistant: Enter Broadcast Code as string Currently, the user sets the Broadcast Code as an array of bytes when prompted from the assistant submenu. However, the Bluetooth Core Specification requires that, on the UI level, the Broadcast Code shall be represented as a string (Vol 3, Part C, 3.2.6). This commit makes the Broadcast Code be parsed as a string from the assistant prompt. The bluetoothctl log below shows a Broadcast Assistant pushing an encrypted stream to a peer: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:31:7E:3F 00-60-37-31-7E-3F [bluetooth]# connect 00:60:37:31:7E:3F Attempting to connect to 00:60:37:31:7E:3F [CHG] Device 00:60:37:31:7E:3F Connected: yes [00-60-37-31-7E-3F]# Connection successful [00-60-37-31-7E-3F]# [NEW] Device 19:9A:7A:71:E5:8B 19-9A-7A-71-E5-8B [00-60-37-31-7E-3F]# [NEW] Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 [00-60-37-31-7E-3F]# assistant.push /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 [Assistant] Enter Metadata (auto/value): a [Assistant] Enter Broadcast Code (auto/value): Borne House [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 State: pending [00-60-37-31-7E-3F]# Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 pushed [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 State: requesting [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_19_9A_7A_71_E5_8B/dev_00_60_37_31_7E_3F/bis1 State: active The btmon log below shows the way the Broadcast Code string is converted into a byte array and sent to the peer via GATT: bluetoothd[6013]: < ACL Data TX: Handle 0 flags 0x00 dlen 28 ATT: Write Command (0x52) len 23 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[21]: 02018be5717a9a1900db5e3a02ffff010100000000 Opcode: Add Source (0x02) Source_Address_Type: 1 Source_Address: 19:9A:7A:71:E5:8B Source_Adv_SID: 0 Broadcast_ID: 0x3a5edb PA_Sync_State: Synchronize to PA - PAST not available PA_Interval: 0xffff Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 > ACL Data RX: Handle 0 flags 0x01 dlen 2 ATT: Handle Multiple Value Notification (0x23) len 24 Length: 0x0014 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[20]: 01018be5717a9a1900db5e3a0201010000000000 Source_ID: 1 Source_Address_Type: 1 Source_Address: 19:9A:7A:71:E5:8B Source_Adv_SID: 0 Broadcast_ID: 0x3a5edb PA_Sync_State: Synchronized to PA BIG_Encryption: Broadcast_Code required Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000000 bluetoothd[6013]: < ACL Data TX: Handle 0 flags 0x00 dlen 25 ATT: Write Command (0x52) len 20 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[18]: 040142c3b8726e6520486f75736500000000 Opcode: Set Broadcast_Code (0x04) Source_ID: 1 Broadcast_Code[16]: 426f726e6520486f7573650000000000 > ACL Data RX: Handle 0 flags 0x01 dlen 2 ATT: Handle Multiple Value Notification (0x23) len 24 Length: 0x0014 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[20]: 01018be5717a9a1900db5e3a0202010100000000 Source_ID: 1 Source_Address_Type: 1 Source_Address: 19:9A:7A:71:E5:8B Source_Adv_SID: 0 Broadcast_ID: 0x3a5edb PA_Sync_State: Synchronized to PA BIG_Encryption: Decrypting Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001
2024-08-29 21:25:06 +08:00
fail:
free(cfg->meta);
g_free(cfg);
return bt_shell_noninteractive_quit(EXIT_FAILURE);
assistant: Implement MediaAssistant Push command This implements the MediaAssistant "Push" command, to trigger the BlueZ Broadcast Assistant to send stream information to the peer. After issuing the "Push" command, the user is prompted to enter any stream metadata to be sent to the peer. If the "auto" value is chosen, the default metadata found in the BASE will be sent. Otherwise, the LTVs found in the BASE will be overwritten by the user input. If the stream is encrypted, the user is also prompted to enter the Broadcast Code for decrypting. If the "auto" value is chosen, a zero filled array will be provided over DBus. Below is a bluetoothctl log to exercise the "Push" command for an unencrypted stream: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:31:7E:3F 00-60-37-31-7E-3F [bluetooth]# connect 00:60:37:31:7E:3F Attempting to connect to 00:60:37:31:7E:3F [CHG] Device 00:60:37:31:7E:3F Connected: yes [00-60-37-31-7E-3F]# Connection successful [00-60-37-31-7E-3F]# [NEW] Device 15:19:44:63:76:7A 15-19-44-63-76-7A [00-60-37-31-7E-3F]# [NEW] Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 [00-60-37-31-7E-3F]# assistant.push /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 [Assistant] Enter Metadata (auto/value): 0x03 0x02 0x04 0x00 [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 State: pending [00-60-37-31-7E-3F]# Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 pushed [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 State: active The btmon log below shows the GATT write command sent by the Assistant and the GATT notification received from the peer: < ACL Data TX: Handle 0 flags 0x00 dlen 32 ATT: Write Command (0x52) len 27 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[25]: 02017a766344191500c21a3702ffff01010000000403020400 Opcode: Add Source (0x02) Source_Address_Type: 1 Source_Address: 15:19:44:63:76:7A Source_Adv_SID: 0 Broadcast_ID: 0x371ac2 PA_Sync_State: Synchronize to PA - PAST not available PA_Interval: 0xffff Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 > ACL Data RX: Handle 0 flags 0x01 dlen 6 ATT: Handle Multiple Value Notification (0x23) len 28 Length: 0x0018 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[24]: 01017a766344191500c21a37020001010000000403020400 Source_ID: 1 Source_Address_Type: 1 Source_Address: 15:19:44:63:76:7A Source_Adv_SID: 0 Broadcast_ID: 0x371ac2 PA_Sync_State: Synchronized to PA BIG_Encryption: Not encrypted Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 The bluetoothctl log below shows the "Push" command flow for an encrypted stream: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:31:7E:3F 00-60-37-31-7E-3F [bluetooth]# connect 00:60:37:31:7E:3F Attempting to connect to 00:60:37:31:7E:3F [CHG] Device 00:60:37:31:7E:3F Connected: yes [00-60-37-31-7E-3F]# Connection successful [00-60-37-31-7E-3F]# [NEW] Device 05:1F:EE:F3:F8:7D 05-1F-EE-F3-F8-7D [00-60-37-31-7E-3F]# [NEW] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 [00-60-37-31-7E-3F]# assistant.push /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 [Assistant] Enter Metadata (auto/value): 0x03 0x02 0x04 0x00 [Assistant] Enter Broadcast Code (auto/value): 0x01 0x02 0x68 0x05 0x53 0xf1 0x41 0x5a 0xa2 0x65 0xbb 0xaf 0xc6 0xea 0x03 0xb8 [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 State: pending [00-60-37-31-7E-3F]# Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 pushed [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 State: requesting [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 State: active The GATT write commands and notifications for this scenario are shown in the btmon log below: < ACL Data TX: Handle 0 flags 0x00 dlen 32 ATT: Write Command (0x52) len 27 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[25]: 02017df8f3ee1f0500f4015d02ffff01010000000403020400 Opcode: Add Source (0x02) Source_Address_Type: 1 Source_Address: 05:1F:EE:F3:F8:7D Source_Adv_SID: 0 Broadcast_ID: 0x5d01f4 PA_Sync_State: Synchronize to PA - PAST not available PA_Interval: 0xffff Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 > ACL Data RX: Handle 0 flags 0x01 dlen 6 ATT: Handle Multiple Value Notification (0x23) len 28 Length: 0x0018 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[24]: 01017df8f3ee1f0500f4015d020101000000000403020400 Source_ID: 1 Source_Address_Type: 1 Source_Address: 05:1F:EE:F3:F8:7D Source_Adv_SID: 0 Broadcast_ID: 0x5d01f4 PA_Sync_State: Synchronized to PA BIG_Encryption: Broadcast_Code required Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000000 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 < ACL Data TX: Handle 0 flags 0x00 dlen 25 ATT: Write Command (0x52) len 20 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[18]: 04010102680553f1415aa265bbafc6ea03b8 Opcode: Set Broadcast_Code (0x04) Source_ID: 1 Broadcast_Code[16]: 0102680553f1415aa265bbafc6ea03b8 > ACL Data RX: Handle 0 flags 0x01 dlen 6 ATT: Handle Multiple Value Notification (0x23) len 28 Length: 0x0018 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[24]: 01017df8f3ee1f0500f4015d020201010000000403020400 Source_ID: 1 Source_Address_Type: 1 Source_Address: 05:1F:EE:F3:F8:7D Source_Adv_SID: 0 Broadcast_ID: 0x5d01f4 PA_Sync_State: Synchronized to PA BIG_Encryption: Decrypting Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00
2024-08-05 20:04:29 +08:00
}
static void assistant_set_metadata_cfg(const char *input, void *user_data)
{
struct assistant_config *cfg = user_data;
DBusMessageIter iter, dict, entry, value;
const char *key;
if (!strcasecmp(input, "a") || !strcasecmp(input, "auto"))
goto done;
if (!cfg->meta)
cfg->meta = g_new0(struct iovec, 1);
cfg->meta->iov_base = str2bytearray((char *) input,
&cfg->meta->iov_len);
if (!cfg->meta->iov_base) {
free(cfg->meta);
cfg->meta = NULL;
}
done:
/* Get QoS property to check if the stream is encrypted */
if (!g_dbus_proxy_get_property(cfg->proxy, "QoS", &iter))
goto fail;
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
goto fail;
dbus_message_iter_recurse(&iter, &dict);
if (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_DICT_ENTRY)
goto fail;
dbus_message_iter_recurse(&dict, &entry);
dbus_message_iter_get_basic(&entry, &key);
if (strcasecmp(key, "Encryption") != 0)
goto fail;
dbus_message_iter_next(&entry);
dbus_message_iter_recurse(&entry, &value);
if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_BYTE)
goto fail;
dbus_message_iter_get_basic(&value, &cfg->qos.bcast.encryption);
if (cfg->qos.bcast.encryption)
/* Prompt user to enter the Broadcast Code to decrypt
* the stream
*/
bt_shell_prompt_input("Assistant",
"Enter Broadcast Code (auto/value):",
assistant_set_bcode_cfg, cfg);
else
if (!g_dbus_proxy_method_call(cfg->proxy, "Push",
push_setup, push_reply,
cfg, NULL)) {
bt_shell_printf("Failed to push assistant\n");
goto fail;
}
return;
fail:
free(cfg->meta);
g_free(cfg);
return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
static void cmd_push_assistant(int argc, char *argv[])
{
struct assistant_config *cfg;
cfg = new0(struct assistant_config, 1);
if (!cfg)
goto fail;
/* Search for DBus object */
cfg->proxy = g_dbus_proxy_lookup(assistants, NULL, argv[1],
MEDIA_ASSISTANT_INTERFACE);
if (!cfg->proxy) {
bt_shell_printf("Assistant %s not found\n", argv[1]);
goto fail;
}
/* Prompt user to enter metadata */
bt_shell_prompt_input("Assistant",
"Enter Metadata (auto/value):",
assistant_set_metadata_cfg, cfg);
return;
fail:
g_free(cfg);
return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
static const struct bt_shell_menu assistant_menu = {
.name = "assistant",
.desc = "Media Assistant Submenu",
.entries = {
{ "push", "<assistant>", cmd_push_assistant,
"Send stream information to peer" },
{} },
};
client: Add assistant submenu This adds the initial implementation for the assistant menu in bluetoothctl, to detect and print MediaAssistant objects. The current BAP Broadcast Assistant implementation can be tested by running bluetoothctl, connecting to a BASS Server, scanning a Broadcast Source that is streaming a number of BISes with audio capabilities matching the capabilities of the peer device, and noticing the MediaAssistant objects being created: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:94:A6:A3 00-60-37-94-A6-A3 [bluetooth]# connect 00:60:37:94:A6:A3 Attempting to connect to 00:60:37:94:A6:A3 [CHG] Device 00:60:37:94:A6:A3 Connected: yes [00-60-37-94-A6-A3]# Connection successful [00-60-37-94-A6-A3]# [NEW] Device 15:65:78:B6:52:F6 15-65-78-B6-52-F6 [00-60-37-94-A6-A3]# [NEW] Assistant /org/bluez/hci0/src_15_65_78_B6_52_F6/dev_00_60_37_94_A6_A3/bis1 [00-60-37-94-A6-A3]# [NEW] Assistant /org/bluez/hci0/src_15_65_78_B6_52_F6/dev_00_60_37_94_A6_A3/bis2 [00-60-37-94-A6-A3]# scan off [00-60-37-94-A6-A3]# Diovery stopped [00-60-37-94-A6-A3]# disconnect Attempting to disconnect from 00:60:37:94:A6:A3 [00-60-37-94-A6-A3]# Successful disconnected [CHG] Device 00:60:37:94:A6:A3 Connected: no [bluetooth]# [DEL] Assistant /org/bluez/hci0/src_15_65_78_B6_52_F6/dev_00_60_37_94_A6_A3/bis1 [bluetooth]# [DEL] Assistant /org/bluez/hci0/src_15_65_78_B6_52_F6/dev_00_60_37_94_A6_A3/bis2
2024-07-16 22:22:07 +08:00
static GDBusClient * client;
void assistant_add_submenu(void)
{
assistant: Implement MediaAssistant Push command This implements the MediaAssistant "Push" command, to trigger the BlueZ Broadcast Assistant to send stream information to the peer. After issuing the "Push" command, the user is prompted to enter any stream metadata to be sent to the peer. If the "auto" value is chosen, the default metadata found in the BASE will be sent. Otherwise, the LTVs found in the BASE will be overwritten by the user input. If the stream is encrypted, the user is also prompted to enter the Broadcast Code for decrypting. If the "auto" value is chosen, a zero filled array will be provided over DBus. Below is a bluetoothctl log to exercise the "Push" command for an unencrypted stream: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:31:7E:3F 00-60-37-31-7E-3F [bluetooth]# connect 00:60:37:31:7E:3F Attempting to connect to 00:60:37:31:7E:3F [CHG] Device 00:60:37:31:7E:3F Connected: yes [00-60-37-31-7E-3F]# Connection successful [00-60-37-31-7E-3F]# [NEW] Device 15:19:44:63:76:7A 15-19-44-63-76-7A [00-60-37-31-7E-3F]# [NEW] Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 [00-60-37-31-7E-3F]# assistant.push /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 [Assistant] Enter Metadata (auto/value): 0x03 0x02 0x04 0x00 [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 State: pending [00-60-37-31-7E-3F]# Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 pushed [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_15_19_44_63_76_7A/dev_00_60_37_31_7E_3F/bis1 State: active The btmon log below shows the GATT write command sent by the Assistant and the GATT notification received from the peer: < ACL Data TX: Handle 0 flags 0x00 dlen 32 ATT: Write Command (0x52) len 27 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[25]: 02017a766344191500c21a3702ffff01010000000403020400 Opcode: Add Source (0x02) Source_Address_Type: 1 Source_Address: 15:19:44:63:76:7A Source_Adv_SID: 0 Broadcast_ID: 0x371ac2 PA_Sync_State: Synchronize to PA - PAST not available PA_Interval: 0xffff Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 > ACL Data RX: Handle 0 flags 0x01 dlen 6 ATT: Handle Multiple Value Notification (0x23) len 28 Length: 0x0018 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[24]: 01017a766344191500c21a37020001010000000403020400 Source_ID: 1 Source_Address_Type: 1 Source_Address: 15:19:44:63:76:7A Source_Adv_SID: 0 Broadcast_ID: 0x371ac2 PA_Sync_State: Synchronized to PA BIG_Encryption: Not encrypted Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 The bluetoothctl log below shows the "Push" command flow for an encrypted stream: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:31:7E:3F 00-60-37-31-7E-3F [bluetooth]# connect 00:60:37:31:7E:3F Attempting to connect to 00:60:37:31:7E:3F [CHG] Device 00:60:37:31:7E:3F Connected: yes [00-60-37-31-7E-3F]# Connection successful [00-60-37-31-7E-3F]# [NEW] Device 05:1F:EE:F3:F8:7D 05-1F-EE-F3-F8-7D [00-60-37-31-7E-3F]# [NEW] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 [00-60-37-31-7E-3F]# assistant.push /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 [Assistant] Enter Metadata (auto/value): 0x03 0x02 0x04 0x00 [Assistant] Enter Broadcast Code (auto/value): 0x01 0x02 0x68 0x05 0x53 0xf1 0x41 0x5a 0xa2 0x65 0xbb 0xaf 0xc6 0xea 0x03 0xb8 [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 State: pending [00-60-37-31-7E-3F]# Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 pushed [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 State: requesting [00-60-37-31-7E-3F]# [CHG] Assistant /org/bluez/hci0/src_05_1F_EE_F3_F8_7D/dev_00_60_37_31_7E_3F/bis1 State: active The GATT write commands and notifications for this scenario are shown in the btmon log below: < ACL Data TX: Handle 0 flags 0x00 dlen 32 ATT: Write Command (0x52) len 27 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[25]: 02017df8f3ee1f0500f4015d02ffff01010000000403020400 Opcode: Add Source (0x02) Source_Address_Type: 1 Source_Address: 05:1F:EE:F3:F8:7D Source_Adv_SID: 0 Broadcast_ID: 0x5d01f4 PA_Sync_State: Synchronize to PA - PAST not available PA_Interval: 0xffff Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 > ACL Data RX: Handle 0 flags 0x01 dlen 6 ATT: Handle Multiple Value Notification (0x23) len 28 Length: 0x0018 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[24]: 01017df8f3ee1f0500f4015d020101000000000403020400 Source_ID: 1 Source_Address_Type: 1 Source_Address: 05:1F:EE:F3:F8:7D Source_Adv_SID: 0 Broadcast_ID: 0x5d01f4 PA_Sync_State: Synchronized to PA BIG_Encryption: Broadcast_Code required Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000000 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00 < ACL Data TX: Handle 0 flags 0x00 dlen 25 ATT: Write Command (0x52) len 20 Handle: 0x0040 Type: Broadcast Audio Scan Control Point (0x2bc7) Data[18]: 04010102680553f1415aa265bbafc6ea03b8 Opcode: Set Broadcast_Code (0x04) Source_ID: 1 Broadcast_Code[16]: 0102680553f1415aa265bbafc6ea03b8 > ACL Data RX: Handle 0 flags 0x01 dlen 6 ATT: Handle Multiple Value Notification (0x23) len 28 Length: 0x0018 Handle: 0x003a Type: Broadcast Receive State (0x2bc8) Data[24]: 01017df8f3ee1f0500f4015d020201010000000403020400 Source_ID: 1 Source_Address_Type: 1 Source_Address: 05:1F:EE:F3:F8:7D Source_Adv_SID: 0 Broadcast_ID: 0x5d01f4 PA_Sync_State: Synchronized to PA BIG_Encryption: Decrypting Num_Subgroups: 1 Subgroup #0: BIS_Sync State: 0x00000001 Metadata: #0: len 0x03 type 0x02 Metadata: 04 00
2024-08-05 20:04:29 +08:00
bt_shell_add_submenu(&assistant_menu);
client: Add assistant submenu This adds the initial implementation for the assistant menu in bluetoothctl, to detect and print MediaAssistant objects. The current BAP Broadcast Assistant implementation can be tested by running bluetoothctl, connecting to a BASS Server, scanning a Broadcast Source that is streaming a number of BISes with audio capabilities matching the capabilities of the peer device, and noticing the MediaAssistant objects being created: client/bluetoothctl [bluetooth]# [CHG] Controller 00:60:37:31:7E:3F Pairable: yes [bluetooth]# AdvertisementMonitor path registered [bluetooth]# scan on [bluetooth]# [NEW] Device 00:60:37:94:A6:A3 00-60-37-94-A6-A3 [bluetooth]# connect 00:60:37:94:A6:A3 Attempting to connect to 00:60:37:94:A6:A3 [CHG] Device 00:60:37:94:A6:A3 Connected: yes [00-60-37-94-A6-A3]# Connection successful [00-60-37-94-A6-A3]# [NEW] Device 15:65:78:B6:52:F6 15-65-78-B6-52-F6 [00-60-37-94-A6-A3]# [NEW] Assistant /org/bluez/hci0/src_15_65_78_B6_52_F6/dev_00_60_37_94_A6_A3/bis1 [00-60-37-94-A6-A3]# [NEW] Assistant /org/bluez/hci0/src_15_65_78_B6_52_F6/dev_00_60_37_94_A6_A3/bis2 [00-60-37-94-A6-A3]# scan off [00-60-37-94-A6-A3]# Diovery stopped [00-60-37-94-A6-A3]# disconnect Attempting to disconnect from 00:60:37:94:A6:A3 [00-60-37-94-A6-A3]# Successful disconnected [CHG] Device 00:60:37:94:A6:A3 Connected: no [bluetooth]# [DEL] Assistant /org/bluez/hci0/src_15_65_78_B6_52_F6/dev_00_60_37_94_A6_A3/bis1 [bluetooth]# [DEL] Assistant /org/bluez/hci0/src_15_65_78_B6_52_F6/dev_00_60_37_94_A6_A3/bis2
2024-07-16 22:22:07 +08:00
dbus_conn = bt_shell_get_env("DBUS_CONNECTION");
if (!dbus_conn || client)
return;
client = g_dbus_client_new(dbus_conn, "org.bluez", "/org/bluez");
g_dbus_client_set_proxy_handlers(client, proxy_added, proxy_removed,
property_changed, NULL);
g_dbus_client_set_disconnect_watch(client, disconnect_handler, NULL);
}
void assistant_remove_submenu(void)
{
g_dbus_client_unref(client);
client = NULL;
}