mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 20:22:09 +00:00
Bluetooth: hci_conn: Fix not cleaning up on LE Connection failure
hci_connect_le_scan_cleanup shall always be invoked to cleanup the
states and re-enable passive scanning if necessary, otherwise it may
cause the pending action to stay active causing multiple attempts to
connect.
Fixes: 9b3628d79b
("Bluetooth: hci_sync: Cleanup hci_conn if it cannot be aborted")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
b9881d9a76
commit
19cf60bf63
@ -68,7 +68,7 @@ static const struct sco_param esco_param_msbc[] = {
|
||||
};
|
||||
|
||||
/* This function requires the caller holds hdev->lock */
|
||||
static void hci_connect_le_scan_cleanup(struct hci_conn *conn)
|
||||
static void hci_connect_le_scan_cleanup(struct hci_conn *conn, u8 status)
|
||||
{
|
||||
struct hci_conn_params *params;
|
||||
struct hci_dev *hdev = conn->hdev;
|
||||
@ -88,9 +88,28 @@ static void hci_connect_le_scan_cleanup(struct hci_conn *conn)
|
||||
|
||||
params = hci_pend_le_action_lookup(&hdev->pend_le_conns, bdaddr,
|
||||
bdaddr_type);
|
||||
if (!params || !params->explicit_connect)
|
||||
if (!params)
|
||||
return;
|
||||
|
||||
if (params->conn) {
|
||||
hci_conn_drop(params->conn);
|
||||
hci_conn_put(params->conn);
|
||||
params->conn = NULL;
|
||||
}
|
||||
|
||||
if (!params->explicit_connect)
|
||||
return;
|
||||
|
||||
/* If the status indicates successful cancellation of
|
||||
* the attempt (i.e. Unknown Connection Id) there's no point of
|
||||
* notifying failure since we'll go back to keep trying to
|
||||
* connect. The only exception is explicit connect requests
|
||||
* where a timeout + cancel does indicate an actual failure.
|
||||
*/
|
||||
if (status && status != HCI_ERROR_UNKNOWN_CONN_ID)
|
||||
mgmt_connect_failed(hdev, &conn->dst, conn->type,
|
||||
conn->dst_type, status);
|
||||
|
||||
/* The connection attempt was doing scan for new RPA, and is
|
||||
* in scan phase. If params are not associated with any other
|
||||
* autoconnect action, remove them completely. If they are, just unmark
|
||||
@ -178,7 +197,7 @@ static void le_scan_cleanup(struct work_struct *work)
|
||||
rcu_read_unlock();
|
||||
|
||||
if (c == conn) {
|
||||
hci_connect_le_scan_cleanup(conn);
|
||||
hci_connect_le_scan_cleanup(conn, 0x00);
|
||||
hci_conn_cleanup(conn);
|
||||
}
|
||||
|
||||
@ -1179,31 +1198,8 @@ EXPORT_SYMBOL(hci_get_route);
|
||||
static void hci_le_conn_failed(struct hci_conn *conn, u8 status)
|
||||
{
|
||||
struct hci_dev *hdev = conn->hdev;
|
||||
struct hci_conn_params *params;
|
||||
|
||||
params = hci_pend_le_action_lookup(&hdev->pend_le_conns, &conn->dst,
|
||||
conn->dst_type);
|
||||
if (params && params->conn) {
|
||||
hci_conn_drop(params->conn);
|
||||
hci_conn_put(params->conn);
|
||||
params->conn = NULL;
|
||||
}
|
||||
|
||||
/* If the status indicates successful cancellation of
|
||||
* the attempt (i.e. Unknown Connection Id) there's no point of
|
||||
* notifying failure since we'll go back to keep trying to
|
||||
* connect. The only exception is explicit connect requests
|
||||
* where a timeout + cancel does indicate an actual failure.
|
||||
*/
|
||||
if (status != HCI_ERROR_UNKNOWN_CONN_ID ||
|
||||
(params && params->explicit_connect))
|
||||
mgmt_connect_failed(hdev, &conn->dst, conn->type,
|
||||
conn->dst_type, status);
|
||||
|
||||
/* Since we may have temporarily stopped the background scanning in
|
||||
* favor of connection establishment, we should restart it.
|
||||
*/
|
||||
hci_update_passive_scan(hdev);
|
||||
hci_connect_le_scan_cleanup(conn, status);
|
||||
|
||||
/* Enable advertising in case this was a failed connection
|
||||
* attempt as a peripheral.
|
||||
@ -1240,7 +1236,7 @@ static void create_le_conn_complete(struct hci_dev *hdev, void *data, int err)
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
if (!err) {
|
||||
hci_connect_le_scan_cleanup(conn);
|
||||
hci_connect_le_scan_cleanup(conn, 0x00);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user