Hi, to, 2025-06-26 kello 12:19 +0800, Yang Li kirjoitti: > Hi Pauli, > > [ EXTERNAL EMAIL ] > > > > Hi, > > > > ke, 2025-06-25 kello 13:24 +0800, Yang Li kirjoitti: > > > > [clip] > > > When music is paused on the pixel 9 phone, the CIS link gets > > > disconnected. As the transport state changes from ACTIVE to IDLE, the > > > stream state transitions from config to qos. > > > > > > > HCI Event: Disconnect Complete (0x05) plen 4 #1425 [hci0] > > > 49.572089 > > > Status: Success (0x00) > > > Handle: 512 Address: 6A:AB:51:47:3B:80 (Resolvable) > > > Identity type: Random (0x01) > > > Identity: E8:D5:2B:59:57:A6 (Static) > > > Reason: Remote User Terminated Connection (0x13) > > > bluetoothd[2313]: src/shared/bap.c:stream_io_disconnected() stream > > > 0x1f9fc20 io disconnected > > > bluetoothd[2313]: src/shared/bap.c:bap_ucast_set_state() stream > > > 0x1f9fc20 dir 0x01: releasing -> config > > > bluetoothd[2313]: src/shared/bap.c:stream_notify() stream 0x1f9fc20 > > > state 1 > > > bluetoothd[2313]: profiles/audio/transport.c:bap_state_changed() > > > stream 0x1f9fc20: releasing(6) -> config(1) > > > bluetoothd[2313]: > > > profiles/audio/transport.c:transport_update_playing() > > > /org/bluez/hci0/dev_6A_AB_51_47_3B_80/fd1 State=TRANSPORT_STATE_ACTIVE > > > Playing=0 > > > bluetoothd[2313]: > > > profiles/audio/transport.c:media_transport_remove_owner() Transport > > > /org/bluez/hci0/dev_6A_AB_51_47_3B_80/fd1 Owner :1.1 > > > bluetoothd[2313]: profiles/audio/transport.c:media_owner_free() Owner > > > :1.1 > > > bluetoothd[2313]: > > > profiles/audio/transport.c:media_transport_suspend() Transport > > > /org/bluez/hci0/dev_6A_AB_51_47_3B_80/fd1 Owner > > > bluetoothd[2313]: profiles/audio/transport.c:transport_set_state() > > > State changed /org/bluez/hci0/dev_6A_AB_51_47_3B_80/fd1: > > > TRANSPORT_STATE_ACTIVE -> TRANSPORT_STATE_IDLE > > > bluetoothd[2313]: src/shared/bap.c:stream_disable() stream 0x1f9fc20 > > AFAICS the bug appears to be: > > > > - bap.c:stream_disable() should do nothing if stream is > > not ENABLING or STREAMING > > > > since it's called from bt_bap_stream_disable() which is called on > > transport suspend which should be noop for BAP server if stream is > > already gone. > > Following your suggestion, I updated the |stream_disable()| function, > which successfully resolved the issue. > > --- a/src/shared/bap.c > +++ b/src/shared/bap.c > @@ -2059,7 +2059,9 @@ 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); Same applies to BT_BAP_SOURCE too. Only the check on top of function needs change. > > > > bluetoothd[2313]: src/shared/bap.c:bap_ucast_set_state() stream > > > 0x1f9fc20 dir 0x01: config -> qos > > > ATTbluetoothd[2313]: < ACL Data TX: H.. flags 0x00 dlen 51 #1426 > > > [hci0] 49.585656 > > > ATT: Handle Value Notification (0x1b) len 46 > > > Handle: 0x007b Type: Sink ASE (0x2bc4) > > > Data[44]: > > > 01010002050a00204e00409c00204e00409c0006000000001302010302020105030300000003042800020501 > > > ASE ID: 1 > > > State: Codec Configured (0x01) > > > Framing: Unframed PDUs supported (0x00) > > > PHY: 0x02 > > > LE 2M PHY preffered (0x02) > > > RTN: 5 > > > Max Transport Latency: 10 > > > Presentation Delay Min: 20000 us > > > ... > > > bluetoothd[2313]: < ACL Data TX: H.. flags 0x00 dlen 24 #1427 [hci0] > > > 49.585725 > > > ATT: Handle Value Notification (0x1b) len 19 > > > Handle: 0x007b Type: Sink ASE (0x2bc4) > > > Data[17]: 0102010010270000025000050a00204e00 > > > ASE ID: 1 > > > State: QoS Configured (0x02) > > > CIG ID: 0x01 > > > CIS ID: 0x00 > > > ... > > > > > > when playback resumes on the phone, it attempts to set the ASE state to > > > Codec. However, since the stream has already transitioned from config to > > > qos, the phone ends up disconnecting the connection. > > > > > > bluetoothd[2313]: < ACL Data TX: H.. flags 0x00 dlen 12 #1433 [hci0] > > > 60.216004 > > > ATT: Handle Value Notification (0x1b) len 7 > > > Handle: 0x0087 Type: ASE Control Point (0x2bc6) > > > Data[5]: 0101010000 > > > Opcode: Codec Configuration (0x01) > > > Number of ASE(s): 1 > > > ASE: #0 > > > ASE ID: 0x01 > > > ASE Response Code: Success (0x00) > > > ASE Response Reason: None (0x00) > > > bluetoothd[2313]: < ACL Data TX: H.. flags 0x00 dlen 51 #1434 [hci0] > > > 60.226086 > > > ATT: Handle Value Notification (0x1b) len 46 > > > Handle: 0x007b Type: Sink ASE (0x2bc4) > > > Data[44]: > > > 01010002050a00204e00409c00204e00409c0006000000001302010302020105030300000003042800020501 > > > ASE ID: 1 > > > State: Codec Configured (0x01) > > > Framing: Unframed PDUs supported (0x00) > > > PHY: 0x02 > > > LE 2M PHY preffered (0x02) > > > RTN: 5 > > > Max Transport Latency: 10 > > > Presentation Delay Min: 20000 us > > > Presentation Delay Max: 40000 us > > > Preferred Presentation Delay Min: 20000 us > > > Preferred Presentation Delay Max: 40000 us > > > Codec: LC3 (0x06) > > > Codec Specific Configuration: #0: len 0x02 type 0x01 > > > Sampling Frequency: 16 Khz (0x03) > > > Codec Specific Configuration: #1: len 0x02 type 0x02 > > > Frame Duration: 10 ms (0x01) > > > Codec Specific Configuration: #2: len 0x05 type 0x03 > > > Location: 0x00000003 > > > Front Left (0x00000001) > > > Front Right (0x00000002) > > > Codec Specific Configuration: #3: len 0x03 type 0x04 > > > Frame Length: 40 (0x0028) > > > Codec Specific Configuration: #4: len 0x02 type 0x05 > > > Frame Blocks per SDU: 1 (0x01) > > > > > > ... > > > > > > > HCI Event: Disconnect Complete (0x05) plen 4 #1445 [hci0] > > > 63.651497 > > > Status: Success (0x00) > > > Handle: 16 Address: 6A:AB:51:47:3B:80 (Resolvable) > > > Identity type: Random (0x01) > > > Identity: E8:D5:2B:59:57:A6 (Static) > > > Reason: Remote User Terminated Connection (0x13) > > > > > > Introducing a check in the stream logic to distinguish between Unicast > > > and Broadcast would indeed make it easier to handle different stream > > > types cleanly. > > > However, if we temporarily ignore Unicast caching, a simpler and cleaner > > > approach would be to transition the stream directly to IDLE when I/O is > > > disconnected. > > This disconnect callback is used for all the roles: unicast client, > > unicast server, broadcast. All of those require different handling, so > > it's probably most clear to split it. > > > > > > For unicast server: > > > > The behavior has to follow BAP v1.0.2 Sec. 5.6.8 and ASCS Table 3.2. > > Transition to IDLE is only allowed from RELEASING --- but one can as > > well go to CONFIG like it is in current master. > > > > CIS loss from STREAMING should go to QOS, and I think it currently does > > so, via bap_stream_set_io. > > > > From a brief look, the current version in master is maybe OK, although > > one could test the above case again with stream_disable() fix. > > > > > > For unicast client: > > > > The current version in master is probably OK, although one could double > > check it again. > > > I've added type checking and made the following modifications. Please > check if this meets the requirements. I believe that unicast source and > broadcast source are active behaviors, so there's no need to change the > stream state through I/O status. Please don't change the unicast behavior, unless you are fixing a deviation from the specification, or can explicitly show there is no change in behavior. I understand this patch is about fixing the behavior on BIS loss. > @@ -6584,10 +6584,15 @@ static bool stream_io_disconnected(struct io > *io, void *user_data) > > DBG(stream->bap, "stream %p io disconnected", stream); > > - if (stream->ep->state == BT_ASCS_ASE_STATE_RELEASING) > + if (stream->lpac->type == BT_BAP_SINK && > + bt_bap_stream_get_state(stream) == > BT_ASCS_ASE_STATE_RELEASING) { > stream_set_state(stream, BT_BAP_STREAM_STATE_CONFIG); > + bt_bap_stream_set_io(stream, -1); > + } > + > + if (stream->lpac->type == BT_BAP_BCAST_SINK) > + stream_set_state(stream, BT_BAP_STREAM_STATE_IDLE); > > - bt_bap_stream_set_io(stream, -1); This doesn't look right vs. unicast server. What performs the transitions to IDLE/CONFIG/QOS for unicast Source? See BAP Sec 5.6.7 and 5.6.8. > return false; > } > > > > Once the Unicast caching issue is properly resolved, we can revisit and > > > introduce stream-type-based handling accordingly. > > > > > > > > + stream_set_state(stream, BT_BAP_STREAM_STATE_IDLE); > > > > > > > > > > - bt_bap_stream_set_io(stream, -1); > > > > > return false; > > > > > } > > > > > > > > > > > > > > > --- > > > > > base-commit: ae1b7f6ba805f82742bbc32ff275e268248ef9f8 > > > > > change-id: 20250624-bap_for_big_sync_lost-63476c679dbb > > > > > > > > > > Best regards, > > > > > -- > > > > > Yang Li <yang.li@xxxxxxxxxxx> > > > > > > > > > > > > > > > > > > > -- > > > > Luiz Augusto von Dentz > > -- > > Pauli Virtanen