summaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_conn.c
diff options
context:
space:
mode:
authorVinicius Costa Gomes <vinicius.gomes@openbossa.org>2012-04-20 15:46:08 -0300
committerGustavo Padovan <gustavo@padovan.org>2012-05-09 01:40:41 -0300
commit9f0caeb1deafa9a894ee03134f6642c3a245b1af (patch)
tree01e7466dfb3a68fc92fd5649ac77f6ab620088fb /net/bluetooth/hci_conn.c
parentc22876814ee9cc72f84996b78203b5530c61bee8 (diff)
downloadlinux-9f0caeb1deafa9a894ee03134f6642c3a245b1af.tar.bz2
Bluetooth: Add support for reusing the same hci_conn for LE links
As most LE devices leave advertising mode when they enter the connected state, we may want to "pass" that connection to other users. The first user will be the pairing procedure, the connection is established without an associated socket, after the pairing is complete, userspace may want to discover via GATT what services the newly bonded device has. If userspace establishes the connection while the timeout still hasn't expired, the connection will be re-used. Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org> Tested-by: João Paulo Rechi Vita <jprvita@openbossa.org> Signed-off-by: Gustavo Padovan <gustavo@padovan.org>
Diffstat (limited to 'net/bluetooth/hci_conn.c')
-rw-r--r--net/bluetooth/hci_conn.c32
1 files changed, 18 insertions, 14 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 5238b6b3ea6a..7db3edc28f77 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -522,23 +522,27 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
BT_DBG("%s dst %s", hdev->name, batostr(dst));
if (type == LE_LINK) {
- struct adv_entry *entry;
+ struct adv_entry *entry = NULL;
le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst);
- if (le)
- return ERR_PTR(-EBUSY);
-
- entry = hci_find_adv_entry(hdev, dst);
- if (!entry)
- return ERR_PTR(-EHOSTUNREACH);
-
- le = hci_conn_add(hdev, LE_LINK, dst);
- if (!le)
- return ERR_PTR(-ENOMEM);
-
- le->dst_type = entry->bdaddr_type;
+ if (!le) {
+ entry = hci_find_adv_entry(hdev, dst);
+ if (!entry)
+ return ERR_PTR(-EHOSTUNREACH);
+
+ le = hci_conn_add(hdev, LE_LINK, dst);
+ if (!le)
+ return ERR_PTR(-ENOMEM);
+
+ le->dst_type = entry->bdaddr_type;
+ le->pending_sec_level = sec_level;
+ le->sec_level = BT_SECURITY_LOW;
+ le->auth_type = auth_type;
+ hci_le_connect(le);
+ }
- hci_le_connect(le);
+ le->pending_sec_level = sec_level;
+ le->auth_type = auth_type;
hci_conn_hold(le);