Linux-Bluetooth Archive mirror
 help / color / mirror / Atom feed
* [PATCH BlueZ 0/5] Create transports for matching BISes
@ 2024-04-19 18:07 Andrei Istodorescu
  2024-04-19 18:07 ` [PATCH BlueZ 1/5] shared/bap: Allow NULL bap endpoint in streams Andrei Istodorescu
                   ` (5 more replies)
  0 siblings, 6 replies; 10+ messages in thread
From: Andrei Istodorescu @ 2024-04-19 18:07 UTC (permalink / raw
  To: linux-bluetooth
  Cc: luiz.dentz, mihai-octavian.urzica, silviu.barbulescu,
	vlad.pruteanu, iulia.tanasescu, Andrei Istodorescu

This patch refactors the flow for the BAP Broadcast Sink.
After observing the BASE information, streams and transports will be
generated for each BIS that matches local PAC capabilities.
Because endpoints are not available any more, local PAC (which contain
local registered capabilities) has a new list of setups. Each setup is 
generated based on the matching BIS observed.
Then, the setup is used to configure a stream which then generates a
MediaTransport.
The transport is in the TRANSPORT_STATE_IDLE state until someone
acquires it. The "Acquire" procedure results in creating the IO using
BIG Create Sync. The successful reply of it causes the transport to be
advanced in TRANSPORT_STATE_ACTIVE state.

bluetoothctl log with two transports being created and acquired:
endpoint.register 00001851-0000-1000-8000-00805f9b34fb 0x06
[/local/endpoint/ep0] Auto Accept (yes/no): y
[/local/endpoint/ep0] Max Transports (auto/value): a
[/local/endpoint/ep0] Locations: 3
[/local/endpoint/ep0] Supported Context (value): 3
Capabilities:
  03 01 ff 00 02 02 03 02 03 03 05 04 1a 00 f0 00  ................
Metadata:
[bluetooth]# Endpoint /local/endpoint/ep0 registered

scan le

[bluetooth]# SetDiscoveryFilter success
[bluetooth]# hci7 type 6 discovering on
[bluetooth]# Discovery started
[bluetooth]# [CHG] Controller 00:60:37:A6:AE:22 Discovering: yes
[bluetooth]# [NEW] Device 07:34:BB:4B:6F:C3 07-34-BB-4B-6F-C3
[bluetooth]# hci7 07:34:BB:4B:6F:C3 type LE Random connected eir_len 0
[bluetooth]# [NEW] Transport /org/bluez/hci7/dev_07_34_BB_4B_6F_C3/bis1/
fd0 
[bluetooth]# Endpoint: SetConfiguration
[bluetooth]# 	Transport /org/bluez/hci7/dev_07_34_BB_4B_6F_C3/bis1/fd0
[bluetooth]# 	Properties.Device: /org/bluez/hci7/dev_07_34_BB_4B_6F_C3
[bluetooth]# Auto Accepting...
[bluetooth]# [NEW] Transport /org/bluez/hci7/dev_07_34_BB_4B_6F_C3/bis2/
fd1 
[bluetooth]# Endpoint: SetConfiguration
[bluetooth]# 	Transport /org/bluez/hci7/dev_07_34_BB_4B_6F_C3/bis2/fd1
[bluetooth]# 	Properties.Device: /org/bluez/hci7/dev_07_34_BB_4B_6F_C3
[bluetooth]# Auto Accepting...
[CHG] Device 07:34:BB:4B:6F:C3 Connected: yes

[07-34-BB-4B-6F-C3]# transport.acquire /org/bluez/hci7/
dev_07_34_BB_4B_6F_C3/bis1/fd0 
auto acquiring...
Transport /org/bluez/hci7/dev_07_34_BB_4B_6F_C3/bis1/fd0 acquiring
[07-34-BB-4B-6F-C3]# hci7 07:34:BB:4B:6F:C3 type LE Random connected 
eir_len 0
[07-34-BB-4B-6F-C3]# hci7 07:34:BB:4B:6F:C3 type LE Random connected 
eir_len 0
[07-34-BB-4B-6F-C3]# Transport /org/bluez/hci7/dev_07_34_BB_4B_6F_C3/
bis1/fd0 acquiring complete
[07-34-BB-4B-6F-C3]# Acquire successful: fd 8 MTU 40:0
[07-34-BB-4B-6F-C3]# [CHG] Transport /org/bluez/hci7/
dev_07_34_BB_4B_6F_C3/bis1/fd0 State: active
hci7 type 6 discovering offm[seq 0] recv: 0 bytes #            1
hci7 type 6 discovering on9m[seq 146] recv: 0 bytes #              7
hci7 type 6 discovering offm[seq 149] recv: 0 bytes #             50
hci7 type 6 discovering on
[seq 2446] recv: 0 bytes #transport.release /org/bluez/hci7/
dev_07_34_BB_4B_6F_C3/bis1/fd0 
[07-34-BB-4B-6F-C3]# [CHG] Transport /org/bluez/hci7/dev_07_34_BB_4B_6F_C3
/bis1/fd0 State: idle
[07-34-BB-4B-6F-C3]# Release successful

[07-34-BB-4B-6F-C3]# transport.acquire /org/bluez/hci7/
dev_07_34_BB_4B_6F_C3/bis2/fd1 
auto acquiring...
Transport /org/bluez/hci7/dev_07_34_BB_4B_6F_C3/bis2/fd1 acquiring
[07-34-BB-4B-6F-C3]# hci7 07:34:BB:4B:6F:C3 type LE Random connected 
eir_len 0
[07-34-BB-4B-6F-C3]# hci7 07:34:BB:4B:6F:C3 type LE Random connected 
eir_len 0
[07-34-BB-4B-6F-C3]# Transport /org/bluez/hci7/dev_07_34_BB_4B_6F_C3/bis2
/fd1 acquiring complete
[07-34-BB-4B-6F-C3]# Acquire successful: fd 9 MTU 40:0
[07-34-BB-4B-6F-C3]# [CHG] Transport /org/bluez/hci7/dev_07_34_BB_4B_6F_C3
/bis2/fd1 State: active
hci7 type 6 discovering off
hci7 type 6 discovering on
[seq 1330] recv: 0 bytes #transport.release /org/bluez/hci7/
dev_07_34_BB_4B_6F_C3/bis2/fd1 
[07-34-BB-4B-6F-C3]#   1;39m[seq 1331] recv: 0 bytes #Transport fd
disconnected
[07-34-BB-4B-6F-C3]# [CHG] Transport /org/bluez/hci7/dev_07_34_BB_4B_6F_C3
/bis2/fd1 State: idle
[07-34-BB-4B-6F-C3]# Release successful

Andrei Istodorescu (5):
  shared/bap: Allow NULL bap endpoint in streams
  shared/bap: Get broadcast channel location from stream capabilities
  shared/bap: Update stream management to avoid PACs
  shared/bap: In case of a BIS-PAC match return also the local pac
  bap: Create streams and transports for each matching BIS

 profiles/audio/bap.c | 184 ++++++++++++++++++++--------
 src/shared/bap.c     | 280 +++++++++++++++++++++----------------------
 src/shared/bap.h     |   6 +-
 3 files changed, 279 insertions(+), 191 deletions(-)

-- 
2.40.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH BlueZ 1/5] shared/bap: Allow NULL bap endpoint in streams
  2024-04-19 18:07 [PATCH BlueZ 0/5] Create transports for matching BISes Andrei Istodorescu
@ 2024-04-19 18:07 ` Andrei Istodorescu
  2024-04-19 21:16   ` Create transports for matching BISes bluez.test.bot
  2024-04-19 18:07 ` [PATCH BlueZ 2/5] shared/bap: Get broadcast channel location from stream capabilities Andrei Istodorescu
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 10+ messages in thread
From: Andrei Istodorescu @ 2024-04-19 18:07 UTC (permalink / raw
  To: linux-bluetooth
  Cc: luiz.dentz, mihai-octavian.urzica, silviu.barbulescu,
	vlad.pruteanu, iulia.tanasescu, Andrei Istodorescu

---
 src/shared/bap.c | 54 +++++++++++++++++++++++++++++++++++-------------
 1 file changed, 40 insertions(+), 14 deletions(-)

diff --git a/src/shared/bap.c b/src/shared/bap.c
index 71eadbdb68b1..6328ff35f3c3 100644
--- a/src/shared/bap.c
+++ b/src/shared/bap.c
@@ -2115,7 +2115,8 @@ static struct bt_bap_stream *bap_stream_new(struct bt_bap *bap,
 	stream = new0(struct bt_bap_stream, 1);
 	stream->bap = bap;
 	stream->ep = ep;
-	ep->stream = stream;
+	if (ep != NULL)
+		ep->stream = stream;
 	stream->lpac = lpac;
 	stream->rpac = rpac;
 	stream->cc = util_iov_dup(data, 1);
@@ -2209,6 +2210,7 @@ static void bap_stream_set_io(void *data, void *user_data)
 	struct bt_bap_stream *stream = data;
 	int fd = PTR_TO_INT(user_data);
 	bool ret;
+	uint8_t state;
 
 	if (fd >= 0)
 		ret = bap_stream_io_attach(stream, fd, false);
@@ -2218,7 +2220,12 @@ static void bap_stream_set_io(void *data, void *user_data)
 	if (!ret)
 		return;
 
-	switch (stream->ep->state) {
+	if (bt_bap_stream_get_type(stream) == BT_BAP_STREAM_TYPE_BCAST)
+		state = stream->state;
+	else
+		state = stream->ep->state;
+
+	switch (state) {
 	case BT_BAP_STREAM_STATE_ENABLING:
 		if (fd < 0)
 			bt_bap_stream_disable(stream, false, NULL, NULL);
@@ -5424,7 +5431,8 @@ uint8_t bt_bap_stream_get_state(struct bt_bap_stream *stream)
 	if (!stream)
 		return BT_BAP_STREAM_STATE_IDLE;
 
-	if (stream->lpac->type != BT_BAP_BCAST_SOURCE)
+	if (stream->lpac->type != BT_BAP_BCAST_SOURCE &&
+			stream->lpac->type != BT_BAP_BCAST_SINK)
 		return stream->ep->state;
 	else
 		return stream->state;
@@ -5611,7 +5619,13 @@ uint8_t bt_bap_stream_get_dir(struct bt_bap_stream *stream)
 	if (!stream)
 		return 0x00;
 
-	return stream->ep->dir;
+	if (stream->ep)
+		return stream->ep->dir;
+
+	if (bt_bap_pac_get_type(stream->lpac) == BT_BAP_BCAST_SINK)
+		return BT_BAP_BCAST_SOURCE;
+	else
+		return BT_BAP_BCAST_SINK;
 }
 
 uint32_t bt_bap_stream_get_location(struct bt_bap_stream *stream)
@@ -5623,15 +5637,17 @@ uint32_t bt_bap_stream_get_location(struct bt_bap_stream *stream)
 
 	pacs = stream->client ? stream->bap->rdb->pacs : stream->bap->ldb->pacs;
 
-	if (stream->ep->dir == BT_BAP_SOURCE)
-		return pacs->source_loc_value;
-	else if (stream->ep->dir == BT_BAP_SINK)
-		return pacs->sink_loc_value;
-	else
-		/* TO DO get the location values from metadata
-		 * for brodcast source and sink
-		 */
-		return stream->bap->ldb->pacs->source_loc_value;
+	if (stream->ep) {
+		if (stream->ep->dir == BT_BAP_SOURCE)
+			return pacs->source_loc_value;
+		else if (stream->ep->dir == BT_BAP_SINK)
+			return pacs->sink_loc_value;
+	}
+
+	/* TO DO get the location values from metadata
+	 * for brodcast source and sink
+	 */
+	return stream->bap->ldb->pacs->source_loc_value;
 }
 
 struct iovec *bt_bap_stream_get_config(struct bt_bap_stream *stream)
@@ -5841,7 +5857,17 @@ uint8_t bt_bap_stream_io_dir(struct bt_bap_stream *stream)
 	if (!stream)
 		return 0x00;
 
-	dir = stream->ep->dir;
+	if (stream->ep)
+		dir = stream->ep->dir;
+	else {
+		uint8_t pac_type = bt_bap_pac_get_type(stream->lpac);
+
+		if (pac_type == BT_BAP_BCAST_SINK)
+			dir = BT_BAP_BCAST_SOURCE;
+		else
+			dir = BT_BAP_BCAST_SINK;
+
+	}
 
 	if (stream->link)
 		dir |= stream->link->ep->dir;
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH BlueZ 2/5] shared/bap: Get broadcast channel location from stream capabilities
  2024-04-19 18:07 [PATCH BlueZ 0/5] Create transports for matching BISes Andrei Istodorescu
  2024-04-19 18:07 ` [PATCH BlueZ 1/5] shared/bap: Allow NULL bap endpoint in streams Andrei Istodorescu
