Re: [PATCH BlueZ] adapter: Include pending flags in device_flags_changed_callback

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Right, makes sense. I did something similar to what you suggested in "[PATCH BlueZ] device: Clear only the pending flags that have been applied".

However, I changed it to `dev->pending_flags &= ~current_flags`, because otherwise we could have left `pending_flags` to some unexpected value.

For example, if we are in `device_set_wake_allowed()` and we want to enable the wake allowed:
- Assume the current flags is 2, i.e. DEVICE_FLAG_DEVICE_PRIVACY
- It calls `adapter_set_device_flags()` with current flags plus DEVICE_FLAG_REMOTE_WAKEUP (aka 3) - In `adapter_set_device_flags()` we have `flags == 3`, which then gets assigned to `pending_flags`
- In `btd_device_flags_changed()` we end up with `changed_flags == 1`

In this situation, if we only remove the `changed_flags`, pending flags will remain with a value of 2 even if there are no other pending changes.
For this reason I remove the current_flags, instead of only changed_flags.

The other two patches that I created "[PATCH BlueZ v2] device: Clear pending_flags on error" and "[PATCH BlueZ] adapter: Fix the pending changing flags check", are kinda related to this one, but I sent them separately because they don't really depend on one another.


On 1/28/25 9:33 PM, Luiz Augusto von Dentz wrote:
Hi Ludovico,

On Tue, Jan 28, 2025 at 5:30 AM Ludovico de Nittis
<ludovico.denittis@xxxxxxxxxxxxx> wrote:
When signalling the new device flags, we need to include the pending
ones. Otherwise, the eventual non-zero `pending_flags` will be wiped out
in `btd_device_flags_changed()`, and we'll lose the pending changed
flags.

Fixes https://github.com/bluez/bluez/issues/1076
---
  src/adapter.c | 5 ++++-
  1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/adapter.c b/src/adapter.c
index 5d4117a49..cbc0f678f 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -5727,6 +5727,7 @@ static void device_flags_changed_callback(uint16_t index, uint16_t length,
         struct btd_adapter *adapter = user_data;
         struct btd_device *dev;
         char addr[18];
+       uint32_t changed_flags = 0;

         if (length < sizeof(*ev)) {
                 btd_error(adapter->dev_id,
@@ -5744,7 +5745,9 @@ static void device_flags_changed_callback(uint16_t index, uint16_t length,
                 return;
         }

-       btd_device_flags_changed(dev, ev->supported_flags, ev->current_flags);
+       changed_flags = ev->current_flags | btd_device_get_pending_flags(dev);
+
+       btd_device_flags_changed(dev, ev->supported_flags, changed_flags);
This doesn't sound right, it would be as if the pending flags always
succeed which I don't think it is always the case, perhaps we should
something like the following:

diff --git a/src/device.c b/src/device.c
index e8bff718c201..4959f36542fb 100644
--- a/src/device.c
+++ b/src/device.c
@@ -7413,7 +7413,7 @@ void btd_device_flags_changed(struct btd_device
*dev, uint32_t supported_flags,

         dev->supported_flags = supported_flags;
         dev->current_flags = current_flags;
-       dev->pending_flags = 0;
+       dev->pending_flags &= ~changed_flags;

         if (!changed_flags)
                 return;

That way we clear pending_flags based on the changed_flags.

  }


--
2.48.1








[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux