1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#[cfg(test)]
mod abs_send_time_extension_test;
use crate::{error::Error, packetizer::Marshaller};
use bytes::{BufMut, Bytes, BytesMut};
use std::time::Duration;
pub const ABS_SEND_TIME_EXTENSION_SIZE: usize = 3;
pub struct AbsSendTimeExtension {
pub timestamp: u64,
}
impl Marshaller for AbsSendTimeExtension {
fn unmarshal(raw_packet: &Bytes) -> Result<Self, Error> {
if raw_packet.len() < ABS_SEND_TIME_EXTENSION_SIZE {
return Err(Error::ErrTooSmall);
}
let b0 = raw_packet[0];
let b1 = raw_packet[1];
let b2 = raw_packet[2];
let timestamp = (b0 as u64) << 16 | (b1 as u64) << 8 | b2 as u64;
Ok(AbsSendTimeExtension { timestamp })
}
fn marshal_size(&self) -> usize {
ABS_SEND_TIME_EXTENSION_SIZE
}
fn marshal_to(&self, buf: &mut BytesMut) -> Result<usize, Error> {
buf.put_u8(((self.timestamp & 0xFF0000) >> 16) as u8);
buf.put_u8(((self.timestamp & 0xFF00) >> 8) as u8);
buf.put_u8((self.timestamp & 0xFF) as u8);
Ok(ABS_SEND_TIME_EXTENSION_SIZE)
}
}
impl AbsSendTimeExtension {
pub fn estimate(&self, receive: Duration) -> Duration {
let receive_ntp = unix2ntp(receive);
let mut ntp = receive_ntp & 0xFFFFFFC000000000 | (self.timestamp & 0xFFFFFF) << 14;
if receive_ntp < ntp {
ntp -= 0x1000000 << 14;
}
ntp2unix(ntp)
}
pub fn new(send_time: Duration) -> Self {
AbsSendTimeExtension {
timestamp: unix2ntp(send_time) >> 14,
}
}
}
pub fn unix2ntp(t: Duration) -> u64 {
let u = t.as_nanos() as u64;
let mut s = u / 1_000_000_000;
s += 0x83AA7E80;
let mut f = u % 1_000_000_000;
f <<= 32;
f /= 1_000_000_000;
s <<= 32;
s | f
}
pub fn ntp2unix(t: u64) -> Duration {
let mut s = t >> 32;
let mut f = t & 0xFFFFFFFF;
f *= 1_000_000_000;
f >>= 32;
s -= 0x83AA7E80;
let u = s * 1_000_000_000 + f;
Duration::new(u / 1_000_000_000, (u % 1_000_000_000) as u32)
}