@ 2024-04-19 18:07 ` Andrei Istodorescu
  2024-04-19 18:07 ` [PATCH BlueZ 3/5] shared/bap: Update stream management to avoid PACs Andrei Istodorescu
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Andrei Istodorescu @ 2024-04-19 18:07 UTC (permalink / raw
  To: linux-bluetooth
  Cc: luiz.dentz, mihai-octavian.urzica, silviu.barbulescu,
	vlad.pruteanu, iulia.tanasescu, Andrei Istodorescu

Get the channel location from the stream's configured capabilities,
rather than from the local PACS database capabilities.
---
 src/shared/bap.c | 38 ++++++++++++++++++++++----------------
 1 file changed, 22 insertions(+), 16 deletions(-)

diff --git a/src/shared/bap.c b/src/shared/bap.c
index 6328ff35f3c3..36f0b0a3b50a 100644
--- a/src/shared/bap.c
+++ b/src/shared/bap.c
@@ -5628,9 +5628,24 @@ uint8_t bt_bap_stream_get_dir(struct bt_bap_stream *stream)
 		return BT_BAP_BCAST_SINK;
 }
 
+static void bap_sink_get_allocation(size_t i, uint8_t l, uint8_t t,
+		uint8_t *v, void *user_data)
+{
+	uint32_t location32;
+
+	if (!v)
+		return;
+
+	memcpy(&location32, v, l);
+	*((uint32_t *)user_data) = le32_to_cpu(location32);
+}
+
 uint32_t bt_bap_stream_get_location(struct bt_bap_stream *stream)
 {
 	struct bt_pacs *pacs;
+	uint8_t type = BAP_CHANNEL_ALLOCATION_LTV_TYPE;
+	uint32_t allocation = 0;
+	struct iovec *caps;
 
 	if (!stream)
 		return 0x00000000;
@@ -5644,10 +5659,13 @@ uint32_t bt_bap_stream_get_location(struct bt_bap_stream *stream)
 			return pacs->sink_loc_value;
 	}
 
-	/* TO DO get the location values from metadata
-	 * for brodcast source and sink
-	 */
-	return stream->bap->ldb->pacs->source_loc_value;
+	caps = bt_bap_stream_get_config(stream);
+
+	/* Get stream allocation from capabilities */
+	util_ltv_foreach(caps->iov_base, caps->iov_len, &type,
+			bap_sink_get_allocation, &allocation);
+
+	return allocation;
 }
 
 struct iovec *bt_bap_stream_get_config(struct bt_bap_stream *stream)
@@ -6322,18 +6340,6 @@ struct iovec *bt_bap_stream_get_base(struct bt_bap_stream *stream)
 	return base_iov;
 }
 
-static void bap_sink_get_allocation(size_t i, uint8_t l, uint8_t t,
-		uint8_t *v, void *user_data)
-{
-	uint32_t location32;
-
-	if (!v)
-		return;
-
-	memcpy(&location32, v, l);
-	*((uint32_t *)user_data) = le32_to_cpu(location32);
-}
-
 /*
  * This function compares PAC Codec Specific Capabilities, with the Codec
  * Specific Configuration LTVs received in the BASE of the BAP Source. The
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH BlueZ 3/5] shared/bap: Update stream management to avoid PACs
  2024-04-19 18:07 [PATCH BlueZ 0/5] Create transports for matching BISes Andrei Istodorescu
  2024-04-19 18:07 ` [PATCH BlueZ 1/5] shared/bap: Allow NULL bap endpoint in streams Andrei Istodorescu
  2024-04-19 18:07 ` [PATCH BlueZ 2/5] shared/bap: Get broadcast channel location from stream capabilities Andrei Istodorescu
@ 2024-04-19 18:07 ` Andrei Istodorescu
  2024-04-19 19:31   ` Luiz Augusto von Dentz
  2024-04-19 18:07 ` [PATCH BlueZ 4/5] shared/bap: In case of a BIS-PAC match return also the local pac Andrei Istodorescu
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 10+ messages in thread
From: Andrei Istodorescu @ 2024-04-19 18:07 UTC (permalink / raw
  To: linux-bluetooth
  Cc: luiz.dentz, mihai-octavian.urzica, silviu.barbulescu,
	vlad.pruteanu, iulia.tanasescu, Andrei Istodorescu

Set the stream to enabling for BAP Broadcast Sink, when the transport is
acquired.
Remove PAC logic for BAP Broadcast Sink stream creation.
---
 src/shared/bap.c | 60 +++++-------------------------------------------
 1 file changed, 6 insertions(+), 54 deletions(-)

diff --git a/src/shared/bap.c b/src/shared/bap.c
index 36f0b0a3b50a..d7a2f9381c53 100644
--- a/src/shared/bap.c
+++ b/src/shared/bap.c
@@ -2006,7 +2006,7 @@ static unsigned int bap_bcast_enable(struct bt_bap_stream *stream,
 					void *user_data)
 {
 	if (bt_bap_stream_io_dir(stream) == BT_BAP_BCAST_SOURCE)
-		stream_set_state(stream, BT_BAP_STREAM_STATE_STREAMING);
+		stream_set_state(stream, BT_BAP_STREAM_STATE_ENABLING);
 	else
 		stream_set_state(stream, BT_BAP_STREAM_STATE_CONFIG);
 
@@ -5287,7 +5287,6 @@ void bt_bap_cancel_select(struct bt_bap_pac *lpac, bt_bap_pac_select_t func,
 
 static struct bt_bap_stream *bap_bcast_stream_new(struct bt_bap *bap,
 					struct bt_bap_pac *lpac,
-					struct bt_bap_pac *rpac,
 					struct bt_bap_qos *pqos,
 					struct iovec *data)
 {
@@ -5298,71 +5297,24 @@ static struct bt_bap_stream *bap_bcast_stream_new(struct bt_bap *bap,
 	if (!bap)
 		return NULL;
 
-	if (!rpac && (lpac->type != BT_BAP_BCAST_SOURCE)
-		&& queue_isempty(bap->remote_eps))
-		return NULL;
-
-	if (lpac && rpac) {
-		if ((rpac->type != BT_BAP_BCAST_SOURCE)
-			&& (!bap_codec_equal(&lpac->codec, &rpac->codec)))
-			return NULL;
-	} else {
-		uint8_t type;
-
+	if (lpac->type == BT_BAP_BCAST_SOURCE) {
 		match.lpac = lpac;
-		match.rpac = rpac;
+		match.rpac = NULL;
 		memset(&match.codec, 0, sizeof(match.codec));
 
-		if (rpac)
-			type = rpac->type;
-		else if (lpac) {
-			switch (lpac->type) {
-			case BT_BAP_BCAST_SOURCE:
-				type = BT_BAP_BCAST_SINK;
-				break;
-			case BT_BAP_BCAST_SINK:
-				type = BT_BAP_BCAST_SOURCE;
-				break;
-			default:
-				return NULL;
-			}
-		} else
-			return NULL;
-
-		bt_bap_foreach_pac(bap, type, match_pac, &match);
+		bt_bap_foreach_pac(bap, BT_BAP_BCAST_SINK, match_pac, &match);
 		if ((!match.lpac) || (!lpac))
 			return NULL;
-		if (!match.rpac && (lpac->type != BT_BAP_BCAST_SOURCE))
-			return NULL;
 
 		lpac = match.lpac;
-		rpac = match.rpac;
-	}
-
-	match.lpac = lpac;
-	match.rpac = rpac;
 
-	if (lpac->type != BT_BAP_BCAST_SOURCE) {
-		/* Check for existing stream */
-		ep = queue_find(bap->remote_eps, find_ep_pacs, &match);
-		if (!ep) {
-			/* Check for unused ASE */
-			ep = queue_find(bap->remote_eps, find_ep_unused,
-					&match);
-			if (!ep) {
-				DBG(bap, "Unable to find unused ASE");
-				return NULL;
-			}
-		}
-		stream = ep->stream;
-	} else {
 		ep = queue_find(bap->remote_eps, find_ep_source, NULL);
 		if (!ep)
 			return NULL;
 	}
 
 	if (!stream)
-		stream = bap_stream_new(bap, ep, lpac, rpac, data, true);
+		stream = bap_stream_new(bap, ep, lpac, NULL, data, true);
 
 	return stream;
 }
@@ -5415,7 +5367,7 @@ struct bt_bap_stream *bt_bap_stream_new(struct bt_bap *bap,
 	if (bt_bap_get_att(bap))
 		return bap_ucast_stream_new(bap, lpac, rpac, pqos, data);
 
-	return bap_bcast_stream_new(bap, lpac, rpac, pqos, data);
+	return bap_bcast_stream_new(bap, lpac, pqos, data);
 }
 
 struct bt_bap *bt_bap_stream_get_session(struct bt_bap_stream *stream)
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH BlueZ 4/5] shared/bap: In case of a BIS-PAC match return also the local pac
  2024-04-19 18:07 [PATCH BlueZ 0/5] Create transports for matching BISes Andrei Istodorescu
                   ` (2 preceding siblings ...)
  2024-04-19 18:07 ` [PATCH BlueZ 3/5] shared/bap: Update stream management to avoid PACs Andrei Istodorescu
@ 2024-04-19 18:07 ` Andrei Istodorescu
  2024-04-19 18:07 ` [PATCH BlueZ 5/5] bap: Create streams and transports for each matching BIS Andrei Istodorescu
  2024-04-23 17:40 ` [PATCH BlueZ 0/5] Create transports for matching BISes patchwork-bot+bluetooth
  5 siblings, 0 replies; 10+ messages in thread
From: Andrei Istodorescu @ 2024-04-19 18:07 UTC (permalink / raw
  To: linux-bluetooth
  Cc: luiz.dentz, mihai-octavian.urzica, silviu.barbulescu,
	vlad.pruteanu, iulia.tanasescu, Andrei Istodorescu

When checking in local PACS for a BIS match return also the local PAC,
along with the status of the operation. This information is required
later when we create the stream.
---
 src/shared/bap.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/src/shared/bap.c b/src/shared/bap.c
index d7a2f9381c53..8c4868f4bf9f 100644
--- a/src/shared/bap.c
+++ b/src/shared/bap.c
@@ -6400,9 +6400,11 @@ static void check_local_pac(void *data, void *user_data)
 
 		/* We have a match if all selected LTVs have a match */
 		if ((bis_compare_data.data32 &
-			CODEC_SPECIFIC_CONFIGURATION_MASK) ==
-			CODEC_SPECIFIC_CONFIGURATION_MASK)
+				CODEC_SPECIFIC_CONFIGURATION_MASK) ==
+				CODEC_SPECIFIC_CONFIGURATION_MASK) {
 			compare_data->found = true;
+			compare_data->data = data;
+		}
 	}
 }
 
@@ -6427,7 +6429,8 @@ static void bap_sink_match_allocation(size_t i, uint8_t l, uint8_t t,
 		data->found = false;
 }
 
-static bool bap_check_bis(struct bt_bap_db *ldb, struct iovec *bis_data)
+static struct bt_ltv_match bap_check_bis(struct bt_bap_db *ldb,
+	struct iovec *bis_data)
 {
 	struct bt_ltv_match compare_data = {};
 
@@ -6453,7 +6456,7 @@ static bool bap_check_bis(struct bt_bap_db *ldb, struct iovec *bis_data)
 				&compare_data);
 	}
 
-	return compare_data.found;
+	return compare_data;
 }
 
 void bt_bap_add_bis(struct bt_bap *bap, uint8_t bis_index,
@@ -6468,6 +6471,7 @@ void bt_bap_add_bis(struct bt_bap *bap, uint8_t bis_index,
 	struct bt_bap_pac_qos bis_qos = {0};
 	uint8_t type = 0;
 	struct bt_ltv_extract merge_data = {0};
+	struct bt_ltv_match match_data = {0};
 
 	merge_data.src = l3_caps;
 	merge_data.result = new0(struct iovec, 1);
@@ -6483,7 +6487,8 @@ void bt_bap_add_bis(struct bt_bap *bap, uint8_t bis_index,
 	/* Check each BIS Codec Specific Configuration LTVs against our Codec
 	 * Specific Capabilities and if the BIS matches create a PAC with it
 	 */
-	if (bap_check_bis(bap->ldb, merge_data.result) == false)
+	match_data = bap_check_bis(bap->ldb, merge_data.result);
+	if (match_data.found == false)
 		goto cleanup;
 
 	DBG(bap, "Matching BIS %i", bis_index);
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH BlueZ 5/5] bap: Create streams and transports for each matching BIS
  2024-04-19 18:07 [PATCH BlueZ 0/5] Create transports for matching BISes Andrei Istodorescu
                   ` (3 preceding siblings ...)
  2024-04-19 18:07 ` [PATCH BlueZ 4/5] shared/bap: In case of a BIS-PAC match return also the local pac Andrei Istodorescu
@ 2024-04-19 18:07 ` Andrei Istodorescu
  2024-04-19 19:28   ` Luiz Augusto von Dentz
  2024-04-23 17:40 ` [PATCH BlueZ 0/5] Create transports for matching BISes patchwork-bot+bluetooth
  5 siblings, 1 reply; 10+ messages in thread
