estim_control/src-tauri/src/cmd/mod.rs

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(())
}