use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use tokio::sync::{Mutex, broadcast, mpsc, oneshot, watch};
use crate::models::{DeviceConfig, DeviceInfo, LogMode, OutputMode};
pub type InfoResponder = oneshot::Sender<Result<DeviceInfo, String>>;
#[derive(Clone)]
pub struct AppState {
pub port_path: Arc<Mutex<String>>,
pub baud_rate: u32,
pub serial_connected: Arc<AtomicBool>,
pub collection_running: Arc<AtomicBool>,
pub cmd_tx: mpsc::Sender<String>,
pub csi_tx: broadcast::Sender<Vec<u8>>,
pub log_mode_tx: Arc<watch::Sender<LogMode>>,
pub output_mode_tx: Arc<watch::Sender<OutputMode>>,
pub session_file_tx: Arc<watch::Sender<Option<String>>>,
pub config: Arc<Mutex<DeviceConfig>>,
pub info_request_tx: mpsc::Sender<InfoResponder>,
pub firmware_verified: Arc<AtomicBool>,
pub device_info: Arc<Mutex<Option<DeviceInfo>>>,
}
impl AppState {
pub fn require_firmware(
&self,
) -> Option<(axum::http::StatusCode, axum::Json<crate::models::ApiResponse>)> {
if self
.firmware_verified
.load(std::sync::atomic::Ordering::SeqCst)
{
None
} else {
Some((
axum::http::StatusCode::PRECONDITION_FAILED,
axum::Json(crate::models::ApiResponse {
success: false,
message:
"Firmware not verified as esp-csi-cli-rs. Call GET /api/info to verify, \
or POST /api/control/reset to power-cycle and re-check."
.to_string(),
}),
))
}
}
}