Add scan command
This commit is contained in:
parent
f66b31ec67
commit
729dab35df
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -539,6 +539,7 @@ dependencies = [
|
|||
"btleplug",
|
||||
"clap",
|
||||
"tokio",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -10,3 +10,4 @@ edition = "2021"
|
|||
btleplug = "0.10.4"
|
||||
clap = { version = "4.1.6", features = ["derive"] }
|
||||
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
|
||||
uuid = "1.3.0"
|
||||
|
|
65
src/ble.rs
Normal file
65
src/ble.rs
Normal file
|
@ -0,0 +1,65 @@
|
|||
use std::error::Error;
|
||||
use std::time::Duration;
|
||||
use tokio::time;
|
||||
use uuid::Uuid;
|
||||
|
||||
use btleplug::api::{Central, Manager as _, Peripheral, ScanFilter};
|
||||
use btleplug::platform::{Adapter, Manager};
|
||||
|
||||
const NORDIC_UART_SERVICE_UUID: Uuid = Uuid::from_u128(0x6e400001_b5a3_f393_e0a9_e50e24dcca9e);
|
||||
|
||||
pub async fn scan(adapter_name: String, scan_time: u64) -> Result<(), Box<dyn Error>> {
|
||||
let manager = Manager::new().await?;
|
||||
let adapter = get_adapter_by_name(&manager, adapter_name).await?;
|
||||
adapter
|
||||
.start_scan(ScanFilter::default())
|
||||
.await
|
||||
.expect("An error occurred while scanning for devices");
|
||||
|
||||
time::sleep(Duration::from_secs(scan_time)).await;
|
||||
|
||||
let peripherals = adapter.peripherals().await?;
|
||||
if peripherals.is_empty() {
|
||||
eprintln!("No devices found");
|
||||
} else {
|
||||
for peripheral in peripherals.iter() {
|
||||
let properties = peripheral.properties().await?;
|
||||
let services = &properties
|
||||
.as_ref()
|
||||
.ok_or_else(|| "Error discovering services".to_string())?
|
||||
.services;
|
||||
if !services.contains(&NORDIC_UART_SERVICE_UUID) {
|
||||
continue;
|
||||
}
|
||||
let address = properties
|
||||
.as_ref()
|
||||
.ok_or_else(|| "Error reading device address".to_string())?
|
||||
.address;
|
||||
let rssi = properties
|
||||
.as_ref()
|
||||
.ok_or_else(|| "Error reading device rssi".to_string())?
|
||||
.rssi
|
||||
.unwrap_or(0);
|
||||
let name = properties
|
||||
.as_ref()
|
||||
.ok_or_else(|| "Error reading device name".to_string())?
|
||||
.local_name
|
||||
.clone()
|
||||
.unwrap_or(address.to_string());
|
||||
println!("{} (rssi:{}) {}", address, rssi, name);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_adapter_by_name(manager: &Manager, name: String) -> Result<Adapter, Box<dyn Error>> {
|
||||
let adapters = manager.adapters().await?;
|
||||
for adapter in adapters {
|
||||
if adapter.adapter_info().await?.contains(&name) {
|
||||
return Ok(adapter);
|
||||
}
|
||||
}
|
||||
|
||||
Err(format!("Can't find adapter: {}", name).into())
|
||||
}
|
21
src/main.rs
21
src/main.rs
|
@ -1,4 +1,7 @@
|
|||
mod ble;
|
||||
|
||||
use clap::{Parser, Subcommand};
|
||||
use std::error::Error;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
|
@ -12,16 +15,24 @@ struct Cli {
|
|||
|
||||
#[derive(Subcommand)]
|
||||
enum Commands {
|
||||
/// Scan to find BLE devices.
|
||||
/// Scan to find Bluetooth LE devices.
|
||||
Scan {
|
||||
/// scan duration
|
||||
#[arg(long, default_value_t = 5.0)]
|
||||
scan_time: f32,
|
||||
#[arg(long, default_value_t = 5)]
|
||||
scan_time: u64,
|
||||
},
|
||||
}
|
||||
|
||||
fn main() {
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn Error>> {
|
||||
let cli = Cli::parse();
|
||||
|
||||
println!("Value for adapter: {}", cli.adapter);
|
||||
match &cli.command {
|
||||
Some(Commands::Scan { scan_time }) => {
|
||||
ble::scan(cli.adapter, *scan_time).await?;
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue