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 <nirav.agrawal@nxp.com>
This commit is contained in:
Nirav Agrawal 2025-06-24 17:22:13 +05:30 committed by Chris Friedt
parent 2784cac77c
commit b59d8d56bf
3 changed files with 8 additions and 31 deletions

View File

@ -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;
}
}

View File

@ -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");

View File

@ -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 {