adapter: Remove temporary devices before power off
authorArchie Pusaka <apusaka@chromium.org>
Wed, 6 Jan 2021 09:26:58 +0000 (17:26 +0800)
committerAyush Garg <ayush.garg@samsung.com>
Fri, 11 Mar 2022 13:38:34 +0000 (19:08 +0530)
If adapter is powered off when a currently connected device is
being removed, there is a possibility that we haven't finish waiting
for the disconnection but the adapter is already powered down.

When this happens, the kernel would fail to clean the device's
information, for example the pairing information. This causes
disagreement between the user space and the kernel about whether the
device is already paired, because the device is successfully removed
from the user space's perspective.

This patch enforces the removal of such devices before allowing the
adapter to power off.

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

index 47abfb9..d5a5765 100644 (file)
@@ -1045,6 +1045,19 @@ static void set_mode_complete(uint8_t status, uint16_t length,
        new_settings_callback(adapter->dev_id, length, param, adapter);
 }
 
+static void remove_temporary_devices(struct btd_adapter *adapter)
+{
+       GSList *l, *next;
+
+       for (l = adapter->devices; l; l = next) {
+               struct btd_device *dev = l->data;
+
+               next = g_slist_next(l);
+               if (device_is_temporary(dev))
+                       btd_adapter_remove_device(adapter, dev);
+       }
+}
+
 static bool set_mode(struct btd_adapter *adapter, uint16_t opcode,
                                                        uint8_t mode)
 {
@@ -7023,8 +7036,10 @@ static void property_set_mode(struct btd_adapter *adapter, uint32_t setting,
                param = &mode;
                len = sizeof(mode);
 
-               if (!mode)
+               if (!mode) {
                        clear_discoverable(adapter);
+                       remove_temporary_devices(adapter);
+               }
 
                break;
        case MGMT_SETTING_DISCOVERABLE:
@@ -16259,6 +16274,7 @@ void adapter_shutdown(void)
                        continue;
 
                clear_discoverable(adapter);
+               remove_temporary_devices(adapter);
                set_mode(adapter, MGMT_OP_SET_POWERED, 0x00);
 
                adapter_remaining++;