This fixes the master BIS cleanup procedure - as opposed to CIS cleanup, no HCI disconnect command should be issued. A master BIS should only be terminated by disabling periodic and extended advertising, and terminatings the BIG. Signed-off-by: Iulia Tanasescu <iulia.tanasescu@xxxxxxx> --- include/net/bluetooth/hci_sync.h | 2 ++ net/bluetooth/hci_conn.c | 1 + net/bluetooth/hci_sync.c | 29 ++++++++++++++--------------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h index 57eeb07aeb25..6efbc2152146 100644 --- a/include/net/bluetooth/hci_sync.h +++ b/include/net/bluetooth/hci_sync.h @@ -80,6 +80,8 @@ int hci_start_per_adv_sync(struct hci_dev *hdev, u8 instance, u8 data_len, u8 *data, u32 flags, u16 min_interval, u16 max_interval, u16 sync_interval); +int hci_disable_per_advertising_sync(struct hci_dev *hdev, u8 instance); + int hci_remove_advertising_sync(struct hci_dev *hdev, struct sock *sk, u8 instance, bool force); int hci_disable_advertising_sync(struct hci_dev *hdev); diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 9d5057cef30a..9d4f63f14ce6 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -759,6 +759,7 @@ static int terminate_big_sync(struct hci_dev *hdev, void *data) bt_dev_dbg(hdev, "big 0x%2.2x bis 0x%2.2x", d->big, d->bis); + hci_disable_per_advertising_sync(hdev, d->bis); hci_remove_ext_adv_instance_sync(hdev, d->bis, NULL); /* Only terminate BIG if it has been created */ diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c index 9b93653c6197..f7da02393b3c 100644 --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c @@ -1317,7 +1317,7 @@ int hci_start_ext_adv_sync(struct hci_dev *hdev, u8 instance) return hci_enable_ext_advertising_sync(hdev, instance); } -static int hci_disable_per_advertising_sync(struct hci_dev *hdev, u8 instance) +int hci_disable_per_advertising_sync(struct hci_dev *hdev, u8 instance) { struct hci_cp_le_set_per_adv_enable cp; struct adv_info *adv = NULL; @@ -5378,6 +5378,12 @@ int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, u8 reason) switch (conn->state) { case BT_CONNECTED: case BT_CONFIG: + if (test_bit(HCI_CONN_BIG_CREATED, &conn->flags)) { + /* This is a BIS connection, hci_conn_del will + * do the necessary cleanup. + */ + goto conn_del; + } err = hci_disconnect_sync(hdev, conn, reason); break; case BT_CONNECT: @@ -5387,26 +5393,19 @@ int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, u8 reason) err = hci_reject_conn_sync(hdev, conn, reason); break; case BT_OPEN: - hci_dev_lock(hdev); + case BT_BOUND: + if (test_bit(HCI_CONN_PA_SYNC, &conn->flags) || + test_bit(HCI_CONN_BIG_SYNC, &conn->flags)) + goto conn_del; - /* Cleanup bis or pa sync connections */ - if (test_and_clear_bit(HCI_CONN_BIG_SYNC_FAILED, &conn->flags) || - test_and_clear_bit(HCI_CONN_PA_SYNC_FAILED, &conn->flags)) { - hci_conn_failed(conn, reason); - } else if (test_bit(HCI_CONN_PA_SYNC, &conn->flags) || - test_bit(HCI_CONN_BIG_SYNC, &conn->flags)) { - conn->state = BT_CLOSED; - hci_disconn_cfm(conn, reason); - hci_conn_del(conn); - } + test_and_clear_bit(HCI_CONN_BIG_SYNC_FAILED, &conn->flags); + test_and_clear_bit(HCI_CONN_PA_SYNC_FAILED, &conn->flags); - hci_dev_unlock(hdev); - return 0; - case BT_BOUND: hci_dev_lock(hdev); hci_conn_failed(conn, reason); hci_dev_unlock(hdev); return 0; +conn_del: default: hci_dev_lock(hdev); conn->state = BT_CLOSED; -- 2.34.1