104 lines
3.1 KiB
Rust
104 lines
3.1 KiB
Rust
use crate::protocol::Parameter;
|
|
use anyhow::{Context, Result, ensure};
|
|
use serde::{Deserialize, Serialize};
|
|
use std::{
|
|
collections::BTreeMap,
|
|
fs,
|
|
path::{Path, PathBuf},
|
|
};
|
|
|
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
|
#[serde(default, deny_unknown_fields)]
|
|
pub struct Config {
|
|
pub monitor_serial: String,
|
|
pub socket: PathBuf,
|
|
pub state_file: PathBuf,
|
|
pub transport: String,
|
|
pub serial_device: Option<PathBuf>,
|
|
pub usb_path: Option<String>,
|
|
pub require_companion: bool,
|
|
pub require_display: bool,
|
|
pub keepalive_ms: u64,
|
|
pub reconnect_ms: u64,
|
|
pub watchdog_ms: u64,
|
|
pub display: Display,
|
|
pub startup: BTreeMap<Parameter, u8>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
|
#[serde(default, deny_unknown_fields)]
|
|
pub struct Display {
|
|
pub enabled: bool,
|
|
pub edid: PathBuf,
|
|
// AMD's virtual hotplug API was verified on the actual machine. Other GPUs
|
|
// should use the portable firmware EDID mechanism or their KMS client.
|
|
pub hotplug: String,
|
|
}
|
|
impl Default for Display {
|
|
fn default() -> Self {
|
|
Self {
|
|
enabled: false,
|
|
edid: "/usr/lib/firmware/edid/dasung-paperlike13k-37hz.bin".into(),
|
|
hotplug: "none".into(),
|
|
}
|
|
}
|
|
}
|
|
impl Default for Config {
|
|
fn default() -> Self {
|
|
Self {
|
|
monitor_serial: "L56051794302".into(),
|
|
socket: "/run/dasungd/control.sock".into(),
|
|
state_file: "/run/dasungd/settings.json".into(),
|
|
transport: "usb".into(),
|
|
serial_device: None,
|
|
usb_path: None,
|
|
require_companion: true,
|
|
require_display: true,
|
|
keepalive_ms: 2000,
|
|
reconnect_ms: 2000,
|
|
watchdog_ms: 30000,
|
|
display: Display::default(),
|
|
startup: BTreeMap::new(),
|
|
}
|
|
}
|
|
}
|
|
impl Config {
|
|
pub fn load(path: &Path) -> Result<Self> {
|
|
let config: Self = toml::from_str(
|
|
&fs::read_to_string(path).with_context(|| format!("read {}", path.display()))?,
|
|
)?;
|
|
ensure!(
|
|
!config.monitor_serial.is_empty(),
|
|
"monitor_serial must identify the intended monitor"
|
|
);
|
|
ensure!(
|
|
(500..=5000).contains(&config.keepalive_ms),
|
|
"keepalive_ms must be 500..5000"
|
|
);
|
|
ensure!(
|
|
(500..=30000).contains(&config.reconnect_ms),
|
|
"reconnect_ms must be 500..30000"
|
|
);
|
|
ensure!(
|
|
config.watchdog_ms >= 20000,
|
|
"watchdog_ms must be at least 20000"
|
|
);
|
|
ensure!(
|
|
matches!(config.transport.as_str(), "usb" | "serial"),
|
|
"transport must be usb or serial"
|
|
);
|
|
ensure!(
|
|
config.transport != "serial" || config.serial_device.is_some(),
|
|
"serial transport needs serial_device"
|
|
);
|
|
ensure!(
|
|
matches!(config.display.hotplug.as_str(), "none" | "amdgpu"),
|
|
"display.hotplug must be none or amdgpu"
|
|
);
|
|
for (¶meter, &value) in &config.startup {
|
|
parameter.validate(value)?;
|
|
}
|
|
Ok(config)
|
|
}
|
|
}
|