rtc_rtcp/extended_report/
rrt.rs

1use super::*;
2
3const RRT_REPORT_BLOCK_LENGTH: u16 = 8;
4
5/// ReceiverReferenceTimeReportBlock encodes a Receiver Reference Time
6/// report block as described in RFC 3611 section 4.4.
7///
8///  0                   1                   2                   3
9///  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
10/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
11/// |     BT=4      |   reserved    |       block length = 2        |
12/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
13/// |              NTP timestamp, most significant word             |
14/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
15/// |             NTP timestamp, least significant word             |
16/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
17#[derive(Debug, Default, PartialEq, Eq, Clone)]
18pub struct ReceiverReferenceTimeReportBlock {
19    pub ntp_timestamp: u64,
20}
21
22impl fmt::Display for ReceiverReferenceTimeReportBlock {
23    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24        write!(f, "{self:?}")
25    }
26}
27
28impl ReceiverReferenceTimeReportBlock {
29    pub fn xr_header(&self) -> XRHeader {
30        XRHeader {
31            block_type: BlockType::ReceiverReferenceTime,
32            type_specific: 0,
33            block_length: (self.raw_size() / 4 - 1) as u16,
34        }
35    }
36}
37
38impl Packet for ReceiverReferenceTimeReportBlock {
39    fn header(&self) -> Header {
40        Header::default()
41    }
42
43    /// destination_ssrc returns an array of ssrc values that this report block refers to.
44    fn destination_ssrc(&self) -> Vec<u32> {
45        vec![]
46    }
47
48    fn raw_size(&self) -> usize {
49        XR_HEADER_LENGTH + RRT_REPORT_BLOCK_LENGTH as usize
50    }
51
52    fn as_any(&self) -> &dyn Any {
53        self
54    }
55    fn equal(&self, other: &dyn Packet) -> bool {
56        other
57            .as_any()
58            .downcast_ref::<ReceiverReferenceTimeReportBlock>()
59            == Some(self)
60    }
61    fn cloned(&self) -> Box<dyn Packet> {
62        Box::new(self.clone())
63    }
64}
65
66impl MarshalSize for ReceiverReferenceTimeReportBlock {
67    fn marshal_size(&self) -> usize {
68        self.raw_size()
69    }
70}
71
72impl Marshal for ReceiverReferenceTimeReportBlock {
73    /// marshal_to encodes the ReceiverReferenceTimeReportBlock in binary
74    fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
75        if buf.remaining_mut() < self.marshal_size() {
76            return Err(Error::BufferTooShort);
77        }
78
79        let h = self.xr_header();
80        let n = h.marshal_to(buf)?;
81        buf = &mut buf[n..];
82
83        buf.put_u64(self.ntp_timestamp);
84
85        Ok(self.marshal_size())
86    }
87}
88
89impl Unmarshal for ReceiverReferenceTimeReportBlock {
90    /// Unmarshal decodes the ReceiverReferenceTimeReportBlock from binary
91    fn unmarshal<B>(raw_packet: &mut B) -> Result<Self>
92    where
93        Self: Sized,
94        B: Buf,
95    {
96        if raw_packet.remaining() < XR_HEADER_LENGTH {
97            return Err(Error::PacketTooShort);
98        }
99
100        let xr_header = XRHeader::unmarshal(raw_packet)?;
101        let block_length = match xr_header.block_length.checked_mul(4) {
102            Some(length) => length,
103            None => return Err(Error::InvalidBlockSize),
104        };
105        if block_length != RRT_REPORT_BLOCK_LENGTH || raw_packet.remaining() < block_length as usize
106        {
107            return Err(Error::PacketTooShort);
108        }
109
110        let ntp_timestamp = raw_packet.get_u64();
111
112        Ok(ReceiverReferenceTimeReportBlock { ntp_timestamp })
113    }
114}