use clock_steering::{Clock, TimeOffset, unix::UnixClock};
use ntp_proto::NtpClock;
use super::util::convert_clock_timestamp;
#[derive(Debug, Clone, Copy)]
pub struct NtpClockWrapper(UnixClock);
impl NtpClockWrapper {
pub fn new(clock: UnixClock) -> Self {
NtpClockWrapper(clock)
}
}
impl Default for NtpClockWrapper {
fn default() -> Self {
NtpClockWrapper(UnixClock::CLOCK_REALTIME)
}
}
impl NtpClock for NtpClockWrapper {
type Error = <UnixClock as Clock>::Error;
fn now(&self) -> Result<ntp_proto::NtpTimestamp, Self::Error> {
self.0.now().map(convert_clock_timestamp)
}
fn set_frequency(&self, freq: f64) -> Result<ntp_proto::NtpTimestamp, Self::Error> {
self.0
.set_frequency(freq * 1e6)
.map(convert_clock_timestamp)
}
fn get_frequency(&self) -> Result<f64, Self::Error> {
self.0.get_frequency().map(|v| v * 1e-6)
}
fn step_clock(
&self,
offset: ntp_proto::NtpDuration,
) -> Result<ntp_proto::NtpTimestamp, Self::Error> {
let (seconds, nanos) = offset.as_seconds_nanos();
self.0
.step_clock(TimeOffset {
seconds: seconds as _,
nanos,
})
.map(convert_clock_timestamp)
}
fn disable_ntp_algorithm(&self) -> Result<(), Self::Error> {
self.0.disable_kernel_ntp_algorithm()
}
fn error_estimate_update(
&self,
est_error: ntp_proto::NtpDuration,
max_error: ntp_proto::NtpDuration,
) -> Result<(), Self::Error> {
self.0.error_estimate_update(
core::time::Duration::from_secs_f64(est_error.to_seconds()),
core::time::Duration::from_secs_f64(max_error.to_seconds()),
)
}
fn status_update(&self, leap_status: ntp_proto::NtpLeapIndicator) -> Result<(), Self::Error> {
self.0.set_leap_seconds(match leap_status {
ntp_proto::NtpLeapIndicator::NoWarning => clock_steering::LeapIndicator::NoWarning,
ntp_proto::NtpLeapIndicator::Leap61 => clock_steering::LeapIndicator::Leap61,
ntp_proto::NtpLeapIndicator::Leap59 => clock_steering::LeapIndicator::Leap59,
ntp_proto::NtpLeapIndicator::Unknown | ntp_proto::NtpLeapIndicator::Unsynchronized => {
clock_steering::LeapIndicator::Unknown
}
})
}
}