Hi Luzi,
[ EXTERNAL EMAIL ]
Hi,
On Mon, Jun 30, 2025 at 4:04 AM Yang Li via B4 Relay
<devnull+yang.li.amlogic.com@xxxxxxxxxx> wrote:
From: Yang Li <yang.li@xxxxxxxxxxx>
Add a state check so that stream_disable() is a no-op when the stream
is not in ENABLING or STREAMING state. This prevents unexpected state
transitions or redundant operations during cleanup.
Signed-off-by: Yang Li <yang.li@xxxxxxxxxxx>
---
src/shared/bap.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/shared/bap.c b/src/shared/bap.c
index 984ae782d..5445ddd14 100644
--- a/src/shared/bap.c
+++ b/src/shared/bap.c
@@ -2134,10 +2134,14 @@ static uint8_t stream_disable(struct bt_bap_stream *stream, struct iovec *rsp)
/* Sink can autonomously transit to QOS while source needs to go to
* Disabling until BT_ASCS_STOP is received.
*/
- if (stream->ep->dir == BT_BAP_SINK)
+ if (stream->ep->dir == BT_BAP_SINK &&
+ (stream->ep->state == BT_ASCS_ASE_STATE_ENABLING ||
+ stream->ep->state == BT_ASCS_ASE_STATE_STREAMING))
stream_set_state(stream, BT_BAP_STREAM_STATE_QOS);
- if (stream->ep->dir == BT_BAP_SOURCE)
+ if (stream->ep->dir == BT_BAP_SOURCE &&
+ (stream->ep->state == BT_ASCS_ASE_STATE_ENABLING ||
+ stream->ep->state == BT_ASCS_ASE_STATE_STREAMING))
stream_set_state(stream, BT_BAP_STREAM_STATE_DISABLING);
return 0;
Well we are doing:
if (!stream || stream->ep->state == BT_BAP_STREAM_STATE_QOS ||
stream->ep->state == BT_BAP_STREAM_STATE_IDLE)
return 0;
And on ep_disable we have:
switch (ep->state) {
/* Valid only if ASE_State field = 0x03 (Enabling) */
case BT_ASCS_ASE_STATE_ENABLING:
/* or 0x04 (Streaming) */
case BT_ASCS_ASE_STATE_STREAMING:
break;
default:
DBG(stream->bap, "Invalid state %s",
bt_bap_stream_statestr(ep->state));
ascs_ase_rsp_add(rsp, ep->id,
BT_ASCS_RSP_INVALID_ASE_STATE,
BT_ASCS_REASON_NONE);
return 0;
}
Perhaps on bap_ucast_disable we shall actually call ep_disale rather
than stream disable directly, that said I wonder why stream_disable
change is suggested here since you were attempting to fix broadcast
and for the likes of bt_bap_stream_disable it shall result in
bap_bcast_disable which doesn't call stream_disable:
static unsigned int bap_bcast_disable(struct bt_bap_stream *stream,
bool disable_links,
bt_bap_stream_func_t func,
void *user_data)
{
bap_stream_io_detach(stream);
stream_set_state(stream, BT_BAP_STREAM_STATE_CONFIG);
return 1;
}
This patch addresses an issue where, after the CIS link is disconnected,
the ASE state incorrectly transitions from config to QoS, which can
cause the CIS client to behave unexpectedly. Detailed discussion can be
found below:
https://lore.kernel.org/all/3ac16d0a7c5569bce0b28f18bc2245bef8ab64c2.camel@xxxxxx/
Alternatively, the patch can be refined as follows:
@@ -2131,14 +2131,20 @@ static uint8_t stream_disable(struct
bt_bap_stream *stream, struct iovec *rsp)
ascs_ase_rsp_success(rsp, stream->ep->id);
- /* Sink can autonomously transit to QOS while source needs to go to
- * Disabling until BT_ASCS_STOP is received.
- */
- if (stream->ep->dir == BT_BAP_SINK)
- stream_set_state(stream, BT_BAP_STREAM_STATE_QOS);
-
- if (stream->ep->dir == BT_BAP_SOURCE)
- stream_set_state(stream, BT_BAP_STREAM_STATE_DISABLING);
+ switch (stream->ep->state) {
+ case BT_ASCS_ASE_STATE_ENABLING:
+ case BT_ASCS_ASE_STATE_STREAMING:
+ if (stream->ep->dir == BT_BAP_SINK)
+ stream_set_state(stream,
BT_BAP_STREAM_STATE_QOS);
+ else if (stream->ep->dir == BT_BAP_SOURCE)
+ /* Sink can autonomously transit to QOS
while source needs to go to
+ * Disabling until BT_ASCS_STOP is received.
+ */
+ stream_set_state(stream,
BT_BAP_STREAM_STATE_DISABLING);
+ break;
+ default:
+ break;
+ }
return 0;
}
--
2.42.0
--
Luiz Augusto von Dentz