* [PATCH BlueZ 00/10] Initial implementation of BAP Broadcast Assistant
@ 2024-07-16 14:21 Iulia Tanasescu
2024-07-16 14:21 ` [PATCH BlueZ 01/10] shared/bap: Add separate API to merge caps Iulia Tanasescu
` (10 more replies)
0 siblings, 11 replies; 13+ messages in thread
From: Iulia Tanasescu @ 2024-07-16 14:21 UTC (permalink / raw)
To: linux-bluetooth
Cc: claudia.rosu, mihai-octavian.urzica, vlad.pruteanu,
andrei.istodorescu, luiz.dentz, Iulia Tanasescu
This patch adds an initial implementation of the BAP Broadcast Assistant
role.
The core implementation resides in the BASS plugin (the BAP Broadcast
Assistant is a BASS Client).
The BAP plugin implements the callback to probe Broadcast Sources and
parse the BASE. Information about each detected stream is notified to
the BASS plugin, which will compare stream audio capabilities with the
capabilities supported by the peer Scan Delegator (discovered by reading
the Sink PAC characteristic).
For each match, the BASS plugin registers a MediaAssistant DBus object.
The MediaAssistant methods will be implemented in a following patch.
This patch also introduces the assistant submenu in bluetoothctl, to
enumerate MediaAssistant objects as they are created. Commands that the
user can call on a MediaAssistant object will be implemented in a
following patch.
Below is a bluetoothctl log which demonstrates a Broadcast Assistant
connecting to a Scan Delegator, scanning a Broadcast Source and
enumerating MediaAssistant objects:
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
Iulia Tanasescu (10):
shared/bap: Add separate API to merge caps
shared/bap: Update bt_bap_verify_bis to receive caps
shared/bap: Remove unused param from bt_bap_verify_bis
shared/bap: Allow checking bis caps against peer caps
shared/bap: Append bcast sink pacs to Sink PAC char
bap: Add API to get bt_bap matching device
shared/bass: Add API to get GATT client reference
bass: Register MediaAssistant objects
bap: Notify scanned BISes to BASS
client: Add assistant submenu
Makefile.plugins | 4 +-
Makefile.tools | 3 +-
client/assistant.c | 164 +++++++++++++++++++++++++++
client/assistant.h | 13 +++
client/main.c | 5 +-
profiles/audio/bap.c | 40 ++++++-
profiles/audio/bap.h | 10 ++
profiles/audio/bass.c | 257 ++++++++++++++++++++++++++++++++++++++++++
profiles/audio/bass.h | 13 +++
src/shared/bap.c | 59 ++++++----
src/shared/bap.h | 9 +-
src/shared/bass.c | 8 ++
src/shared/bass.h | 1 +
unit/test-bap.c | 13 +--
14 files changed, 555 insertions(+), 44 deletions(-)
create mode 100644 client/assistant.c
create mode 100644 client/assistant.h
create mode 100644 profiles/audio/bap.h
create mode 100644 profiles/audio/bass.h
base-commit: 73266377b0185c56c921b8cece257df428612d73
--
2.39.2
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH BlueZ 01/10] shared/bap: Add separate API to merge caps
2024-07-16 14:21 [PATCH BlueZ 00/10] Initial implementation of BAP Broadcast Assistant Iulia Tanasescu
@ 2024-07-16 14:21 ` Iulia Tanasescu
2024-07-16 19:51 ` Initial implementation of BAP Broadcast Assistant bluez.test.bot
2024-07-16 14:21 ` [PATCH BlueZ 02/10] shared/bap: Update bt_bap_verify_bis to receive caps Iulia Tanasescu
` (9 subsequent siblings)
10 siblings, 1 reply; 13+ messages in thread
From: Iulia Tanasescu @ 2024-07-16 14:21 UTC (permalink / raw)
To: linux-bluetooth
Cc: claudia.rosu, mihai-octavian.urzica, vlad.pruteanu,
andrei.istodorescu, luiz.dentz, Iulia Tanasescu
This moves the logic to merge L2 and L3 capabilities discovered
inside a BASE structure in a public API.
---
src/shared/bap.c | 40 ++++++++++++++++++++++++----------------
src/shared/bap.h | 2 ++
2 files changed, 26 insertions(+), 16 deletions(-)
diff --git a/src/shared/bap.c b/src/shared/bap.c
index d59eac8cc..1259ee3c9 100644
--- a/src/shared/bap.c
+++ b/src/shared/bap.c
@@ -6607,29 +6607,21 @@ static struct bt_ltv_match bap_check_bis(struct bt_bap_db *ldb,
return compare_data;
}
-void bt_bap_verify_bis(struct bt_bap *bap, uint8_t bis_index,
- struct bt_bap_codec *codec,
- struct iovec *l2_caps,
- struct iovec *l3_caps,
- struct bt_bap_pac **lpac,
- struct iovec **caps)
+struct iovec *bt_bap_merge_caps(struct iovec *l2_caps, struct iovec *l3_caps)
{
struct bt_ltv_extract merge_data = {0};
- struct bt_ltv_match match_data;
if (!l2_caps)
/* Codec_Specific_Configuration parameters shall
* be present at Level 2.
*/
- return;
+ return NULL;
- if (!l3_caps) {
+ if (!l3_caps)
/* Codec_Specific_Configuration parameters may
* be present at Level 3.
*/
- merge_data.result = util_iov_dup(l2_caps, 1);
- goto done;
- }
+ return util_iov_dup(l2_caps, 1);
merge_data.src = l3_caps;
merge_data.result = new0(struct iovec, 1);
@@ -6642,17 +6634,33 @@ void bt_bap_verify_bis(struct bt_bap *bap, uint8_t bis_index,
NULL,
bap_sink_check_level2_ltv, &merge_data);
-done:
+ return merge_data.result;
+}
+
+void bt_bap_verify_bis(struct bt_bap *bap, uint8_t bis_index,
+ struct bt_bap_codec *codec,
+ struct iovec *l2_caps,
+ struct iovec *l3_caps,
+ struct bt_bap_pac **lpac,
+ struct iovec **caps)
+{
+ struct iovec *merged_caps;
+ struct bt_ltv_match match_data;
+
+ merged_caps = bt_bap_merge_caps(l2_caps, l3_caps);
+ if (!merged_caps)
+ return;
+
/* Check each BIS Codec Specific Configuration LTVs against our Codec
* Specific Capabilities and if the BIS matches create a PAC with it
*/
- match_data = bap_check_bis(bap->ldb, merge_data.result);
+ match_data = bap_check_bis(bap->ldb, merged_caps);
if (match_data.found == true) {
- *caps = merge_data.result;
+ *caps = merged_caps;
*lpac = match_data.data;
DBG(bap, "Matching BIS %i", bis_index);
} else {
- util_iov_free(merge_data.result, 1);
+ util_iov_free(merged_caps, 1);
*caps = NULL;
*lpac = NULL;
}
diff --git a/src/shared/bap.h b/src/shared/bap.h
index b35b2711e..e63161dca 100644
--- a/src/shared/bap.h
+++ b/src/shared/bap.h
@@ -251,6 +251,8 @@ bool bt_bap_pac_bcast_is_local(struct bt_bap *bap, struct bt_bap_pac *pac);
struct iovec *bt_bap_stream_get_base(struct bt_bap_stream *stream);
+struct iovec *bt_bap_merge_caps(struct iovec *l2_caps, struct iovec *l3_caps);
+
void bt_bap_verify_bis(struct bt_bap *bap, uint8_t bis_index,
struct bt_bap_codec *codec,
struct iovec *l2_caps,
--
2.39.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH BlueZ 02/10] shared/bap: Update bt_bap_verify_bis to receive caps
2024-07-16 14:21 [PATCH BlueZ 00/10] Initial implementation of BAP Broadcast Assistant Iulia Tanasescu
2024-07-16 14:21 ` [PATCH BlueZ 01/10] shared/bap: Add separate API to merge caps Iulia Tanasescu
@ 2024-07-16 14:21 ` Iulia Tanasescu
2024-07-16 14:22 ` [PATCH BlueZ 03/10] shared/bap: Remove unused param from bt_bap_verify_bis Iulia Tanasescu
` (8 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Iulia Tanasescu @ 2024-07-16 14:21 UTC (permalink / raw)
To: linux-bluetooth
Cc: claudia.rosu, mihai-octavian.urzica, vlad.pruteanu,
andrei.istodorescu, luiz.dentz, Iulia Tanasescu
This updates bt_bap_verify_bis to receive the already merged L2 and L3
capabilities, instead of computing it internally.
---
profiles/audio/bap.c | 11 ++++++++---
src/shared/bap.c | 15 ++++-----------
src/shared/bap.h | 6 ++----
unit/test-bap.c | 7 ++++---
4 files changed, 18 insertions(+), 21 deletions(-)
diff --git a/profiles/audio/bap.c b/profiles/audio/bap.c
index afa938091..2f37d33eb 100644
--- a/profiles/audio/bap.c
+++ b/profiles/audio/bap.c
@@ -1191,12 +1191,17 @@ static bool parse_base(struct bap_data *bap_data, struct bt_iso_base *base,
l3_caps->iov_len, NULL, print_ltv,
func);
+ merged_caps = bt_bap_merge_caps(l2_caps, l3_caps);
+ if (!merged_caps) {
+ free(path);
+ continue;
+ }
+
/* Check if this BIS matches any local PAC */
bt_bap_verify_bis(bap_data->bap, bis_index, &codec,
- l2_caps, l3_caps, &matched_lpac,
- &merged_caps);
+ merged_caps, &matched_lpac);
- if (matched_lpac == NULL || merged_caps == NULL) {
+ if (matched_lpac == NULL) {
free(path);
continue;
}
diff --git a/src/shared/bap.c b/src/shared/bap.c
index 1259ee3c9..3381ffdd4 100644
--- a/src/shared/bap.c
+++ b/src/shared/bap.c
@@ -6639,29 +6639,22 @@ struct iovec *bt_bap_merge_caps(struct iovec *l2_caps, struct iovec *l3_caps)
void bt_bap_verify_bis(struct bt_bap *bap, uint8_t bis_index,
struct bt_bap_codec *codec,
- struct iovec *l2_caps,
- struct iovec *l3_caps,
- struct bt_bap_pac **lpac,
- struct iovec **caps)
+ struct iovec *caps,
+ struct bt_bap_pac **lpac)
{
- struct iovec *merged_caps;
struct bt_ltv_match match_data;
- merged_caps = bt_bap_merge_caps(l2_caps, l3_caps);
- if (!merged_caps)
+ if (!caps)
return;
/* Check each BIS Codec Specific Configuration LTVs against our Codec
* Specific Capabilities and if the BIS matches create a PAC with it
*/
- match_data = bap_check_bis(bap->ldb, merged_caps);
+ match_data = bap_check_bis(bap->ldb, caps);
if (match_data.found == true) {
- *caps = merged_caps;
*lpac = match_data.data;
DBG(bap, "Matching BIS %i", bis_index);
} else {
- util_iov_free(merged_caps, 1);
- *caps = NULL;
*lpac = NULL;
}
diff --git a/src/shared/bap.h b/src/shared/bap.h
index e63161dca..3e68f00e2 100644
--- a/src/shared/bap.h
+++ b/src/shared/bap.h
@@ -255,8 +255,6 @@ struct iovec *bt_bap_merge_caps(struct iovec *l2_caps, struct iovec *l3_caps);
void bt_bap_verify_bis(struct bt_bap *bap, uint8_t bis_index,
struct bt_bap_codec *codec,
- struct iovec *l2_caps,
- struct iovec *l3_caps,
- struct bt_bap_pac **lpac,
- struct iovec **caps);
+ struct iovec *caps,
+ struct bt_bap_pac **lpac);
diff --git a/unit/test-bap.c b/unit/test-bap.c
index 9dd7a45e8..4b47d6363 100644
--- a/unit/test-bap.c
+++ b/unit/test-bap.c
@@ -587,12 +587,13 @@ static void bsnk_pac_added(struct bt_bap_pac *pac, void *user_data)
codec.id = LC3_ID;
for (uint8_t i = 0; i < data->cfg->streams; i++) {
- bt_bap_verify_bis(data->bap, bis_idx++, &codec,
- &data->cfg->cc, NULL, &lpac, &cc);
+ cc = bt_bap_merge_caps(&data->cfg->cc, NULL);
+ g_assert(cc);
+
+ bt_bap_verify_bis(data->bap, bis_idx++, &codec, cc, &lpac);
g_assert(lpac);
g_assert(pac == lpac);
- g_assert(cc);
stream = bt_bap_stream_new(data->bap,
pac, NULL, &data->cfg->qos, cc);
--
2.39.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH BlueZ 03/10] shared/bap: Remove unused param from bt_bap_verify_bis
2024-07-16 14:21 [PATCH BlueZ 00/10] Initial implementation of BAP Broadcast Assistant Iulia Tanasescu
2024-07-16 14:21 ` [PATCH BlueZ 01/10] shared/bap: Add separate API to merge caps Iulia Tanasescu
2024-07-16 14:21 ` [PATCH BlueZ 02/10] shared/bap: Update bt_bap_verify_bis to receive caps Iulia Tanasescu
@ 2024-07-16 14:22 ` Iulia Tanasescu
2024-07-16 14:22 ` [PATCH BlueZ 04/10] shared/bap: Allow checking bis caps against peer caps Iulia Tanasescu
` (7 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Iulia Tanasescu @ 2024-07-16 14:22 UTC (permalink / raw)
To: linux-bluetooth
Cc: claudia.rosu, mihai-octavian.urzica, vlad.pruteanu,
andrei.istodorescu, luiz.dentz, Iulia Tanasescu
This removes the codec parameter from bt_bap_verify_bis,
since it is not used.
---
profiles/audio/bap.c | 2 +-
src/shared/bap.c | 1 -
src/shared/bap.h | 1 -
unit/test-bap.c | 8 +-------
4 files changed, 2 insertions(+), 10 deletions(-)
diff --git a/profiles/audio/bap.c b/profiles/audio/bap.c
index 2f37d33eb..6d8289418 100644
--- a/profiles/audio/bap.c
+++ b/profiles/audio/bap.c
@@ -1198,7 +1198,7 @@ static bool parse_base(struct bap_data *bap_data, struct bt_iso_base *base,
}
/* Check if this BIS matches any local PAC */
- bt_bap_verify_bis(bap_data->bap, bis_index, &codec,
+ bt_bap_verify_bis(bap_data->bap, bis_index,
merged_caps, &matched_lpac);
if (matched_lpac == NULL) {
diff --git a/src/shared/bap.c b/src/shared/bap.c
index 3381ffdd4..d2a500e48 100644
--- a/src/shared/bap.c
+++ b/src/shared/bap.c
@@ -6638,7 +6638,6 @@ struct iovec *bt_bap_merge_caps(struct iovec *l2_caps, struct iovec *l3_caps)
}
void bt_bap_verify_bis(struct bt_bap *bap, uint8_t bis_index,
- struct bt_bap_codec *codec,
struct iovec *caps,
struct bt_bap_pac **lpac)
{
diff --git a/src/shared/bap.h b/src/shared/bap.h
index 3e68f00e2..bf928bc2d 100644
--- a/src/shared/bap.h
+++ b/src/shared/bap.h
@@ -254,7 +254,6 @@ struct iovec *bt_bap_stream_get_base(struct bt_bap_stream *stream);
struct iovec *bt_bap_merge_caps(struct iovec *l2_caps, struct iovec *l3_caps);
void bt_bap_verify_bis(struct bt_bap *bap, uint8_t bis_index,
- struct bt_bap_codec *codec,
struct iovec *caps,
struct bt_bap_pac **lpac);
diff --git a/unit/test-bap.c b/unit/test-bap.c
index 4b47d6363..9cfc8c403 100644
--- a/unit/test-bap.c
+++ b/unit/test-bap.c
@@ -575,22 +575,16 @@ static void bsnk_pac_added(struct bt_bap_pac *pac, void *user_data)
struct test_data *data = user_data;
struct bt_bap_pac *lpac;
struct iovec *cc;
- struct bt_bap_codec codec = {0};
struct bt_bap_stream *stream;
uint8_t bis_idx = 1;
bt_bap_pac_set_ops(pac, &bcast_pac_ops, NULL);
- if (data->cfg->vs)
- codec.id = 0xff;
- else
- codec.id = LC3_ID;
-
for (uint8_t i = 0; i < data->cfg->streams; i++) {
cc = bt_bap_merge_caps(&data->cfg->cc, NULL);
g_assert(cc);
- bt_bap_verify_bis(data->bap, bis_idx++, &codec, cc, &lpac);
+ bt_bap_verify_bis(data->bap, bis_idx++, cc, &lpac);
g_assert(lpac);
g_assert(pac == lpac);
--
2.39.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH BlueZ 04/10] shared/bap: Allow checking bis caps against peer caps
2024-07-16 14:21 [PATCH BlueZ 00/10] Initial implementation of BAP Broadcast Assistant Iulia Tanasescu
` (2 preceding siblings ...)
2024-07-16 14:22 ` [PATCH BlueZ 03/10] shared/bap: Remove unused param from bt_bap_verify_bis Iulia Tanasescu
@ 2024-07-16 14:22 ` Iulia Tanasescu
2024-07-16 14:22 ` [PATCH BlueZ 05/10] shared/bap: Append bcast sink pacs to Sink PAC char Iulia Tanasescu
` (6 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Iulia Tanasescu @ 2024-07-16 14:22 UTC (permalink / raw)
To: linux-bluetooth
Cc: claudia.rosu, mihai-octavian.urzica, vlad.pruteanu,
andrei.istodorescu, luiz.dentz, Iulia Tanasescu
A BAP Broadcast Assistant needs to match stream capabilities with
capabilities discovered in the Sink PAC characteristic on the peer.
This updates bt_bap_verify_bis to check the provided stream capabilities
against local or remote capabilities, depending on the bap structure
provided:
If the device is acting as a BAP Broadcast Sink and the bap session was
created after scanning a Broadcast Source, the stream caps will be matched
with the local broadcast sink PAC.
If the device is acting as a Broadcast Assistant and the bap session is a
client session with a BAP Scan Delegator, the stream caps will be matched
with the PAC records populated in the rdb at service discovery.
---
src/shared/bap.c | 26 ++++++++++++++++++++------
1 file changed, 20 insertions(+), 6 deletions(-)
diff --git a/src/shared/bap.c b/src/shared/bap.c
index d2a500e48..44fb06169 100644
--- a/src/shared/bap.c
+++ b/src/shared/bap.c
@@ -6577,7 +6577,7 @@ static void bap_sink_match_allocation(size_t i, uint8_t l, uint8_t t,
data->found = false;
}
-static struct bt_ltv_match bap_check_bis(struct bt_bap_db *ldb,
+static struct bt_ltv_match bap_check_bis(uint32_t sink_loc, struct queue *pacs,
struct iovec *bis_data)
{
struct bt_ltv_match compare_data = {};
@@ -6588,10 +6588,10 @@ static struct bt_ltv_match bap_check_bis(struct bt_bap_db *ldb,
*/
compare_data.found = true;
- if (ldb->pacs->sink_loc_value) {
+ if (sink_loc) {
uint8_t type = BAP_CHANNEL_ALLOCATION_LTV_TYPE;
- compare_data.data32 = ldb->pacs->sink_loc_value;
+ compare_data.data32 = sink_loc;
util_ltv_foreach(bis_data->iov_base, bis_data->iov_len, &type,
bap_sink_match_allocation, &compare_data);
}
@@ -6600,8 +6600,7 @@ static struct bt_ltv_match bap_check_bis(struct bt_bap_db *ldb,
if (compare_data.found) {
compare_data.data = bis_data;
compare_data.found = false;
- queue_foreach(ldb->broadcast_sinks, check_local_pac,
- &compare_data);
+ queue_foreach(pacs, check_local_pac, &compare_data);
}
return compare_data;
@@ -6642,14 +6641,29 @@ void bt_bap_verify_bis(struct bt_bap *bap, uint8_t bis_index,
struct bt_bap_pac **lpac)
{
struct bt_ltv_match match_data;
+ uint32_t sink_loc;
+ struct queue *pacs;
if (!caps)
return;
+ /* If the bap session corresponds to a client connection with
+ * a BAP Server, bis caps should be checked against peer caps.
+ * If the bap session corresponds to a scanned broadcast source,
+ * bis caps should be checked against local broadcast sink caps.
+ */
+ if (bap->client) {
+ sink_loc = bap->rdb->pacs->sink_loc_value;
+ pacs = bap->rdb->sinks;
+ } else {
+ sink_loc = bap->ldb->pacs->sink_loc_value;
+ pacs = bap->ldb->broadcast_sinks;
+ }
+
/* Check each BIS Codec Specific Configuration LTVs against our Codec
* Specific Capabilities and if the BIS matches create a PAC with it
*/
- match_data = bap_check_bis(bap->ldb, caps);
+ match_data = bap_check_bis(sink_loc, pacs, caps);
if (match_data.found == true) {
*lpac = match_data.data;
DBG(bap, "Matching BIS %i", bis_index);
--
2.39.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH BlueZ 05/10] shared/bap: Append bcast sink pacs to Sink PAC char
2024-07-16 14:21 [PATCH BlueZ 00/10] Initial implementation of BAP Broadcast Assistant Iulia Tanasescu
` (3 preceding siblings ...)
2024-07-16 14:22 ` [PATCH BlueZ 04/10] shared/bap: Allow checking bis caps against peer caps Iulia Tanasescu
@ 2024-07-16 14:22 ` Iulia Tanasescu
2024-07-16 14:22 ` [PATCH BlueZ 06/10] bap: Add API to get bt_bap matching device Iulia Tanasescu
` (5 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Iulia Tanasescu @ 2024-07-16 14:22 UTC (permalink / raw)
To: linux-bluetooth
Cc: claudia.rosu, mihai-octavian.urzica, vlad.pruteanu,
andrei.istodorescu, luiz.dentz, Iulia Tanasescu
It is mandatory for a BAP Broadcast Sink to support the PACS Server role.
The Sink PAC characteristic should contain PAC records that expose
supported audio capabilities for receiving both unicast and broadcast
streams.
A BAP Broadcast Assistant acting as a GATT Client needs to discover the
Sink PAC characteristic on the BAP Scan Delegator peer (BAP Broadcast
Sink), in order to discover supported capabilities for receiving streams.
This commit updates the callback for handling read requests for the Sink
PAC characteristic, to also append Broadcast Sink pac structures to the
read response.
---
src/shared/bap.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/shared/bap.c b/src/shared/bap.c
index 44fb06169..0aa89c278 100644
--- a/src/shared/bap.c
+++ b/src/shared/bap.c
@@ -441,6 +441,7 @@ static void pacs_sink_read(struct gatt_db_attribute *attrib,
iov.iov_len = 0;
queue_foreach(bdb->sinks, pac_foreach, &iov);
+ queue_foreach(bdb->broadcast_sinks, pac_foreach, &iov);
gatt_db_attribute_read_result(attrib, id, 0, iov.iov_base,
iov.iov_len);
--
2.39.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH BlueZ 06/10] bap: Add API to get bt_bap matching device
2024-07-16 14:21 [PATCH BlueZ 00/10] Initial implementation of BAP Broadcast Assistant Iulia Tanasescu
` (4 preceding siblings ...)
2024-07-16 14:22 ` [PATCH BlueZ 05/10] shared/bap: Append bcast sink pacs to Sink PAC char Iulia Tanasescu
@ 2024-07-16 14:22 ` Iulia Tanasescu
2024-07-16 14:22 ` [PATCH BlueZ 07/10] shared/bass: Add API to get GATT client reference Iulia Tanasescu
` (4 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Iulia Tanasescu @ 2024-07-16 14:22 UTC (permalink / raw)
To: linux-bluetooth
Cc: claudia.rosu, mihai-octavian.urzica, vlad.pruteanu,
andrei.istodorescu, luiz.dentz, Iulia Tanasescu
This adds a public BAP API to obtain a reference to the bt_bap session
with a peer device.
---
Makefile.plugins | 2 +-
profiles/audio/bap.c | 21 +++++++++++++++++++++
profiles/audio/bap.h | 10 ++++++++++
3 files changed, 32 insertions(+), 1 deletion(-)
create mode 100644 profiles/audio/bap.h
diff --git a/Makefile.plugins b/Makefile.plugins
index 44fda4536..9dd8134b4 100644
--- a/Makefile.plugins
+++ b/Makefile.plugins
@@ -115,7 +115,7 @@ endif
if BAP
builtin_modules += bap
-builtin_sources += profiles/audio/bap.c
+builtin_sources += profiles/audio/bap.h profiles/audio/bap.c
endif
if BASS
diff --git a/profiles/audio/bap.c b/profiles/audio/bap.c
index 6d8289418..fe5390e6a 100644
--- a/profiles/audio/bap.c
+++ b/profiles/audio/bap.c
@@ -56,6 +56,8 @@
#include "src/log.h"
#include "src/error.h"
+#include "bap.h"
+
#define ISO_SOCKET_UUID "6fbaf188-05e0-496a-9885-d6ddfdb4e03e"
#define PACS_UUID_STR "00001850-0000-1000-8000-00805f9b34fb"
#define BCAAS_UUID_STR "00001852-0000-1000-8000-00805f9b34fb"
@@ -2751,6 +2753,25 @@ static void pac_removed_broadcast(struct bt_bap_pac *pac, void *user_data)
ep_unregister(ep);
}
+static bool match_device(const void *data, const void *match_data)
+{
+ const struct bap_data *bdata = data;
+ const struct btd_device *device = match_data;
+
+ return bdata->device == device;
+}
+
+struct bt_bap *bap_get_session(struct btd_device *device)
+{
+ struct bap_data *data;
+
+ data = queue_find(sessions, match_device, device);
+ if (!data)
+ return NULL;
+
+ return data->bap;
+}
+
static struct bap_data *bap_data_new(struct btd_device *device)
{
struct bap_data *data;
diff --git a/profiles/audio/bap.h b/profiles/audio/bap.h
new file mode 100644
index 000000000..66f8db887
--- /dev/null
+++ b/profiles/audio/bap.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright 2024 NXP
+ *
+ */
+
+struct bt_bap *bap_get_session(struct btd_device *device);
--
2.39.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH BlueZ 07/10] shared/bass: Add API to get GATT client reference
2024-07-16 14:21 [PATCH BlueZ 00/10] Initial implementation of BAP Broadcast Assistant Iulia Tanasescu
` (5 preceding siblings ...)
2024-07-16 14:22 ` [PATCH BlueZ 06/10] bap: Add API to get bt_bap matching device Iulia Tanasescu
@ 2024-07-16 14:22 ` Iulia Tanasescu
2024-07-16 14:22 ` [PATCH BlueZ 08/10] bass: Register MediaAssistant objects Iulia Tanasescu
` (3 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Iulia Tanasescu @ 2024-07-16 14:22 UTC (permalink / raw)
To: linux-bluetooth
Cc: claudia.rosu, mihai-octavian.urzica, vlad.pruteanu,
andrei.istodorescu, luiz.dentz, Iulia Tanasescu
Some use cases require the BASS plugin to differentiate between client and
server BASS sessions - for example, the BAP Broadcast Assistant role only
considers client BASS sessions.
This adds a BASS API to obtain a reference to the bt_gatt_client structure
attached to the bt_bass session.
---
src/shared/bass.c | 8 ++++++++
src/shared/bass.h | 1 +
2 files changed, 9 insertions(+)
diff --git a/src/shared/bass.c b/src/shared/bass.c
index d82c043ac..268e3bd86 100644
--- a/src/shared/bass.c
+++ b/src/shared/bass.c
@@ -1683,6 +1683,14 @@ struct bt_att *bt_bass_get_att(struct bt_bass *bass)
return bt_gatt_client_get_att(bass->client);
}
+struct bt_gatt_client *bt_bass_get_client(struct bt_bass *bass)
+{
+ if (!bass)
+ return NULL;
+
+ return bass->client;
+}
+
bool bt_bass_set_debug(struct bt_bass *bass, bt_bass_debug_func_t func,
void *user_data, bt_bass_destroy_func_t destroy)
{
diff --git a/src/shared/bass.h b/src/shared/bass.h
index c4b5b76ba..1674146bc 100644
--- a/src/shared/bass.h
+++ b/src/shared/bass.h
@@ -121,6 +121,7 @@ typedef void (*bt_bass_destroy_func_t)(void *user_data);
typedef void (*bt_bass_debug_func_t)(const char *str, void *user_data);
struct bt_att *bt_bass_get_att(struct bt_bass *bass);
+struct bt_gatt_client *bt_bass_get_client(struct bt_bass *bass);
unsigned int bt_bass_register(bt_bass_func_t attached, bt_bass_func_t detached,
void *user_data);
bool bt_bass_unregister(unsigned int id);
--
2.39.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH BlueZ 08/10] bass: Register MediaAssistant objects
2024-07-16 14:21 [PATCH BlueZ 00/10] Initial implementation of BAP Broadcast Assistant Iulia Tanasescu
` (6 preceding siblings ...)
2024-07-16 14:22 ` [PATCH BlueZ 07/10] shared/bass: Add API to get GATT client reference Iulia Tanasescu
@ 2024-07-16 14:22 ` Iulia Tanasescu
2024-07-16 14:22 ` [PATCH BlueZ 09/10] bap: Notify scanned BISes to BASS Iulia Tanasescu
` (2 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Iulia Tanasescu @ 2024-07-16 14:22 UTC (permalink / raw)
To: linux-bluetooth
Cc: claudia.rosu, mihai-octavian.urzica, vlad.pruteanu,
andrei.istodorescu, luiz.dentz, Iulia Tanasescu
This adds an initial implementation of the BAP Broadcast Assistant role
in the BASS plugin, by introducing the MediaAssistant DBus object.
The BAP plugin implements the callback to probe Broadcast Sources and
parse the BASE. This commit adds 2 BASS APIs, that will be called by the
BAP plugin to notify BISes discovered in the BASE of a broadcaster to
BASS, or to inform the BASS plugin that a broadcaster has been removed.
For each BASS client session, the BASS plugin checks BIS caps against
the peer caps, and registers a MediaAssistant object for each match.
---
Makefile.plugins | 2 +-
profiles/audio/bass.c | 257 ++++++++++++++++++++++++++++++++++++++++++
profiles/audio/bass.h | 13 +++
3 files changed, 271 insertions(+), 1 deletion(-)
create mode 100644 profiles/audio/bass.h
diff --git a/Makefile.plugins b/Makefile.plugins
index 9dd8134b4..9da29a3ce 100644
--- a/Makefile.plugins
+++ b/Makefile.plugins
@@ -120,7 +120,7 @@ endif
if BASS
builtin_modules += bass
-builtin_sources += profiles/audio/bass.c
+builtin_sources += profiles/audio/bass.h profiles/audio/bass.c
endif
if MCP
diff --git a/profiles/audio/bass.c b/profiles/audio/bass.c
index 7952105c5..083988358 100644
--- a/profiles/audio/bass.c
+++ b/profiles/audio/bass.c
@@ -39,6 +39,7 @@
#include "src/shared/gatt-server.h"
#include "src/adapter.h"
#include "src/shared/bass.h"
+#include "src/shared/bap.h"
#include "src/plugin.h"
#include "src/gatt-database.h"
@@ -48,21 +49,265 @@
#include "src/log.h"
#include "src/error.h"
+#include "bass.h"
+#include "bap.h"
+
#define BASS_UUID_STR "0000184f-0000-1000-8000-00805f9b34fb"
+#define MEDIA_ASSISTANT_INTERFACE "org.bluez.MediaAssistant1"
+
+enum assistant_state {
+ ASSISTANT_STATE_IDLE, /* Assistant object was created for
+ * the stream
+ */
+ ASSISTANT_STATE_PENDING, /* Assistant object was pushed */
+ ASSISTANT_STATE_REQUESTING, /* Remote device requires
+ * Broadcast_Code
+ */
+ ASSISTANT_STATE_ACTIVE, /* Remote device started receiving
+ * stream
+ */
+};
+
struct bass_data {
struct btd_device *device;
struct btd_service *service;
struct bt_bass *bass;
};
+struct bass_assistant {
+ struct btd_device *device; /* Broadcast source device */
+ struct bass_data *data; /* BASS session with peer device */
+ uint8_t sgrp;
+ uint8_t bis;
+ struct bt_iso_qos qos;
+ struct iovec *meta;
+ struct iovec *caps;
+ enum assistant_state state;
+ char *path;
+};
+
static struct queue *sessions;
+static struct queue *assistants;
static void bass_debug(const char *str, void *user_data)
{
DBG_IDX(0xffff, "%s", str);
}
+static DBusMessage *push(DBusConnection *conn, DBusMessage *msg,
+ void *user_data)
+{
+ return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+}
+
+static const GDBusMethodTable assistant_methods[] = {
+ {GDBUS_EXPERIMENTAL_ASYNC_METHOD("Push",
+ GDBUS_ARGS({ "Props", "a{sv}" }),
+ NULL, push)},
+ {},
+};
+
+static const char *state2str(enum assistant_state state)
+{
+ switch (state) {
+ case ASSISTANT_STATE_IDLE:
+ return "idle";
+ case ASSISTANT_STATE_PENDING:
+ return "pending";
+ case ASSISTANT_STATE_REQUESTING:
+ return "requesting";
+ case ASSISTANT_STATE_ACTIVE:
+ return "active";
+ }
+
+ return NULL;
+}
+
+static gboolean get_state(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct bass_assistant *assistant = data;
+ const char *state = state2str(assistant->state);
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &state);
+
+ return TRUE;
+}
+
+static gboolean get_metadata(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct bass_assistant *assistant = data;
+ DBusMessageIter array;
+
+ dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_BYTE_AS_STRING, &array);
+
+ if (assistant->meta)
+ dbus_message_iter_append_fixed_array(&array, DBUS_TYPE_BYTE,
+ &assistant->meta->iov_base,
+ assistant->meta->iov_len);
+
+ dbus_message_iter_close_container(iter, &array);
+
+ return TRUE;
+}
+
+static gboolean get_qos(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct bass_assistant *assistant = data;
+ DBusMessageIter dict;
+ uint8_t *bcode = assistant->qos.bcast.bcode;
+
+ dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+ &dict);
+
+ dict_append_entry(&dict, "Encryption", DBUS_TYPE_BYTE,
+ &assistant->qos.bcast.encryption);
+ dict_append_array(&dict, "BCode", DBUS_TYPE_BYTE,
+ &bcode, BT_BASS_BCAST_CODE_SIZE);
+
+ dbus_message_iter_close_container(iter, &dict);
+
+ return TRUE;
+}
+
+static const GDBusPropertyTable assistant_properties[] = {
+ { "State", "s", get_state },
+ { "Metadata", "ay", get_metadata, NULL, NULL,
+ G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
+ { "QoS", "a{sv}", get_qos, NULL, NULL,
+ G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
+ { }
+};
+
+static void assistant_free(void *data)
+{
+ struct bass_assistant *assistant = data;
+
+ g_free(assistant->path);
+ util_iov_free(assistant->meta, 1);
+ util_iov_free(assistant->caps, 1);
+
+ free(assistant);
+}
+
+static struct bass_assistant *assistant_new(struct btd_adapter *adapter,
+ struct btd_device *device, struct bass_data *data,
+ uint8_t sgrp, uint8_t bis, struct bt_iso_qos *qos,
+ struct iovec *meta, struct iovec *caps)
+{
+ struct bass_assistant *assistant;
+ char src_addr[18];
+ char dev_addr[18];
+
+ assistant = new0(struct bass_assistant, 1);
+ if (!assistant)
+ return NULL;
+
+ DBG("assistant %p", assistant);
+
+ assistant->device = device;
+ assistant->data = data;
+ assistant->sgrp = sgrp;
+ assistant->bis = bis;
+ assistant->qos = *qos;
+ assistant->meta = util_iov_dup(meta, 1);
+ assistant->caps = util_iov_dup(caps, 1);
+
+ ba2str(device_get_address(device), src_addr);
+ ba2str(device_get_address(data->device), dev_addr);
+
+ assistant->path = g_strdup_printf("%s/src_%s/dev_%s/bis%d",
+ adapter_get_path(adapter), src_addr, dev_addr, bis);
+
+ g_strdelimit(assistant->path, ":", '_');
+
+ if (!assistants)
+ assistants = queue_new();
+
+ queue_push_tail(assistants, assistant);
+
+ return assistant;
+}
+
+void bass_add_stream(struct btd_device *device, struct iovec *meta,
+ struct iovec *caps, struct bt_iso_qos *qos,
+ uint8_t sgrp, uint8_t bis)
+{
+ const struct queue_entry *entry;
+ struct bt_bap *bap;
+ struct bt_bap_pac *pac;
+ struct bass_assistant *assistant;
+ char addr[18];
+
+ for (entry = queue_get_entries(sessions); entry; entry = entry->next) {
+ struct bass_data *data = entry->data;
+ struct btd_adapter *adapter = device_get_adapter(data->device);
+
+ if (!bt_bass_get_client(data->bass))
+ /* Only client sessions must be handled */
+ continue;
+
+ bap = bap_get_session(data->device);
+ if (!bap)
+ continue;
+
+ /* Check stream capabilities against peer caps. */
+ bt_bap_verify_bis(bap, bis, caps, &pac);
+
+ if (!pac)
+ /* Capabilities did not match. */
+ continue;
+
+ ba2str(device_get_address(device), addr);
+
+ DBG("%s data %p BIS %d", addr, data, bis);
+
+ assistant = assistant_new(adapter, device, data, sgrp,
+ bis, qos, meta, caps);
+
+ if (g_dbus_register_interface(btd_get_dbus_connection(),
+ assistant->path,
+ MEDIA_ASSISTANT_INTERFACE,
+ assistant_methods, NULL,
+ assistant_properties,
+ assistant,
+ assistant_free) == FALSE)
+ DBG("Could not register path %s", assistant->path);
+ }
+}
+
+static bool assistant_match_device(const void *data, const void *match_data)
+{
+ const struct bass_assistant *assistant = data;
+ const struct btd_device *device = match_data;
+
+ return (assistant->device == device);
+}
+
+static void unregister_assistant(void *data)
+{
+ struct bass_assistant *assistant = data;
+
+ DBG("%p", assistant);
+
+ g_dbus_unregister_interface(btd_get_dbus_connection(),
+ assistant->path, MEDIA_ASSISTANT_INTERFACE);
+}
+
+void bass_remove_stream(struct btd_device *device)
+{
+ queue_remove_all(assistants, assistant_match_device,
+ device, unregister_assistant);
+}
+
static struct bass_data *bass_data_new(struct btd_device *device)
{
struct bass_data *data;
@@ -101,6 +346,14 @@ static bool match_data(const void *data, const void *match_data)
return bdata->bass == bass;
}
+static bool assistant_match_data(const void *data, const void *match_data)
+{
+ const struct bass_assistant *assistant = data;
+ const struct bass_data *bdata = match_data;
+
+ return (assistant->data == bdata);
+}
+
static void bass_data_free(struct bass_data *data)
{
if (data->service) {
@@ -109,6 +362,10 @@ static void bass_data_free(struct bass_data *data)
}
bt_bass_unref(data->bass);
+
+ queue_remove_all(assistants, assistant_match_data,
+ data, unregister_assistant);
+
free(data);
}
diff --git a/profiles/audio/bass.h b/profiles/audio/bass.h
new file mode 100644
index 000000000..5bef92946
--- /dev/null
+++ b/profiles/audio/bass.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright 2024 NXP
+ *
+ */
+
+void bass_add_stream(struct btd_device *device, struct iovec *meta,
+ struct iovec *caps, struct bt_iso_qos *qos,
+ uint8_t sgrp, uint8_t bis);
+void bass_remove_stream(struct btd_device *device);
--
2.39.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH BlueZ 09/10] bap: Notify scanned BISes to BASS
2024-07-16 14:21 [PATCH BlueZ 00/10] Initial implementation of BAP Broadcast Assistant Iulia Tanasescu
` (7 preceding siblings ...)
2024-07-16 14:22 ` [PATCH BlueZ 08/10] bass: Register MediaAssistant objects Iulia Tanasescu
@ 2024-07-16 14:22 ` Iulia Tanasescu
2024-07-16 14:22 ` [PATCH BlueZ 10/10] client: Add assistant submenu Iulia Tanasescu
2024-07-18 18:30 ` [PATCH BlueZ 00/10] Initial implementation of BAP Broadcast Assistant patchwork-bot+bluetooth
10 siblings, 0 replies; 13+ messages in thread
From: Iulia Tanasescu @ 2024-07-16 14:22 UTC (permalink / raw)
To: linux-bluetooth
Cc: claudia.rosu, mihai-octavian.urzica, vlad.pruteanu,
andrei.istodorescu, luiz.dentz, Iulia Tanasescu
This updates the BAP implementation to also notify the BASS plugin about
scanned broadcast streams, or when a scanned broadcaster is removed. This
is needed for the BAP Broadcast Assistant role - the BASS plugin registers
MediaAssistant objects for each detected stream that matches the audio
capabilities of peer Scan Delegator devices.
---
profiles/audio/bap.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/profiles/audio/bap.c b/profiles/audio/bap.c
index fe5390e6a..50a68f27a 100644
--- a/profiles/audio/bap.c
+++ b/profiles/audio/bap.c
@@ -57,6 +57,7 @@
#include "src/error.h"
#include "bap.h"
+#include "bass.h"
#define ISO_SOCKET_UUID "6fbaf188-05e0-496a-9885-d6ddfdb4e03e"
#define PACS_UUID_STR "00001850-0000-1000-8000-00805f9b34fb"
@@ -1199,6 +1200,9 @@ static bool parse_base(struct bap_data *bap_data, struct bt_iso_base *base,
continue;
}
+ bass_add_stream(bap_data->device, meta, merged_caps,
+ qos, idx, bis_index);
+
/* Check if this BIS matches any local PAC */
bt_bap_verify_bis(bap_data->bap, bis_index,
merged_caps, &matched_lpac);
@@ -3227,6 +3231,8 @@ static void bap_bcast_remove(struct btd_service *service)
free(req);
bap_data_remove(data);
+
+ bass_remove_stream(device);
}
static int bap_probe(struct btd_service *service)
--
2.39.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH BlueZ 10/10] client: Add assistant submenu
2024-07-16 14:21 [PATCH BlueZ 00/10] Initial implementation of BAP Broadcast Assistant Iulia Tanasescu
` (8 preceding siblings ...)
2024-07-16 14:22 ` [PATCH BlueZ 09/10] bap: Notify scanned BISes to BASS Iulia Tanasescu
@ 2024-07-16 14:22 ` Iulia Tanasescu
2024-07-18 18:30 ` [PATCH BlueZ 00/10] Initial implementation of BAP Broadcast Assistant patchwork-bot+bluetooth
10 siblings, 0 replies; 13+ messages in thread
From: Iulia Tanasescu @ 2024-07-16 14:22 UTC (permalink / raw)
To: linux-bluetooth
Cc: claudia.rosu, mihai-octavian.urzica, vlad.pruteanu,
andrei.istodorescu, luiz.dentz, Iulia Tanasescu
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
---
Makefile.tools | 3 +-
client/assistant.c | 164 +++++++++++++++++++++++++++++++++++++++++++++
client/assistant.h | 13 ++++
client/main.c | 5 +-
4 files changed, 183 insertions(+), 2 deletions(-)
create mode 100644 client/assistant.c
create mode 100644 client/assistant.h
diff --git a/Makefile.tools b/Makefile.tools
index 679c914bf..f4f9e82dc 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -13,7 +13,8 @@ client_bluetoothctl_SOURCES = client/main.c \
client/gatt.h client/gatt.c \
client/admin.h client/admin.c \
client/player.h client/player.c \
- client/mgmt.h client/mgmt.c
+ client/mgmt.h client/mgmt.c \
+ client/assistant.h client/assistant.c
client_bluetoothctl_LDADD = lib/libbluetooth-internal.la \
gdbus/libgdbus-internal.la src/libshared-glib.la \
$(GLIB_LIBS) $(DBUS_LIBS) -lreadline
diff --git a/client/assistant.c b/client/assistant.c
new file mode 100644
index 000000000..69a955c18
--- /dev/null
+++ b/client/assistant.c
@@ -0,0 +1,164 @@
+// 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"
+
+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;
+}
+
+static GDBusClient * client;
+
+void assistant_add_submenu(void)
+{
+ 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;
+}
+
diff --git a/client/assistant.h b/client/assistant.h
new file mode 100644
index 000000000..418b0b840
--- /dev/null
+++ b/client/assistant.h
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright 2024 NXP
+ *
+ *
+ */
+
+void assistant_add_submenu(void);
+void assistant_remove_submenu(void);
+
diff --git a/client/main.c b/client/main.c
index f012ddd43..a96a42638 100644
--- a/client/main.c
+++ b/client/main.c
@@ -4,7 +4,7 @@
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2012 Intel Corporation. All rights reserved.
- *
+ * Copyright 2024 NXP
*
*/
@@ -34,6 +34,7 @@
#include "admin.h"
#include "player.h"
#include "mgmt.h"
+#include "assistant.h"
/* String display constants */
#define COLORED_NEW COLOR_GREEN "NEW" COLOR_OFF
@@ -3205,6 +3206,7 @@ int main(int argc, char *argv[])
admin_add_submenu();
player_add_submenu();
mgmt_add_submenu();
+ assistant_add_submenu();
client = g_dbus_client_new(dbus_conn, "org.bluez", "/org/bluez");
@@ -3222,6 +3224,7 @@ int main(int argc, char *argv[])
admin_remove_submenu();
player_remove_submenu();
mgmt_remove_submenu();
+ assistant_remove_submenu();
g_dbus_client_unref(client);
--
2.39.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* RE: Initial implementation of BAP Broadcast Assistant
2024-07-16 14:21 ` [PATCH BlueZ 01/10] shared/bap: Add separate API to merge caps Iulia Tanasescu
@ 2024-07-16 19:51 ` bluez.test.bot
0 siblings, 0 replies; 13+ messages in thread
From: bluez.test.bot @ 2024-07-16 19:51 UTC (permalink / raw)
To: linux-bluetooth, iulia.tanasescu
[-- Attachment #1: Type: text/plain, Size: 3564 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=871698
---Test result---
Test Summary:
CheckPatch PASS 5.26 seconds
GitLint PASS 4.31 seconds
BuildEll PASS 24.50 seconds
BluezMake PASS 1613.31 seconds
MakeCheck PASS 13.73 seconds
MakeDistcheck PASS 177.55 seconds
CheckValgrind PASS 251.52 seconds
CheckSmatch WARNING 355.39 seconds
bluezmakeextell PASS 120.08 seconds
IncrementalBuild PASS 15176.95 seconds
ScanBuild PASS 997.92 seconds
Details
##############################
Test: CheckSmatch - WARNING
Desc: Run smatch tool with source
Output:
src/shared/bap.c:288:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structuressrc/shared/bap.c:288:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structuressrc/shared/bap.c:288:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structuressrc/shared/bap.c:288:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structuressrc/shared/bap.c:288:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structuressrc/shared/bap.c:288:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structuressrc/shared/bap.c:288:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structuressrc/shared/bap.c:288:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structuressrc/shared/bap.c:288:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structuressrc/shared/bap.c:288:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structuressrc/shared/bap.c:288:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structuressrc/shared/bap.c:288:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structuressrc/shared/bap.c:288:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structuressrc/shared/bap.c:288:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structuressrc/shared/bap.c:288:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structures
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH BlueZ 00/10] Initial implementation of BAP Broadcast Assistant
2024-07-16 14:21 [PATCH BlueZ 00/10] Initial implementation of BAP Broadcast Assistant Iulia Tanasescu
` (9 preceding siblings ...)
2024-07-16 14:22 ` [PATCH BlueZ 10/10] client: Add assistant submenu Iulia Tanasescu
@ 2024-07-18 18:30 ` patchwork-bot+bluetooth
10 siblings, 0 replies; 13+ messages in thread
From: patchwork-bot+bluetooth @ 2024-07-18 18:30 UTC (permalink / raw)
To: Iulia Tanasescu
Cc: linux-bluetooth, claudia.rosu, mihai-octavian.urzica,
vlad.pruteanu, andrei.istodorescu, luiz.dentz
Hello:
This series was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:
On Tue, 16 Jul 2024 17:21:57 +0300 you wrote:
> This patch adds an initial implementation of the BAP Broadcast Assistant
> role.
>
> The core implementation resides in the BASS plugin (the BAP Broadcast
> Assistant is a BASS Client).
>
> The BAP plugin implements the callback to probe Broadcast Sources and
> parse the BASE. Information about each detected stream is notified to
> the BASS plugin, which will compare stream audio capabilities with the
> capabilities supported by the peer Scan Delegator (discovered by reading
> the Sink PAC characteristic).
>
> [...]
Here is the summary with links:
- [BlueZ,01/10] shared/bap: Add separate API to merge caps
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=caa4202a7ee3
- [BlueZ,02/10] shared/bap: Update bt_bap_verify_bis to receive caps
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=679349fbc9f2
- [BlueZ,03/10] shared/bap: Remove unused param from bt_bap_verify_bis
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=bbcf4891cd46
- [BlueZ,04/10] shared/bap: Allow checking bis caps against peer caps
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=662aee4357f8
- [BlueZ,05/10] shared/bap: Append bcast sink pacs to Sink PAC char
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=2c98c478863e
- [BlueZ,06/10] bap: Add API to get bt_bap matching device
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=f16391348810
- [BlueZ,07/10] shared/bass: Add API to get GATT client reference
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=88bf423eb525
- [BlueZ,08/10] bass: Register MediaAssistant objects
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=77e4c0976c0d
- [BlueZ,09/10] bap: Notify scanned BISes to BASS
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=22779f0bce61
- [BlueZ,10/10] client: Add assistant submenu
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=a3f9970f7a8b
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2024-07-18 18:30 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-16 14:21 [PATCH BlueZ 00/10] Initial implementation of BAP Broadcast Assistant Iulia Tanasescu
2024-07-16 14:21 ` [PATCH BlueZ 01/10] shared/bap: Add separate API to merge caps Iulia Tanasescu
2024-07-16 19:51 ` Initial implementation of BAP Broadcast Assistant bluez.test.bot
2024-07-16 14:21 ` [PATCH BlueZ 02/10] shared/bap: Update bt_bap_verify_bis to receive caps Iulia Tanasescu
2024-07-16 14:22 ` [PATCH BlueZ 03/10] shared/bap: Remove unused param from bt_bap_verify_bis Iulia Tanasescu
2024-07-16 14:22 ` [PATCH BlueZ 04/10] shared/bap: Allow checking bis caps against peer caps Iulia Tanasescu
2024-07-16 14:22 ` [PATCH BlueZ 05/10] shared/bap: Append bcast sink pacs to Sink PAC char Iulia Tanasescu
2024-07-16 14:22 ` [PATCH BlueZ 06/10] bap: Add API to get bt_bap matching device Iulia Tanasescu
2024-07-16 14:22 ` [PATCH BlueZ 07/10] shared/bass: Add API to get GATT client reference Iulia Tanasescu
2024-07-16 14:22 ` [PATCH BlueZ 08/10] bass: Register MediaAssistant objects Iulia Tanasescu
2024-07-16 14:22 ` [PATCH BlueZ 09/10] bap: Notify scanned BISes to BASS Iulia Tanasescu
2024-07-16 14:22 ` [PATCH BlueZ 10/10] client: Add assistant submenu Iulia Tanasescu
2024-07-18 18:30 ` [PATCH BlueZ 00/10] Initial implementation of BAP Broadcast Assistant patchwork-bot+bluetooth
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).