csi-webserver-core 0.1.0

Embeddable HTTP/WebSocket library for streaming ESP32 CSI data over USB serial
Documentation
//! Device registry listing at `GET /api/devices`.

use std::sync::atomic::Ordering;

use axum::{Json, extract::State};
use serde::Serialize;

use crate::{models::DeviceInfo, state::AppState};

/// One row of `GET /api/devices` — a snapshot of an attached device.
#[derive(Serialize)]
pub struct DeviceSummary {
    pub id: String,
    /// Stable board MAC from the USB `iSerialNumber` descriptor; the id is
    /// derived from this. `None` for adapters that expose no serial number.
    pub mac: Option<String>,
    pub port_path: String,
    pub baud_rate: u32,
    pub serial_connected: bool,
    pub collection_running: bool,
    pub firmware_verified: bool,
    pub device_info: Option<DeviceInfo>,
    /// Detected chip fault with recovery action (e.g. the ESP32-C5/C6
    /// USB-JTAG reset-loop wedge that only a USB power cycle clears).
    /// `None` for a healthy device; cleared when verification succeeds.
    pub fault: Option<String>,
}

/// `GET /api/devices` — list all currently attached devices and their status.
///
/// The set is maintained by the hotplug supervisor, so newly plugged-in boards
/// appear here within one scan interval and unplugged ones drop off after the
/// debounce window.
pub async fn list_devices(State(state): State<AppState>) -> Json<Vec<DeviceSummary>> {
    let mut out = Vec::new();
    for dev in state.devices.snapshot() {
        out.push(DeviceSummary {
            id: dev.id.clone(),
            mac: dev.mac.clone(),
            port_path: dev.port_path.clone(),
            baud_rate: dev.baud_rate,
            serial_connected: dev.serial_connected.load(Ordering::SeqCst),
            collection_running: dev.collection_running.load(Ordering::SeqCst),
            firmware_verified: dev.firmware_verified.load(Ordering::SeqCst),
            device_info: dev.device_info.lock().await.clone(),
            fault: dev.fault.lock().await.clone(),
        });
    }
    Json(out)
}