Crate sntpc[−][src]
Expand description
Rust SNTP client
Overview
This crate provides a method for sending requests to NTP servers and process responses, extracting received timestamp. Supported SNTP protocol versions:
Usage
Put this in your Cargo.toml
:
[dependencies]
sntpc = "0.3"
Features
Sntpc supports several features:
std
: includes functionality that depends on the standard libraryutils
: includes functionality that mostly OS specific and allows system time synclog
: enables library debug output during execution
Warning:
utils
feature is not stable and may change in the future.
Details
There are multiple approaches how the library can be used:
- under environments where a networking stuff is hidden in system/RTOS kernel,
get_time
can be used since it encapsulates network I/O - under environments where TCP/IP stack requires to call some helper functions like
poll
,wait
, etc. and/or there are no options to perform I/O operations within a single call,sntp_send_request
andsntp_process_response
can be used
As sntpc
supports no_std
environment as well, it was
decided to provide a set of traits to implement for a network object (UdpSocket
)
and timestamp generator:
NtpUdpSocket
trait should be implemented forUdpSocket
-like objects for the library to be able to send and receive data from NTP serversNtpTimestampGenerator
trait should be implemented for timestamp generator objects to provide the library with system related timestamps
Logging support
Library debug logs can be enabled in executables by enabling log
feature. Server
addresses, response payload will be printed.
Example
use sntpc::{Error, NtpContext, NtpTimestampGenerator, NtpUdpSocket, Result};
#[cfg(not(feature = "std"))]
use no_std_net::{SocketAddr, ToSocketAddrs, IpAddr, Ipv4Addr};
#[cfg(feature = "std")]
use std::net::{SocketAddr, ToSocketAddrs, UdpSocket};
use std::time::Duration;
#[derive(Copy, Clone, Default)]
struct StdTimestampGen {
duration: Duration,
}
impl NtpTimestampGenerator for StdTimestampGen {
fn init(&mut self) {
self.duration = std::time::SystemTime::now()
.duration_since(std::time::SystemTime::UNIX_EPOCH)
.unwrap();
}
fn timestamp_sec(&self) -> u64 {
self.duration.as_secs()
}
fn timestamp_subsec_micros(&self) -> u32 {
self.duration.subsec_micros()
}
}
#[derive(Debug)]
struct UdpSocketWrapper(UdpSocket);
impl NtpUdpSocket for UdpSocketWrapper {
fn send_to<T: ToSocketAddrs>(
&self,
buf: &[u8],
addr: T,
) -> Result<usize> {
match self.0.send_to(buf, addr) {
Ok(usize) => Ok(usize),
Err(_) => Err(Error::Network),
}
}
fn recv_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr)> {
match self.0.recv_from(buf) {
Ok((size, addr)) => Ok((size, addr)),
Err(_) => Err(Error::Network),
}
}
}
fn main() {
let socket =
UdpSocket::bind("0.0.0.0:0").expect("Unable to crate UDP socket");
socket
.set_read_timeout(Some(Duration::from_secs(2)))
.expect("Unable to set UDP socket read timeout");
let sock_wrapper = UdpSocketWrapper(socket);
let ntp_context = NtpContext::new(StdTimestampGen::default());
let result =
sntpc::get_time("time.google.com:123", sock_wrapper, ntp_context);
match result {
Ok(time) => {
println!("Got time: {}.{}", time.sec(), time.sec_fraction());
}
Err(err) => println!("Err: {:?}", err),
}
}
Structs
SNTP client context that contains of objects that may be required for client’s operation
SNTP request result representation
Preserve SNTP request sending operation result required during receiving and processing state
Enums
The error type for SNTP client Errors originate on network layer or during processing response from a NTP server
Traits
A trait encapsulating timestamp generator’s operations
A trait encapsulating UDP socket interface required for SNTP client operations
Functions
Send request to a NTP server with the given address and process the response in a single call
Process SNTP response from a server
Send SNTP request to a server
Type Definitions
SNTP library result type