// See the "macOS permissions note" in README.md before running this on macOS // Big Sur or later. use btleplug::api::{ bleuuid::BleUuid, Central, CentralEvent, Manager as _, Peripheral, ScanFilter, }; use btleplug::platform::{Adapter, Manager}; use futures::stream::StreamExt; use std::error::Error; async fn get_central(manager: &Manager) -> Adapter { let adapters = manager.adapters().await.unwrap(); adapters.into_iter().nth(0).unwrap() } #[tokio::main] async fn main() -> Result<(), Box> { pretty_env_logger::init(); let manager = Manager::new().await?; // get the first bluetooth adapter // connect to the adapter let central = get_central(&manager).await; let central_state = central.adapter_state().await.unwrap(); println!("CentralState: {:?}", central_state); // Each adapter has an event stream, we fetch via events(), // simplifying the type, this will return what is essentially a // Future>>. let mut events = central.events().await?; // start scanning for devices central.start_scan(ScanFilter::default()).await?; // Print based on whatever the event receiver outputs. Note that the event // receiver blocks, so in a real program, this should be run in its own // thread (not task, as this library does not yet use async channels). while let Some(event) = events.next().await { match event { CentralEvent::DeviceDiscovered(id) => { let peripheral = central.peripheral(&id).await?; let properties = peripheral.properties().await?; let name = properties .and_then(|p| p.local_name) .map(|local_name| format!("Name: {local_name}")) .unwrap_or_default(); println!("DeviceDiscovered: {:?} {}", id, name); } CentralEvent::StateUpdate(state) => { println!("AdapterStatusUpdate {:?}", state); } CentralEvent::DeviceConnected(id) => { println!("DeviceConnected: {:?}", id); } CentralEvent::DeviceDisconnected(id) => { println!("DeviceDisconnected: {:?}", id); } CentralEvent::ManufacturerDataAdvertisement { id, manufacturer_data, } => { println!( "ManufacturerDataAdvertisement: {:?}, {:?}", id, manufacturer_data ); } CentralEvent::ServiceDataAdvertisement { id, service_data } => { println!("ServiceDataAdvertisement: {:?}, {:?}", id, service_data); } CentralEvent::ServicesAdvertisement { id, services } => { let services: Vec = services.into_iter().map(|s| s.to_short_string()).collect(); println!("ServicesAdvertisement: {:?}, {:?}", id, services); } _ => {} } } Ok(()) }