mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-06 05:06:29 +00:00
Bluetooth: ISO: Fix BIS cleanup
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 terminating the BIG. In case of a Broadcast Receiver, all BIS and PA connections can be cleaned up by calling hci_conn_failed, since it contains all function calls that are necessary for successful cleanup. Signed-off-by: Iulia Tanasescu <iulia.tanasescu@nxp.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
d6e48462e8
commit
a254b90c9a
@ -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 */
|
||||
@ -1247,6 +1248,12 @@ void hci_conn_failed(struct hci_conn *conn, u8 status)
|
||||
break;
|
||||
}
|
||||
|
||||
/* In case of BIG/PA sync failed, clear conn flags so that
|
||||
* the conns will be correctly cleaned up by ISO layer
|
||||
*/
|
||||
test_and_clear_bit(HCI_CONN_BIG_SYNC_FAILED, &conn->flags);
|
||||
test_and_clear_bit(HCI_CONN_PA_SYNC_FAILED, &conn->flags);
|
||||
|
||||
conn->state = BT_CLOSED;
|
||||
hci_connect_cfm(conn, status);
|
||||
hci_conn_del(conn);
|
||||
|
@ -1312,7 +1312,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;
|
||||
@ -5232,6 +5232,17 @@ static int hci_disconnect_sync(struct hci_dev *hdev, struct hci_conn *conn,
|
||||
if (conn->type == AMP_LINK)
|
||||
return hci_disconnect_phy_link_sync(hdev, conn->handle, reason);
|
||||
|
||||
if (test_bit(HCI_CONN_BIG_CREATED, &conn->flags)) {
|
||||
/* This is a BIS connection, hci_conn_del will
|
||||
* do the necessary cleanup.
|
||||
*/
|
||||
hci_dev_lock(hdev);
|
||||
hci_conn_failed(conn, reason);
|
||||
hci_dev_unlock(hdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&cp, 0, sizeof(cp));
|
||||
cp.handle = cpu_to_le16(conn->handle);
|
||||
cp.reason = reason;
|
||||
@ -5384,21 +5395,6 @@ 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);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
hci_dev_unlock(hdev);
|
||||
return 0;
|
||||
case BT_BOUND:
|
||||
break;
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user