Add chrony SOCK refclock and initial UCCM source
This commit is contained in:
76
src/chrony_refclock.rs
Normal file
76
src/chrony_refclock.rs
Normal file
@@ -0,0 +1,76 @@
|
||||
use async_trait::async_trait;
|
||||
use chimemon::{ChimemonMessage, ChimemonTarget, ChimemonTargetChannel, ChronySockConfig};
|
||||
use libc::{c_double, c_int, timeval};
|
||||
use log::debug;
|
||||
use std::io::prelude::*;
|
||||
use std::mem;
|
||||
use std::os::unix::net::UnixDatagram;
|
||||
use std::path::Path;
|
||||
|
||||
const CHRONY_MAGIC: c_int = 0x534f434b;
|
||||
|
||||
pub struct ChronySockServer {
|
||||
sock: UnixDatagram,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct ChronyTimeReport {
|
||||
tv: timeval,
|
||||
offset: c_double,
|
||||
pulse: c_int,
|
||||
leap: c_int,
|
||||
_pad: c_int,
|
||||
magic: c_int,
|
||||
}
|
||||
|
||||
impl ChronySockServer {
|
||||
pub fn new(config: ChronySockConfig) -> Self {
|
||||
debug!(
|
||||
"Size of chrony refclock report: {}",
|
||||
mem::size_of::<ChronyTimeReport>()
|
||||
);
|
||||
let sock = UnixDatagram::unbound().unwrap();
|
||||
// TODO: Don't connect to the socket or we break when chrony restarts
|
||||
// use sock.send_to instead and fail gracefully
|
||||
sock.connect(&config.sock).expect("Unable to open socket");
|
||||
ChronySockServer { sock }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl ChimemonTarget for ChronySockServer {
|
||||
async fn run(mut self, mut chan: ChimemonTargetChannel) {
|
||||
loop {
|
||||
let msg = chan.recv().await.unwrap();
|
||||
match msg {
|
||||
ChimemonMessage::TimeReport(tr) => {
|
||||
if tr.valid {
|
||||
{
|
||||
let frame = ChronyTimeReport {
|
||||
tv: timeval {
|
||||
tv_sec: tr.system_time.timestamp().try_into().unwrap_or_default(),
|
||||
tv_usec: tr.system_time.timestamp_subsec_micros().try_into().unwrap_or_default(),
|
||||
},
|
||||
offset: tr.offset.num_nanoseconds().unwrap() as f64 / 1e9,
|
||||
leap: if tr.leap_flag { 1 } else { 0 },
|
||||
pulse: 0,
|
||||
_pad: 0,
|
||||
magic: CHRONY_MAGIC,
|
||||
};
|
||||
unsafe {
|
||||
let bs = std::slice::from_raw_parts(
|
||||
(&frame as *const ChronyTimeReport) as *const u8,
|
||||
mem::size_of::<ChronyTimeReport>(),
|
||||
);
|
||||
debug!("Sending to chrony sock {:#?}", frame);
|
||||
self.sock.send(bs).unwrap();
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => continue,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user