deviceplug / btleplug

Rust Cross-Platform Host-Side Bluetooth LE Access Library
Other
789 stars 146 forks source link

Turning off OSX bluetooth adapter results in undetectable disconnect #277

Open mmastrac opened 1 year ago

mmastrac commented 1 year ago

Describe the bug

In 0.10.1, turning off the BT adapter on a MacBook 2019 Intel device would cause a disconnection event 100% of the time. It would print Event receiver died, breaking out of corebluetooth device loop multiple times, but disconnects would be correctly received.

In 0.10.2, turning off the BT adapter prints Event receiver died, breaking out of corebluetooth device loop and no disconnect events are received.

Expected behavior

Turning off the bluetooth adapter should send a disconnect event for all peripherals.

Actual behavior

Nothing happens, and the device does not send a disconnection event. Something may also be blocking the tokio event loop, as a select! that includes the BT device and a timeout stops sending the timeout.

Additional context

0.10.1 sort of worked, but 0.10.2 is definitely not working.

qdot commented 1 year ago

Ooof. Feels like the weight of our crappy macOS kludge may be getting the better of us. Will take a look, thanks for letting me know.

mmastrac commented 1 year ago

No worries. I've worked around this for now using a non-tokio thread with a watchdog that detects a wedged future and it seems to be working.

I'm currently putting the final polish on my project that makes use of it - I can definitely dig into the OSX code and get my hands dirty.

Apologies for reporting so many bugs and forgetting to mention what an awesome library this is. It's pretty much the core part of my latest project (https://github.com/mmastrac/longshot/). 😀

bxb100 commented 9 months ago

I use a timeout before write to avoid this problem

code like this:


   // edge case: https://github.com/deviceplug/btleplug/issues/277
    tokio::select! {
        _ = time::sleep(Duration::from_secs(2)) => {
            log::error!(target: "call_printer", "printer timeout");
            return Err(anyhow!("printer timeout"));
        }
        // connect to the device
        _ = printer.is_connected() => {
            log::debug!("connected to printer");
        }
    }