deviceplug / btleplug

Rust Cross-Platform Host-Side Bluetooth LE Access Library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ERROR btleplug::corebluetooth::peripheral > Event receiver died, breaking out of corebluetooth device loop.

mmastrac opened this issue · comments

Describe the bug

While trying to connect and disconnect from a Delonghi BLE-enabled coffee maker, the CoreBluetooth event loop error is being shown reliably. I am using a copy of discover_adapters_peripherals.rs in my local code for testing.

This bug happens each and every time I try to connect to the machine.

Running Monterey 12.6 (21G115), Intel 2019 Mac.

Expected behavior

The code should connect and disconnect reliably.

Actual behavior

Starting scan on CoreBluetooth...
Peripheral "D1538664" is connected: false
Connecting to peripheral "D1538664"...
Now connected (true) to peripheral "D1538664"...
Discover peripheral "D1538664" services...
Service UUID 00035b03-58e6-07dd-021a-08123a000300, primary: true
  Characteristic { uuid: 00035b03-58e6-07dd-021a-08123a000301, service_uuid: 00035b03-58e6-07dd-021a-08123a000300, properties: READ | WRITE | INDICATE }
  Characteristic { uuid: 00035b03-58e6-07dd-021a-08123a0003ff, service_uuid: 00035b03-58e6-07dd-021a-08123a000300, properties: READ | WRITE }
Disconnecting from peripheral "D1538664"...
 ERROR btleplug::corebluetooth::peripheral > Event receiver died, breaking out of corebluetooth device loop.

The ERROR line appears to be directly caused by a disconnection attempt, as commenting this line out removes it reliably:

                        peripheral
                            .disconnect()
                            .await
                            .expect("Error disconnecting from BLE peripheral");

Additional context

n/a

@qdot I can second these findings. When I used the code at the bottom on my MacOs (12.6) Mac Book Pro 2018 Intel.

  • OK: Removing the disconnect from the code and having my BLE device (iPhone 8) close to it works.
  • FAIL: It breaks again if I turn OFF BLE on my Device and the Library calls the pub fn confirm_disconnect(&mut self) by it self.
  • FAIL: When I then implement #274 it still shows ERROR btleplug::corebluetooth::peripheral > Event receiver died, breaking out of corebluetooth device loop.
    pub fn confirm_disconnect(&mut self) {
        // Fulfill the disconnected future, if there is one.
        // There might not be a future if the device disconnects unexpectedly.
        if let Some(future) = self.disconnected_future_state.take() {
            future
                .lock()
                .unwrap()
                .set_reply(CoreBluetoothReply::Ok)
        }
    }

CLI shows the following,( confirm_disconnect0 comment is from me to make sure the BTLEplug was rebuild):

Peripheral "(peripheral name unknown)" is connected: false
Peripheral "(peripheral name unknown)" is connected: false
Peripheral "(peripheral name unknown)" is connected: false
Peripheral "(peripheral name unknown)" is connected: false
Peripheral "(peripheral name unknown)" is connected: false
Peripheral "Bob" is connected: true
Now connected (true) to peripheral "Bob"...
Discover peripheral "Bob" services...
Service UUID 00001805-0000-1000-8000-00805f9b34fb, primary: true
  Characteristic { uuid: 00002a0f-0000-1000-8000-00805f9b34fb, service_uuid: 00001805-0000-1000-8000-00805f9b34fb, properties: READ }
  Characteristic { uuid: 00002a2b-0000-1000-8000-00805f9b34fb, service_uuid: 00001805-0000-1000-8000-00805f9b34fb, properties: READ | NOTIFY }
Service UUID 0000180a-0000-1000-8000-00805f9b34fb, primary: true
  Characteristic { uuid: 00002a24-0000-1000-8000-00805f9b34fb, service_uuid: 0000180a-0000-1000-8000-00805f9b34fb, properties: READ }
  Characteristic { uuid: 00002a29-0000-1000-8000-00805f9b34fb, service_uuid: 0000180a-0000-1000-8000-00805f9b34fb, properties: READ }
