@@ -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);
@@ -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 */
@@ -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;
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@nxp.com> --- 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(-)