Bluetooth: Store current RPA and update it if needed
authorMarcel Holtmann <marcel@holtmann.org>
Mon, 24 Feb 2014 04:39:22 +0000 (20:39 -0800)
committerJohan Hedberg <johan.hedberg@intel.com>
Mon, 24 Feb 2014 06:49:31 +0000 (08:49 +0200)
The RPA needs to be stored to know which is the current one. Otherwise
it is impossible to ensure that always the correct RPA can be programmed
into the controller when it is needed.

Current code checks if the address in the controller is a RPA, but that
can potentially lead to using a RPA that can not be resolved with the
IRK that has been distributed.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
include/net/bluetooth/hci_core.h
net/bluetooth/hci_core.c

index 0ee9cd11b3ef2f518576ffe5424961c7920b9001..fb3b677ff8a62277abba510d0c29430699752ff8 100644 (file)
@@ -308,6 +308,7 @@ struct hci_dev {
        __u8                    irk[16];
        __u32                   rpa_timeout;
        struct delayed_work     rpa_expired;
+       bdaddr_t                rpa;
 
        int (*open)(struct hci_dev *hdev);
        int (*close)(struct hci_dev *hdev);
index 31e68ade309dc5e92c086f5e0fb5cc00878c8271..9f1c3d7d1d745a1e71f024fa7a88e6dbdca4206f 100644 (file)
@@ -3339,26 +3339,25 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy,
        int err;
 
        /* If privacy is enabled use a resolvable private address. If
-        * the current RPA has expired or there's something else than an
-        * RPA currently in use regenerate a new one.
+        * current RPA has expired or there is something else than
+        * the current RPA in use, then generate a new one.
         */
        if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) {
-               bdaddr_t rpa;
                int to;
 
                *own_addr_type = ADDR_LE_DEV_RANDOM;
 
                if (!test_and_clear_bit(HCI_RPA_EXPIRED, &hdev->dev_flags) &&
-                   hci_bdaddr_is_rpa(&hdev->random_addr, ADDR_LE_DEV_RANDOM))
+                   !bacmp(&hdev->random_addr, &hdev->rpa))
                        return 0;
 
-               err = smp_generate_rpa(hdev->tfm_aes, hdev->irk, &rpa);
+               err = smp_generate_rpa(hdev->tfm_aes, hdev->irk, &hdev->rpa);
                if (err < 0) {
                        BT_ERR("%s failed to generate new RPA", hdev->name);
                        return err;
                }
 
-               hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6, &rpa);
+               hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6, &hdev->rpa);
 
                to = msecs_to_jiffies(hdev->rpa_timeout * 1000);
                queue_delayed_work(hdev->workqueue, &hdev->rpa_expired, to);