From 6cfcd660ce9bbfc5fb7d333aeba116841192e87e Mon Sep 17 00:00:00 2001 From: torlando-tech Date: Thu, 6 Nov 2025 00:36:14 -0500 Subject: [PATCH] fix(ble): Retry ConnectDevice() on every connection to prevent BR/EDR fallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes "br-connection-canceled" and "Operation already in progress" errors caused by BlueZ attempting Classic Bluetooth (BR/EDR) instead of BLE (LE). Problem: - ConnectDevice() with AddressType="public" forces LE-only connections - Previously only tried once (has_connect_device is None check) - After first failure, ALL future connections skipped ConnectDevice() - Fell back to client.connect() which may trigger BR/EDR on dual-mode adapters Solution: - Changed condition from "is None" to "!= False" - Now retries ConnectDevice() on every connection (unless definitively unavailable) - Improved error handling: * AttributeError → method doesn't exist, disable permanently * Other exceptions → transient failure, retry next time - Elevated log level to INFO for successful LE connections Impact: - Eliminates BR/EDR connection attempts on BLE-only devices - Fixes immediate disconnects after pairing - Prevents connection blacklisting due to protocol mismatch Tested on: Raspberry Pi with BlueZ 5.66 + experimental mode --- src/RNS/Interfaces/linux_bluetooth_driver.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/RNS/Interfaces/linux_bluetooth_driver.py b/src/RNS/Interfaces/linux_bluetooth_driver.py index dcbf4e1..41c8d9c 100644 --- a/src/RNS/Interfaces/linux_bluetooth_driver.py +++ b/src/RNS/Interfaces/linux_bluetooth_driver.py @@ -756,14 +756,19 @@ class LinuxBluetoothDriver(BLEDriverInterface): # Try LE-specific connection if BlueZ >= 5.49 le_connection_attempted = False - if self.bluez_version and self.bluez_version >= (5, 49) and self.has_connect_device is None: + if self.bluez_version and self.bluez_version >= (5, 49) and self.has_connect_device != False: try: await self._connect_via_dbus_le(address) le_connection_attempted = True - self._log(f"LE-specific connection initiated for {address}", "DEBUG") - except Exception as e: - self._log(f"ConnectDevice() unavailable, falling back to standard connection", "DEBUG") + self._log(f"LE-specific connection initiated for {address}", "INFO") + except AttributeError as e: + # ConnectDevice method doesn't exist in this BlueZ version + self._log(f"ConnectDevice() method not available: {e}", "WARNING") self.has_connect_device = False + except Exception as e: + # ConnectDevice exists but failed - retry on next connection + self._log(f"ConnectDevice() failed (will retry): {e}", "WARNING") + # Don't set has_connect_device to False - allow retry # Create BleakClient client = BleakClient(address, disconnected_callback=disconnected_callback, timeout=self.connection_timeout)