1
0
Fork 0

Add send command

This commit is contained in:
Daniele Tricoli 2023-03-02 20:41:45 +01:00
parent 846ff22f67
commit 58ccfe9fe6
4 changed files with 160 additions and 2 deletions

86
Cargo.lock generated
View File

@ -2,6 +2,15 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "aho-corasick"
version = "0.7.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
dependencies = [
"memchr",
]
[[package]]
name = "async-trait"
version = "0.1.64"
@ -13,6 +22,17 @@ dependencies = [
"syn",
]
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi 0.1.19",
"libc",
"winapi",
]
[[package]]
name = "autocfg"
version = "1.1.0"
@ -293,6 +313,19 @@ version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]]
name = "env_logger"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
dependencies = [
"atty",
"humantime",
"log",
"regex",
"termcolor",
]
[[package]]
name = "errno"
version = "0.2.8"
@ -430,6 +463,15 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "hermit-abi"
version = "0.2.6"
@ -445,6 +487,15 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
[[package]]
name = "humantime"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
dependencies = [
"quick-error",
]
[[package]]
name = "indicatif"
version = "0.17.3"
@ -576,7 +627,9 @@ version = "0.1.0"
dependencies = [
"btleplug",
"clap",
"futures",
"indicatif",
"pretty_env_logger",
"tokio",
"uuid",
]
@ -682,6 +735,16 @@ version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26f6a7b87c2e435a3241addceeeff740ff8b7e76b74c13bf9acb17fa454ea00b"
[[package]]
name = "pretty_env_logger"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d"
dependencies = [
"env_logger",
"log",
]
[[package]]
name = "proc-macro-error"
version = "1.0.4"
@ -715,6 +778,12 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "quick-error"
version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
[[package]]
name = "quote"
version = "1.0.23"
@ -733,6 +802,23 @@ dependencies = [
"bitflags",
]
[[package]]
name = "regex"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
[[package]]
name = "rustix"
version = "0.36.8"

View File

@ -9,6 +9,8 @@ edition = "2021"
[dependencies]
btleplug = "0.10.4"
clap = { version = "4.1.6", features = ["derive"] }
futures = "0.3.26"
indicatif = { version = "0.17.3", features = ["tokio"] }
pretty_env_logger = "0.4.0"
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
uuid = "1.3.0"

View File

@ -1,14 +1,18 @@
use std::error::Error;
use std::time::Duration;
use btleplug::api::{BDAddr, Central, Manager as _, Peripheral, ScanFilter};
use btleplug::platform::{Adapter, Manager};
use btleplug::api::{
BDAddr, Central, CentralEvent, Manager as _, Peripheral as _, ScanFilter, WriteType,
};
use btleplug::platform::{Adapter, Manager, Peripheral};
use futures::stream::StreamExt;
use tokio::time;
use uuid::Uuid;
use crate::utils::progress_bar;
const NORDIC_UART_SERVICE_UUID: Uuid = Uuid::from_u128(0x6e400001_b5a3_f393_e0a9_e50e24dcca9e);
const NORDIC_UART_TX_CHAR_UUID: Uuid = Uuid::from_u128(0x6e400002_b5a3_f393_e0a9_e50e24dcca9e);
const INVALID_RSSI: i16 = i16::MIN;
/// A result from Bluetooth scan.
@ -82,3 +86,56 @@ async fn get_adapter_by_name(manager: &Manager, name: String) -> Result<Adapter,
Err(format!("Can't find adapter: {}", name).into())
}
async fn find_device_by_address(
adapter_name: String,
address: String,
) -> Result<Peripheral, Box<dyn Error>> {
let manager = Manager::new().await?;
let adapter = get_adapter_by_name(&manager, adapter_name).await?;
let mut events = adapter.events().await?;
adapter.start_scan(ScanFilter::default()).await?;
while let Some(event) = events.next().await {
match event {
CentralEvent::DeviceDiscovered(_id) => {
let peripherals = adapter.peripherals().await?;
for peripheral in peripherals.iter() {
let properties = peripheral.properties().await?;
let device_address = properties
.as_ref()
.ok_or_else(|| "Error reading device address".to_string())?
.address;
if device_address.to_string() == address {
return Ok(peripheral.clone());
}
}
}
_ => {}
}
}
Err("no device found".into())
}
pub async fn send(
adapter_name: String,
address: String,
text: String,
) -> Result<(), Box<dyn Error>> {
let device = find_device_by_address(adapter_name, address).await?;
device.connect().await?;
device.discover_services().await?;
let chars = device.characteristics();
let tx_char = chars
.iter()
.find(|c| c.uuid == NORDIC_UART_TX_CHAR_UUID)
.ok_or("Unable to find characterics")?;
device
.write(&tx_char, text.as_bytes(), WriteType::WithResponse)
.await?;
device.disconnect().await?;
Ok(())
}

View File

@ -23,10 +23,20 @@ enum Commands {
#[arg(long, default_value_t = 5)]
scan_time: u64,
},
/// Send messages to a device
Send {
/// device's address
#[arg(long)]
device: String,
#[arg(required = true)]
text: Vec<String>,
},
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
pretty_env_logger::init();
let cli = Cli::parse();
match &cli.command {
@ -40,6 +50,9 @@ async fn main() -> Result<(), Box<dyn Error>> {
);
}
}
Some(Commands::Send { device, text }) => {
ble::send(cli.adapter, device.clone(), text.join(" ")).await?;
}
None => {}
}