extern crate bluez;
use std::io::BufRead;
use anyhow::Context;
use bluez::communication::stream::BluetoothStream;
use bluez::Address;
use bluez::AddressType;
use bluez::Protocol;
use clap::Parser;
use tokio::io::BufReader;
use tokio::io::{AsyncBufReadExt, AsyncWriteExt};
use tokio::spawn;
#[derive(Parser, Debug)]
struct Args {
address: Address,
port: u16,
}
#[tokio::main(worker_threads = 2)]
pub async fn main() -> Result<(), anyhow::Error> {
let (input_tx, mut input_rx) = tokio::sync::mpsc::channel(16);
std::thread::spawn(move || -> anyhow::Result<()> {
let stdin = std::io::stdin();
let mut stdin = stdin.lock();
loop {
let mut line = String::new();
stdin.read_line(&mut line)?;
input_tx.blocking_send(line)?;
}
});
let args = Args::parse();
let stream =
BluetoothStream::connect(Protocol::L2CAP, args.address, AddressType::BREDR, args.port)
.await?;
println!(
"l2cap client connected to {} on port {}",
args.address, args.port
);
let (reader, mut writer) = stream.into_split();
let read_task = spawn(async move {
let mut line = String::new();
let mut reader = BufReader::new(reader);
while reader.read_line(&mut line).await.unwrap() > 0 {
println!("> {}", line);
line.clear();
}
});
let write_task = spawn(async move {
loop {
let line = input_rx.recv().await.context("stdin ended").unwrap();
writer.write_all(line.as_bytes()).await.unwrap();
println!("< {}", line);
}
});
read_task.await?;
write_task.abort();
Ok(())
}