use std::{fmt::Debug, time::Duration};
use serde::{Deserialize, Serialize, de::DeserializeOwned};
use crate::{
PollInterval,
clock::NtpClock,
config::{SourceConfig, SynchronizationConfig},
source::Measurement,
system::TimeSnapshot,
time_types::{NtpDuration, NtpTimestamp},
};
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct ObservableSourceTimedata {
pub offset: NtpDuration,
pub uncertainty: NtpDuration,
pub delay: NtpDuration,
pub remote_delay: NtpDuration,
pub remote_uncertainty: NtpDuration,
pub last_update: NtpTimestamp,
}
#[derive(Debug, Clone)]
pub struct StateUpdate<SourceId, ControllerMessage> {
pub source_message: Option<ControllerMessage>,
pub time_snapshot: Option<TimeSnapshot>,
pub used_sources: Option<Vec<SourceId>>,
pub next_update: Option<Duration>,
}
impl<SourceId, ControllerMessage> Default for StateUpdate<SourceId, ControllerMessage> {
fn default() -> Self {
Self {
source_message: None,
time_snapshot: None,
used_sources: None,
next_update: None,
}
}
}
pub trait TimeSyncController: Sized + Send + 'static {
type Clock: NtpClock;
type SourceId;
type AlgorithmConfig: Debug + Copy + DeserializeOwned + Send;
type ControllerMessage: Debug + Clone + Send + 'static;
type SourceMessage: Debug + Clone + Send + 'static;
type NtpSourceController: SourceController<
ControllerMessage = Self::ControllerMessage,
SourceMessage = Self::SourceMessage,
MeasurementDelay = NtpDuration,
>;
type OneWaySourceController: SourceController<
ControllerMessage = Self::ControllerMessage,
SourceMessage = Self::SourceMessage,
MeasurementDelay = (),
>;
fn new(
clock: Self::Clock,
synchronization_config: SynchronizationConfig,
algorithm_config: Self::AlgorithmConfig,
) -> Result<Self, <Self::Clock as NtpClock>::Error>;
fn take_control(&mut self) -> Result<(), <Self::Clock as NtpClock>::Error>;
fn add_source(
&mut self,
id: Self::SourceId,
source_config: SourceConfig,
) -> Self::NtpSourceController;
fn add_one_way_source(
&mut self,
id: Self::SourceId,
source_config: SourceConfig,
measurement_noise_estimate: f64,
measurement_accuracy_estimate: f64,
period: Option<f64>,
) -> Self::OneWaySourceController;
fn remove_source(&mut self, id: Self::SourceId);
fn source_update(&mut self, id: Self::SourceId, usable: bool);
fn source_message(
&mut self,
id: Self::SourceId,
message: Self::SourceMessage,
) -> StateUpdate<Self::SourceId, Self::ControllerMessage>;
fn time_update(&mut self) -> StateUpdate<Self::SourceId, Self::ControllerMessage>;
}
pub trait SourceController: Sized + Send + 'static {
type ControllerMessage: Debug + Clone + Send + 'static;
type SourceMessage: Debug + Clone + Send + 'static;
type MeasurementDelay: Debug + Copy + Clone;
fn handle_message(&mut self, message: Self::ControllerMessage);
fn handle_measurement(
&mut self,
measurement: Measurement<Self::MeasurementDelay>,
) -> Option<Self::SourceMessage>;
fn desired_poll_interval(&self) -> PollInterval;
fn observe(&self) -> ObservableSourceTimedata;
}
mod kalman;
pub use kalman::{
KalmanClockController, KalmanControllerMessage, KalmanSourceController, KalmanSourceMessage,
TwoWayKalmanSourceController, config::AlgorithmConfig,
};