diff mbox series

[BlueZ,v2,08/15] shared/bap: Fix not always sending Releasing state

Message ID 20250407200124.881534-9-luiz.dentz@gmail.com
State New
Headers show
Series BAP Server test cases | expand

Commit Message

Luiz Augusto von Dentz April 7, 2025, 8:01 p.m. UTC
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

In order for states to be sent the stream cannot be freed since
pending_states could be pending due to be processing a CP operation, so
this attempts to grap a reference to the stream so it is not freed
while states are pending.
---
 src/shared/bap.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)
diff mbox series

Patch

diff --git a/src/shared/bap.c b/src/shared/bap.c
index 650bea2f4e8d..dbeb43fe509d 100644
--- a/src/shared/bap.c
+++ b/src/shared/bap.c
@@ -1130,11 +1130,9 @@  static void stream_notify_release(struct bt_bap_stream *stream)
 
 	DBG(stream->bap, "stream %p", stream);
 
-
 	memset(&status, 0, sizeof(status));
 	status.id = ep->id;
-	ep->state = BT_BAP_STREAM_STATE_RELEASING;
-	status.state = ep->state;
+	status.state = BT_ASCS_ASE_STATE_RELEASING;
 
 	gatt_db_attribute_notify(ep->attr, (void *)&status, sizeof(status),
 					bt_bap_get_att(stream->bap));
@@ -1283,8 +1281,10 @@  static void bap_abort_stream_req(struct bt_bap *bap,
 	queue_remove_all(bap->reqs, match_req_stream, stream, bap_req_abort);
 }
 
-static void bt_bap_stream_unref(struct bt_bap_stream *stream)
+static void bt_bap_stream_unref(void *data)
 {
+	struct bt_bap_stream *stream = data;
+
 	if (!stream)
 		return;
 
@@ -1308,7 +1308,6 @@  static void bap_ucast_detach(struct bt_bap_stream *stream)
 	queue_remove(stream->bap->streams, stream);
 	bap_stream_clear_cfm(stream);
 
-	stream->ep = NULL;
 	ep->stream = NULL;
 	bt_bap_stream_unref(stream);
 }
@@ -1751,6 +1750,16 @@  static bool stream_notify_state(void *data)
 	return false;
 }
 
+static struct bt_bap_stream *bt_bap_stream_ref(struct bt_bap_stream *stream)
+{
+	if (!stream)
+		return NULL;
+
+	__sync_fetch_and_add(&stream->ref_count, 1);
+
+	return stream;
+}
+
 static void bap_ucast_set_state(struct bt_bap_stream *stream, uint8_t state)
 {
 	struct bt_bap_endpoint *ep = stream->ep;
@@ -1771,7 +1780,8 @@  static void bap_ucast_set_state(struct bt_bap_stream *stream, uint8_t state)
 	else if (!stream->state_id)
 		stream->state_id = timeout_add(BAP_PROCESS_TIMEOUT,
 						stream_notify_state,
-						stream, NULL);
+						bt_bap_stream_ref(stream),
+						bt_bap_stream_unref);
 	else /* If a state_id is already pending then queue the old one */
 		queue_push_tail(stream->pending_states,
 				UINT_TO_PTR(ep->old_state));
@@ -2258,16 +2268,6 @@  static unsigned int bap_ucast_release(struct bt_bap_stream *stream,
 	return req->id;
 }
 
-static struct bt_bap_stream *bt_bap_stream_ref(struct bt_bap_stream *stream)
-{
-	if (!stream)
-		return NULL;
-
-	__sync_fetch_and_add(&stream->ref_count, 1);
-
-	return stream;
-}
-
 static void bap_bcast_set_state(struct bt_bap_stream *stream, uint8_t state)
 {
 	struct bt_bap *bap = stream->bap;