From b59d8d56bf0d9c0867a0734cccc07ae75d5b911e Mon Sep 17 00:00:00 2001 From: Nirav Agrawal Date: Tue, 24 Jun 2025 17:22:13 +0530 Subject: [PATCH] bluetooth: bap_unicast_client: fix PTS BAP/UCL/SCC/BV-103-C failure - In bap_unicast_client, it was assumed that ASE is binded with CIS handler during sending "received_stop_ready" to unicast_server. - In case where unicast_client has not started the stream with "receiver_start_ready" att command to server, but wants to disable ASE which was Enabled previously (but not stream!) causes failure since there is no cis_create has happened and linked to ASE. - In BAP_TS, "BAP/UCL/SCC/BV-103-C" has a same test conditions where client first enables the ASE, disable the ASE, and expecting "receiver_stop_ready" att command from client to server followed by server notification to enter its ASE in QoS_configured state. - Removed this condition checks to send expected att command to server from Enabling ASE state to Disable ASE. Signed-off-by: Nirav Agrawal --- subsys/bluetooth/audio/bap_stream.c | 7 ++++--- subsys/bluetooth/audio/bap_unicast_client.c | 23 +-------------------- subsys/bluetooth/audio/cap_initiator.c | 9 +++----- 3 files changed, 8 insertions(+), 31 deletions(-) diff --git a/subsys/bluetooth/audio/bap_stream.c b/subsys/bluetooth/audio/bap_stream.c index 761ef9d8a8d..f06baebecac 100644 --- a/subsys/bluetooth/audio/bap_stream.c +++ b/subsys/bluetooth/audio/bap_stream.c @@ -483,10 +483,11 @@ bool bt_bap_stream_can_disconnect(const struct bt_bap_stream *stream) pair_ep = bt_bap_iso_get_paired_ep(stream_ep); - /* If there are no paired endpoint, or the paired endpoint is - * not in the streaming state, we can disconnect the CIS + /* If there are no paired endpoint, or the paired endpoint is in the QoS Configured + * or Codec Configured state, we can disconnect the CIS */ - if (pair_ep == NULL || pair_ep->status.state != BT_BAP_EP_STATE_STREAMING) { + if (pair_ep == NULL || pair_ep->status.state == BT_BAP_EP_STATE_QOS_CONFIGURED || + pair_ep->status.state == BT_BAP_EP_STATE_CODEC_CONFIGURED) { return true; } } diff --git a/subsys/bluetooth/audio/bap_unicast_client.c b/subsys/bluetooth/audio/bap_unicast_client.c index 2e2b40957de..cd2f59255f5 100644 --- a/subsys/bluetooth/audio/bap_unicast_client.c +++ b/subsys/bluetooth/audio/bap_unicast_client.c @@ -5,6 +5,7 @@ /* * Copyright (c) 2020 Intel Corporation * Copyright (c) 2022-2025 Nordic Semiconductor ASA + * Copyright 2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -3517,7 +3518,6 @@ int bt_bap_unicast_client_disable(struct bt_bap_stream *stream) int bt_bap_unicast_client_stop(struct bt_bap_stream *stream) { struct bt_bap_ep *ep = stream->ep; - enum bt_iso_state iso_state; struct net_buf_simple *buf; struct bt_ascs_start_op *req; int err; @@ -3530,27 +3530,6 @@ int bt_bap_unicast_client_stop(struct bt_bap_stream *stream) return -ENOTCONN; } - /* ASCS_v1.0 3.2 ASE state machine transitions - * - * If the server detects link loss of a CIS for an ASE in the Streaming state or the - * Disabling state, the server shall immediately transition that ASE to the QoS Configured - * state. - * - * This effectively means that if an ASE no longer has a connected CIS, the server shall - * bring it to the QoS Configured state. That means that we, as a unicast client, should not - * attempt to stop it - */ - if (ep->iso == NULL) { - LOG_DBG("Stream endpoint does not have a CIS, server will stop the ASE"); - return -EALREADY; - } - - iso_state = ep->iso->chan.state; - if (iso_state != BT_ISO_STATE_CONNECTED && iso_state != BT_ISO_STATE_CONNECTING) { - LOG_DBG("Stream endpoint CIS is not connected, server will stop the ASE"); - return -EALREADY; - } - buf = bt_bap_unicast_client_ep_create_pdu(stream->conn, BT_ASCS_STOP_OP); if (buf == NULL) { LOG_DBG("Could not create PDU"); diff --git a/subsys/bluetooth/audio/cap_initiator.c b/subsys/bluetooth/audio/cap_initiator.c index 811709620da..5fa6d3305aa 100644 --- a/subsys/bluetooth/audio/cap_initiator.c +++ b/subsys/bluetooth/audio/cap_initiator.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2022-2025 Nordic Semiconductor ASA + * Copyright 2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -2389,13 +2390,11 @@ void bt_cap_initiator_disabled(struct bt_cap_stream *cap_stream) proc_param->in_progress = true; err = bt_bap_stream_stop(next_bap_stream); - if (err != 0 && err != -EALREADY) { + if (err != 0) { LOG_DBG("Failed to stop stream %p: %d", next_cap_stream, err); bt_cap_common_abort_proc(next_bap_stream->conn, err); cap_initiator_unicast_audio_proc_complete(); - } else if (err == -EALREADY) { - proc_param->in_progress = false; } /* else wait for server notification*/ } } @@ -2449,13 +2448,11 @@ void bt_cap_initiator_stopped(struct bt_cap_stream *cap_stream) proc_param->in_progress = true; err = bt_bap_stream_stop(next_bap_stream); - if (err != 0 && err != -EALREADY) { + if (err != 0) { LOG_DBG("Failed to stop stream %p: %d", next_cap_stream, err); bt_cap_common_abort_proc(next_bap_stream->conn, err); cap_initiator_unicast_audio_proc_complete(); - } else if (err == -EALREADY) { - proc_param->in_progress = false; } } /* else await notification from server */ } else {