diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2015-03-10 16:34:40 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2015-03-10 16:42:05 -0400 |
commit | 55e76b38986a61259f3079afd0f9a865651a34fe (patch) | |
tree | 896a09d711e70975b996268dea4d77c60a5bd47a /net/bluetooth | |
parent | 406ef2a67bd0bb13d77d5e5d700e36a2caea09ae (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.c | 27 | ||||
-rw-r--r-- | net/bluetooth/mgmt.c | 7 |
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 | ||
2519 | bool 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 */ |
2520 | static void hci_cmd_timeout(struct work_struct *work) | 2547 | static 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 | ||