Summary
On BlueZ 5.87 (and possibly earlier versions), calling SetDiscoveryFilter before StartDiscovery causes BlueZ to return org.bluez.Error.InProgress ("Operation already in progress") even when Discovering reports false.
Affected code
gap_linux.go lines 247-287 — Adapter.Scan calls SetDiscoveryFilter({Transport:"le"}) at line 247 before calling StartDiscovery at line 287.
Environment
- BlueZ: 5.87
- Kernel: 7.1.8
tinygo.org/x/bluetooth: v0.15.0 (latest) and current main (commit 5372045)
Reproduction
A minimal Go program that calls adapter.Scan fails with:
Scan returned: Operation already in progress
The error is confirmed to come directly from BlueZ via D-Bus, not from the library itself (errScanning has a different message: "bluetooth: a scan is already in progress").
D-Bus reproduction (Python)
import dbus
import time
bus = dbus.SystemBus()
adapter = bus.get_object('org.bluez', '/org/bluez/hci0')
# Reset
try: adapter.StopDiscovery(dbus_interface='org.bluez.Adapter1')
except: pass
time.sleep(1)
# This sequence FAILS:
try:
adapter.SetDiscoveryFilter({'Transport': 'le'}, dbus_interface='org.bluez.Adapter1')
print("SetDiscoveryFilter OK")
except Exception as e:
print("SetDiscoveryFilter:", e)
try:
adapter.StartDiscovery(dbus_interface='org.bluez.Adapter1')
print("StartDiscovery OK")
except Exception as e:
print("StartDiscovery error:", repr(e)) # <-- "Operation already in progress"
Output:
SetDiscoveryFilter OK
StartDiscovery error: DBusException('Operation already in progress')
Proposed fix
Reversing the call order fixes the issue — StartDiscovery first, then SetDiscoveryFilter:
# This sequence WORKS:
adapter.StartDiscovery(dbus_interface='org.bluez.Adapter1')
adapter.SetDiscoveryFilter({'Transport': 'le'}, dbus_interface='org.bluez.Adapter1')
Additionally, calling StartDiscovery without any prior SetDiscoveryFilter also works and is repeatable across multiple cycles.
Proposed change in gap_linux.go
Move the StartDiscovery call (line 287) before the SetDiscoveryFilter call (line 247), or skip the SetDiscoveryFilter call entirely since the manufacturer-data filter on the client side achieves the same practical result.
I'm also maintaining a local workaround in my project (midea-ble-go) that reimplements Scan with the reversed call order via direct D-Bus calls, which I'd like to upstream or remove once this is fixed here.
Summary
On BlueZ 5.87 (and possibly earlier versions), calling
SetDiscoveryFilterbeforeStartDiscoverycauses BlueZ to returnorg.bluez.Error.InProgress("Operation already in progress") even whenDiscoveringreportsfalse.Affected code
gap_linux.golines 247-287 —Adapter.ScancallsSetDiscoveryFilter({Transport:"le"})at line 247 before callingStartDiscoveryat line 287.Environment
tinygo.org/x/bluetooth: v0.15.0 (latest) and currentmain(commit 5372045)Reproduction
A minimal Go program that calls
adapter.Scanfails with:The error is confirmed to come directly from BlueZ via D-Bus, not from the library itself (
errScanninghas a different message:"bluetooth: a scan is already in progress").D-Bus reproduction (Python)
Output:
Proposed fix
Reversing the call order fixes the issue —
StartDiscoveryfirst, thenSetDiscoveryFilter:Additionally, calling
StartDiscoverywithout any priorSetDiscoveryFilteralso works and is repeatable across multiple cycles.Proposed change in gap_linux.go
Move the
StartDiscoverycall (line 287) before theSetDiscoveryFiltercall (line 247), or skip theSetDiscoveryFiltercall entirely since the manufacturer-data filter on the client side achieves the same practical result.I'm also maintaining a local workaround in my project (midea-ble-go) that reimplements
Scanwith the reversed call order via direct D-Bus calls, which I'd like to upstream or remove once this is fixed here.