xref: /webrtc/rtcp/src/extended_report/rrt.rs (revision 5d8fe953)
1 use super::*;
2 
3 const 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)]
18 pub struct ReceiverReferenceTimeReportBlock {
19     pub ntp_timestamp: u64,
20 }
21 
22 impl fmt::Display for ReceiverReferenceTimeReportBlock {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result23     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24         write!(f, "{self:?}")
25     }
26 }
27 
28 impl ReceiverReferenceTimeReportBlock {
xr_header(&self) -> XRHeader29     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 
38 impl Packet for ReceiverReferenceTimeReportBlock {
header(&self) -> Header39     fn header(&self) -> Header {
40         Header::default()
41     }
42 
43     /// destination_ssrc returns an array of ssrc values that this report block refers to.
destination_ssrc(&self) -> Vec<u32>44     fn destination_ssrc(&self) -> Vec<u32> {
45         vec![]
46     }
47 
raw_size(&self) -> usize48     fn raw_size(&self) -> usize {
49         XR_HEADER_LENGTH + RRT_REPORT_BLOCK_LENGTH as usize
50     }
51 
as_any(&self) -> &(dyn Any + Send + Sync)52     fn as_any(&self) -> &(dyn Any + Send + Sync) {
53         self
54     }
equal(&self, other: &(dyn Packet + Send + Sync)) -> bool55     fn equal(&self, other: &(dyn Packet + Send + Sync)) -> bool {
56         other
57             .as_any()
58             .downcast_ref::<ReceiverReferenceTimeReportBlock>()
59             .map_or(false, |a| self == a)
60     }
cloned(&self) -> Box<dyn Packet + Send + Sync>61     fn cloned(&self) -> Box<dyn Packet + Send + Sync> {
62         Box::new(self.clone())
63     }
64 }
65 
66 impl MarshalSize for ReceiverReferenceTimeReportBlock {
marshal_size(&self) -> usize67     fn marshal_size(&self) -> usize {
68         self.raw_size()
69     }
70 }
71 
72 impl Marshal for ReceiverReferenceTimeReportBlock {
73     /// marshal_to encodes the ReceiverReferenceTimeReportBlock in binary
marshal_to(&self, mut buf: &mut [u8]) -> Result<usize>74     fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
75         if buf.remaining_mut() < self.marshal_size() {
76             return Err(error::Error::BufferTooShort.into());
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 
89 impl Unmarshal for ReceiverReferenceTimeReportBlock {
90     /// Unmarshal decodes the ReceiverReferenceTimeReportBlock from binary
unmarshal<B>(raw_packet: &mut B) -> Result<Self> where Self: Sized, B: Buf,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::Error::PacketTooShort.into());
98         }
99 
100         let xr_header = XRHeader::unmarshal(raw_packet)?;
101         let block_length = xr_header.block_length * 4;
102         if block_length != RRT_REPORT_BLOCK_LENGTH || raw_packet.remaining() < block_length as usize
103         {
104             return Err(error::Error::PacketTooShort.into());
105         }
106 
107         let ntp_timestamp = raw_packet.get_u64();
108 
109         Ok(ReceiverReferenceTimeReportBlock { ntp_timestamp })
110     }
111 }
112