Re: [PATCH BlueZ bluez v2 2/2] shared/bap: Add stream state check in stream_disable

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux