blob: 3d3710820b0f687bc553c313ed49d4afee52ab52 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//! A collection of enumerations that are used widely across Timekeeper, usually in both
//! operational and in diagnostics code.
use {
crate::rtc::RtcCreationError,
time_metrics_registry::{
RealTimeClockEventsMetricDimensionEventType as CobaltRtcEvent, TimeMetricDimensionRole,
TimeMetricDimensionTrack,
TimekeeperTimeSourceEventsMetricDimensionEventType as CobaltTimeSourceEvent,
TimekeeperTrackEventsMetricDimensionEventType as CobaltTrackEvent,
},
};
/// The state of the userspace UTC clock when Timekeeper was initialized.
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum InitialClockState {
NotSet,
PreviouslySet,
}
/// The possible outcomes of an attempt to initialize and read the real time clock.
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum InitializeRtcOutcome {
NoDevices,
MultipleDevices,
ConnectionFailed,
ReadNotAttempted,
ReadFailed,
InvalidBeforeBackstop,
Succeeded,
}
impl From<RtcCreationError> for InitializeRtcOutcome {
fn from(other: RtcCreationError) -> InitializeRtcOutcome {
match other {
RtcCreationError::NoDevices => Self::NoDevices,
RtcCreationError::MultipleDevices(_) => Self::MultipleDevices,
RtcCreationError::ConnectionFailed(_) => Self::ConnectionFailed,
}
}
}
impl Into<CobaltRtcEvent> for InitializeRtcOutcome {
fn into(self) -> CobaltRtcEvent {
match self {
Self::NoDevices => CobaltRtcEvent::NoDevices,
Self::MultipleDevices => CobaltRtcEvent::MultipleDevices,
Self::ConnectionFailed => CobaltRtcEvent::ConnectionFailed,
Self::ReadFailed => CobaltRtcEvent::ReadFailed,
// TODO(jsankey): Define a better Cobalt enum for this case
Self::ReadNotAttempted => CobaltRtcEvent::ReadSucceeded,
Self::InvalidBeforeBackstop => CobaltRtcEvent::ReadInvalidBeforeBackstop,
Self::Succeeded => CobaltRtcEvent::ReadSucceeded,
}
}
}
/// The possible outcomes of an attempt to write to the real time clock.
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum WriteRtcOutcome {
Failed,
Succeeded,
}
impl Into<CobaltRtcEvent> for WriteRtcOutcome {
fn into(self) -> CobaltRtcEvent {
match self {
Self::Failed => CobaltRtcEvent::WriteFailed,
Self::Succeeded => CobaltRtcEvent::WriteSucceeded,
}
}
}
/// The role a time source is playing within time synchronization.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Role {
Primary,
Monitor,
// TODO(jsankey): Add Gating and Fallback when some product requires them.
}
impl Into<TimeMetricDimensionRole> for Role {
fn into(self) -> TimeMetricDimensionRole {
match self {
Self::Primary => TimeMetricDimensionRole::Primary,
Self::Monitor => TimeMetricDimensionRole::Monitor,
}
}
}
/// Which of the independent estimates of time is applicable. Timekeeper maintains a Primary track
/// that is externally visible and optionally a internal Monitor track that is used to validate
/// proposed changes to the time synchronization source or algorithms.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Track {
Primary,
Monitor,
}
impl From<Role> for Track {
fn from(role: Role) -> Track {
match role {
Role::Primary => Track::Primary,
Role::Monitor => Track::Monitor,
}
}
}
impl Into<TimeMetricDimensionTrack> for Track {
fn into(self) -> TimeMetricDimensionTrack {
match self {
Self::Primary => TimeMetricDimensionTrack::Primary,
Self::Monitor => TimeMetricDimensionTrack::Monitor,
}
}
}
/// The time sources from which the userspace clock might be started.
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum StartClockSource {
Rtc,
External(Role),
}
/// The strategies that can be used to align a clock with the estimated UTC.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum ClockCorrectionStrategy {
/// The clock will be immediately stepped to the new value.
Step,
/// The clock will be gradually slewed to the new value by applying a small rate change for
/// as long as is necessary.
NominalRateSlew,
/// The clock will be slewed to the new value by applying whatever rate change is necessary to
/// complete the correction within the maximum allowed duration.
MaxDurationSlew,
}
// Required to instantiate a circular buffer of clock corrections in inspect.
impl Default for ClockCorrectionStrategy {
fn default() -> Self {
ClockCorrectionStrategy::Step
}
}
impl Into<CobaltTrackEvent> for ClockCorrectionStrategy {
fn into(self) -> CobaltTrackEvent {
match self {
Self::Step => CobaltTrackEvent::CorrectionByStep,
Self::NominalRateSlew => CobaltTrackEvent::CorrectionByNominalRateSlew,
Self::MaxDurationSlew => CobaltTrackEvent::CorrectionByMaxDurationSlew,
}
}
}
/// The reasons a clock may have been updated.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum ClockUpdateReason {
TimeStep,
BeginSlew,
EndSlew,
ReduceError,
IncreaseError,
}
impl Into<CobaltTrackEvent> for ClockUpdateReason {
fn into(self) -> CobaltTrackEvent {
match self {
Self::TimeStep => CobaltTrackEvent::ClockUpdateTimeStep,
Self::BeginSlew => CobaltTrackEvent::ClockUpdateBeginSlew,
Self::EndSlew => CobaltTrackEvent::ClockUpdateEndSlew,
Self::ReduceError => CobaltTrackEvent::ClockUpdateReduceError,
Self::IncreaseError => CobaltTrackEvent::ClockUpdateIncreaseError,
}
}
}
/// The reasons a received time sample may not be valid.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum SampleValidationError {
MonotonicInFuture,
MonotonicTooOld,
BeforeBackstop,
TooCloseToPrevious,
}
impl Into<CobaltTimeSourceEvent> for SampleValidationError {
fn into(self) -> CobaltTimeSourceEvent {
match self {
Self::MonotonicInFuture => CobaltTimeSourceEvent::SampleRejectedMonotonicInFuture,
Self::MonotonicTooOld => CobaltTimeSourceEvent::SampleRejectedMonotonicTooOld,
Self::BeforeBackstop => CobaltTimeSourceEvent::SampleRejectedBeforeBackstop,
Self::TooCloseToPrevious => CobaltTimeSourceEvent::SampleRejectedTooCloseToPrevious,
}
}
}
/// The reasons a partially accumulated frequency window may be discarded.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum FrequencyDiscardReason {
UtcBeforeWindow,
InsufficientSamples,
PotentialLeapSecond,
}
/// The reasons a time source may have failed.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum TimeSourceError {
LaunchFailed,
StreamFailed,
CallFailed,
SampleTimeOut,
}
impl Into<CobaltTimeSourceEvent> for TimeSourceError {
fn into(self) -> CobaltTimeSourceEvent {
match self {
Self::LaunchFailed => CobaltTimeSourceEvent::LaunchFailed,
Self::StreamFailed => CobaltTimeSourceEvent::RestartedStreamFailed,
Self::CallFailed => CobaltTimeSourceEvent::RestartedCallFailed,
Self::SampleTimeOut => CobaltTimeSourceEvent::RestartedSampleTimeOut,
}
}
}