diff mbox series

[v4] device: Remove device after all bearers are disconnected

Message ID 20240927023854.2447283-1-quic_chejiang@quicinc.com
State New
Headers show
Series [v4] device: Remove device after all bearers are disconnected | expand

Commit Message

Cheng Jiang Sept. 27, 2024, 2:38 a.m. UTC
For a combo mode remote, both BR/EDR and BLE may be connected.
RemoveDevice should be handled after all bearers are dropped,
otherwise, remove device is not performed in adapter_remove_connection.
---
 src/device.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/src/device.c b/src/device.c
index f8f61e643..4efd755a0 100644
--- a/src/device.c
+++ b/src/device.c
@@ -3492,8 +3492,27 @@  void device_remove_connection(struct btd_device *device, uint8_t bdaddr_type,
 		DBusMessage *msg = device->disconnects->data;
 
 		if (dbus_message_is_method_call(msg, ADAPTER_INTERFACE,
-								"RemoveDevice"))
+							"RemoveDevice")) {
+
+			/* Don't handle the RemoveDevice msg if device is
+			 * connected. For a dual-mode remote, both BR/EDR
+			 * and BLE may be connected, RemoveDevice should
+			 * be handled after all bearers are disconnects.
+			 * Otherwise, if msg is removed, but not all
+			 * connection are dropped, this function returns
+			 * before *remove is updated, then after all
+			 * connections are dropped, but device->disconnects
+			 * is NULL, remove_device is not updated. Consequently
+			 * *remove is not set to true. The device is not removed
+			 * for adapter in adapter_remove_connection. Need
+			 * to wait for temporary device timeout to remove
+			 * the device.
+			 */
+			if (device->bredr_state.connected ||
+					device->le_state.connected)
+				break;
 			remove_device = true;
+		}
 
 		g_dbus_send_reply(dbus_conn, msg, DBUS_TYPE_INVALID);
 		device->disconnects = g_slist_remove(device->disconnects, msg);