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