#![warn(clippy::all, future_incompatible, nonstandard_style, rust_2018_idioms)]
mod characteristic;
mod common;
mod device;
mod scanner;
pub use self::{
characteristic::Characteristic,
common::*,
device::{Device, DeviceEvent},
scanner::{
config::{Filter, ScanConfig},
Scanner,
},
};
pub use btleplug::{
api::{BDAddr, PeripheralProperties},
Error, Result,
};
#[cfg(test)]
mod tests {
use crate::{Filter, ScanConfig, Scanner};
use btleplug::{api::BDAddr, Error};
use std::time::Duration;
use tokio_stream::StreamExt;
use uuid::Uuid;
#[tokio::test]
async fn test_discover() -> anyhow::Result<()> {
rsutil::log::Log4rsConfig::default().initialize().unwrap();
let cfg = ScanConfig::default().stop_after_timeout(Duration::from_secs(10));
let mut scanner = Scanner::new();
scanner.start(cfg).await?;
while let Some(device) = scanner.device_stream()?.next().await {
println!("Found device: {}", device.address());
}
Ok(())
}
#[tokio::test]
async fn test_filter_by_address() -> Result<(), Error> {
rsutil::log::Log4rsConfig::default().initialize().unwrap();
let mac_addr = [0xE3, 0x9E, 0x2A, 0x4D, 0xAA, 0x97];
let filers = vec![Filter::Address("E3:9E:2A:4D:AA:97".into())];
let cfg = ScanConfig::default()
.with_filters(&filers)
.stop_after_timeout(Duration::from_secs(10))
.stop_after_first_match();
let mut scanner = Scanner::default();
scanner.start(cfg).await?;
while let Some(device) = scanner.device_stream()?.next().await {
assert_eq!(device.address(), BDAddr::from(mac_addr));
}
Ok(())
}
#[tokio::test]
async fn test_filter_by_character() -> Result<(), Error> {
rsutil::log::Log4rsConfig::default().initialize().unwrap();
let filers = vec![Filter::Characteristic(Uuid::from_u128(
0x6e400001_b5a3_f393_e0a9_e50e24dcca9e,
))];
let cfg = ScanConfig::default()
.with_filters(&filers)
.stop_after_timeout(Duration::from_secs(10))
.stop_after_first_match();
let mut scanner = Scanner::default();
scanner.start(cfg).await?;
while let Some(device) = scanner.device_stream()?.next().await {
println!("device: {:?} found", device);
}
Ok(())
}
#[tokio::test]
async fn test_filter_by_name() -> Result<(), Error> {
rsutil::log::Log4rsConfig::default().initialize().unwrap();
let name = "73429485";
let filers = vec![Filter::Name(name.into())];
let cfg = ScanConfig::default()
.with_filters(&filers)
.stop_after_timeout(Duration::from_secs(10))
.stop_after_first_match();
let mut scanner = Scanner::default();
scanner.start(cfg).await?;
while let Some(device) = scanner.device_stream()?.next().await {
assert_eq!(device.local_name().await, Some(name.into()));
}
Ok(())
}
#[tokio::test]
async fn test_filter_by_rssi() -> Result<(), Error> {
rsutil::log::Log4rsConfig::default().initialize().unwrap();
let filers = vec![Filter::Rssi(-70)];
let cfg = ScanConfig::default()
.with_filters(&filers)
.stop_after_timeout(Duration::from_secs(10))
.stop_after_first_match();
let mut scanner = Scanner::default();
scanner.start(cfg).await?;
while let Some(device) = scanner.device_stream()?.next().await {
println!("device: {:?} found", device);
}
Ok(())
}
#[tokio::test]
async fn test_filter_by_service() -> Result<(), Error> {
rsutil::log::Log4rsConfig::default().initialize().unwrap();
let service = Uuid::from_u128(0x6e400001_b5a3_f393_e0a9_e50e24dcca9e);
let filers = vec![Filter::Service(service)];
let cfg = ScanConfig::default()
.with_filters(&filers)
.stop_after_timeout(Duration::from_secs(10))
.stop_after_first_match();
let mut scanner = Scanner::default();
scanner.start(cfg).await?;
while let Some(device) = scanner.device_stream()?.next().await {
println!("device: {:?} found", device);
}
Ok(())
}
}