Commit 2b5224dc authored by Marcel Holtmann's avatar Marcel Holtmann Committed by Johan Hedberg

Bluetooth: Store current RPA and update it if needed

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: default avatarMarcel Holtmann <marcel@holtmann.org>
Signed-off-by: default avatarJohan Hedberg <johan.hedberg@intel.com>
parent 41c90c18
...@@ -308,6 +308,7 @@ struct hci_dev { ...@@ -308,6 +308,7 @@ struct hci_dev {
__u8 irk[16]; __u8 irk[16];
__u32 rpa_timeout; __u32 rpa_timeout;
struct delayed_work rpa_expired; struct delayed_work rpa_expired;
bdaddr_t rpa;
int (*open)(struct hci_dev *hdev); int (*open)(struct hci_dev *hdev);
int (*close)(struct hci_dev *hdev); int (*close)(struct hci_dev *hdev);
......
...@@ -3339,26 +3339,25 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy, ...@@ -3339,26 +3339,25 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy,
int err; int err;
/* If privacy is enabled use a resolvable private address. If /* If privacy is enabled use a resolvable private address. If
* the current RPA has expired or there's something else than an * current RPA has expired or there is something else than
* RPA currently in use regenerate a new one. * the current RPA in use, then generate a new one.
*/ */
if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) { if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) {
bdaddr_t rpa;
int to; int to;
*own_addr_type = ADDR_LE_DEV_RANDOM; *own_addr_type = ADDR_LE_DEV_RANDOM;
if (!test_and_clear_bit(HCI_RPA_EXPIRED, &hdev->dev_flags) && 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; 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) { if (err < 0) {
BT_ERR("%s failed to generate new RPA", hdev->name); BT_ERR("%s failed to generate new RPA", hdev->name);
return err; 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); to = msecs_to_jiffies(hdev->rpa_timeout * 1000);
queue_delayed_work(hdev->workqueue, &hdev->rpa_expired, to); queue_delayed_work(hdev->workqueue, &hdev->rpa_expired, to);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment