aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2015-03-10 16:34:40 -0400
committerMarcel Holtmann <marcel@holtmann.org>2015-03-10 16:42:05 -0400
commit55e76b38986a61259f3079afd0f9a865651a34fe (patch)
tree896a09d711e70975b996268dea4d77c60a5bd47a /net/bluetooth
parent406ef2a67bd0bb13d77d5e5d700e36a2caea09ae (diff)
Bluetooth: Add 'Already Paired' error for Pair Device command
To make the behavior predictable when attempting to pair with a device for which we already have a Link Key or Long Term Key, this patch adds a new 'Already Paired' error which gets sent in such a scenario. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hci_core.c27
-rw-r--r--net/bluetooth/mgmt.c7
2 files changed, 34 insertions, 0 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index bba4c344c6e0..a35d8441187a 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2516,6 +2516,33 @@ void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
2516 } 2516 }
2517} 2517}
2518 2518
2519bool hci_bdaddr_is_paired(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
2520{
2521 struct smp_ltk *k;
2522 u8 addr_type;
2523
2524 if (type == BDADDR_BREDR) {
2525 if (hci_find_link_key(hdev, bdaddr))
2526 return true;
2527 return false;
2528 }
2529
2530 /* Convert to HCI addr type which struct smp_ltk uses */
2531 if (type == BDADDR_LE_PUBLIC)
2532 addr_type = ADDR_LE_DEV_PUBLIC;
2533 else
2534 addr_type = ADDR_LE_DEV_RANDOM;
2535
2536 rcu_read_lock();
2537 list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
2538 if (k->bdaddr_type == addr_type && !bacmp(bdaddr, &k->bdaddr))
2539 return true;
2540 }
2541 rcu_read_unlock();
2542
2543 return false;
2544}
2545
2519/* HCI command timer function */ 2546/* HCI command timer function */
2520static void hci_cmd_timeout(struct work_struct *work) 2547static void hci_cmd_timeout(struct work_struct *work)
2521{ 2548{
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 49b8e09ffe67..600636c00d34 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -3245,6 +3245,13 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
3245 goto unlock; 3245 goto unlock;
3246 } 3246 }
3247 3247
3248 if (hci_bdaddr_is_paired(hdev, &cp->addr.bdaddr, cp->addr.type)) {
3249 err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE,
3250 MGMT_STATUS_ALREADY_PAIRED, &rp,
3251 sizeof(rp));
3252 goto unlock;
3253 }
3254
3248 sec_level = BT_SECURITY_MEDIUM; 3255 sec_level = BT_SECURITY_MEDIUM;
3249 auth_type = HCI_AT_DEDICATED_BONDING; 3256 auth_type = HCI_AT_DEDICATED_BONDING;
3250 3257