//! This example allows you to chat over L2CAP with another bluetooth device. //! //! Copyright (c) 2022 Ibiyemi Abiodun extern crate bluez; use std::{io::BufRead, sync::Arc}; use anyhow::Context; use bluez::communication::stream::BluetoothListener; use bluez::management::*; use bluez::AddressType; use bluez::Protocol; use tokio::{ io::{AsyncBufReadExt, AsyncWriteExt, BufReader}, spawn, sync::Mutex, }; #[tokio::main(worker_threads = 2)] pub async fn main() -> Result<(), anyhow::Error> { let (input_tx, input_rx) = tokio::sync::mpsc::channel(16); std::thread::spawn(move || { let stdin = std::io::stdin(); let mut stdin = stdin.lock(); loop { let mut line = String::new(); stdin.read_line(&mut line).unwrap(); input_tx.blocking_send(line).unwrap(); } }); let mut mgmt = ManagementStream::open()?; let controllers = get_controller_list(&mut mgmt, None).await?; if controllers.len() < 1 { panic!("there are no bluetooth controllers on this device") } let controller_info = get_controller_info(&mut mgmt, controllers[0], None).await?; let listener = BluetoothListener::bind( Protocol::L2CAP, controller_info.address, AddressType::BREDR, 0, )?; let (addr, port) = listener.local_addr()?; println!("l2cap server listening at {} on port {}", addr, port); let input_rx = Arc::new(Mutex::new(input_rx)); loop { let (stream, (addr, port)) = listener.accept().await?; println!("l2cap client connected from {} on port {}", addr, 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 input_rx = input_rx.clone(); let write_task = spawn(async move { let mut input_rx = input_rx.lock().await; loop { let line = input_rx.recv().await.context("stdin ended").unwrap(); println!("< {}", line); writer.write_all(line.as_bytes()).await.unwrap(); println!("<< {}", line); } }); read_task.await?; write_task.abort(); println!("l2cap client disconnected, listening again"); } }