adapter: Set Device Privacy Mode
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Thu, 4 Nov 2021 00:26:30 +0000 (17:26 -0700)
committerAyush Garg <ayush.garg@samsung.com>
Fri, 11 Mar 2022 13:38:37 +0000 (19:08 +0530)
This adds support for setting Device Privacy flag when enabled in
main.conf via Privacy = device,limited-device.

Signed-off-by: Anuj Jain <anuj01.jain@samsung.com>
Signed-off-by: Ayush Garg <ayush.garg@samsung.com>
lib/mgmt.h
src/adapter.c
src/adapter.h
src/device.c
src/device.h

index 0b613be..75de186 100644 (file)
@@ -675,7 +675,8 @@ struct mgmt_rp_get_device_flags {
        uint32_t current_flags;
 } __packed;
 
-#define DEVICE_FLAG_REMOTE_WAKEUP      (1 << 0)
+#define DEVICE_FLAG_REMOTE_WAKEUP      BIT(0)
+#define DEVICE_FLAG_DEVICE_PRIVACY     BIT(1)
 
 #define MGMT_OP_SET_DEVICE_FLAGS       0x0050
 #define MGMT_SET_DEVICE_FLAGS_SIZE     11
index 2f6396e..2e54edb 100644 (file)
@@ -10173,6 +10173,23 @@ void adapter_accept_list_remove(struct btd_adapter *adapter,
                                remove_accept_list_complete, adapter, NULL);
 }
 
