use csm_protocol::{Frame, MessageType, HardwareAsset}; use std::time::Duration; use tokio::sync::mpsc::Sender; use tracing::{info, error}; use sysinfo::System; pub async fn start_collecting(tx: Sender, device_uid: String) { let interval = Duration::from_secs(86400); // Once per day // Initial collection on startup if let Err(e) = collect_and_send(&tx, &device_uid).await { error!("Initial asset collection failed: {}", e); } loop { tokio::time::sleep(interval).await; if let Err(e) = collect_and_send(&tx, &device_uid).await { error!("Asset collection failed: {}", e); } } } async fn collect_and_send(tx: &Sender, device_uid: &str) -> anyhow::Result<()> { let hardware = collect_hardware(device_uid)?; let frame = Frame::new_json(MessageType::AssetReport, &hardware)?; tx.send(frame).await.map_err(|e| anyhow::anyhow!("Channel send failed: {}", e))?; info!("Asset report sent for {}", device_uid); Ok(()) } fn collect_hardware(device_uid: &str) -> anyhow::Result { let mut sys = System::new_all(); sys.refresh_all(); let cpu_model = sys.cpus().first() .map(|c| c.brand().to_string()) .unwrap_or_else(|| "Unknown".to_string()); let cpu_cores = sys.cpus().len() as u32; let memory_total_mb = sys.total_memory() / 1024 / 1024; // bytes to MB (sysinfo 0.30) Ok(HardwareAsset { device_uid: device_uid.to_string(), cpu_model, cpu_cores, memory_total_mb: memory_total_mb as u64, disk_model: "Unknown".to_string(), disk_total_mb: 0, gpu_model: None, motherboard: None, serial_number: None, }) }