use std::net::Ipv4Addr;
use crate::wire::{DeviceUid, UnitCommandFlag, UnitCommandKind, UnitFlag};
pub const UNIT_MAX_TEMPERATURES: usize = 6;
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct UnitStatus {
pub flags: UnitFlag,
pub uptime: u32,
pub boot_count: u32,
pub reboot_count: u32,
pub encoder_health: u32,
pub decoder_health: u32,
pub network: UnitNetConfig,
pub fan_rpm: u16,
pub fan_duty: u8,
pub status: u8,
pub net_revert_s: u8,
pub temperatures: Vec<i8>,
pub status_message: String,
}
impl UnitStatus {
pub const fn boot_count(&self) -> Option<u32> {
if !self.flags.has(UnitFlag::BOOT_COUNT) {
return None;
}
Some(self.boot_count)
}
pub const fn fan_rpm(&self) -> Option<u16> {
if !self.flags.has(UnitFlag::FAN_SPEED) {
return None;
}
Some(self.fan_rpm)
}
pub const fn network_pending(&self) -> bool {
self.flags.has(UnitFlag::NET_PENDING)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct UnitNetConfig {
pub ip: Ipv4Addr,
pub netmask: Ipv4Addr,
pub gateway: Ipv4Addr,
pub dns1: Ipv4Addr,
pub dns2: Ipv4Addr,
}
impl Default for UnitNetConfig {
fn default() -> Self {
Self {
ip: Ipv4Addr::UNSPECIFIED,
netmask: Ipv4Addr::UNSPECIFIED,
gateway: Ipv4Addr::UNSPECIFIED,
dns1: Ipv4Addr::UNSPECIFIED,
dns2: Ipv4Addr::UNSPECIFIED,
}
}
}
impl UnitNetConfig {
pub fn is_valid(&self) -> bool {
let ip = self.ip;
let mask = u32::from(self.netmask);
!ip.is_unspecified()
&& !ip.is_broadcast()
&& !ip.is_multicast()
&& mask != 0
&& mask.leading_ones() + mask.trailing_zeros() == 32
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct UnitCommand {
pub target: DeviceUid,
pub command: UnitCommandKind,
pub flags: UnitCommandFlag,
pub network: Option<UnitNetConfig>,
}