bluetooth
bluetooth copied to clipboard
adapter.Scan() can't recover from panic on linux
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.
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
StartDiscoveryto 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
}
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.
I think that https://github.com/tinygo-org/bluetooth/pull/351 handles this exact issue.