Skip to main content

rtime_core/
source.rs

1use std::net::SocketAddr;
2
3use crate::clock::LeapIndicator;
4use crate::timestamp::{NtpDuration, NtpTimestamp};
5
6/// Unique identifier for a time source.
7#[derive(Clone, Debug, PartialEq, Eq, Hash)]
8pub enum SourceId {
9    Ntp {
10        address: SocketAddr,
11        reference_id: u32,
12    },
13    Ptp {
14        clock_identity: [u8; 8],
15        port_number: u16,
16    },
17    RefClock {
18        driver: String,
19        unit: u8,
20    },
21}
22
23impl std::fmt::Display for SourceId {
24    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25        match self {
26            Self::Ntp { address, .. } => write!(f, "NTP:{}", address),
27            Self::Ptp {
28                clock_identity,
29                port_number,
30            } => {
31                write!(
32                    f,
33                    "PTP:{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}-{}",
34                    clock_identity[0],
35                    clock_identity[1],
36                    clock_identity[2],
37                    clock_identity[3],
38                    clock_identity[4],
39                    clock_identity[5],
40                    clock_identity[6],
41                    clock_identity[7],
42                    port_number
43                )
44            }
45            Self::RefClock { driver, unit } => write!(f, "REF:{}({})", driver, unit),
46        }
47    }
48}
49
50/// Measurement from a single time source after filtering.
51#[derive(Clone, Debug)]
52pub struct SourceMeasurement {
53    pub id: SourceId,
54    /// Offset from local clock.
55    pub offset: NtpDuration,
56    /// Round-trip delay.
57    pub delay: NtpDuration,
58    /// Error bound.
59    pub dispersion: NtpDuration,
60    /// RMS jitter estimate.
61    pub jitter: f64,
62    /// Stratum of this source.
63    pub stratum: u8,
64    /// Leap indicator from source.
65    pub leap_indicator: LeapIndicator,
66    /// Root delay to primary reference.
67    pub root_delay: NtpDuration,
68    /// Root dispersion.
69    pub root_dispersion: NtpDuration,
70    /// When this measurement was taken.
71    pub time: NtpTimestamp,
72}
73
74impl SourceMeasurement {
75    /// Root distance: total error budget from this source to the primary reference.
76    /// root_distance = root_delay/2 + root_dispersion + |delay|/2 + dispersion
77    pub fn root_distance(&self) -> NtpDuration {
78        self.root_delay.abs() / 2 + self.root_dispersion + self.delay.abs() / 2 + self.dispersion
79    }
80}