zephyrproject-rtos / zephyr

Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
https://docs.zephyrproject.org
Apache License 2.0
10.24k stars 6.27k forks source link

LE Audio: Invalid behavior bt_cap_initiator_unicast_audio_stop for some remote devices #70818

Open Thalley opened 4 months ago

Thalley commented 4 months ago

Describe the bug bt_cap_initiator_unicast_audio_stop has been implemented to release a stream, and when the stream goes into the idle or codec configured state (as per ASCS) then the next stream is released.

Several remote platforms does not allow fully releasing a stream that still connected to a CIS, such as the case where 2 streams (sink and source) share a single ASE. This behavior is based on the following test from BAP:

The Unicast Client should not initiate the Release operation for an ASE that is in the Enabling state or the Streaming state if the CIS_ID and CIG_ID parameters are identical to other ASEs exposed by the Unicast Server that are in the Enabling state or the Streaming state; the Unicast Client should instead disable the ASE.

And the text

The Unicast Client shall terminate any CIS established for that ASE by following the Connected Isochronous Stream Terminate procedure defined in Volume 3, Part C, Section 9.3.15 in [1], when the Unicast Client has determined that the ASE is in the Releasing state.

So by the BAP spec, it's clearly hinted (and somewhat required) that the CIS is terminated as part of releasing a stream, which is not what we do when we release streams as part of bt_cap_initiator_unicast_audio_stop.

The CAP spec allows the initiator to use either disable or release for the unicast audio stop procedure:

An Initiator shall execute the BAP Unicast ASE Control operation - Disabling an ASE (see Section 5.6.5 in [2]) or the BAP Unicast ASE Control operation - Releasing an ASE (see Section 5.6.6 in [2]) on all ASEs in the use case in the Enabling or Streaming state.

So the issue may be fixed by simply using disable instead of release. This would also fix another issue which is that once a stream goes from e.g. enabling -> codec configured, then it cannot go back into QoS Configured, as the BAP spec requires all streams in the CIG to be QoS Configured at the same time, which is not possible if one is in the e.g. streaming state and the other in the Codec Configured state.

To Reproduce Cannot be locally produced in Zephyr as we allow it (unless rejected by the application). Information about the products that does not allow it cannot be disclosed either, as this was found during a Bluetooth SIG UPF event.

Expected behavior The bt_cap_initiator_unicast_audio_stop should use the disable operation instead of the release. We then either need to add an additional bt_cap_initiator_unicast_audio_release to allow for releasing streams that do not have a CIS, or do release after disable for streams that can be released. This could be part of the stop parameters so it can be controlled by the application.

In the end the result should be that we never attempt to release a stream that will end up in the releasing state because the CIS cannot be disconnected.

The bt_cap_initiator_unicast_audio_start also need to be updated to support streams in other states, such as QoS Configured (the resulting state of disable) so it's possible to do bt_cap_initiator_unicast_audio_start after a bt_cap_initiator_unicast_audio_stop.

Impact It can be worked around by the application by using the BAP API, but that is less than ideal, and from a CAP perspective this is can be a showstopper.

Logs and console output N/A

Environment (please complete the following information):

Additional context N/A

github-actions[bot] commented 2 months ago

This issue has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this issue will automatically be closed in 14 days. Note, that you can always re-open a closed issue at any time.

github-actions[bot] commented 1 week ago

This issue has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this issue will automatically be closed in 14 days. Note, that you can always re-open a closed issue at any time.