bluetooth icon indicating copy to clipboard operation
bluetooth copied to clipboard

adapter.Scan() can't recover from panic on linux

Open jasday opened this issue 1 year ago • 3 comments
trafficstars

In gap_linux.go, you cannot recover from a panic made within the callback to adapter.Scan().

If you attempt to recover from a panic, and re-call Scan() after the recovery, a.adapter.Call("org.bluez.Adapter1.StartDiscovery", 0).Err returns an Operation already in progress error.

It looks like cancelChan was meant to be used to call a.adapter.Call("org.bluez.Adapter1.StopDiscovery", 0), but if the callback panics, the channel is never consumed, so the call to stop the discovery is never sent. This leads to the above error when attempting to rescan.

jasday avatar Aug 20 '24 13:08 jasday

I think the solution is as follows, but would like some input from maintainers before putting up a pr.

  • Add a deferred call to a.adapter.Call("org.bluez.Adapter1.StopDiscovery", 0) to cleanup after function exit
  • Add a check before calling StartDiscovery to ensure that the device hasn't already started - this should prevent the above error:
// Instruct BlueZ to start discovering if it isn't already.
if disc, err := a.adapter.GetProperty("org.bluez.Adapter1.Discovering"); disc.Value().(bool) == false && err == nil {
	err = a.adapter.Call("org.bluez.Adapter1.StartDiscovery", 0).Err
	if err != nil {
		return err
	}
        // Add the defer a.adapter.Call("org.bluez.Adapter1.StopDiscovery", 0) here
} else if err != nil {
	return err
}

jasday avatar Aug 20 '24 13:08 jasday

I think I am seeing something related to this too, where sometimes I get the same "Operation already in progress" error and I can't seem to get out of that error state without restarting the bluetooth service or my application.

smatton avatar Sep 16 '24 14:09 smatton

I think that https://github.com/tinygo-org/bluetooth/pull/351 handles this exact issue.

deadprogram avatar Mar 05 '25 16:03 deadprogram