From: Andrei Istodorescu @ 2024-04-19 18:07 UTC (permalink / raw
  To: linux-bluetooth
  Cc: luiz.dentz, mihai-octavian.urzica, silviu.barbulescu,
	vlad.pruteanu, iulia.tanasescu, Andrei Istodorescu

Rename bt_bap_add_bis to bt_bap_check_bis as its scope has changed.
Use the BIS index received in the BASE to synchronize to the BIG.
Allow bt_bap_endpoint to be NULL.
Remove the Broadcast Sink code from set_configuration.
Update BASE parsing so that it creates streams and transports, without a
remote PAC and endpoint.
Update bap_find_setup_by_stream to find the setup in case the stream does
not contain an endpoint.
Update BAP Broadcast Sink state machine:
* BIS matched over the air -> create stream and transport and set the
  stream state to BT_BAP_STREAM_STATE_CONFIG
* transport acquire sets stream state to BT_BAP_STREAM_STATE_ENABLING
  and do BIG Create Sync
* BIG Sync Established received sets stream state to
  BT_BAP_STREAM_STATE_STREAMING
---
 profiles/audio/bap.c | 184 +++++++++++++++++++++++++++++----------
 src/shared/bap.c     | 199 ++++++++++++++++++++++---------------------
 src/shared/bap.h     |   6 +-
 3 files changed, 244 insertions(+), 145 deletions(-)

diff --git a/profiles/audio/bap.c b/profiles/audio/bap.c
index ff6d6d881346..b59ef405ab74 100644
--- a/profiles/audio/bap.c
+++ b/profiles/audio/bap.c
@@ -109,6 +109,7 @@ struct bap_data {
 	struct queue *srcs;
 	struct queue *snks;
 	struct queue *bcast;
+	struct queue *bcast_snks;
 	struct queue *streams;
 	GIOChannel *listen_io;
 	int selecting;
@@ -125,7 +126,10 @@ struct bap_bcast_pa_req {
 	bool in_progress;
 	union {
 		struct btd_service *service;
-		struct bap_setup *setup;
+		struct bap_accept {
+			struct bap_setup *setup;
+			struct bap_data *bap_data;
+		} accept_data;
 	} data;
 };
 
@@ -197,6 +201,8 @@ static void ep_unregister(void *data)
 						MEDIA_ENDPOINT_INTERFACE);
 }
 
