statime/lib.rs
1//! Statime is a library providing an implementation of PTP version 2.1
2//! (IEEE1588-2019). It provides all the building blocks to setup PTP ordinary
3//! and boundary clocks.
4//!
5//! `statime` is designed to be able to work with many different underlying
6//! platforms, including embedded targets. This does mean that it cannot use the
7//! standard library and platform specific libraries to interact with the system
8//! clock and to access the network. That needs to be provided by the user of
9//! the library.
10//!
11//! On modern linux kernels, the `statime-linux` crate provides ready to use
12//! implementations of these interfaces. For other platforms the user will need
13//! to implement these themselves.
14//!
15//! The `statime-stm32` crate gives an example of how to use `statime` on an
16//! embedded target.
17//!
18//! # Implementing a PTP clock with `statime`
19//! Implementing a clock device requires three parts. The [`PtpInstance`]
20//! handles the logic for the Best Master Clock Algorithm (BMCA). A
21//! [`Port`](`port::Port`) handles the logic for a single network interface of
22//! the device. And a [`Clock`] per [`Port`](`port::Port`) that is a struct
23//! provided by the user that can read and control a clock device that is
24//! associated with a [`Port`](`port::Port`).
25//!
26//! ## Setup
27//! The first step for a new implementation is to gather the configurations
28//! needed, these are:
29//! * A [`InstanceConfig`](`config::InstanceConfig`) that describes the device
30//! * A [`TimePropertiesDS`](`config::TimePropertiesDS`) that describes the
31//! timescale that is used
32//! * A [`PortConfig`](`config::PortConfig`) per [`Port`](`port::Port`) to
33//! configure its behavior
34//!
35//! The [`PtpInstance`] can then be created with [`PtpInstance::new`], providing
36//! [`InstanceConfig`](`config::InstanceConfig`) and
37//! [`TimePropertiesDS`](`config::TimePropertiesDS`). From that instance
38//! [`Port`](`port::Port`)s can be created using [`PtpInstance::add_port`]
39//! proviging it [`PortConfig`](`config::PortConfig`), its [`Clock`] and a
40//! [`Filter`](`filters::Filter`).
41//!
42//! ## Running
43//! The [`PtpInstance`] expects to execute the BMCA periodically. For this the
44//! user must provide a slice containing all ports in the
45//! [`InBmca`](`port::InBmca`) state.
46//!
47//! [`Port`](`port::Port`)s start out in the [`InBmca`](`port::InBmca`) state
48//! and can be turned into [`Running`](`port::Running`) mode by calling
49//! [`Port::end_bmca`](`port::Port::end_bmca`). And for running the BMCA
50//! [`Port::start_bmca`](`port::Port::start_bmca`) turns it back into the
51//! [`InBmca`](`port::InBmca`) state.
52//!
53//! While [`Running`](`port::Running`) a [`Port`](`port::Port`) expects the user
54//! to keep track of a few different timers as well as two network sockets. The
55//! [`Port`](`port::Port`) is informed about any events via one of the
56//! [`Port::handle_*`](`port::Port::handle_send_timestamp`) methods. Actions the
57//! [`Port`](`port::Port`) expects to be performed are returned in the form of
58//! [`PortAction`](`port::PortAction`)s.
59//!
60//! # Testing a new implementation
61//! A basic option for testing is to run `statime-linux` on your developer
62//! machine and connecting your new implementation to a dedicated network port.
63//! Now both the time synchronization can be observed e.g. by using a
64//! pulse-per-second (PPS) pin. Additionally the protocol excahnge can be
65//! observed with a tool like [Wireshark](https://www.wireshark.org/).
66//!
67//! # Cargo Features
68//! This crate exposes two features `std` and `fuzz`. `std` enables a dependency
69//! on the Rust standard library providing:
70//! * [`std::error::Error`] implementations for error types
71//! * Implementations of the [`config::AcceptableMasterList`] trait on types in
72//! [`std`]
73//! * Usage of methods on [`f32`] and [`f64`] directly from [`std`] instead of
74//! [`libm`]
75//!
76//! The `fuzz` feature exposes internal types for fuzzing implementations in the
77//! `statime::fuzz` module.
78
79#![no_std]
80#![deny(missing_docs)]
81#![deny(rustdoc::broken_intra_doc_links)]
82#![warn(rustdoc::unescaped_backticks)]
83#[cfg(feature = "std")]
84extern crate std;
85
86mod bmc;
87mod clock;
88pub mod config;
89pub(crate) mod datastructures;
90pub mod filters;
91mod float_polyfill;
92pub mod observability;
93mod overlay_clock;
94pub mod port;
95mod ptp_instance;
96#[cfg(feature = "std")]
97mod shared_clock;
98pub mod time;
99
100pub use clock::Clock;
101pub use overlay_clock::OverlayClock;
102pub use ptp_instance::{PtpInstance, PtpInstanceState, PtpInstanceStateMutex};
103#[cfg(feature = "std")]
104pub use shared_clock::SharedClock;
105
106/// Helper types used for fuzzing
107///
108/// Enabled by the `fuzz` `feature`
109#[cfg(feature = "fuzz")]
110pub mod fuzz {
111 pub use crate::datastructures::messages::FuzzMessage;
112}