From 7950cbeb8ec6cfabdef8726ab5cd3042a579cd63 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 3 Nov 2021 17:26:30 -0700 Subject: [PATCH] adapter: Set Device Privacy Mode This adds support for setting Device Privacy flag when enabled in main.conf via Privacy = device,limited-device. Signed-off-by: Anuj Jain Signed-off-by: Ayush Garg --- lib/mgmt.h | 3 ++- src/adapter.c | 76 ++++++++++++++++++++++++++--------------------------------- src/adapter.h | 9 +++++-- src/device.c | 57 ++++++++++++++++++++++++++++++++------------ src/device.h | 1 - 5 files changed, 85 insertions(+), 61 deletions(-) diff --git a/lib/mgmt.h b/lib/mgmt.h index 0b613be..75de186 100644 --- a/lib/mgmt.h +++ b/lib/mgmt.h @@ -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 diff --git a/src/adapter.c b/src/adapter.c index 2f6396e..2e54edb 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -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, diff --git a/src/adapter.h b/src/adapter.h index 66051fd..d085a22 100644 --- a/src/adapter.h +++ b/src/adapter.h @@ -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, diff --git a/src/device.c b/src/device.c index bb26724..2439977 100644 --- a/src/device.c +++ b/src/device.c @@ -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); } diff --git a/src/device.h b/src/device.h index 8bc91d0..8a6cf1a 100644 --- a/src/device.h +++ b/src/device.h @@ -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); -- 2.7.4