use std::net::SocketAddr;
use std::time::Duration;
use super::constants::{IDNFLG_SERVICEMAP_DSID, IDNVAL_STYPE_DMX512, IDNVAL_STYPE_LAPRO, IDN_PORT};
#[derive(Clone, Debug)]
pub struct Service {
pub service_id: u8,
pub service_type: u8,
pub name: String,
pub flags: u8,
pub relay_number: u8,
}
impl Service {
pub fn laser_projector(service_id: u8, name: &str) -> Self {
Self {
service_id,
service_type: IDNVAL_STYPE_LAPRO,
name: name.to_string(),
flags: 0,
relay_number: 0,
}
}
pub fn dmx512(service_id: u8, name: &str) -> Self {
Self {
service_id,
service_type: IDNVAL_STYPE_DMX512,
name: name.to_string(),
flags: 0,
relay_number: 0,
}
}
pub fn with_relay(mut self, relay_number: u8) -> Self {
self.relay_number = relay_number;
self
}
pub fn with_dsid(mut self) -> Self {
self.flags |= IDNFLG_SERVICEMAP_DSID;
self
}
}
#[derive(Clone, Debug)]
pub struct Relay {
pub relay_number: u8,
pub name: String,
}
impl Relay {
pub fn new(relay_number: u8, name: &str) -> Self {
Self {
relay_number,
name: name.to_string(),
}
}
}
#[derive(Clone, Debug)]
pub struct ServerConfig {
pub hostname: String,
pub unit_id: [u8; 16],
pub protocol_version: u8,
pub services: Vec<Service>,
pub relays: Vec<Relay>,
pub bind_address: SocketAddr,
pub read_timeout: Duration,
pub link_timeout: Duration,
pub force_disconnect_window: Duration,
}
impl ServerConfig {
pub fn new(hostname: &str) -> Self {
let mut unit_id = [0u8; 16];
let bytes = hostname.as_bytes();
let id_len = bytes.len().min(14);
unit_id[0] = (id_len + 1) as u8;
unit_id[1] = 0x7F;
unit_id[2..2 + id_len].copy_from_slice(&bytes[..id_len]);
Self {
hostname: hostname.to_string(),
unit_id,
protocol_version: 0x10, services: vec![Service::laser_projector(1, "Laser1")],
relays: Vec::new(),
bind_address: "127.0.0.1:0".parse().unwrap(),
read_timeout: Duration::from_millis(100),
link_timeout: Duration::from_millis(1000),
force_disconnect_window: Duration::from_secs(3),
}
}
pub fn new_on_standard_port(hostname: &str) -> Self {
Self::new(hostname).with_bind_address(format!("0.0.0.0:{}", IDN_PORT).parse().unwrap())
}
pub fn with_unit_id(mut self, unit_id: [u8; 16]) -> Self {
self.unit_id = unit_id;
self
}
pub fn with_protocol_version(mut self, major: u8, minor: u8) -> Self {
self.protocol_version = (major << 4) | (minor & 0x0F);
self
}
pub fn with_services(mut self, services: Vec<Service>) -> Self {
self.services = services;
self
}
pub fn with_relays(mut self, relays: Vec<Relay>) -> Self {
self.relays = relays;
self
}
pub fn with_bind_address(mut self, addr: SocketAddr) -> Self {
self.bind_address = addr;
self
}
pub fn with_read_timeout(mut self, timeout: Duration) -> Self {
self.read_timeout = timeout;
self
}
pub fn with_link_timeout(mut self, timeout: Duration) -> Self {
self.link_timeout = timeout;
self
}
pub fn with_force_disconnect_window(mut self, window: Duration) -> Self {
self.force_disconnect_window = window;
self
}
}