statime/config/
port.rs

1use rand::Rng;
2
3use crate::time::{Duration, Interval};
4#[cfg(doc)]
5use crate::{config::AcceptableMasterList, port::Port};
6
7/// Which delay mechanism a port is using.
8///
9/// Currently, statime only supports the end to end (E2E) delay mechanism.
10#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
11pub enum DelayMechanism {
12    /// End to end delay mechanism. Delay measurement is done directly to the
13    /// chosen master, across potential transparent nodes in between.
14    E2E {
15        /// The time between sending two delay requests
16        interval: Interval,
17    },
18    /// Peer to peer delay mechanism. Delay measurement is done on the
19    /// individaul links.
20    P2P {
21        /// The time between sending two peer delay requests
22        interval: Interval,
23    },
24    // No support for other delay mechanisms
25}
26
27#[repr(u8)]
28#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, PartialOrd, Ord)]
29/// Minor version to be used in PTP protocol messages
30pub enum PtpMinorVersion {
31    /// 0
32    Zero = 0,
33    /// 1
34    One = 1,
35}
36
37impl TryFrom<u8> for PtpMinorVersion {
38    type Error = &'static str;
39
40    fn try_from(value: u8) -> Result<Self, Self::Error> {
41        match value {
42            0 => Ok(PtpMinorVersion::Zero),
43            1 => Ok(PtpMinorVersion::One),
44            _ => Err(""),
45        }
46    }
47}
48
49impl From<PtpMinorVersion> for u8 {
50    fn from(value: PtpMinorVersion) -> Self {
51        value as u8
52    }
53}
54
55/// Configuration items of the PTP PortDS dataset. Dynamical fields are kept
56/// as part of [crate::port::Port].
57#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
58pub struct PortConfig<A> {
59    /// A list that contains all nodes that this [`Port`] will accept as a
60    /// master.
61    ///
62    /// This should implement the [`AcceptableMasterList`] trait.
63    pub acceptable_master_list: A,
64
65    /// The mechanism used to measure the delay at this [`Port`].
66    pub delay_mechanism: DelayMechanism,
67
68    /// The time between announcements.
69    pub announce_interval: Interval,
70
71    /// Specifies how many [`announce_interval`](`Self::announce_interval`)s to
72    /// wait until the announce message expires.
73    pub announce_receipt_timeout: u8,
74
75    /// Time between two sync messages when this [`Port`] is in master mode.
76    pub sync_interval: Interval,
77
78    /// Never let this [`Port`] become a slave.
79    pub master_only: bool,
80
81    /// The estimated asymmetry in the link connected to this [`Port`]
82    pub delay_asymmetry: Duration,
83
84    /// Minor version number to use.
85    pub minor_ptp_version: PtpMinorVersion,
86    // Notes:
87    // Fields specific for delay mechanism are kept as part of [DelayMechanism].
88    // Major version is always 2, so not stored (versionNumber)
89}
90
91impl<A> PortConfig<A> {
92    /// Minimum time between two delay request messages
93    pub fn min_delay_req_interval(&self) -> Interval {
94        match self.delay_mechanism {
95            DelayMechanism::E2E { interval } => interval,
96            DelayMechanism::P2P { interval } => interval,
97        }
98    }
99
100    /// Time between two announce messages
101    ///
102    /// For more information see *IEEE1588-2019 section 9.2.6.12*
103    pub fn announce_duration(&self, rng: &mut impl Rng) -> core::time::Duration {
104        // add some randomness so that not all timers expire at the same time
105        let factor = 1.0 + rng.sample::<f64, _>(rand::distributions::Open01);
106        let duration = self.announce_interval.as_core_duration();
107
108        duration.mul_f64(factor * self.announce_receipt_timeout as u32 as f64)
109    }
110}