From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx> This adds support for setting Device Privacy flag when enabled in main.conf via Privacy = device,limited-device. --- lib/mgmt.h | 3 +- src/adapter.c | 76 +++++++++++++++++++++++---------------------------- src/adapter.h | 9 ++++-- src/device.c | 58 +++++++++++++++++++++++++++++---------- src/device.h | 1 - 5 files changed, 86 insertions(+), 61 deletions(-) diff --git a/lib/mgmt.h b/lib/mgmt.h index 0d1678f01..400167e9b 100644 --- a/lib/mgmt.h +++ b/lib/mgmt.h @@ -665,7 +665,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 508917e58..309956bbb 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -5308,6 +5308,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) { @@ -5342,6 +5359,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, @@ -5383,42 +5412,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; @@ -5433,14 +5429,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 db3c17f23..d191daf5d 100644 --- a/src/adapter.h +++ b/src/adapter.h @@ -219,8 +219,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 1b4dae685..6b398bd39 100644 --- a/src/device.c +++ b/src/device.c @@ -1403,9 +1403,45 @@ 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. @@ -1415,25 +1451,17 @@ 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); } - static gboolean dev_property_get_wake_allowed(const GDBusPropertyTable *property, DBusMessageIter *iter, void *data) diff --git a/src/device.h b/src/device.h index 5f615cb4b..b37a0a3d2 100644 --- a/src/device.h +++ b/src/device.h @@ -132,7 +132,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, -- 2.31.1