Bluetooth: Remove conn_unfinished variable from hci_connect_le()

The conn_unfinished variable makes the entire logic of
hci_connect_le() rather confusing. By restructuring and clarifying the
logic we can actually remove the conn_unfinished variable and still
keep the same behavior.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This commit is contained in:
Johan Hedberg 2015-11-11 14:44:59 +02:00 committed by Marcel Holtmann
parent 658aead94b
commit e2caced407
1 changed files with 12 additions and 36 deletions

View File

@ -785,7 +785,7 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
u8 role) u8 role)
{ {
struct hci_conn_params *params; struct hci_conn_params *params;
struct hci_conn *conn, *conn_unfinished; struct hci_conn *conn;
struct smp_irk *irk; struct smp_irk *irk;
struct hci_request req; struct hci_request req;
int err; int err;
@ -804,27 +804,14 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
if (hci_lookup_le_connect(hdev)) if (hci_lookup_le_connect(hdev))
return ERR_PTR(-EBUSY); return ERR_PTR(-EBUSY);
/* Some devices send ATT messages as soon as the physical link is /* If there's already a connection object but it's not in
* established. To be able to handle these ATT messages, the user- * scanning state it means it must already be established, in
* space first establishes the connection and then starts the pairing * which case we can't do anything else except report a failure
* process. * to connect.
*
* So if a hci_conn object already exists for the following connection
* attempt, we simply update pending_sec_level and auth_type fields
* and return the object found.
*/ */
conn = hci_conn_hash_lookup_le(hdev, dst, dst_type); conn = hci_conn_hash_lookup_le(hdev, dst, dst_type);
conn_unfinished = NULL; if (conn && !test_bit(HCI_CONN_SCANNING, &conn->flags)) {
if (conn) { return ERR_PTR(-EBUSY);
if (conn->state == BT_CONNECT &&
test_bit(HCI_CONN_SCANNING, &conn->flags)) {
BT_DBG("will continue unfinished conn %pMR", dst);
conn_unfinished = conn;
} else {
if (conn->pending_sec_level < sec_level)
conn->pending_sec_level = sec_level;
goto done;
}
} }
/* When given an identity address with existing identity /* When given an identity address with existing identity
@ -842,23 +829,20 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
dst_type = ADDR_LE_DEV_RANDOM; dst_type = ADDR_LE_DEV_RANDOM;
} }
if (conn_unfinished) { if (conn) {
conn = conn_unfinished;
bacpy(&conn->dst, dst); bacpy(&conn->dst, dst);
} else { } else {
conn = hci_conn_add(hdev, LE_LINK, dst, role); conn = hci_conn_add(hdev, LE_LINK, dst, role);
if (!conn)
return ERR_PTR(-ENOMEM);
hci_conn_hold(conn);
conn->pending_sec_level = sec_level;
} }
if (!conn)
return ERR_PTR(-ENOMEM);
conn->dst_type = dst_type; conn->dst_type = dst_type;
conn->sec_level = BT_SECURITY_LOW; conn->sec_level = BT_SECURITY_LOW;
conn->conn_timeout = conn_timeout; conn->conn_timeout = conn_timeout;
if (!conn_unfinished)
conn->pending_sec_level = sec_level;
hci_req_init(&req, hdev); hci_req_init(&req, hdev);
/* Disable advertising if we're active. For master role /* Disable advertising if we're active. For master role
@ -922,14 +906,6 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
return ERR_PTR(err); return ERR_PTR(err);
} }
done:
/* If this is continuation of connect started by hci_connect_le_scan,
* it already called hci_conn_hold and calling it again would mess the
* counter.
*/
if (!conn_unfinished)
hci_conn_hold(conn);
return conn; return conn;
} }