Service UUID 0000180f-0000-1000-8000-00805f9b34fb, primary: true
  Characteristic { uuid: 00002a19-0000-1000-8000-00805f9b34fb, service_uuid: 0000180f-0000-1000-8000-00805f9b34fb, properties: READ | NOTIFY }
Service UUID 9fa480e0-4967-4542-9390-d343dc5d04ae, primary: true
  Characteristic { uuid: af0badb1-5b99-43cd-917a-a77bc549e3cc, service_uuid: 9fa480e0-4967-4542-9390-d343dc5d04ae, properties: WRITE | NOTIFY }
Service UUID d0611e78-bbb4-4591-a5f8-487910ae4366, primary: true
  Characteristic { uuid: 8667556c-9a37-4c91-84ed-54ee27d90049, service_uuid: d0611e78-bbb4-4591-a5f8-487910ae4366, properties: WRITE | NOTIFY }
Peripheral "(peripheral name unknown)" is connected: false
Peripheral "(peripheral name unknown)" is connected: false
Peripheral "(peripheral name unknown)" is connected: false
Peripheral "(peripheral name unknown)" is connected: false
Peripheral "(peripheral name unknown)" is connected: false
confirm_disconnect0
 ERROR btleplug::corebluetooth::peripheral > Event receiver died, breaking out of corebluetooth device loop.
Peripheral "Bob" is connected: true
// See the "macOS permissions note" in README.md before running this on macOS
// Big Sur or later.

use std::error::Error;
use std::time::Duration;
use tokio::time;

use btleplug::api::{Central, Manager as _, Peripheral, ScanFilter};
use btleplug::platform::Manager;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    pretty_env_logger::init();

    let manager = Manager::new().await?;
    let adapter_list = manager.adapters().await?;
    if adapter_list.is_empty() {
        eprintln!("No Bluetooth adapters found");
    }

    for adapter in adapter_list.iter() {
        println!("Starting scan on {}...", adapter.adapter_info().await?);
        adapter
            .start_scan(ScanFilter::default())
            .await
            .expect("Can't scan BLE adapter for connected devices...");
        time::sleep(Duration::from_secs(5)).await;

        loop {
            let peripherals = adapter.peripherals().await?;
            if peripherals.is_empty() {
                eprintln!("->>> BLE peripheral devices were not found, sorry. Exiting...");
            } else {
                // All peripheral devices in range
                for peripheral in peripherals.iter() {
                    let properties = peripheral.properties().await?;
                    let is_connected = peripheral.is_connected().await?;
                    let local_name = properties
                        .unwrap()
                        .local_name
                        .unwrap_or(String::from("(peripheral name unknown)"));
                    println!(
                        "Peripheral {:?} is connected: {:?}",
                        local_name, is_connected
                    );

                    if local_name.contains("Bob") {
                        if !is_connected {
                            println!("Connecting to peripheral {:?}...", &local_name);
                            if let Err(err) = peripheral.connect().await {
                                eprintln!("Error connecting to peripheral, skipping: {}", err);
                                continue;
                            }
                        }
                        let is_connected = peripheral.is_connected().await?;
                        println!(
                            "Now connected ({:?}) to peripheral {:?}...",
                            is_connected, &local_name
                        );
                        peripheral.discover_services().await?;
                        println!("Discover peripheral {:?} services...", &local_name);
                        for service in peripheral.services() {
                            println!(
                                "Service UUID {}, primary: {}",
                                service.uuid, service.primary
                            );
                            for characteristic in service.characteristics {
                                println!("  {:?}", characteristic);
                            }
                        }
                        // if is_connected {
                        //     println!("Disconnecting from peripheral {:?}...", &local_name);
                        //     peripheral
                        //         .disconnect()
                        //         .await
                        //         .expect("Error disconnecting from BLE peripheral");
                        // }
                    }
                }
            }
        }
    }
    Ok(())
}

Bob
Rust-Trends.com

commented

Fixed as part of #274