#[cfg(all(feature = "linux", target_os = "linux"))]
mod scanner {
use peat_btle::observer::{PeatEvent, PeatObserver};
use peat_btle::{BleConfig, NodeId, PeatMesh, PeatMeshConfig, PEAT_SERVICE_UUID};
use std::sync::Arc;
use std::time::Duration;
struct ScanObserver;
impl PeatObserver for ScanObserver {
fn on_event(&self, event: PeatEvent) {
match event {
PeatEvent::PeerDiscovered { peer } => {
println!(
"Discovered Peat peer: {} (Node ID: {:08X}, RSSI: {} dBm)",
peer.display_name(),
peer.node_id.as_u32(),
peer.rssi
);
}
PeatEvent::PeerConnected { node_id } => {
println!("Connected to: {:08X}", node_id.as_u32());
}
PeatEvent::MeshStateChanged {
peer_count,
connected_count,
} => {
println!(
"Mesh: {} peers discovered, {} connected",
peer_count, connected_count
);
}
_ => {}
}
}
}
pub async fn run() -> Result<(), Box<dyn std::error::Error>> {
use peat_btle::platform::linux::BluerAdapter;
use peat_btle::platform::BleAdapter;
println!("=== PEAT-BTLE Linux Scanner ===\n");
println!("Peat Service UUID: {}", PEAT_SERVICE_UUID);
println!();
let node_id = NodeId::new(
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs() as u32,
);
println!("Our Node ID: {:08X}", node_id.as_u32());
let config = BleConfig::peat_lite(node_id);
println!("Power profile: {:?}", config.power_profile);
println!();
println!("Initializing Bluetooth adapter...");
let mut adapter = BluerAdapter::new().await?;
adapter.init(&config).await?;
println!("Adapter address: {:?}", adapter.address());
println!("Coded PHY support: {}", adapter.supports_coded_phy());
println!(
"Extended advertising: {}",
adapter.supports_extended_advertising()
);
println!("Max MTU: {}", adapter.max_mtu());
println!();
let mesh_config = PeatMeshConfig::new(node_id, "SCANNER", "DEMO");
let mesh = Arc::new(PeatMesh::new(mesh_config));
mesh.add_observer(Arc::new(ScanObserver));
let mesh_clone = mesh.clone();
adapter.set_discovery_callback(Some(Arc::new(
move |device: peat_btle::DiscoveredDevice| {
let now_ms = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_millis() as u64;
if device.is_peat_node {
mesh_clone.on_ble_discovered(
&device.address,
device.name.as_deref(),
device.rssi,
Some("DEMO"), now_ms,
);
} else {
if let Some(name) = &device.name {
println!("Non-Peat device: {} ({})", name, device.address);
}
}
},
)));
println!("Starting BLE scan...");
println!("Press Ctrl+C to stop.\n");
adapter.start_scan(&config.discovery).await?;
for i in 0..30 {
tokio::time::sleep(Duration::from_secs(1)).await;
let now_ms = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_millis() as u64;
if let Some(_doc) = mesh.tick(now_ms) {
}
if (i + 1) % 5 == 0 {
println!(
"... {} seconds elapsed, {} peers found",
i + 1,
mesh.peer_count()
);
}
}
println!("\nStopping scan...");
adapter.stop_scan().await?;
println!("\n=== Scan Summary ===");
println!("Total peers discovered: {}", mesh.peer_count());
for peer in mesh.get_peers() {
println!(
" - {} ({:08X}) RSSI: {} dBm",
peer.display_name(),
peer.node_id.as_u32(),
peer.rssi
);
}
Ok(())
}
}
#[cfg(all(feature = "linux", target_os = "linux"))]
#[tokio::main]
async fn main() {
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
if let Err(e) = scanner::run().await {
eprintln!("Error: {}", e);
std::process::exit(1);
}
}
#[cfg(not(all(feature = "linux", target_os = "linux")))]
fn main() {
println!("This example requires the 'linux' feature and Linux OS.");
println!("Run with: cargo run --example linux_scanner --features linux");
}