+static void setup_free(void *data);
+
 static void bap_data_free(struct bap_data *data)
 {
 	if (data->listen_io) {
@@ -213,6 +219,7 @@ static void bap_data_free(struct bap_data *data)
 	queue_destroy(data->srcs, ep_unregister);
 	queue_destroy(data->bcast, ep_unregister);
 	queue_destroy(data->streams, NULL);
+	queue_destroy(data->bcast_snks, setup_free);
 	bt_bap_ready_unregister(data->bap, data->ready_id);
 	bt_bap_state_unregister(data->bap, data->state_id);
 	bt_bap_pac_unregister(data->bap, data->pac_id);
@@ -850,7 +857,11 @@ static struct bap_setup *setup_new(struct bap_ep *ep)
 	setup = new0(struct bap_setup, 1);
 	setup->ep = ep;
 
-	if (queue_find(ep->data->bcast, NULL, ep)) {
+	/* Broadcast Source has endpoints in bcast list, Broadcast Sink
+	 * does not have endpoints
+	 */
+	if (((ep != NULL) && queue_find(ep->data->bcast, NULL, ep)) ||
+			(ep == NULL)) {
 		/* Mark BIG and BIS to be auto assigned */
 		setup->qos.bcast.big = BT_ISO_QOS_BIG_UNSET;
 		setup->qos.bcast.bis = BT_ISO_QOS_BIS_UNSET;
@@ -866,12 +877,14 @@ static struct bap_setup *setup_new(struct bap_ep *ep)
 		setup->qos_parser = setup_parse_ucast_qos;
 	}
 
-	if (!ep->setups)
-		ep->setups = queue_new();
+	if (ep) {
+		if (!ep->setups)
+			ep->setups = queue_new();
 
-	queue_push_tail(ep->setups, setup);
+		queue_push_tail(ep->setups, setup);
 
-	DBG("ep %p setup %p", ep, setup);
+		DBG("ep %p setup %p", ep, setup);
+	}
 
 	return setup;
 }
@@ -942,17 +955,6 @@ static DBusMessage *set_configuration(DBusConnection *conn, DBusMessage *msg,
 		return btd_error_invalid_args(msg);
 	}
 
-	/* For BAP Broadcast Sink, the capabilities and metadata are coming
-	 * from the source's BIS, which are present in the remote PAC
-	 */
-	if (bt_bap_pac_get_type(ep->lpac) == BT_BAP_BCAST_SINK) {
-		util_iov_free(setup->caps, 1);
-		setup->caps = util_iov_dup(bt_bap_pac_get_data(ep->rpac), 1);
-		util_iov_free(setup->metadata, 1);
-		setup->metadata = util_iov_dup(
-				bt_bap_pac_get_metadata(ep->rpac), 1);
-	}
-
 	setup->stream = bt_bap_stream_new(ep->data->bap, ep->lpac, ep->rpac,
 						&setup->qos, setup->caps);
 	bt_bap_stream_set_user_data(setup->stream, ep->path);
@@ -988,20 +990,24 @@ static DBusMessage *set_configuration(DBusConnection *conn, DBusMessage *msg,
 static void iso_bcast_confirm_cb(GIOChannel *io, GError *err, void *user_data)
 {
 	struct bap_bcast_pa_req *req = user_data;
-	struct bap_setup *setup = req->data.setup;
+	struct bap_setup *setup = req->data.accept_data.setup;
 	int fd;
 
 	DBG("BIG Sync completed");
 
 	queue_remove(bcast_pa_requests, req);
 
+	g_io_channel_unref(setup->io);
+	g_io_channel_shutdown(setup->io, TRUE, NULL);
+	setup->io = NULL;
+
 	/* This device is no longer needed */
-	btd_service_connecting_complete(setup->ep->data->service, 0);
+	btd_service_connecting_complete(req->data.accept_data.bap_data->service,
+			0);
 
 	fd = g_io_channel_unix_get_fd(io);
 
 	if (bt_bap_stream_set_io(setup->stream, fd)) {
-		bt_bap_stream_enable(setup->stream, true, NULL, NULL, NULL);
 		g_io_channel_set_close_on_unref(io, FALSE);
 		return;
 	}
@@ -1014,8 +1020,54 @@ static void print_ltv(size_t i, uint8_t l, uint8_t t, uint8_t *v,
 	util_hexdump(' ', v, l, user_data, NULL);
 }
 
-static bool parse_base(struct bt_bap *bap, struct bt_iso_base *base,
-		util_debug_func_t func)
+static void create_stream_for_bis(struct bap_data *bap_data,
+		struct bt_bap_pac *lpac, struct bt_iso_qos *qos,
+		struct iovec *caps, struct iovec *meta, char *path)
+{
+	struct bap_setup *setup;
+
+	setup = setup_new(NULL);
+
+	/* Create BAP QoS structure */
+	setup->qos.bcast.big = qos->bcast.big;
+	setup->qos.bcast.bis = qos->bcast.bis;
+	setup->qos.bcast.sync_factor = qos->bcast.sync_factor;
+	setup->qos.bcast.packing = qos->bcast.packing;
+	setup->qos.bcast.framing = qos->bcast.framing;
+	setup->qos.bcast.encryption = qos->bcast.encryption;
+	if (setup->qos.bcast.encryption)
+		util_iov_append(setup->qos.bcast.bcode,
+				qos->bcast.bcode,
+				sizeof(qos->bcast.bcode));
+	setup->qos.bcast.options = qos->bcast.options;
+	setup->qos.bcast.skip = qos->bcast.skip;
+	setup->qos.bcast.sync_timeout = qos->bcast.sync_timeout;
+	setup->qos.bcast.sync_cte_type =
+			qos->bcast.sync_cte_type;
+	setup->qos.bcast.mse = qos->bcast.mse;
+	setup->qos.bcast.timeout = qos->bcast.timeout;
+	setup->qos.bcast.io_qos.interval =
+			qos->bcast.in.interval;
+	setup->qos.bcast.io_qos.latency = qos->bcast.in.latency;
+	setup->qos.bcast.io_qos.phy = qos->bcast.in.phy;
+	setup->qos.bcast.io_qos.rtn = qos->bcast.in.rtn;
+	setup->qos.bcast.io_qos.sdu = qos->bcast.in.sdu;
+
+	queue_push_tail(bap_data->bcast_snks, setup);
+
+	/* Create and configure stream */
+	setup->stream = bt_bap_stream_new(bap_data->bap,
+			lpac, NULL, &setup->qos, caps);
+
+	bt_bap_stream_set_user_data(setup->stream, path);
+	bt_bap_stream_config(setup->stream, &setup->qos,
+			caps, NULL, NULL);
+	bt_bap_stream_metadata(setup->stream, meta,
+			NULL, NULL);
+}
+
+static bool parse_base(struct bap_data *bap_data, struct bt_iso_base *base,
+		struct bt_iso_qos *qos, util_debug_func_t func)
 {
 	struct iovec iov = {
 		.iov_base = base->base,
@@ -1087,11 +1139,20 @@ static bool parse_base(struct bt_bap *bap, struct bt_iso_base *base,
 		for (; num_bis; num_bis--) {
 			uint8_t bis_index;
 			struct iovec *l3_caps;
+			struct iovec *merged_caps;
+			struct bt_bap_pac *matched_lpac;
+			char *path;
+			int err;
 
 			if (!util_iov_pull_u8(&iov, &bis_index))
 				goto fail;
 
 			util_debug(func, NULL, "BIS #%d", bis_index);
+			err = asprintf(&path, "%s/bis%d",
+					device_get_path(bap_data->device),
+					bis_index);
+			if (err < 0)
+				continue;
 
 			/* Read Codec Specific Configuration */
 			l3_caps = new0(struct iovec, 1);
@@ -1110,9 +1171,16 @@ static bool parse_base(struct bt_bap *bap, struct bt_iso_base *base,
 					l3_caps->iov_len, NULL, print_ltv,
 					func);
 
-			/* Try to create a PAC using this BIS information */
-			bt_bap_add_bis(bap, bis_index, &codec, l2_caps, l3_caps,
-					meta);
+			/* 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);
+
+			if (matched_lpac == NULL || merged_caps == NULL)
+				continue;
+
+			create_stream_for_bis(bap_data, matched_lpac, qos,
+					merged_caps, meta, path);
 		}
 
 	}
@@ -1155,7 +1223,9 @@ static void iso_pa_sync_confirm_cb(GIOChannel *io, void *user_data)
 	/* Analyze received BASE data and create remote media endpoints for each
 	 * BIS matching our capabilities
 	 */
-	parse_base(data->bap, &base, bap_debug);
+	parse_base(data, &base, &qos, bap_debug);
+
+	service_set_connecting(pa_req->data.service);
 }
 
 static bool match_data_bap_data(const void *data, const void *match_data)
@@ -1558,6 +1628,7 @@ static struct bap_setup *bap_find_setup_by_stream(struct bap_data *data,
 					struct bt_bap_stream *stream)
 {
 	struct bap_ep *ep = NULL;
+	struct queue *queue = NULL;
 
 	switch (bt_bap_stream_get_type(stream)) {
 	case BT_BAP_STREAM_TYPE_UCAST:
@@ -1572,9 +1643,11 @@ static struct bap_setup *bap_find_setup_by_stream(struct bap_data *data,
 	}
 
 	if (ep)
-		return queue_find(ep->setups, match_setup_stream, stream);
+		queue = ep->setups;
+	else
+		queue = data->bcast_snks;
 
-	return NULL;
+	return queue_find(queue, match_setup_stream, stream);
 }
 
 static void iso_connect_bcast_cb(GIOChannel *chan, GError *err,
@@ -2097,7 +2170,8 @@ static void setup_accept_io_broadcast(struct bap_data *data,
 	 */
 	pa_req->type = BAP_PA_BIG_SYNC_REQ;
 	pa_req->in_progress = FALSE;
-	pa_req->data.setup = setup;
+	pa_req->data.accept_data.setup = setup;
+	pa_req->data.accept_data.bap_data = data;
 	queue_push_tail(bcast_pa_requests, pa_req);
 }
 
@@ -2157,7 +2231,7 @@ static void setup_create_bcast_io(struct bap_data *data,
 	memcpy(&iso_qos.bcast.out, &setup->qos.bcast.io_qos,
 				sizeof(struct bt_iso_io_qos));
 
-	if (bt_bap_pac_get_type(setup->ep->lpac) == BT_BAP_BCAST_SOURCE)
+	if (bt_bap_stream_get_dir(stream) == BT_BAP_BCAST_SINK)
 		setup_connect_io_broadcast(data, setup, stream, &iso_qos,
 			defer);
 	else
@@ -2399,12 +2473,7 @@ static void bap_state_bcast(struct bt_bap_stream *stream, uint8_t old_state,
 		if (!setup || setup->id)
 			break;
 		if (bt_bap_stream_io_dir(stream) ==
-				BT_BAP_BCAST_SOURCE)
-			/* If the stream is attached to a
-			 * broadcast sink endpoint.
-			 */
-			setup_create_io(data, setup, stream, defer);
-		else {
+				BT_BAP_BCAST_SINK) {
 			/* If the stream attached to a broadcast
 			 * source endpoint generate the base.
 			 */
@@ -2455,6 +2524,14 @@ static void bap_state_bcast(struct bt_bap_stream *stream, uint8_t old_state,
 			}
 		}
 		break;
+	case BT_BAP_STREAM_STATE_ENABLING:
+		if (bt_bap_stream_io_dir(stream) == BT_BAP_BCAST_SOURCE)
+			setup_create_io(data, setup, stream, defer);
+		break;
+	case BT_BAP_STREAM_STATE_RELEASING:
+		if (bt_bap_stream_io_dir(stream) == BT_BAP_BCAST_SOURCE)
+			setup_io_close(setup, NULL);
+		break;
 	}
 }
 
@@ -2794,6 +2871,7 @@ static int short_lived_pa_sync(struct bap_bcast_pa_req *req)
 		error("BAP unable to attach");
 		return -EINVAL;
 	}
+	data->bcast_snks = queue_new();
 
 	bap_data_add(data);
 
@@ -2833,29 +2911,41 @@ static void iso_do_big_sync(GIOChannel *io, void *user_data)
 {
 	GError *err = NULL;
 	struct bap_bcast_pa_req *req = user_data;
-	struct bap_setup *setup = req->data.setup;
-	struct bap_data *data = setup->ep->data;
+	struct bap_setup *setup = req->data.accept_data.setup;
+	struct bap_data *data = req->data.accept_data.bap_data;
 	struct sockaddr_iso_bc iso_bc_addr;
 	struct bt_iso_qos qos;
+	char *path;
+	int bis_index = 1;
+	char device_name[40] = {0};
+	int s_err;
 
-	DBG("PA Sync done, do BIG Sync");
+	DBG("PA Sync done");
 	g_io_channel_unref(setup->io);
-	setup->io = NULL;
-
+	g_io_channel_shutdown(setup->io, TRUE, NULL);
 	setup->io = io;
 	g_io_channel_ref(setup->io);
 
 	/* TODO
 	 * We can only synchronize with a single BIS to a BIG.
 	 * In order to have multiple BISes targeting this BIG we need to have
-	 * all the BISes before doing this request. This request is triggered
-	 * by an endpoint "SetConfiguration" command. For multiple BISes
-	 * we need another way to specify which BISes user is requesting
+	 * all the BISes before doing bt_io_bcast_accept.
+	 * This request comes from a transport "Acquire" call.
+	 * For multiple BISes in the same BIG we need to either wait for all
+	 * transports in the same BIG to be acquired or tell when to do the
+	 * bt_io_bcast_accept by other means
 	 */
+	path = bt_bap_stream_get_user_data(setup->stream);
+	s_err = sscanf(path, "%s/bis%d", device_name, &bis_index);
+	if (s_err == -1)
+		DBG("sscanf error");
+
+	DBG("Do BIG Sync with BIS %d", bis_index);
+
 	iso_bc_addr.bc_bdaddr_type = btd_device_get_bdaddr_type(data->device);
 	memcpy(&iso_bc_addr.bc_bdaddr, device_get_address(data->device),
 			sizeof(bdaddr_t));
-	iso_bc_addr.bc_bis[0] = 1;
+	iso_bc_addr.bc_bis[0] = bis_index;
 	iso_bc_addr.bc_num_bis = 1;
 
 	/* Set the user requested QOS */
@@ -2898,8 +2988,8 @@ static void iso_do_big_sync(GIOChannel *io, void *user_data)
 static void pa_and_big_sync(struct bap_bcast_pa_req *req)
 {
 	GError *err = NULL;
-	struct bap_setup *setup = req->data.setup;
-	struct bap_data *data = setup->ep->data;
+	struct bap_setup *setup = req->data.accept_data.setup;
+	struct bap_data *data = req->data.accept_data.bap_data;
 
 	req->in_progress = TRUE;
 
diff --git a/src/shared/bap.c b/src/shared/bap.c
index 8c4868f4bf9f..e69f6cec99bf 100644
--- a/src/shared/bap.c
+++ b/src/shared/bap.c
@@ -226,6 +226,7 @@ struct bt_bap_stream_io {
 struct bt_bap_stream_ops {
 	uint8_t type;
 	void (*set_state)(struct bt_bap_stream *stream, uint8_t state);
+	unsigned int (*get_state)(struct bt_bap_stream *stream);
 	unsigned int (*config)(struct bt_bap_stream *stream,
 				struct bt_bap_qos *qos, struct iovec *data,
 				bt_bap_stream_func_t func, void *user_data);
@@ -245,6 +246,8 @@ struct bt_bap_stream_ops {
 	unsigned int (*metadata)(struct bt_bap_stream *stream,
 				struct iovec *data, bt_bap_stream_func_t func,
 				void *user_data);
+	unsigned int (*get_dir)(struct bt_bap_stream *stream);
+	unsigned int (*get_loc)(struct bt_bap_stream *stream);
 	unsigned int (*release)(struct bt_bap_stream *stream,
 				bt_bap_stream_func_t func, void *user_data);
 };
@@ -1578,6 +1581,11 @@ done:
 	bap_stream_state_changed(stream);
 }
 
+static unsigned int bap_ucast_get_state(struct bt_bap_stream *stream)
+{
+	return stream->ep->state;
+}
+
 static unsigned int bap_ucast_config(struct bt_bap_stream *stream,
 					struct bt_bap_qos *qos,
 					struct iovec *data,
@@ -1923,6 +1931,27 @@ static bool bap_stream_valid(struct bt_bap_stream *stream)
 	return queue_find(stream->bap->streams, NULL, stream);
 }
 
+static unsigned int bap_ucast_get_dir(struct bt_bap_stream *stream)
+{
+	return stream->ep->dir;
+}
+
+static unsigned int bap_ucast_get_location(struct bt_bap_stream *stream)
+{
+	struct bt_pacs *pacs;
+
+	if (!stream)
+		return 0x00000000;
+
+	pacs = stream->client ? stream->bap->rdb->pacs : stream->bap->ldb->pacs;
+
+	if (stream->ep->dir == BT_BAP_SOURCE)
+		return pacs->source_loc_value;
+	else if (stream->ep->dir == BT_BAP_SINK)
+		return pacs->sink_loc_value;
+	return 0x00000000;
+}
+
 static unsigned int bap_ucast_release(struct bt_bap_stream *stream,
 					bt_bap_stream_func_t func,
 					void *user_data)
@@ -2000,6 +2029,11 @@ static void bap_bcast_set_state(struct bt_bap_stream *stream, uint8_t state)
 	}
 }
 
+static unsigned int bap_bcast_get_state(struct bt_bap_stream *stream)
+{
+	return stream->state;
+}
+
 static unsigned int bap_bcast_enable(struct bt_bap_stream *stream,
 					bool enable_links, struct iovec *data,
 					bt_bap_stream_func_t func,
@@ -2043,6 +2077,41 @@ static unsigned int bap_bcast_metadata(struct bt_bap_stream *stream,
 	return 1;
 }
 
+static unsigned int bap_bcast_get_dir(struct bt_bap_stream *stream)
+{
+	if (bt_bap_pac_get_type(stream->lpac) == BT_BAP_BCAST_SINK)
+		return BT_BAP_BCAST_SOURCE;
+	else
+		return BT_BAP_BCAST_SINK;
+}
+
+static void bap_sink_get_allocation(size_t i, uint8_t l, uint8_t t,
+		uint8_t *v, void *user_data)
+{
+	uint32_t location32;
+
+	if (!v)
+		return;
+
+	memcpy(&location32, v, l);
+	*((uint32_t *)user_data) = le32_to_cpu(location32);
+}
+
+static unsigned int bap_bcast_get_location(struct bt_bap_stream *stream)
+{
+	uint8_t type = BAP_CHANNEL_ALLOCATION_LTV_TYPE;
+	uint32_t allocation = 0;
+	struct iovec *caps;
+
+	caps = bt_bap_stream_get_config(stream);
+
+	/* Get stream allocation from capabilities */
+	util_ltv_foreach(caps->iov_base, caps->iov_len, &type,
+			bap_sink_get_allocation, &allocation);
+
+	return allocation;
+}
+
 static unsigned int bap_bcast_release(struct bt_bap_stream *stream,
 					bt_bap_stream_func_t func,
 					void *user_data)
@@ -2052,11 +2121,12 @@ static unsigned int bap_bcast_release(struct bt_bap_stream *stream,
 	return 1;
 }
 
-#define STREAM_OPS(_type, _set_state, _config, _qos, _enable, _start, \
-			_disable, _stop, _metadata, _release) \
+#define STREAM_OPS(_type, _set_state, _get_state, _config, _qos, _enable, \
+	_start, _disable, _stop, _metadata, _get_dir, _get_loc, _release) \
 { \
 	.type = _type, \
 	.set_state = _set_state, \
+	.get_state = _get_state, \
 	.config = _config, \
 	.qos = _qos, \
 	.enable = _enable, \
@@ -2064,26 +2134,40 @@ static unsigned int bap_bcast_release(struct bt_bap_stream *stream,
 	.disable = _disable, \
 	.stop = _stop, \
 	.metadata = _metadata, \
+	.get_dir = _get_dir,\
+	.get_loc = _get_loc, \
 	.release = _release, \
 }
 
 static const struct bt_bap_stream_ops stream_ops[] = {
 	STREAM_OPS(BT_BAP_SINK, bap_ucast_set_state,
+			bap_ucast_get_state,
 			bap_ucast_config, bap_ucast_qos, bap_ucast_enable,
 			bap_ucast_start, bap_ucast_disable, bap_ucast_stop,
-			bap_ucast_metadata, bap_ucast_release),
+			bap_ucast_metadata, bap_ucast_get_dir,
+			bap_ucast_get_location,
+			bap_ucast_release),
 	STREAM_OPS(BT_BAP_SOURCE, bap_ucast_set_state,
+			bap_ucast_get_state,
 			bap_ucast_config, bap_ucast_qos, bap_ucast_enable,
 			bap_ucast_start, bap_ucast_disable, bap_ucast_stop,
-			bap_ucast_metadata, bap_ucast_release),
+			bap_ucast_metadata, bap_ucast_get_dir,
+			bap_ucast_get_location,
+			bap_ucast_release),
 	STREAM_OPS(BT_BAP_BCAST_SINK, bap_bcast_set_state,
+			bap_bcast_get_state,
 			bap_bcast_config, NULL, bap_bcast_enable,
 			bap_bcast_start, bap_bcast_disable, NULL,
-			bap_bcast_metadata, bap_bcast_release),
+			bap_bcast_metadata, bap_bcast_get_dir,
+			bap_bcast_get_location,
+			bap_bcast_release),
 	STREAM_OPS(BT_BAP_BCAST_SOURCE, bap_bcast_set_state,
+			bap_bcast_get_state,
 			bap_bcast_config, NULL, bap_bcast_enable,
 			bap_bcast_start, bap_bcast_disable, NULL,
-			bap_bcast_metadata, bap_bcast_release),
+			bap_bcast_metadata, bap_bcast_get_dir,
+			bap_bcast_get_location,
+			bap_bcast_release),
 };
 
 static const struct bt_bap_stream_ops *
@@ -5383,11 +5467,7 @@ uint8_t bt_bap_stream_get_state(struct bt_bap_stream *stream)
 	if (!stream)
 		return BT_BAP_STREAM_STATE_IDLE;
 
-	if (stream->lpac->type != BT_BAP_BCAST_SOURCE &&
-			stream->lpac->type != BT_BAP_BCAST_SINK)
-		return stream->ep->state;
-	else
-		return stream->state;
+	return stream->ops->get_state(stream);
 }
 
 bool bt_bap_stream_set_user_data(struct bt_bap_stream *stream, void *user_data)
@@ -5571,53 +5651,15 @@ uint8_t bt_bap_stream_get_dir(struct bt_bap_stream *stream)
 	if (!stream)
 		return 0x00;
 
-	if (stream->ep)
-		return stream->ep->dir;
-
-	if (bt_bap_pac_get_type(stream->lpac) == BT_BAP_BCAST_SINK)
-		return BT_BAP_BCAST_SOURCE;
-	else
-		return BT_BAP_BCAST_SINK;
-}
-
-static void bap_sink_get_allocation(size_t i, uint8_t l, uint8_t t,
-		uint8_t *v, void *user_data)
-{
-	uint32_t location32;
-
-	if (!v)
-		return;
-
-	memcpy(&location32, v, l);
-	*((uint32_t *)user_data) = le32_to_cpu(location32);
+	return stream->ops->get_dir(stream);
 }
 
 uint32_t bt_bap_stream_get_location(struct bt_bap_stream *stream)
 {
-	struct bt_pacs *pacs;
-	uint8_t type = BAP_CHANNEL_ALLOCATION_LTV_TYPE;
-	uint32_t allocation = 0;
-	struct iovec *caps;
-
 	if (!stream)
 		return 0x00000000;
 
-	pacs = stream->client ? stream->bap->rdb->pacs : stream->bap->ldb->pacs;
-
-	if (stream->ep) {
-		if (stream->ep->dir == BT_BAP_SOURCE)
-			return pacs->source_loc_value;
-		else if (stream->ep->dir == BT_BAP_SINK)
-			return pacs->sink_loc_value;
-	}
-
-	caps = bt_bap_stream_get_config(stream);
-
-	/* Get stream allocation from capabilities */
-	util_ltv_foreach(caps->iov_base, caps->iov_len, &type,
-			bap_sink_get_allocation, &allocation);
-
-	return allocation;
+	return stream->ops->get_loc(stream);
 }
 
 struct iovec *bt_bap_stream_get_config(struct bt_bap_stream *stream)
@@ -6459,17 +6501,13 @@ static struct bt_ltv_match bap_check_bis(struct bt_bap_db *ldb,
 	return compare_data;
 }
 
-void bt_bap_add_bis(struct bt_bap *bap, uint8_t bis_index,
+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 iovec *meta)
+		struct bt_bap_pac **lpac,
+		struct iovec **caps)
 {
-	struct bt_bap_pac *pac_source_bis;
-	struct bt_bap_endpoint *ep;
-	int err = 0;
-	struct bt_bap_pac_qos bis_qos = {0};
-	uint8_t type = 0;
 	struct bt_ltv_extract merge_data = {0};
 	struct bt_ltv_match match_data = {0};
 
@@ -6488,43 +6526,14 @@ void bt_bap_add_bis(struct bt_bap *bap, uint8_t bis_index,
 	 * Specific Capabilities and if the BIS matches create a PAC with it
 	 */
 	match_data = bap_check_bis(bap->ldb, merge_data.result);
-	if (match_data.found == false)
-		goto cleanup;
-
-	DBG(bap, "Matching BIS %i", bis_index);
-
-	/* Create a QoS structure based on the received BIS information to
-	 * specify the desired channel for this BIS/PAC
-	 */
-	type = BAP_CHANNEL_ALLOCATION_LTV_TYPE;
-	util_ltv_foreach(merge_data.result->iov_base,
-			merge_data.result->iov_len, &type,
-			bap_sink_get_allocation, &bis_qos.location);
-
-	/* Create a remote PAC */
-	pac_source_bis = bap_pac_new(bap->rdb, NULL,
-				BT_BAP_BCAST_SOURCE, codec, &bis_qos,
-				merge_data.result, meta);
-
-	err = asprintf(&pac_source_bis->name, "%d", bis_index);
-
-	if (err < 0) {
-		DBG(bap, "error in asprintf");
-		goto cleanup;
+	if (match_data.found == true) {
+		*caps = merge_data.result;
+		*lpac = match_data.data;
+		DBG(bap, "Matching BIS %i", bis_index);
+	} else {
+		util_iov_free(merge_data.result, 1);
+		*caps = NULL;
+		*lpac = NULL;
 	}
 
-	/* Add remote source endpoint */
-	if (!bap->rdb->broadcast_sources)
-		bap->rdb->broadcast_sources = queue_new();
-	queue_push_tail(bap->rdb->broadcast_sources, pac_source_bis);
-
-	queue_foreach(bap->pac_cbs, notify_pac_added, pac_source_bis);
-	/* Push remote endpoint with direction sink */
-	ep = bap_endpoint_new_broadcast(bap->rdb, BT_BAP_BCAST_SINK);
-
-	if (ep)
-		queue_push_tail(bap->remote_eps, ep);
-
-cleanup:
-	util_iov_free(merge_data.result, 1);
 }
diff --git a/src/shared/bap.h b/src/shared/bap.h
index 62e2104850c7..35524df0b451 100644
--- a/src/shared/bap.h
+++ b/src/shared/bap.h
@@ -251,9 +251,9 @@ 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);
 
-void bt_bap_add_bis(struct bt_bap *bap, uint8_t bis_index,
+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 iovec *meta);
-
+		struct bt_bap_pac **lpac,
+		struct iovec **caps);
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH BlueZ 5/5] bap: Create streams and transports for each matching BIS
  2024-04-19 18:07 ` [PATCH BlueZ 5/5] bap: Create streams and transports for each matching BIS Andrei Istodorescu
@ 2024-04-19 19:28   ` Luiz Augusto von Dentz
  0 siblings, 0 replies; 10+ messages in thread
From: Luiz Augusto von Dentz @ 2024-04-19 19:28 UTC (permalink / raw
  To: Andrei Istodorescu
  Cc: linux-bluetooth, mihai-octavian.urzica, silviu.barbulescu,
	vlad.pruteanu, iulia.tanasescu

Hi Andrei,

On Fri, Apr 19, 2024 at 2:08 PM Andrei Istodorescu
<andrei.istodorescu@nxp.com> wrote:
>
> Rename bt_bap_add_bis to bt_bap_check_bis as its scope has changed.

The scope being changed doesn't mean we need to change its name,
except if you add an explanation on why check is a better term than
add here, or perhaps we want to add something like
bt_bap_stream_new_bis? Which shall return the bt_bap_stream already
configured from BIS.

> Use the BIS index received in the BASE to synchronize to the BIG.
> Allow bt_bap_endpoint to be NULL.
> Remove the Broadcast Sink code from set_configuration.
> Update BASE parsing so that it creates streams and transports, without a
> remote PAC and endpoint.
> Update bap_find_setup_by_stream to find the setup in case the stream does
> not contain an endpoint.
> Update BAP Broadcast Sink state machine:
> * BIS matched over the air -> create stream and transport and set the
>   stream state to BT_BAP_STREAM_STATE_CONFIG
> * transport acquire sets stream state to BT_BAP_STREAM_STATE_ENABLING
>   and do BIG Create Sync

If we were to follow the BAP spec to the letter then there is no
Enabling state, nor Enable procedure:

https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/16212-BAP-html5/out/en/index-en.html#UUID-4a295bf2-6e50-be11-e827-c23e63569087_figure-idm4631863059107233170457600297

Broadcast streams can only be on Idle, Configured or Streaming states,
so I suggest we follow that as closely as possible.

> * BIG Sync Established received sets stream state to
>   BT_BAP_STREAM_STATE_STREAMING
> ---
>  profiles/audio/bap.c | 184 +++++++++++++++++++++++++++++----------
>  src/shared/bap.c     | 199 ++++++++++++++++++++++---------------------
>  src/shared/bap.h     |   6 +-
>  3 files changed, 244 insertions(+), 145 deletions(-)
>
> diff --git a/profiles/audio/bap.c b/profiles/audio/bap.c
> index ff6d6d881346..b59ef405ab74 100644
> --- a/profiles/audio/bap.c
> +++ b/profiles/audio/bap.c
> @@ -109,6 +109,7 @@ struct bap_data {
>         struct queue *srcs;
>         struct queue *snks;
>         struct queue *bcast;
> +       struct queue *bcast_snks;
>         struct queue *streams;
>         GIOChannel *listen_io;
>         int selecting;
> @@ -125,7 +126,10 @@ struct bap_bcast_pa_req {
>         bool in_progress;
>         union {
>                 struct btd_service *service;
> -               struct bap_setup *setup;
> +               struct bap_accept {
> +                       struct bap_setup *setup;
> +                       struct bap_data *bap_data;
> +               } accept_data;
>         } data;
>  };
>
> @@ -197,6 +201,8 @@ static void ep_unregister(void *data)
>                                                 MEDIA_ENDPOINT_INTERFACE);
>  }
>
> +static void setup_free(void *data);
> +
>  static void bap_data_free(struct bap_data *data)
>  {
>         if (data->listen_io) {
> @@ -213,6 +219,7 @@ static void bap_data_free(struct bap_data *data)
>         queue_destroy(data->srcs, ep_unregister);
>         queue_destroy(data->bcast, ep_unregister);
>         queue_destroy(data->streams, NULL);
> +       queue_destroy(data->bcast_snks, setup_free);
>         bt_bap_ready_unregister(data->bap, data->ready_id);
>         bt_bap_state_unregister(data->bap, data->state_id);
>         bt_bap_pac_unregister(data->bap, data->pac_id);
> @@ -850,7 +857,11 @@ static struct bap_setup *setup_new(struct bap_ep *ep)
>         setup = new0(struct bap_setup, 1);
>         setup->ep = ep;
>
> -       if (queue_find(ep->data->bcast, NULL, ep)) {
> +       /* Broadcast Source has endpoints in bcast list, Broadcast Sink
> +        * does not have endpoints
> +        */
> +       if (((ep != NULL) && queue_find(ep->data->bcast, NULL, ep)) ||
> +                       (ep == NULL)) {
>                 /* Mark BIG and BIS to be auto assigned */
>                 setup->qos.bcast.big = BT_ISO_QOS_BIG_UNSET;
>                 setup->qos.bcast.bis = BT_ISO_QOS_BIS_UNSET;
> @@ -866,12 +877,14 @@ static struct bap_setup *setup_new(struct bap_ep *ep)
>                 setup->qos_parser = setup_parse_ucast_qos;
>         }
>
> -       if (!ep->setups)
> -               ep->setups = queue_new();
> +       if (ep) {
> +               if (!ep->setups)
> +                       ep->setups = queue_new();
>
> -       queue_push_tail(ep->setups, setup);
> +               queue_push_tail(ep->setups, setup);
>
> -       DBG("ep %p setup %p", ep, setup);
> +               DBG("ep %p setup %p", ep, setup);
> +       }
>
>         return setup;
>  }
> @@ -942,17 +955,6 @@ static DBusMessage *set_configuration(DBusConnection *conn, DBusMessage *msg,
>                 return btd_error_invalid_args(msg);
>         }
>
> -       /* For BAP Broadcast Sink, the capabilities and metadata are coming
> -        * from the source's BIS, which are present in the remote PAC
> -        */
> -       if (bt_bap_pac_get_type(ep->lpac) == BT_BAP_BCAST_SINK) {
> -               util_iov_free(setup->caps, 1);
> -               setup->caps = util_iov_dup(bt_bap_pac_get_data(ep->rpac), 1);
> -               util_iov_free(setup->metadata, 1);
> -               setup->metadata = util_iov_dup(
> -                               bt_bap_pac_get_metadata(ep->rpac), 1);
> -       }
> -
>         setup->stream = bt_bap_stream_new(ep->data->bap, ep->lpac, ep->rpac,
>                                                 &setup->qos, setup->caps);
>         bt_bap_stream_set_user_data(setup->stream, ep->path);
> @@ -988,20 +990,24 @@ static DBusMessage *set_configuration(DBusConnection *conn, DBusMessage *msg,
>  static void iso_bcast_confirm_cb(GIOChannel *io, GError *err, void *user_data)
>  {
>         struct bap_bcast_pa_req *req = user_data;
> -       struct bap_setup *setup = req->data.setup;
> +       struct bap_setup *setup = req->data.accept_data.setup;
>         int fd;
>
>         DBG("BIG Sync completed");
>
>         queue_remove(bcast_pa_requests, req);
>
> +       g_io_channel_unref(setup->io);
> +       g_io_channel_shutdown(setup->io, TRUE, NULL);
> +       setup->io = NULL;
> +
>         /* This device is no longer needed */
> -       btd_service_connecting_complete(setup->ep->data->service, 0);
> +       btd_service_connecting_complete(req->data.accept_data.bap_data->service,
> +                       0);
>
>         fd = g_io_channel_unix_get_fd(io);
>
>         if (bt_bap_stream_set_io(setup->stream, fd)) {
> -               bt_bap_stream_enable(setup->stream, true, NULL, NULL, NULL);
>                 g_io_channel_set_close_on_unref(io, FALSE);
>                 return;
>         }
> @@ -1014,8 +1020,54 @@ static void print_ltv(size_t i, uint8_t l, uint8_t t, uint8_t *v,
>         util_hexdump(' ', v, l, user_data, NULL);
>  }
>
> -static bool parse_base(struct bt_bap *bap, struct bt_iso_base *base,
> -               util_debug_func_t func)
> +static void create_stream_for_bis(struct bap_data *bap_data,
> +               struct bt_bap_pac *lpac, struct bt_iso_qos *qos,
> +               struct iovec *caps, struct iovec *meta, char *path)
> +{
> +       struct bap_setup *setup;
> +
> +       setup = setup_new(NULL);
> +
> +       /* Create BAP QoS structure */
> +       setup->qos.bcast.big = qos->bcast.big;
> +       setup->qos.bcast.bis = qos->bcast.bis;
> +       setup->qos.bcast.sync_factor = qos->bcast.sync_factor;
> +       setup->qos.bcast.packing = qos->bcast.packing;
> +       setup->qos.bcast.framing = qos->bcast.framing;
> +       setup->qos.bcast.encryption = qos->bcast.encryption;
> +       if (setup->qos.bcast.encryption)
> +               util_iov_append(setup->qos.bcast.bcode,
> +                               qos->bcast.bcode,
> +                               sizeof(qos->bcast.bcode));
> +       setup->qos.bcast.options = qos->bcast.options;
> +       setup->qos.bcast.skip = qos->bcast.skip;
> +       setup->qos.bcast.sync_timeout = qos->bcast.sync_timeout;
> +       setup->qos.bcast.sync_cte_type =
> +                       qos->bcast.sync_cte_type;
> +       setup->qos.bcast.mse = qos->bcast.mse;
> +       setup->qos.bcast.timeout = qos->bcast.timeout;
> +       setup->qos.bcast.io_qos.interval =
> +                       qos->bcast.in.interval;
> +       setup->qos.bcast.io_qos.latency = qos->bcast.in.latency;
> +       setup->qos.bcast.io_qos.phy = qos->bcast.in.phy;
> +       setup->qos.bcast.io_qos.rtn = qos->bcast.in.rtn;
> +       setup->qos.bcast.io_qos.sdu = qos->bcast.in.sdu;
> +
> +       queue_push_tail(bap_data->bcast_snks, setup);
> +
> +       /* Create and configure stream */
> +       setup->stream = bt_bap_stream_new(bap_data->bap,
> +                       lpac, NULL, &setup->qos, caps);
> +
> +       bt_bap_stream_set_user_data(setup->stream, path);
> +       bt_bap_stream_config(setup->stream, &setup->qos,
> +                       caps, NULL, NULL);
> +       bt_bap_stream_metadata(setup->stream, meta,
> +                       NULL, NULL);
> +}
> +
> +static bool parse_base(struct bap_data *bap_data, struct bt_iso_base *base,
> +               struct bt_iso_qos *qos, util_debug_func_t func)
>  {
>         struct iovec iov = {
>                 .iov_base = base->base,
> @@ -1087,11 +1139,20 @@ static bool parse_base(struct bt_bap *bap, struct bt_iso_base *base,
>                 for (; num_bis; num_bis--) {
>                         uint8_t bis_index;
>                         struct iovec *l3_caps;
> +                       struct iovec *merged_caps;
> +                       struct bt_bap_pac *matched_lpac;
> +                       char *path;
> +                       int err;
>
>                         if (!util_iov_pull_u8(&iov, &bis_index))
>                                 goto fail;
>
>                         util_debug(func, NULL, "BIS #%d", bis_index);
> +                       err = asprintf(&path, "%s/bis%d",
> +                                       device_get_path(bap_data->device),
> +                                       bis_index);
> +                       if (err < 0)
> +                               continue;
>
>                         /* Read Codec Specific Configuration */
>                         l3_caps = new0(struct iovec, 1);
> @@ -1110,9 +1171,16 @@ static bool parse_base(struct bt_bap *bap, struct bt_iso_base *base,
>                                         l3_caps->iov_len, NULL, print_ltv,
>                                         func);
>
> -                       /* Try to create a PAC using this BIS information */
> -                       bt_bap_add_bis(bap, bis_index, &codec, l2_caps, l3_caps,
> -                                       meta);
> +                       /* 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);
> +
> +                       if (matched_lpac == NULL || merged_caps == NULL)
> +                               continue;
> +
> +                       create_stream_for_bis(bap_data, matched_lpac, qos,
> +                                       merged_caps, meta, path);
>                 }
>
>         }
> @@ -1155,7 +1223,9 @@ static void iso_pa_sync_confirm_cb(GIOChannel *io, void *user_data)
>         /* Analyze received BASE data and create remote media endpoints for each
>          * BIS matching our capabilities
>          */
> -       parse_base(data->bap, &base, bap_debug);
> +       parse_base(data, &base, &qos, bap_debug);
> +
> +       service_set_connecting(pa_req->data.service);
>  }
>
>  static bool match_data_bap_data(const void *data, const void *match_data)
> @@ -1558,6 +1628,7 @@ static struct bap_setup *bap_find_setup_by_stream(struct bap_data *data,
>                                         struct bt_bap_stream *stream)
>  {
>         struct bap_ep *ep = NULL;
> +       struct queue *queue = NULL;
>
>         switch (bt_bap_stream_get_type(stream)) {
>         case BT_BAP_STREAM_TYPE_UCAST:
> @@ -1572,9 +1643,11 @@ static struct bap_setup *bap_find_setup_by_stream(struct bap_data *data,
>         }
>
>         if (ep)
> -               return queue_find(ep->setups, match_setup_stream, stream);
> +               queue = ep->setups;
> +       else
> +               queue = data->bcast_snks;
>
> -       return NULL;
> +       return queue_find(queue, match_setup_stream, stream);
>  }
>
>  static void iso_connect_bcast_cb(GIOChannel *chan, GError *err,
> @@ -2097,7 +2170,8 @@ static void setup_accept_io_broadcast(struct bap_data *data,
>          */
>         pa_req->type = BAP_PA_BIG_SYNC_REQ;
>         pa_req->in_progress = FALSE;
> -       pa_req->data.setup = setup;
> +       pa_req->data.accept_data.setup = setup;
> +       pa_req->data.accept_data.bap_data = data;
>         queue_push_tail(bcast_pa_requests, pa_req);
>  }
>
> @@ -2157,7 +2231,7 @@ static void setup_create_bcast_io(struct bap_data *data,
>         memcpy(&iso_qos.bcast.out, &setup->qos.bcast.io_qos,
>                                 sizeof(struct bt_iso_io_qos));
>
> -       if (bt_bap_pac_get_type(setup->ep->lpac) == BT_BAP_BCAST_SOURCE)
> +       if (bt_bap_stream_get_dir(stream) == BT_BAP_BCAST_SINK)
>                 setup_connect_io_broadcast(data, setup, stream, &iso_qos,
>                         defer);
>         else
> @@ -2399,12 +2473,7 @@ static void bap_state_bcast(struct bt_bap_stream *stream, uint8_t old_state,
>                 if (!setup || setup->id)
>                         break;
>                 if (bt_bap_stream_io_dir(stream) ==
> -                               BT_BAP_BCAST_SOURCE)
> -                       /* If the stream is attached to a
> -                        * broadcast sink endpoint.
> -                        */
> -                       setup_create_io(data, setup, stream, defer);
> -               else {
> +                               BT_BAP_BCAST_SINK) {
>                         /* If the stream attached to a broadcast
>                          * source endpoint generate the base.
>                          */
> @@ -2455,6 +2524,14 @@ static void bap_state_bcast(struct bt_bap_stream *stream, uint8_t old_state,
>                         }
>                 }
>                 break;
> +       case BT_BAP_STREAM_STATE_ENABLING:
> +               if (bt_bap_stream_io_dir(stream) == BT_BAP_BCAST_SOURCE)
> +                       setup_create_io(data, setup, stream, defer);
> +               break;
> +       case BT_BAP_STREAM_STATE_RELEASING:
> +               if (bt_bap_stream_io_dir(stream) == BT_BAP_BCAST_SOURCE)
> +                       setup_io_close(setup, NULL);
> +               break;
>         }
>  }
>
> @@ -2794,6 +2871,7 @@ static int short_lived_pa_sync(struct bap_bcast_pa_req *req)
>                 error("BAP unable to attach");
>                 return -EINVAL;
>         }
> +       data->bcast_snks = queue_new();
>
>         bap_data_add(data);
>
> @@ -2833,29 +2911,41 @@ static void iso_do_big_sync(GIOChannel *io, void *user_data)
>  {
>         GError *err = NULL;
>         struct bap_bcast_pa_req *req = user_data;
> -       struct bap_setup *setup = req->data.setup;
> -       struct bap_data *data = setup->ep->data;
> +       struct bap_setup *setup = req->data.accept_data.setup;
> +       struct bap_data *data = req->data.accept_data.bap_data;
>         struct sockaddr_iso_bc iso_bc_addr;
>         struct bt_iso_qos qos;
> +       char *path;
> +       int bis_index = 1;
> +       char device_name[40] = {0};
> +       int s_err;
>
> -       DBG("PA Sync done, do BIG Sync");
> +       DBG("PA Sync done");
>         g_io_channel_unref(setup->io);
> -       setup->io = NULL;
> -
> +       g_io_channel_shutdown(setup->io, TRUE, NULL);
>         setup->io = io;
>         g_io_channel_ref(setup->io);
>
>         /* TODO
>          * We can only synchronize with a single BIS to a BIG.
>          * In order to have multiple BISes targeting this BIG we need to have
> -        * all the BISes before doing this request. This request is triggered
> -        * by an endpoint "SetConfiguration" command. For multiple BISes
> -        * we need another way to specify which BISes user is requesting
> +        * all the BISes before doing bt_io_bcast_accept.
> +        * This request comes from a transport "Acquire" call.
> +        * For multiple BISes in the same BIG we need to either wait for all
> +        * transports in the same BIG to be acquired or tell when to do the
> +        * bt_io_bcast_accept by other means
>          */
> +       path = bt_bap_stream_get_user_data(setup->stream);
> +       s_err = sscanf(path, "%s/bis%d", device_name, &bis_index);
> +       if (s_err == -1)
> +               DBG("sscanf error");
> +
> +       DBG("Do BIG Sync with BIS %d", bis_index);
> +
>         iso_bc_addr.bc_bdaddr_type = btd_device_get_bdaddr_type(data->device);
>         memcpy(&iso_bc_addr.bc_bdaddr, device_get_address(data->device),
>                         sizeof(bdaddr_t));
> -       iso_bc_addr.bc_bis[0] = 1;
> +       iso_bc_addr.bc_bis[0] = bis_index;
>         iso_bc_addr.bc_num_bis = 1;
>
>         /* Set the user requested QOS */
> @@ -2898,8 +2988,8 @@ static void iso_do_big_sync(GIOChannel *io, void *user_data)
>  static void pa_and_big_sync(struct bap_bcast_pa_req *req)
>  {
>         GError *err = NULL;
> -       struct bap_setup *setup = req->data.setup;
> -       struct bap_data *data = setup->ep->data;
> +       struct bap_setup *setup = req->data.accept_data.setup;
> +       struct bap_data *data = req->data.accept_data.bap_data;
>
>         req->in_progress = TRUE;
>
> diff --git a/src/shared/bap.c b/src/shared/bap.c
> index 8c4868f4bf9f..e69f6cec99bf 100644
> --- a/src/shared/bap.c
> +++ b/src/shared/bap.c
> @@ -226,6 +226,7 @@ struct bt_bap_stream_io {
>  struct bt_bap_stream_ops {
>         uint8_t type;
>         void (*set_state)(struct bt_bap_stream *stream, uint8_t state);
> +       unsigned int (*get_state)(struct bt_bap_stream *stream);
>         unsigned int (*config)(struct bt_bap_stream *stream,
>                                 struct bt_bap_qos *qos, struct iovec *data,
>                                 bt_bap_stream_func_t func, void *user_data);
> @@ -245,6 +246,8 @@ struct bt_bap_stream_ops {
>         unsigned int (*metadata)(struct bt_bap_stream *stream,
>                                 struct iovec *data, bt_bap_stream_func_t func,
>                                 void *user_data);
> +       unsigned int (*get_dir)(struct bt_bap_stream *stream);
> +       unsigned int (*get_loc)(struct bt_bap_stream *stream);
>         unsigned int (*release)(struct bt_bap_stream *stream,
>                                 bt_bap_stream_func_t func, void *user_data);
>  };
> @@ -1578,6 +1581,11 @@ done:
>         bap_stream_state_changed(stream);
>  }
>
> +static unsigned int bap_ucast_get_state(struct bt_bap_stream *stream)
> +{
> +       return stream->ep->state;
> +}
> +
>  static unsigned int bap_ucast_config(struct bt_bap_stream *stream,
>                                         struct bt_bap_qos *qos,
>                                         struct iovec *data,
> @@ -1923,6 +1931,27 @@ static bool bap_stream_valid(struct bt_bap_stream *stream)
>         return queue_find(stream->bap->streams, NULL, stream);
>  }
>
> +static unsigned int bap_ucast_get_dir(struct bt_bap_stream *stream)
> +{
> +       return stream->ep->dir;
> +}
> +
> +static unsigned int bap_ucast_get_location(struct bt_bap_stream *stream)
> +{
> +       struct bt_pacs *pacs;
> +
> +       if (!stream)
> +               return 0x00000000;
> +
> +       pacs = stream->client ? stream->bap->rdb->pacs : stream->bap->ldb->pacs;
> +
> +       if (stream->ep->dir == BT_BAP_SOURCE)
> +               return pacs->source_loc_value;
> +       else if (stream->ep->dir == BT_BAP_SINK)
> +               return pacs->sink_loc_value;
> +       return 0x00000000;
> +}
> +
>  static unsigned int bap_ucast_release(struct bt_bap_stream *stream,
>                                         bt_bap_stream_func_t func,
>                                         void *user_data)
> @@ -2000,6 +2029,11 @@ static void bap_bcast_set_state(struct bt_bap_stream *stream, uint8_t state)
>         }
>  }
>
> +static unsigned int bap_bcast_get_state(struct bt_bap_stream *stream)
> +{
> +       return stream->state;
> +}
> +
>  static unsigned int bap_bcast_enable(struct bt_bap_stream *stream,
>                                         bool enable_links, struct iovec *data,
>                                         bt_bap_stream_func_t func,
> @@ -2043,6 +2077,41 @@ static unsigned int bap_bcast_metadata(struct bt_bap_stream *stream,
>         return 1;
>  }
>
> +static unsigned int bap_bcast_get_dir(struct bt_bap_stream *stream)
> +{
> +       if (bt_bap_pac_get_type(stream->lpac) == BT_BAP_BCAST_SINK)
> +               return BT_BAP_BCAST_SOURCE;
> +       else
> +               return BT_BAP_BCAST_SINK;
> +}
> +
> +static void bap_sink_get_allocation(size_t i, uint8_t l, uint8_t t,
> +               uint8_t *v, void *user_data)
> +{
> +       uint32_t location32;
> +
> +       if (!v)
> +               return;
> +
> +       memcpy(&location32, v, l);
> +       *((uint32_t *)user_data) = le32_to_cpu(location32);
> +}
> +
> +static unsigned int bap_bcast_get_location(struct bt_bap_stream *stream)
> +{
> +       uint8_t type = BAP_CHANNEL_ALLOCATION_LTV_TYPE;
> +       uint32_t allocation = 0;
> +       struct iovec *caps;
> +
> +       caps = bt_bap_stream_get_config(stream);
> +
> +       /* Get stream allocation from capabilities */
> +       util_ltv_foreach(caps->iov_base, caps->iov_len, &type,
> +                       bap_sink_get_allocation, &allocation);
> +
> +       return allocation;
> +}
> +
>  static unsigned int bap_bcast_release(struct bt_bap_stream *stream,
>                                         bt_bap_stream_func_t func,
>                                         void *user_data)
> @@ -2052,11 +2121,12 @@ static unsigned int bap_bcast_release(struct bt_bap_stream *stream,
>         return 1;
>  }
>
> -#define STREAM_OPS(_type, _set_state, _config, _qos, _enable, _start, \
> -                       _disable, _stop, _metadata, _release) \
> +#define STREAM_OPS(_type, _set_state, _get_state, _config, _qos, _enable, \
> +       _start, _disable, _stop, _metadata, _get_dir, _get_loc, _release) \
>  { \
>         .type = _type, \
>         .set_state = _set_state, \
> +       .get_state = _get_state, \
>         .config = _config, \
>         .qos = _qos, \
>         .enable = _enable, \
> @@ -2064,26 +2134,40 @@ static unsigned int bap_bcast_release(struct bt_bap_stream *stream,
>         .disable = _disable, \
>         .stop = _stop, \
>         .metadata = _metadata, \
> +       .get_dir = _get_dir,\
> +       .get_loc = _get_loc, \
>         .release = _release, \
>  }
>
>  static const struct bt_bap_stream_ops stream_ops[] = {
>         STREAM_OPS(BT_BAP_SINK, bap_ucast_set_state,
> +                       bap_ucast_get_state,
>                         bap_ucast_config, bap_ucast_qos, bap_ucast_enable,
>                         bap_ucast_start, bap_ucast_disable, bap_ucast_stop,
> -                       bap_ucast_metadata, bap_ucast_release),
> +                       bap_ucast_metadata, bap_ucast_get_dir,
> +                       bap_ucast_get_location,
> +                       bap_ucast_release),
>         STREAM_OPS(BT_BAP_SOURCE, bap_ucast_set_state,
> +                       bap_ucast_get_state,
>                         bap_ucast_config, bap_ucast_qos, bap_ucast_enable,
>                         bap_ucast_start, bap_ucast_disable, bap_ucast_stop,
> -                       bap_ucast_metadata, bap_ucast_release),
> +                       bap_ucast_metadata, bap_ucast_get_dir,
> +                       bap_ucast_get_location,
> +                       bap_ucast_release),
>         STREAM_OPS(BT_BAP_BCAST_SINK, bap_bcast_set_state,
> +                       bap_bcast_get_state,
>                         bap_bcast_config, NULL, bap_bcast_enable,
>                         bap_bcast_start, bap_bcast_disable, NULL,
> -                       bap_bcast_metadata, bap_bcast_release),
> +                       bap_bcast_metadata, bap_bcast_get_dir,
> +                       bap_bcast_get_location,
> +                       bap_bcast_release),
>         STREAM_OPS(BT_BAP_BCAST_SOURCE, bap_bcast_set_state,
> +                       bap_bcast_get_state,
>                         bap_bcast_config, NULL, bap_bcast_enable,
>                         bap_bcast_start, bap_bcast_disable, NULL,
> -                       bap_bcast_metadata, bap_bcast_release),
> +                       bap_bcast_metadata, bap_bcast_get_dir,
> +                       bap_bcast_get_location,
> +                       bap_bcast_release),
>  };
>
>  static const struct bt_bap_stream_ops *
> @@ -5383,11 +5467,7 @@ uint8_t bt_bap_stream_get_state(struct bt_bap_stream *stream)
>         if (!stream)
>                 return BT_BAP_STREAM_STATE_IDLE;
>
> -       if (stream->lpac->type != BT_BAP_BCAST_SOURCE &&
> -                       stream->lpac->type != BT_BAP_BCAST_SINK)
> -               return stream->ep->state;
> -       else
> -               return stream->state;
> +       return stream->ops->get_state(stream);
>  }
>
>  bool bt_bap_stream_set_user_data(struct bt_bap_stream *stream, void *user_data)
> @@ -5571,53 +5651,15 @@ uint8_t bt_bap_stream_get_dir(struct bt_bap_stream *stream)
>         if (!stream)
>                 return 0x00;
>
> -       if (stream->ep)
> -               return stream->ep->dir;
> -
> -       if (bt_bap_pac_get_type(stream->lpac) == BT_BAP_BCAST_SINK)
> -               return BT_BAP_BCAST_SOURCE;
> -       else
> -               return BT_BAP_BCAST_SINK;
> -}
> -
> -static void bap_sink_get_allocation(size_t i, uint8_t l, uint8_t t,
> -               uint8_t *v, void *user_data)
> -{
> -       uint32_t location32;
> -
> -       if (!v)
> -               return;
> -
> -       memcpy(&location32, v, l);
> -       *((uint32_t *)user_data) = le32_to_cpu(location32);
> +       return stream->ops->get_dir(stream);
>  }
>
>  uint32_t bt_bap_stream_get_location(struct bt_bap_stream *stream)
>  {
> -       struct bt_pacs *pacs;
> -       uint8_t type = BAP_CHANNEL_ALLOCATION_LTV_TYPE;
> -       uint32_t allocation = 0;
> -       struct iovec *caps;
> -
>         if (!stream)
>                 return 0x00000000;
>
> -       pacs = stream->client ? stream->bap->rdb->pacs : stream->bap->ldb->pacs;
> -
> -       if (stream->ep) {
> -               if (stream->ep->dir == BT_BAP_SOURCE)
> -                       return pacs->source_loc_value;
> -               else if (stream->ep->dir == BT_BAP_SINK)
> -                       return pacs->sink_loc_value;
> -       }
> -
> -       caps = bt_bap_stream_get_config(stream);
> -
> -       /* Get stream allocation from capabilities */
> -       util_ltv_foreach(caps->iov_base, caps->iov_len, &type,
> -                       bap_sink_get_allocation, &allocation);
> -
> -       return allocation;
> +       return stream->ops->get_loc(stream);
>  }
>
>  struct iovec *bt_bap_stream_get_config(struct bt_bap_stream *stream)
> @@ -6459,17 +6501,13 @@ static struct bt_ltv_match bap_check_bis(struct bt_bap_db *ldb,
>         return compare_data;
>  }
>
> -void bt_bap_add_bis(struct bt_bap *bap, uint8_t bis_index,
> +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 iovec *meta)
> +               struct bt_bap_pac **lpac,
> +               struct iovec **caps)
>  {
> -       struct bt_bap_pac *pac_source_bis;
> -       struct bt_bap_endpoint *ep;
> -       int err = 0;
> -       struct bt_bap_pac_qos bis_qos = {0};
> -       uint8_t type = 0;
>         struct bt_ltv_extract merge_data = {0};
>         struct bt_ltv_match match_data = {0};
>
> @@ -6488,43 +6526,14 @@ void bt_bap_add_bis(struct bt_bap *bap, uint8_t bis_index,
>          * Specific Capabilities and if the BIS matches create a PAC with it
>          */
>         match_data = bap_check_bis(bap->ldb, merge_data.result);
> -       if (match_data.found == false)
> -               goto cleanup;
> -
> -       DBG(bap, "Matching BIS %i", bis_index);
> -
> -       /* Create a QoS structure based on the received BIS information to
> -        * specify the desired channel for this BIS/PAC
> -        */
> -       type = BAP_CHANNEL_ALLOCATION_LTV_TYPE;
> -       util_ltv_foreach(merge_data.result->iov_base,
> -                       merge_data.result->iov_len, &type,
> -                       bap_sink_get_allocation, &bis_qos.location);
> -
> -       /* Create a remote PAC */
> -       pac_source_bis = bap_pac_new(bap->rdb, NULL,
> -                               BT_BAP_BCAST_SOURCE, codec, &bis_qos,
> -                               merge_data.result, meta);
> -
> -       err = asprintf(&pac_source_bis->name, "%d", bis_index);
> -
> -       if (err < 0) {
> -               DBG(bap, "error in asprintf");
> -               goto cleanup;
> +       if (match_data.found == true) {
> +               *caps = merge_data.result;
> +               *lpac = match_data.data;
> +               DBG(bap, "Matching BIS %i", bis_index);
> +       } else {
> +               util_iov_free(merge_data.result, 1);
> +               *caps = NULL;
> +               *lpac = NULL;
>         }
>
> -       /* Add remote source endpoint */
> -       if (!bap->rdb->broadcast_sources)
> -               bap->rdb->broadcast_sources = queue_new();
> -       queue_push_tail(bap->rdb->broadcast_sources, pac_source_bis);
> -
> -       queue_foreach(bap->pac_cbs, notify_pac_added, pac_source_bis);
> -       /* Push remote endpoint with direction sink */
> -       ep = bap_endpoint_new_broadcast(bap->rdb, BT_BAP_BCAST_SINK);
> -
> -       if (ep)
> -               queue_push_tail(bap->remote_eps, ep);
> -
> -cleanup:
> -       util_iov_free(merge_data.result, 1);
>  }
> diff --git a/src/shared/bap.h b/src/shared/bap.h
> index 62e2104850c7..35524df0b451 100644
> --- a/src/shared/bap.h
> +++ b/src/shared/bap.h
> @@ -251,9 +251,9 @@ 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);
>
> -void bt_bap_add_bis(struct bt_bap *bap, uint8_t bis_index,
> +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 iovec *meta);
> -
> +               struct bt_bap_pac **lpac,
> +               struct iovec **caps);
> --
> 2.40.1
>


-- 
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH BlueZ 3/5] shared/bap: Update stream management to avoid PACs
  2024-04-19 18:07 ` [PATCH BlueZ 3/5] shared/bap: Update stream management to avoid PACs Andrei Istodorescu
@ 2024-04-19 19:31   ` Luiz Augusto von Dentz
  0 siblings, 0 replies; 10+ messages in thread
From: Luiz Augusto von Dentz @ 2024-04-19 19:31 UTC (permalink / raw
  To: Andrei Istodorescu
  Cc: linux-bluetooth, mihai-octavian.urzica, silviu.barbulescu,
	vlad.pruteanu, iulia.tanasescu

Hi Andrei,

On Fri, Apr 19, 2024 at 2:08 PM Andrei Istodorescu
<andrei.istodorescu@nxp.com> wrote:
>
> Set the stream to enabling for BAP Broadcast Sink, when the transport is
> acquired.
> Remove PAC logic for BAP Broadcast Sink stream creation.
> ---
>  src/shared/bap.c | 60 +++++-------------------------------------------
>  1 file changed, 6 insertions(+), 54 deletions(-)
>
> diff --git a/src/shared/bap.c b/src/shared/bap.c
> index 36f0b0a3b50a..d7a2f9381c53 100644
> --- a/src/shared/bap.c
> +++ b/src/shared/bap.c
> @@ -2006,7 +2006,7 @@ static unsigned int bap_bcast_enable(struct bt_bap_stream *stream,
>                                         void *user_data)
>  {
>         if (bt_bap_stream_io_dir(stream) == BT_BAP_BCAST_SOURCE)
> -               stream_set_state(stream, BT_BAP_STREAM_STATE_STREAMING);
> +               stream_set_state(stream, BT_BAP_STREAM_STATE_ENABLING);

There is no Enabling state for Broadcast Stream in BAP:

https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/16212-BAP-html5/out/en/index-en.html#UUID-4a295bf2-6e50-be11-e827-c23e63569087_figure-idm4631863059107233170457600297

>         else
>                 stream_set_state(stream, BT_BAP_STREAM_STATE_CONFIG);
>
> @@ -5287,7 +5287,6 @@ void bt_bap_cancel_select(struct bt_bap_pac *lpac, bt_bap_pac_select_t func,
>
>  static struct bt_bap_stream *bap_bcast_stream_new(struct bt_bap *bap,
>                                         struct bt_bap_pac *lpac,
> -                                       struct bt_bap_pac *rpac,
>                                         struct bt_bap_qos *pqos,
>                                         struct iovec *data)
>  {
> @@ -5298,71 +5297,24 @@ static struct bt_bap_stream *bap_bcast_stream_new(struct bt_bap *bap,
>         if (!bap)
>                 return NULL;
>
> -       if (!rpac && (lpac->type != BT_BAP_BCAST_SOURCE)
> -               && queue_isempty(bap->remote_eps))
> -               return NULL;
> -
> -       if (lpac && rpac) {
> -               if ((rpac->type != BT_BAP_BCAST_SOURCE)
> -                       && (!bap_codec_equal(&lpac->codec, &rpac->codec)))
> -                       return NULL;
> -       } else {
> -               uint8_t type;
> -
> +       if (lpac->type == BT_BAP_BCAST_SOURCE) {
>                 match.lpac = lpac;
> -               match.rpac = rpac;
> +               match.rpac = NULL;
>                 memset(&match.codec, 0, sizeof(match.codec));
>
> -               if (rpac)
> -                       type = rpac->type;
> -               else if (lpac) {
> -                       switch (lpac->type) {
> -                       case BT_BAP_BCAST_SOURCE:
> -                               type = BT_BAP_BCAST_SINK;
> -                               break;
> -                       case BT_BAP_BCAST_SINK:
> -                               type = BT_BAP_BCAST_SOURCE;
> -                               break;
> -                       default:
> -                               return NULL;
> -                       }
> -               } else
> -                       return NULL;
> -
> -               bt_bap_foreach_pac(bap, type, match_pac, &match);
> +               bt_bap_foreach_pac(bap, BT_BAP_BCAST_SINK, match_pac, &match);
>                 if ((!match.lpac) || (!lpac))
>                         return NULL;
> -               if (!match.rpac && (lpac->type != BT_BAP_BCAST_SOURCE))
> -                       return NULL;
>
>                 lpac = match.lpac;
> -               rpac = match.rpac;
> -       }
> -
> -       match.lpac = lpac;
> -       match.rpac = rpac;
>
> -       if (lpac->type != BT_BAP_BCAST_SOURCE) {
> -               /* Check for existing stream */
> -               ep = queue_find(bap->remote_eps, find_ep_pacs, &match);
> -               if (!ep) {
> -                       /* Check for unused ASE */
> -                       ep = queue_find(bap->remote_eps, find_ep_unused,
> -                                       &match);
> -                       if (!ep) {
> -                               DBG(bap, "Unable to find unused ASE");
> -                               return NULL;
> -                       }
> -               }
> -               stream = ep->stream;
> -       } else {
>                 ep = queue_find(bap->remote_eps, find_ep_source, NULL);
>                 if (!ep)
>                         return NULL;
>         }
>
>         if (!stream)
> -               stream = bap_stream_new(bap, ep, lpac, rpac, data, true);
> +               stream = bap_stream_new(bap, ep, lpac, NULL, data, true);
>
>         return stream;
>  }
> @@ -5415,7 +5367,7 @@ struct bt_bap_stream *bt_bap_stream_new(struct bt_bap *bap,
>         if (bt_bap_get_att(bap))
>                 return bap_ucast_stream_new(bap, lpac, rpac, pqos, data);
>
> -       return bap_bcast_stream_new(bap, lpac, rpac, pqos, data);
> +       return bap_bcast_stream_new(bap, lpac, pqos, data);
>  }
>
>  struct bt_bap *bt_bap_stream_get_session(struct bt_bap_stream *stream)
> --
> 2.40.1
>


-- 
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: Create transports for matching BISes
  2024-04-19 18:07 ` [PATCH BlueZ 1/5] shared/bap: Allow NULL bap endpoint in streams Andrei Istodorescu
@ 2024-04-19 21:16   ` bluez.test.bot
  0 siblings, 0 replies; 10+ messages in thread
From: bluez.test.bot @ 2024-04-19 21:16 UTC (permalink / raw
  To: linux-bluetooth, andrei.istodorescu

[-- Attachment #1: Type: text/plain, Size: 3866 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=846208

---Test result---

Test Summary:
CheckPatch                    PASS      2.49 seconds
GitLint                       PASS      1.56 seconds
BuildEll                      PASS      24.81 seconds
BluezMake                     PASS      1572.58 seconds
MakeCheck                     PASS      12.93 seconds
MakeDistcheck                 PASS      175.06 seconds
CheckValgrind                 PASS      245.01 seconds
CheckSmatch                   WARNING   348.03 seconds
bluezmakeextell               PASS      121.49 seconds
IncrementalBuild              PASS      7288.83 seconds
ScanBuild                     WARNING   973.23 seconds

Details
##############################
Test: CheckSmatch - WARNING
Desc: Run smatch tool with source
Output:
src/shared/bap.c:285: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:285: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:285: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:285: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:285: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:285: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:285: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:285: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:285: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:285: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:285: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:285: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:285: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:285: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:285:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structures
##############################
Test: ScanBuild - WARNING
Desc: Run Scan Build
Output:
src/shared/bap.c:6512:22: warning: Value stored to 'match_data' during its initialization is never read
        struct bt_ltv_match match_data = {0};
                            ^~~~~~~~~~   ~~~
1 warning generated.



---
Regards,
Linux Bluetooth


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH BlueZ 0/5] Create transports for matching BISes
  2024-04-19 18:07 [PATCH BlueZ 0/5] Create transports for matching BISes Andrei Istodorescu
                   ` (4 preceding siblings ...)
  2024-04-19 18:07 ` [PATCH BlueZ 5/5] bap: Create streams and transports for each matching BIS Andrei Istodorescu
@ 2024-04-23 17:40 ` patchwork-bot+bluetooth
  5 siblings, 0 replies; 10+ messages in thread
From: patchwork-bot+bluetooth @ 2024-04-23 17:40 UTC (permalink / raw
  To: Andrei Istodorescu
  Cc: linux-bluetooth, luiz.dentz, mihai-octavian.urzica,
	silviu.barbulescu, vlad.pruteanu, iulia.tanasescu

Hello:

This series was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:

On Fri, 19 Apr 2024 21:07:47 +0300 you wrote:
> This patch refactors the flow for the BAP Broadcast Sink.
> After observing the BASE information, streams and transports will be
> generated for each BIS that matches local PAC capabilities.
> Because endpoints are not available any more, local PAC (which contain
> local registered capabilities) has a new list of setups. Each setup is
> generated based on the matching BIS observed.
> Then, the setup is used to configure a stream which then generates a
> MediaTransport.
> The transport is in the TRANSPORT_STATE_IDLE state until someone
> acquires it. The "Acquire" procedure results in creating the IO using
> BIG Create Sync. The successful reply of it causes the transport to be
> advanced in TRANSPORT_STATE_ACTIVE state.
> 
> [...]

Here is the summary with links:
  - [BlueZ,1/5] shared/bap: Allow NULL bap endpoint in streams
    https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=5b4d9abfdeee
  - [BlueZ,2/5] shared/bap: Get broadcast channel location from stream capabilities
    https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=30b741baa569
  - [BlueZ,3/5] shared/bap: Update stream management to avoid PACs
    (no matching commit)
  - [BlueZ,4/5] shared/bap: In case of a BIS-PAC match return also the local pac
    (no matching commit)
  - [BlueZ,5/5] bap: Create streams and transports for each matching BIS
    (no matching commit)

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] 10+ messages in thread

end of thread, other threads:[~2024-04-23 17:40 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-04-19 18:07 [PATCH BlueZ 0/5] Create transports for matching BISes Andrei Istodorescu
2024-04-19 18:07 ` [PATCH BlueZ 1/5] shared/bap: Allow NULL bap endpoint in streams Andrei Istodorescu
2024-04-19 21:16   ` Create transports for matching BISes bluez.test.bot
2024-04-19 18:07 ` [PATCH BlueZ 2/5] shared/bap: Get broadcast channel location from stream capabilities Andrei Istodorescu
2024-04-19 18:07 ` [PATCH BlueZ 3/5] shared/bap: Update stream management to avoid PACs Andrei Istodorescu
2024-04-19 19:31   ` Luiz Augusto von Dentz
2024-04-19 18:07 ` [PATCH BlueZ 4/5] shared/bap: In case of a BIS-PAC match return also the local pac Andrei Istodorescu
2024-04-19 18:07 ` [PATCH BlueZ 5/5] bap: Create streams and transports for each matching BIS Andrei Istodorescu
2024-04-19 19:28   ` Luiz Augusto von Dentz
2024-04-23 17:40 ` [PATCH BlueZ 0/5] Create transports for matching BISes 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 read-only IMAP folder(s) and NNTP newsgroup(s).