use crate::{Error, Result};
use bluer::{Address, Session};
use std::str::FromStr;
use tracing::{error, info, warn};
pub struct BluetoothPairing {
session: Session,
}
impl BluetoothPairing {
pub async fn new() -> Result<Self> {
let session = Session::new().await
.map_err(|e| Error::General(format!("Failed to create Bluetooth session: {}", e)))?;
Ok(Self { session })
}
pub async fn pair_device(&self, address: &str) -> Result<bool> {
info!("Starting Bluetooth pairing with device: {}", address);
let addr = Address::from_str(address)
.map_err(|e| Error::General(format!("Invalid Bluetooth address {}: {}", address, e)))?;
let adapter = self.session.default_adapter().await
.map_err(|e| Error::General(format!("Failed to get default Bluetooth adapter: {}", e)))?;
let device = adapter.device(addr)
.map_err(|e| Error::General(format!("Failed to get device {}: {}", address, e)))?;
if device.is_paired().await
.map_err(|e| Error::General(format!("Failed to check pairing status: {}", e)))? {
info!("Device {} is already paired", address);
return Ok(true);
}
match device.pair().await {
Ok(()) => {
info!("Successfully paired with device: {}", address);
Ok(true)
}
Err(e) => {
error!("Failed to pair with device {}: {}", address, e);
Ok(false)
}
}
}
pub async fn unpair_device(&self, address: &str) -> Result<bool> {
info!("Removing Bluetooth pairing with device: {}", address);
let addr = Address::from_str(address)
.map_err(|e| Error::General(format!("Invalid Bluetooth address {}: {}", address, e)))?;
let adapter = self.session.default_adapter().await
.map_err(|e| Error::General(format!("Failed to get default Bluetooth adapter: {}", e)))?;
let device = adapter.device(addr)
.map_err(|e| Error::General(format!("Failed to get device {}: {}", address, e)))?;
if !device.is_paired().await
.map_err(|e| Error::General(format!("Failed to check pairing status: {}", e)))? {
warn!("Device {} is not paired", address);
return Ok(false);
}
match adapter.remove_device(addr).await {
Ok(()) => {
info!("Successfully unpaired device: {}", address);
Ok(true)
}
Err(e) => {
error!("Failed to unpair device {}: {}", address, e);
Ok(false)
}
}
}
pub async fn is_device_paired(&self, address: &str) -> Result<bool> {
let addr = Address::from_str(address)
.map_err(|e| Error::General(format!("Invalid Bluetooth address {}: {}", address, e)))?;
let adapter = self.session.default_adapter().await
.map_err(|e| Error::General(format!("Failed to get default Bluetooth adapter: {}", e)))?;
let device = adapter.device(addr)
.map_err(|e| Error::General(format!("Failed to get device {}: {}", address, e)))?;
device.is_paired().await
.map_err(|e| Error::General(format!("Failed to check pairing status for {}: {}", address, e)))
}
pub async fn is_device_connected(&self, address: &str) -> Result<bool> {
let addr = Address::from_str(address)
.map_err(|e| Error::General(format!("Invalid Bluetooth address {}: {}", address, e)))?;
let adapter = self.session.default_adapter().await
.map_err(|e| Error::General(format!("Failed to get default Bluetooth adapter: {}", e)))?;
let device = adapter.device(addr)
.map_err(|e| Error::General(format!("Failed to get device {}: {}", address, e)))?;
device.is_connected().await
.map_err(|e| Error::General(format!("Failed to check connection status for {}: {}", address, e)))
}
}