|
6 | 6 | * SPDX-License-Identifier: Apache-2.0 |
7 | 7 | */ |
8 | 8 |
|
| 9 | +#include <stdbool.h> |
9 | 10 | #include <stddef.h> |
10 | 11 | #include <stdint.h> |
11 | 12 | #include <errno.h> |
|
16 | 17 | #include <zephyr/bluetooth/conn.h> |
17 | 18 | #include <zephyr/bluetooth/iso.h> |
18 | 19 | #include <zephyr/sys/__assert.h> |
| 20 | +#include <zephyr/sys/util_macro.h> |
19 | 21 | #include <zephyr/types.h> |
20 | 22 | #include <zephyr/kernel.h> |
21 | 23 | #include <zephyr/sys/ring_buffer.h> |
@@ -558,22 +560,41 @@ static void stream_qos_set_cb(struct bt_bap_stream *stream) |
558 | 560 |
|
559 | 561 | static void stream_enabled_cb(struct bt_bap_stream *stream) |
560 | 562 | { |
561 | | - struct bt_bap_ep_info info; |
562 | | - struct bt_conn_info conn_info; |
| 563 | + const bool iso_connected = |
| 564 | + stream->iso == NULL ? false : stream->iso->state == BT_ISO_STATE_CONNECTED; |
563 | 565 | int err; |
564 | 566 |
|
565 | 567 | LOG_DBG("Enabled stream %p", stream); |
566 | 568 |
|
567 | | - (void)bt_bap_ep_get_info(stream->ep, &info); |
568 | | - (void)bt_conn_get_info(stream->conn, &conn_info); |
569 | | - if (conn_info.role == BT_HCI_ROLE_PERIPHERAL && info.dir == BT_AUDIO_DIR_SINK) { |
570 | | - /* Automatically do the receiver start ready operation */ |
571 | | - /* TODO: This should ideally be done by the upper tester */ |
572 | | - err = bt_bap_stream_start(stream); |
573 | | - if (err != 0) { |
574 | | - LOG_DBG("Failed to start stream %p", stream); |
| 569 | + if (iso_connected) { |
| 570 | + struct bt_bap_ep_info ep_info; |
| 571 | + struct bt_conn_info conn_info; |
575 | 572 |
|
576 | | - return; |
| 573 | + err = bt_bap_ep_get_info(stream->ep, &ep_info); |
| 574 | + __ASSERT(err == 0, "Failed to get ISO chan info: %d", err); |
| 575 | + err = bt_conn_get_info(stream->conn, &conn_info); |
| 576 | + __ASSERT(err == 0, "Failed to get ISO chan info: %d", err); |
| 577 | + |
| 578 | + /* If we are central and the endpoint is a source or if we are a peripheral and the |
| 579 | + * endpoint is a sink, then we can start it, else the remote device needs to start |
| 580 | + * the endpoint |
| 581 | + */ |
| 582 | + const bool start_stream = |
| 583 | + (IS_ENABLED(CONFIG_BT_CENTRAL) && conn_info.role == BT_HCI_ROLE_CENTRAL && |
| 584 | + ep_info.dir == BT_AUDIO_DIR_SOURCE) || |
| 585 | + (IS_ENABLED(CONFIG_BT_PERIPHERAL) && |
| 586 | + conn_info.role == BT_HCI_ROLE_PERIPHERAL && |
| 587 | + ep_info.dir == BT_AUDIO_DIR_SINK); |
| 588 | + |
| 589 | + if (start_stream) { |
| 590 | + /* Automatically do the receiver start ready operation */ |
| 591 | + /* TODO: This should ideally be done by the upper tester */ |
| 592 | + err = bt_bap_stream_start(stream); |
| 593 | + if (err != 0) { |
| 594 | + LOG_DBG("Failed to start stream %p", stream); |
| 595 | + |
| 596 | + return; |
| 597 | + } |
577 | 598 | } |
578 | 599 | } |
579 | 600 |
|
@@ -688,12 +709,16 @@ static void stream_connected_cb(struct bt_bap_stream *stream) |
688 | 709 | } |
689 | 710 |
|
690 | 711 | if (ep_info.dir == BT_AUDIO_DIR_SOURCE) { |
691 | | - /* Automatically do the receiver start ready operation for source ASEs as |
692 | | - * the client |
693 | | - */ |
694 | | - err = bt_bap_stream_start(stream); |
695 | | - if (err != 0) { |
696 | | - LOG_ERR("Failed to start stream %p", stream); |
| 712 | + if (ep_info.state == BT_BAP_EP_STATE_ENABLING) { |
| 713 | + /* Automatically do the receiver start ready operation for source |
| 714 | + * ASEs as the client when in the enabling state. |
| 715 | + * The CIS may be connected in the QoS Configured state as well, in |
| 716 | + * which case we should wait until we enter the enabling state. |
| 717 | + */ |
| 718 | + err = bt_bap_stream_start(stream); |
| 719 | + if (err != 0) { |
| 720 | + LOG_ERR("Failed to start stream %p", stream); |
| 721 | + } |
697 | 722 | } |
698 | 723 | } else { |
699 | 724 | struct btp_bap_unicast_stream *u_stream = stream_bap_to_unicast(stream); |
|
0 commit comments