Bluetooth: Refactor hci_connect_le
authorAndre Guedes <andre.guedes@openbossa.org>
Tue, 8 Oct 2013 11:21:18 +0000 (08:21 -0300)
committerMarcel Holtmann <marcel@holtmann.org>
Thu, 10 Oct 2013 08:30:18 +0000 (01:30 -0700)
This patch does some code refactoring in hci_connect_le() by moving
the exception code into if statements and letting the main flow in
first level of function scope. It also adds extra comments to improve
the code readability.

Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
net/bluetooth/hci_conn.c

index 1800b50558e4c6e1a69d13ec1d2cf23569fe4bab..dedd1ea5dd4c984e7ec990bd693b7c39c5a8a0f8 100644 (file)
@@ -594,32 +594,47 @@ static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
        if (test_bit(HCI_ADVERTISING, &hdev->flags))
                return ERR_PTR(-ENOTSUPP);
 
+       /* Some devices send ATT messages as soon as the physical link is
+        * established. To be able to handle these ATT messages, the user-
+        * space first establishes the connection and then starts the pairing
+        * process.
+        *
+        * 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_ba(hdev, LE_LINK, dst);
-       if (!conn) {
-               conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
-               if (conn)
-                       return ERR_PTR(-EBUSY);
-
-               conn = hci_conn_add(hdev, LE_LINK, dst);
-               if (!conn)
-                       return ERR_PTR(-ENOMEM);
+       if (conn) {
+               conn->pending_sec_level = sec_level;
+               conn->auth_type = auth_type;
+               goto done;
+       }
 
-               conn->dst_type = bdaddr_to_le(dst_type);
-               conn->state = BT_CONNECT;
-               conn->out = true;
-               conn->link_mode |= HCI_LM_MASTER;
-               conn->sec_level = BT_SECURITY_LOW;
+       /* Since the controller supports only one LE connection attempt at a
+        * time, we return -EBUSY if there is any connection attempt running.
+        */
+       conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
+       if (conn)
+               return ERR_PTR(-EBUSY);
 
-               err = hci_create_le_conn(conn);
-               if (err)
-                       return ERR_PTR(err);
-       }
+       conn = hci_conn_add(hdev, LE_LINK, dst);
+       if (!conn)
+               return ERR_PTR(-ENOMEM);
 
+       conn->dst_type = bdaddr_to_le(dst_type);
+       conn->state = BT_CONNECT;
+       conn->out = true;
+       conn->link_mode |= HCI_LM_MASTER;
+       conn->sec_level = BT_SECURITY_LOW;
        conn->pending_sec_level = sec_level;
        conn->auth_type = auth_type;
 
-       hci_conn_hold(conn);
+       err = hci_create_le_conn(conn);
+       if (err)
+               return ERR_PTR(err);
 
+done:
+       hci_conn_hold(conn);
        return conn;
 }