use rand::Rng;
use crate::time::{Duration, Interval};
#[cfg(doc)]
use crate::{config::AcceptableMasterList, port::Port};
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum DelayMechanism {
E2E {
interval: Interval,
},
P2P {
interval: Interval,
},
}
#[repr(u8)]
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, PartialOrd, Ord)]
pub enum PtpMinorVersion {
Zero = 0,
One = 1,
}
impl TryFrom<u8> for PtpMinorVersion {
type Error = &'static str;
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
0 => Ok(PtpMinorVersion::Zero),
1 => Ok(PtpMinorVersion::One),
_ => Err(""),
}
}
}
impl From<PtpMinorVersion> for u8 {
fn from(value: PtpMinorVersion) -> Self {
value as u8
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct PortConfig<A> {
pub acceptable_master_list: A,
pub delay_mechanism: DelayMechanism,
pub announce_interval: Interval,
pub announce_receipt_timeout: u8,
pub sync_interval: Interval,
pub master_only: bool,
pub delay_asymmetry: Duration,
pub minor_ptp_version: PtpMinorVersion,
}
impl<A> PortConfig<A> {
pub fn min_delay_req_interval(&self) -> Interval {
match self.delay_mechanism {
DelayMechanism::E2E { interval } => interval,
DelayMechanism::P2P { interval } => interval,
}
}
pub fn announce_duration(&self, rng: &mut impl Rng) -> core::time::Duration {
let factor = 1.0 + rng.sample::<f64, _>(rand::distributions::Open01);
let duration = self.announce_interval.as_core_duration();
duration.mul_f64(factor * self.announce_receipt_timeout as u32 as f64)
}
}