Skip to content

Commit 8dcec59

Browse files
MariuszSkamracarlescufi
authored andcommitted
Bluetooth: audio: ascs: Fix ASE state transition due to CIS link loss
This fixes ASE state transition to QoS Configured state that shall be done autononously when CIS has been terminated due to link loss. As per ASCS v1.0: "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. Link loss of a CIS for an ASE in any state other than Streaming or Disabling shall not cause a transition of the ASE state machine." Fixes: #60669 Signed-off-by: Mariusz Skamra <[email protected]>
1 parent c7476fd commit 8dcec59

File tree

1 file changed

+23
-11
lines changed

1 file changed

+23
-11
lines changed

subsys/bluetooth/audio/ascs.c

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ static struct bt_ascs_ase {
6363
struct k_work_delayable disconnect_work;
6464
struct k_work state_transition_work;
6565
enum bt_bap_ep_state state_pending;
66+
bool unexpected_iso_link_loss;
6667
} ase_pool[CONFIG_BT_ASCS_MAX_ACTIVE_ASES];
6768

6869
#define MAX_CODEC_CONFIG \
@@ -354,6 +355,10 @@ static void ase_set_state_disabling(struct bt_ascs_ase *ase)
354355
if (ops != NULL && ops->disabled != NULL) {
355356
ops->disabled(stream);
356357
}
358+
359+
if (ase->unexpected_iso_link_loss) {
360+
ascs_ep_set_state(&ase->ep, BT_BAP_EP_STATE_QOS_CONFIGURED);
361+
}
357362
}
358363

359364
static void ase_set_state_releasing(struct bt_ascs_ase *ase)
@@ -399,9 +404,6 @@ static void state_transition_work_handler(struct k_work *work)
399404
if (reason == BT_HCI_ERR_SUCCESS) {
400405
/* Default to BT_HCI_ERR_UNSPECIFIED if no other reason is set */
401406
reason = BT_HCI_ERR_UNSPECIFIED;
402-
} else {
403-
/* Reset reason */
404-
ep->reason = BT_HCI_ERR_SUCCESS;
405407
}
406408

407409
if (ops != NULL && ops->stopped != NULL) {
@@ -823,6 +825,7 @@ static void ascs_update_sdu_size(struct bt_bap_ep *ep)
823825

824826
static void ascs_ep_iso_connected(struct bt_bap_ep *ep)
825827
{
828+
struct bt_ascs_ase *ase = CONTAINER_OF(ep, struct bt_ascs_ase, ep);
826829
struct bt_bap_stream *stream;
827830

828831
if (ep->status.state != BT_BAP_EP_STATE_ENABLING) {
@@ -837,6 +840,10 @@ static void ascs_ep_iso_connected(struct bt_bap_ep *ep)
837840
return;
838841
}
839842

843+
/* Reset reason */
844+
ep->reason = BT_HCI_ERR_SUCCESS;
845+
ase->unexpected_iso_link_loss = false;
846+
840847
/* Some values are not provided by the HCI events when the CIS is established for the
841848
* peripheral, so we update them here based on the parameters provided by the BAP Unicast
842849
* Client
@@ -897,18 +904,23 @@ static void ascs_ep_iso_disconnected(struct bt_bap_ep *ep, uint8_t reason)
897904

898905
if (ep->status.state == BT_BAP_EP_STATE_RELEASING) {
899906
ascs_ep_set_state(ep, BT_BAP_EP_STATE_IDLE);
900-
} else {
907+
} else if (ep->status.state == BT_BAP_EP_STATE_STREAMING) {
908+
/* CIS has been unexpectedly disconnected */
909+
ase->unexpected_iso_link_loss = true;
910+
901911
/* The ASE state machine goes into different states from this operation
902912
* based on whether it is a source or a sink ASE.
903913
*/
904-
if (ep->status.state == BT_BAP_EP_STATE_STREAMING ||
905-
ep->status.state == BT_BAP_EP_STATE_ENABLING) {
906-
if (ep->dir == BT_AUDIO_DIR_SOURCE) {
907-
ascs_ep_set_state(ep, BT_BAP_EP_STATE_DISABLING);
908-
} else {
909-
ascs_ep_set_state(ep, BT_BAP_EP_STATE_QOS_CONFIGURED);
910-
}
914+
if (ep->dir == BT_AUDIO_DIR_SOURCE) {
915+
ascs_ep_set_state(ep, BT_BAP_EP_STATE_DISABLING);
916+
} else {
917+
ascs_ep_set_state(ep, BT_BAP_EP_STATE_QOS_CONFIGURED);
911918
}
919+
} else if (ep->status.state == BT_BAP_EP_STATE_DISABLING) {
920+
/* CIS has been unexpectedly disconnected */
921+
ase->unexpected_iso_link_loss = true;
922+
923+
ascs_ep_set_state(ep, BT_BAP_EP_STATE_QOS_CONFIGURED);
912924
}
913925
}
914926

0 commit comments

Comments
 (0)