OpenBluetoothToolbox / SimpleBLE

SimpleBLE - the all-in-one Bluetooth library for MacOS, iOS, Windows, Linux and Android.
https://www.simpleble.org
Other
655 stars 110 forks source link

SimpleBLE C++ has a strange interface. Confusing mix of blocking and non-blocking functions #247

Closed ZaneL closed 1 year ago

ZaneL commented 1 year ago

This makes sense to me. First you start the scan (non-blocking)

bleAdapter.scan_start();

..and these callbacks get fired asynchronously

bleAdapter.set_callback_on_scan_start([]() 
bleAdapter.set_callback_on_scan_stop([]() 
bleAdapter.set_callback_on_scan_found([&](SimpleBLE::Peripheral peripheral) 

Then you connect to a peripheral

selectedPeripheral.connect();

...but this function blocks, and there is no way to tell if it connected successfully or not. There are these callback functions, but these still won't tell you if the connection failed, unless you wait for 10 seconds and assume that if on_connected wasn't fired, it failed, which isn't really a great assumption to make.

void set_callback_on_connected(std::function<void()> on_connected)
void set_callback_on_disconnected(std::function<void()> on_disconnected)

To make connect() non blocking, I did something like this:

std::future<void> connectPeripheralAsync()
{
    return std::async(std::launch::async, []() {
        selectedPeripheral.connect();
    });
}

I feel like I'm not understanding how all this was intended to be used.

cwahn commented 1 year ago

I do agree that it does have a strange C++ API. Aysncness is hidden and documented nowhere in docs and examples. So I wasted hours to find out that the weird behaviors of the library are due to the internal async operation.

Also as @ZaneL pointed out, the connect() is blocking, and does not work properly if it gets called by another callback. I believe It has to be called after the scanning is completely terminated.

kdewald commented 1 year ago

Hey @ZaneL and @cwahn, thanks for reaching out. I'd first like to point out that in a similar manner to a lot of open-source projects this library is maintained in my free time out of my own good will without receiving any kind of remuneration for it, which implies no direct obligation to users. Documentation contributions are certainly appreciated.

The API design for SimpleBLE follows a blocking+callback architecture. Each action will block for as much as it needs to complete and once they return, all side-effects have been propagated. The fact that some of these actions are short (like scan_start) doesn't mean they are non-blocking.

Going to the issue described here, it's possible that there's a deadlock happening when connect is called from within a callback. If you can write a reproducible example and provide some information about your platform, feel free to open an issue specifically for that.