134 lines
4.0 KiB
Rust
134 lines
4.0 KiB
Rust
use std::sync::Arc;
|
|
|
|
use btleplug::{
|
|
api::{Central as _, Peripheral as _},
|
|
platform::PeripheralId,
|
|
};
|
|
pub use state::{CentralState, ChannelState, PeripheralItem};
|
|
use tauri::{async_runtime::RwLock, AppHandle, Emitter, State};
|
|
|
|
use crate::{bluetooth, errors, state::AppState};
|
|
|
|
mod state;
|
|
|
|
#[tauri::command]
|
|
pub async fn activate_central_adapter(
|
|
app_handle: AppHandle,
|
|
app_state: State<'_, Arc<RwLock<AppState>>>,
|
|
) -> Result<(), errors::AppError> {
|
|
let app = Arc::new(app_handle);
|
|
let adapter = bluetooth::get_central_adapter().await?;
|
|
{
|
|
let state = app_state.read().await;
|
|
state.set_central_adapter(adapter).await;
|
|
state.clear_central_event_handler().await;
|
|
}
|
|
let handle =
|
|
bluetooth::handle_bluetooth_events(Arc::clone(&app), Arc::clone(&app_state)).await?;
|
|
{
|
|
let state = app_state.write().await;
|
|
state.set_central_event_handler(handle).await;
|
|
}
|
|
app.emit("central_state_updated", ()).unwrap();
|
|
Ok(())
|
|
}
|
|
|
|
#[tauri::command]
|
|
pub async fn central_device_state(
|
|
app_state: State<'_, Arc<RwLock<AppState>>>,
|
|
) -> Result<CentralState, errors::AppError> {
|
|
let state = app_state.read().await;
|
|
let central = state.get_central_adapter().await;
|
|
if let Some(central) = central {
|
|
let central_device_state = central
|
|
.adapter_state()
|
|
.await
|
|
.map_err(|_| errors::AppError::BluetoothNotReady)?;
|
|
Ok(CentralState {
|
|
is_ready: central_device_state == btleplug::api::CentralState::PoweredOn,
|
|
is_scanning: *state.scanning.lock().await,
|
|
connected: state.get_connected_peripheral().await,
|
|
})
|
|
} else {
|
|
Ok(CentralState::default())
|
|
}
|
|
}
|
|
|
|
#[tauri::command]
|
|
pub async fn connected_peripheral_state(
|
|
app_state: State<'_, Arc<RwLock<AppState>>>,
|
|
) -> Result<Option<PeripheralItem>, errors::AppError> {
|
|
let state = app_state.read().await;
|
|
let connected_peripheral = state
|
|
.connected_peripheral
|
|
.lock()
|
|
.await
|
|
.clone()
|
|
.ok_or(errors::AppError::NoConnectedPeripheral)?;
|
|
let central = state
|
|
.get_central_adapter()
|
|
.await
|
|
.ok_or(errors::AppError::BluetoothAdapterNotFound)?;
|
|
if let Ok(peripheral) = central.peripheral(&connected_peripheral).await {
|
|
let properties = peripheral
|
|
.properties()
|
|
.await
|
|
.map_err(|_| errors::AppError::UnableToRetrievePeripheralProperties)?;
|
|
Ok(Some(
|
|
PeripheralItem::new(&peripheral, properties.as_ref()).await,
|
|
))
|
|
} else {
|
|
Ok(None)
|
|
}
|
|
}
|
|
|
|
#[tauri::command]
|
|
pub async fn specific_peripheral_state(
|
|
app_state: State<'_, Arc<RwLock<AppState>>>,
|
|
id: PeripheralId,
|
|
) -> Result<PeripheralItem, errors::AppError> {
|
|
let state = app_state.read().await;
|
|
let central = state
|
|
.get_central_adapter()
|
|
.await
|
|
.ok_or(errors::AppError::BluetoothAdapterNotFound)?;
|
|
let peripheral = central
|
|
.peripheral(&id)
|
|
.await
|
|
.map_err(|_| errors::AppError::UnableToRetrievePeripheralState)?;
|
|
let properties = peripheral.properties().await.unwrap_or(None);
|
|
Ok(PeripheralItem::new(&peripheral, properties.as_ref()).await)
|
|
}
|
|
|
|
#[tauri::command]
|
|
pub async fn channel_a_state(
|
|
_app_state: State<'_, Arc<RwLock<AppState>>>,
|
|
) -> Result<ChannelState, errors::AppError> {
|
|
Ok(ChannelState::default())
|
|
}
|
|
|
|
#[tauri::command]
|
|
pub async fn channel_b_state(
|
|
_app_state: State<'_, Arc<RwLock<AppState>>>,
|
|
) -> Result<ChannelState, errors::AppError> {
|
|
Ok(ChannelState::default())
|
|
}
|
|
|
|
#[tauri::command]
|
|
pub async fn start_scan_devices(
|
|
app_handle: AppHandle,
|
|
app_state: State<'_, Arc<RwLock<AppState>>>,
|
|
) -> Result<(), errors::AppError> {
|
|
bluetooth::start_scan(Arc::new(app_handle), app_state).await?;
|
|
Ok(())
|
|
}
|
|
|
|
#[tauri::command]
|
|
pub async fn stop_scan_devices(
|
|
app_handle: AppHandle,
|
|
app_state: State<'_, Arc<RwLock<AppState>>>,
|
|
) -> Result<(), errors::AppError> {
|
|
bluetooth::stop_scan(Arc::new(app_handle), app_state).await?;
|
|
Ok(())
|
|
}
|