1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
use rand::Rng;
use crate::time::{Duration, Interval};
#[cfg(doc)]
use crate::{config::AcceptableMasterList, port::Port};
/// Which delay mechanism a port is using.
///
/// Currently, statime only supports the end to end (E2E) delay mechanism.
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum DelayMechanism {
/// End to end delay mechanism. Delay measurement is done directly to the
/// chosen master, across potential transparent nodes in between.
E2E {
/// The time between sending two delay requests
interval: Interval,
},
/// Peer to peer delay mechanism. Delay measurement is done on the
/// individaul links.
P2P {
/// The time between sending two peer delay requests
interval: Interval,
},
// No support for other delay mechanisms
}
/// Configuration items of the PTP PortDS dataset. Dynamical fields are kept
/// as part of [crate::port::Port].
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct PortConfig<A> {
/// A list that contains all nodes that this [`Port`] will accept as a
/// master.
///
/// This should implement the [`AcceptableMasterList`] trait.
pub acceptable_master_list: A,
/// The mechanism used to measure the delay at this [`Port`].
pub delay_mechanism: DelayMechanism,
/// The time between announcements.
pub announce_interval: Interval,
/// Specifies how many [`announce_interval`](`Self::announce_interval`)s to
/// wait until the announce message expires.
pub announce_receipt_timeout: u8,
/// Time between two sync messages when this [`Port`] is in master mode.
pub sync_interval: Interval,
/// Never let this [`Port`] become a slave.
pub master_only: bool,
/// The estimated asymmetry in the link connected to this [`Port`]
pub delay_asymmetry: Duration,
// Notes:
// Fields specific for delay mechanism are kept as part of [DelayMechanism].
// Version is always 2.1, so not stored (versionNumber, minorVersionNumber)
}
impl<A> PortConfig<A> {
/// Minimum time between two delay request messages
pub fn min_delay_req_interval(&self) -> Interval {
match self.delay_mechanism {
DelayMechanism::E2E { interval } => interval,
DelayMechanism::P2P { interval } => interval,
}
}
/// Time between two announce messages
///
/// For more information see *IEEE1588-2019 section 9.2.6.12*
pub fn announce_duration(&self, rng: &mut impl Rng) -> core::time::Duration {
// add some randomness so that not all timers expire at the same time
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)
}
}