106 lines
3.1 KiB
Rust
106 lines
3.1 KiB
Rust
use anyhow::bail;
|
|
use embedded_svc::sys_time::SystemTime;
|
|
use esp_idf_svc::sntp::{self, EspSntp};
|
|
use esp_idf_svc::systime::EspSystemTime;
|
|
use log::{warn, info};
|
|
use sntpc::{Error, NtpContext, NtpResult, NtpTimestampGenerator, NtpUdpSocket, Result};
|
|
use std::net::{SocketAddr, ToSocketAddrs, UdpSocket};
|
|
use std::time::{Duration};
|
|
|
|
pub struct Time {
|
|
result: Option<NtpResult>,
|
|
sntp: Option<Box<EspSntp>>,
|
|
}
|
|
|
|
impl Time {
|
|
pub fn new () -> Time {
|
|
return Time {
|
|
result: None,
|
|
sntp: None
|
|
}
|
|
}
|
|
|
|
pub fn sync(&mut self) -> anyhow::Result<()> {
|
|
let sntp = sntp::EspSntp::new_default().map_err(|err| {
|
|
anyhow::anyhow!("ESP SNTP Failed: {:?}", err)
|
|
})?;
|
|
self.sntp = Some(Box::new(sntp));
|
|
return anyhow::Ok(())
|
|
}
|
|
|
|
pub fn get_time(&mut self) -> Duration {
|
|
if let Some(ref mut sntp) = self.sntp {
|
|
info!("ESP SNTP sync status {:?}", sntp.get_sync_status());
|
|
}
|
|
EspSystemTime {}.now()
|
|
}
|
|
|
|
// pub fn sync(&mut self) -> anyhow::Result<()> {
|
|
// let mut error = None;
|
|
|
|
// for _ in 0..10 {
|
|
// 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("pool.ntp.org:123", sock_wrapper, ntp_context);
|
|
// match result {
|
|
// Ok(res_time) => {
|
|
// println!("Got time: {}.{}", res_time.sec(), res_time.sec_fraction());
|
|
// self.result = Some(res_time);
|
|
// return anyhow::Ok(())
|
|
// }
|
|
// Err(err) => {
|
|
// error = Some(err);
|
|
// warn!("fetch dateTime from ntp failed: {:?}", err);
|
|
// },
|
|
// }
|
|
// }
|
|
// bail!("fetch dateTime from ntp failed: {:?}", error)
|
|
// }
|
|
|
|
}
|
|
|
|
#[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),
|
|
}
|
|
}
|
|
}
|