+static void set_device_privacy_complete(uint8_t status, uint16_t length,
+                                        const void *param, void *user_data)
+{
+       const struct mgmt_rp_set_device_flags *rp = param;
+
+       if (status != MGMT_STATUS_SUCCESS) {
+               error("Set device flags return status: %s",
+                                       mgmt_errstr(status));
+               return;
+       }
+
+       if (length < sizeof(*rp)) {
+               error("Too small Set Device Flags complete event: %d", length);
+               return;
+       }
+}
+
 static void add_device_complete(uint8_t status, uint16_t length,
                                        const void *param, void *user_data)
 {
@@ -10207,6 +10224,18 @@ static void add_device_complete(uint8_t status, uint16_t length,
        }
 
        DBG("%s (%u) added to kernel connect list", addr, rp->addr.type);
+
+       if (btd_opts.device_privacy) {
+               uint32_t flags = btd_device_get_current_flags(dev);
+
+               /* Set Device Privacy Mode has not set the flag yet. */
+               if (!(flags & DEVICE_FLAG_DEVICE_PRIVACY)) {
+                       adapter_set_device_flags(adapter, dev, flags |
+                                               DEVICE_FLAG_DEVICE_PRIVACY,
+                                               set_device_privacy_complete,
+                                               NULL);
+               }
+       }
 }
 
 void adapter_auto_connect_add(struct btd_adapter *adapter,
@@ -10248,42 +10277,9 @@ void adapter_auto_connect_add(struct btd_adapter *adapter,
        adapter->connect_list = g_slist_append(adapter->connect_list, device);
 }
 
-static void set_device_wakeable_complete(uint8_t status, uint16_t length,
-                                        const void *param, void *user_data)
-{
-       const struct mgmt_rp_set_device_flags *rp = param;
-       struct btd_adapter *adapter = user_data;
-       struct btd_device *dev;
-       char addr[18];
-
-       if (status != MGMT_STATUS_SUCCESS) {
-               btd_error(adapter->dev_id, "Set device flags return status: %s",
-                         mgmt_errstr(status));
-               return;
-       }
-
-       if (length < sizeof(*rp)) {
-               btd_error(adapter->dev_id,
-                         "Too small Set Device Flags complete event: %d",
-                         length);
-               return;
-       }
-
-       ba2str(&rp->addr.bdaddr, addr);
-
-       dev = btd_adapter_find_device(adapter, &rp->addr.bdaddr, rp->addr.type);
-       if (!dev) {
-               btd_error(adapter->dev_id,
-                         "Set Device Flags complete for unknown device %s",
-                         addr);
-               return;
-       }
-
-       device_set_wake_allowed_complete(dev);
-}
-
-void adapter_set_device_wakeable(struct btd_adapter *adapter,
-                                struct btd_device *device, bool wakeable)
+void adapter_set_device_flags(struct btd_adapter *adapter,
+                               struct btd_device *device, uint32_t flags,
+                               mgmt_request_func_t func, void *user_data)
 {
        struct mgmt_cp_set_device_flags cp;
        const bdaddr_t *bdaddr;
@@ -10298,14 +10294,10 @@ void adapter_set_device_wakeable(struct btd_adapter *adapter,
        memset(&cp, 0, sizeof(cp));
        bacpy(&cp.addr.bdaddr, bdaddr);
        cp.addr.type = bdaddr_type;
-       cp.current_flags = btd_device_get_current_flags(device);
-       if (wakeable)
-               cp.current_flags |= DEVICE_FLAG_REMOTE_WAKEUP;
-       else
-               cp.current_flags &= ~DEVICE_FLAG_REMOTE_WAKEUP;
+       cp.current_flags = cpu_to_le32(flags);
 
        mgmt_send(adapter->mgmt, MGMT_OP_SET_DEVICE_FLAGS, adapter->dev_id,
-                 sizeof(cp), &cp, set_device_wakeable_complete, adapter, NULL);
+                 sizeof(cp), &cp, func, user_data, NULL);
 }
 
 static void device_flags_changed_callback(uint16_t index, uint16_t length,
index 66051fd..d085a22 100644 (file)
@@ -311,8 +311,13 @@ int adapter_connect_list_add(struct btd_adapter *adapter,
                                        struct btd_device *device);
 void adapter_connect_list_remove(struct btd_adapter *adapter,
                                                struct btd_device *device);
-void adapter_set_device_wakeable(struct btd_adapter *adapter,
-                                struct btd_device *dev, bool wakeable);
+typedef void (*adapter_set_device_flags_func_t)(uint8_t status, uint16_t length,
+                                               const void *param,
+                                               void *user_data);
+void adapter_set_device_flags(struct btd_adapter *adapter,
+                               struct btd_device *device, uint32_t flags,
+                               adapter_set_device_flags_func_t func,
+                               void *user_data);
 void adapter_auto_connect_add(struct btd_adapter *adapter,
                                        struct btd_device *device);
 void adapter_auto_connect_remove(struct btd_adapter *adapter,
index bb26724..2439977 100644 (file)
@@ -1926,9 +1926,44 @@ void device_set_wake_override(struct btd_device *device, bool wake_override)
        }
 }
 
+static void device_set_wake_allowed_complete(struct btd_device *device)
+{
+       if (device->wake_id != -1U) {
+               g_dbus_pending_property_success(device->wake_id);
+               device->wake_id = -1U;
+       }
+
+       device->wake_allowed = device->pending_wake_allowed;
+       g_dbus_emit_property_changed(dbus_conn, device->path,
+                                       DEVICE_INTERFACE, "WakeAllowed");
+
+       store_device_info(device);
+}
+
+static void set_wake_allowed_complete(uint8_t status, uint16_t length,
+                                        const void *param, void *user_data)
+{
+       const struct mgmt_rp_set_device_flags *rp = param;
+       struct btd_device *dev = user_data;
+
+       if (status != MGMT_STATUS_SUCCESS) {
+               error("Set device flags return status: %s",
+                                       mgmt_errstr(status));
+               return;
+       }
+
+       if (length < sizeof(*rp)) {
+               error("Too small Set Device Flags complete event: %d", length);
+               return;
+       }
+
+       device_set_wake_allowed_complete(dev);
+}
+
 void device_set_wake_allowed(struct btd_device *device, bool wake_allowed,
                             GDBusPendingPropertySet id)
 {
+       uint32_t flags;
        /* Pending and current value are the same unless there is a change in
         * progress. Only update wake allowed if pending value doesn't match the
         * new value.
@@ -1938,22 +1973,14 @@ void device_set_wake_allowed(struct btd_device *device, bool wake_allowed,
 
        device->wake_id = id;
        device->pending_wake_allowed = wake_allowed;
-       adapter_set_device_wakeable(device_get_adapter(device), device,
-                                   wake_allowed);
-}
-
-void device_set_wake_allowed_complete(struct btd_device *device)
-{
-       if (device->wake_id != -1U) {
-               g_dbus_pending_property_success(device->wake_id);
-               device->wake_id = -1U;
-       }
-
-       device->wake_allowed = device->pending_wake_allowed;
-       g_dbus_emit_property_changed(dbus_conn, device->path,
-                                       DEVICE_INTERFACE, "WakeAllowed");
+       flags = device->current_flags;
+       if (wake_allowed)
+               flags |= DEVICE_FLAG_REMOTE_WAKEUP;
+       else
+               flags &= ~DEVICE_FLAG_REMOTE_WAKEUP;
 
-       store_device_info(device);
+       adapter_set_device_flags(device->adapter, device, flags,
+                                       set_wake_allowed_complete, device);
 }
 
 
index 8bc91d0..8a6cf1a 100644 (file)
@@ -177,7 +177,6 @@ void device_set_wake_support(struct btd_device *device, bool wake_support);
 void device_set_wake_override(struct btd_device *device, bool wake_override);
 void device_set_wake_allowed(struct btd_device *device, bool wake_allowed,
                             guint32 id);
-void device_set_wake_allowed_complete(struct btd_device *device);
 void device_set_refresh_discovery(struct btd_device *dev, bool refresh);
 typedef void (*disconnect_watch) (struct btd_device *device, gboolean removal,
                                        void *user_data);