universal_ble icon indicating copy to clipboard operation
universal_ble copied to clipboard

Linux device scanning is weak

Open Erhannis opened this issue 1 year ago • 8 comments

I've tested the package on Windows, iOS, Mac, Android, and now Linux. With like 40 hours of work, I've gotten it to work fairly reliably across all of these (thank you), except that Linux device scans only occasionally return a device. Since, a la https://github.com/Navideck/universal_ble/issues/69#issuecomment-2332472762 , it appears that scanning a device is crucial to connecting to it, this means difficulties (re)connecting. My instinct is that e.g. Linux is only returning a single result for a device and expecting you to cache it, no matter how long it's been since the last scan - or something. Like, I've turned BLE off and on and then gotten a device in a scan, but otherwise frequently (always?) fail to get the device in a scan. I'll do some more testing later, but atm that's my impression - any thoughts, based on having worked with the API more directly?

Erhannis avatar Sep 05 '24 21:09 Erhannis

@Erhannis we are using Bluez internally for Linux, can you try Bluez once to confirm if its UniversalBle issue, or Bluez not discovering devices properly

import 'package:bluez/bluez.dart';

void main() async {
  var client = BlueZClient();
  await client.connect();

  if (client.adapters.isEmpty) {
    print('No Bluetooth adapters found');
    await client.close();
    return;
  }

  BlueZAdapter adapter = client.adapters.first;

  client.deviceAdded.listen((BlueZDevice device) {
    // Get your device here
 
  });

  adapter.startDiscovery();
}

rohitsangwan01 avatar Sep 06 '24 04:09 rohitsangwan01

Yeah, adapting the code you gave, when I first start scanning, I get the expected bluetooth devices, but if I stop scanning and start scanning again, nothing is shown. (My impression, again, is that it only reports a given device once per app run, for the most part.) I'm inclined to consider this a failing on BlueZ's part - first, because it's a pain having to cache the results yourself, and second, because caching can't distinguish "devices that are no longer present" from "devices that simply have already been scanned", and so BlueZ does not permit the user to refresh the list of actively visible devices.

Erhannis avatar Sep 09 '24 23:09 Erhannis

Ah - poking around the BlueZ git, I do notice there's a "client.devices" list, which contains previously scanned devices. It doesn't really fix the "unknown-stale devices" problem, but perhaps universal_ble could use it to report to listeners on scan re-start, similar as I think happens on other platforms?

Erhannis avatar Sep 09 '24 23:09 Erhannis

Ok, I no longer know WHAT exactly BlueZ is doing. Devices are disappearing from client.devices, showing up again in the scan, who knows. Nevertheless, the impression I'm getting from its antics is that if, on scan start, universal_ble were to listen for new devices and also return the list of client.devices, that should give the user the most up-to-date list currently available. It seems like any active device can be found EITHER in client.devices or the subsequent result of a scan.

Erhannis avatar Sep 09 '24 23:09 Erhannis

@Erhannis Thank you for the detailed explanation. We're following a similar approach. After calling startScan, we invoke _client.devices and also initiate device discovery. But seems like even after combining both, discovery is not that great compared to other platforms

rohitsangwan01 avatar Sep 10 '24 04:09 rohitsangwan01

Ok, I think I pinpointed the problem I was running into:

  1. Scan for devices
  2. Connect to a device
  3. Turn off the device
  4. Disconnect from the device
  5. After 10 seconds the disconnect should timeout

I don't know at exactly what point things go weird, but from this point on, the BlueZ call startDiscovery does not return. This means (among other things) that Universal BLE's code never reaches the point where it iterates through the existing devices. ALSO no new devices are discovered. In my tests, this state lasts until you turn bluetooth (or the computer) off and on again - restarting the flutter program doesn't fix it. So, I suspect this is either somehow a bug in BlueZ, or maybe the linux bluetooth code.

Btw, I'm on Ubuntu 24.04.1 LTS

Erhannis avatar Sep 21 '24 23:09 Erhannis

This means (among other things) that Universal BLE's code never reaches the point where it iterates through the existing devices

This might be because of queue, because disconnect still not completed, so startScan will wait for it to complete, try to disable queue on linux to confirm

rohitsangwan01 avatar Sep 22 '24 02:09 rohitsangwan01

I had the last days the same problem on Linux. On my side, the flutter package dbus (Version 0.7.8) was the problem. A lot of signals on the D-Bus did not come in. When I use dbus from git, everything works fine.

marcel-cd avatar Oct 13 '24 12:10 marcel-cd

@marcel-cd @Erhannis I would encourage you to open an issue at dbus and bluez flutter packages and ask for a new release. I will keep this issue open for tracking the status.

fotiDim avatar Dec 09 '24 16:12 fotiDim

Bluez.dart, in it's newest version 0.8.3, does now have dbus 0.7.11 integrated.

marcel-cd avatar Feb 11 '25 20:02 marcel-cd

It will be included in 0.16.0 coming out next week.

fotiDim avatar Feb 15 '25 15:02 fotiDim