Bluetooth: Introduce HCI_CONN_FLAG_DEVICE_PRIVACY device flag
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Fri, 3 Dec 2021 22:07:22 +0000 (14:07 -0800)
committerMarcel Holtmann <marcel@holtmann.org>
Tue, 7 Dec 2021 16:05:51 +0000 (17:05 +0100)
This introduces HCI_CONN_FLAG_DEVICE_PRIVACY which can be used by
userspace to indicate to the controller to use Device Privacy Mode to a
specific device.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
include/net/bluetooth/hci_core.h
net/bluetooth/mgmt.c

index d1b6775..cf24af6 100644 (file)
@@ -154,6 +154,7 @@ struct bdaddr_list_with_irk {
 
 enum hci_conn_flags {
        HCI_CONN_FLAG_REMOTE_WAKEUP,
+       HCI_CONN_FLAG_DEVICE_PRIVACY,
 
        __HCI_CONN_NUM_FLAGS,
 };
@@ -1466,6 +1467,9 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
 #define use_ll_privacy(dev) (ll_privacy_capable(dev) && \
                             hci_dev_test_flag(dev, HCI_ENABLE_LL_PRIVACY))
 
+#define privacy_mode_capable(dev) (use_ll_privacy(dev) && \
+                                  (hdev->commands[39] & 0x04))
+
 /* Use enhanced synchronous connection if command is supported */
 #define enhanced_sco_capable(dev) ((dev)->commands[29] & 0x08)
 
index 7d3c69c..17a5f97 100644 (file)
@@ -3978,6 +3978,11 @@ static int exp_ll_privacy_feature_changed(bool enabled, struct hci_dev *hdev,
        memcpy(ev.uuid, rpa_resolution_uuid, 16);
        ev.flags = cpu_to_le32((enabled ? BIT(0) : 0) | BIT(1));
 
+       if (enabled && privacy_mode_capable(hdev))
+               set_bit(HCI_CONN_FLAG_DEVICE_PRIVACY, hdev->conn_flags);
+       else
+               clear_bit(HCI_CONN_FLAG_DEVICE_PRIVACY, hdev->conn_flags);
+
        return mgmt_limited_event(MGMT_EV_EXP_FEATURE_CHANGED, hdev,
                                  &ev, sizeof(ev),
                                  HCI_MGMT_EXP_FEATURE_EVENTS, skip);
@@ -4461,6 +4466,13 @@ static int set_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
                if (params) {
                        bitmap_from_u64(params->flags, current_flags);
                        status = MGMT_STATUS_SUCCESS;
+
+                       /* Update passive scan if HCI_CONN_FLAG_DEVICE_PRIVACY
+                        * has been set.
+                        */
+                       if (test_bit(HCI_CONN_FLAG_DEVICE_PRIVACY,
+                                    params->flags))
+                               hci_update_passive_scan(hdev);
                } else {
                        bt_dev_warn(hdev, "No such LE device %pMR (0x%x)",
                                    &cp->addr.bdaddr,