void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8],
__u8 ltk[16]);
-int hci_update_random_address(struct hci_request *req, u8 *own_addr_type);
+int hci_update_random_address(struct hci_request *req, bool require_privacy,
+ u8 *own_addr_type);
#define SCO_AIRMODE_MASK 0x0003
#define SCO_AIRMODE_CVSD 0x0000
memset(&cp, 0, sizeof(cp));
- err = hci_update_random_address(&req, &own_addr_type);
+ /* Update random address, but set require_privacy to false so
+ * that we never connect with an unresolvable address.
+ */
+ err = hci_update_random_address(&req, false, &own_addr_type);
if (err < 0)
return err;
BT_ERR("Disable LE scanning request failed: err %d", err);
}
-int hci_update_random_address(struct hci_request *req, u8 *own_addr_type)
+int hci_update_random_address(struct hci_request *req, bool require_privacy,
+ u8 *own_addr_type)
{
struct hci_dev *hdev = req->hdev;
int err;
return 0;
}
+ /* In case of required privacy without resolvable private address,
+ * use an unresolvable private address. This is useful for active
+ * scanning and non-connectable advertising.
+ */
+ if (require_privacy) {
+ bdaddr_t urpa;
+
+ get_random_bytes(&urpa, 6);
+ urpa.b[5] &= 0x3f; /* Clear two most significant bits */
+
+ *own_addr_type = ADDR_LE_DEV_RANDOM;
+ hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6, &urpa);
+ return 0;
+ }
+
/* If forcing static address is in use or there is no public
* address use the static address as random address (but skip
* the HCI command if the current random address is already the
memset(&cp, 0, sizeof(cp));
- if (hci_update_random_address(req, &own_addr_type) < 0)
+ if (hci_update_random_address(req, false, &own_addr_type) < 0)
return;
cp.min_interval = __constant_cpu_to_le16(0x0800);
memset(¶m_cp, 0, sizeof(param_cp));
- err = hci_update_random_address(&req, &own_addr_type);
+ /* All active scans will be done with either a resolvable
+ * private address (when privacy feature has been enabled)
+ * or unresolvable private address.
+ */
+ err = hci_update_random_address(&req, true, &own_addr_type);
if (err < 0) {
err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
MGMT_STATUS_FAILED);