rtc_rtcp/extended_report/
prt.rs

1use super::*;
2
3const PRT_REPORT_BLOCK_MIN_LENGTH: u16 = 8;
4
5/// PacketReceiptTimesReportBlock represents a Packet Receipt Times
6/// report block, as described in RFC 3611 section 4.3.
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=3      | rsvd. |   t   |         block length          |
12/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
13/// |                        ssrc of source                         |
14/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
15/// |          begin_seq            |             end_seq           |
16/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
17/// |       Receipt time of packet begin_seq                        |
18/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
19/// |       Receipt time of packet (begin_seq + 1) mod 65536        |
20/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
21/// :                              ...                              :
22/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23/// |       Receipt time of packet (end_seq - 1) mod 65536          |
24/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
25#[derive(Debug, Default, PartialEq, Eq, Clone)]
26pub struct PacketReceiptTimesReportBlock {
27    //not included in marshal/unmarshal
28    pub t: u8,
29
30    //marshal/unmarshal
31    pub ssrc: u32,
32    pub begin_seq: u16,
33    pub end_seq: u16,
34    pub receipt_time: Vec<u32>,
35}
36
37impl fmt::Display for PacketReceiptTimesReportBlock {
38    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39        write!(f, "{self:?}")
40    }
41}
42
43impl PacketReceiptTimesReportBlock {
44    pub fn xr_header(&self) -> XRHeader {
45        XRHeader {
46            block_type: BlockType::PacketReceiptTimes,
47            type_specific: self.t & 0x0F,
48            block_length: (self.raw_size() / 4 - 1) as u16,
49        }
50    }
51}
52
53impl Packet for PacketReceiptTimesReportBlock {
54    fn header(&self) -> Header {
55        Header::default()
56    }
57
58    /// destination_ssrc returns an array of ssrc values that this report block refers to.
59    fn destination_ssrc(&self) -> Vec<u32> {
60        vec![self.ssrc]
61    }
62
63    fn raw_size(&self) -> usize {
64        XR_HEADER_LENGTH + PRT_REPORT_BLOCK_MIN_LENGTH as usize + self.receipt_time.len() * 4
65    }
66
67    fn as_any(&self) -> &dyn Any {
68        self
69    }
70    fn equal(&self, other: &dyn Packet) -> bool {
71        other
72            .as_any()
73            .downcast_ref::<PacketReceiptTimesReportBlock>()
74            == Some(self)
75    }
76    fn cloned(&self) -> Box<dyn Packet> {
77        Box::new(self.clone())
78    }
79}
80
81impl MarshalSize for PacketReceiptTimesReportBlock {
82    fn marshal_size(&self) -> usize {
83        self.raw_size()
84    }
85}
86
87impl Marshal for PacketReceiptTimesReportBlock {
88    /// marshal_to encodes the PacketReceiptTimesReportBlock in binary
89    fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
90        if buf.remaining_mut() < self.marshal_size() {
91            return Err(Error::BufferTooShort);
92        }
93
94        let h = self.xr_header();
95        let n = h.marshal_to(buf)?;
96        buf = &mut buf[n..];
97
98        buf.put_u32(self.ssrc);
99        buf.put_u16(self.begin_seq);
100        buf.put_u16(self.end_seq);
101        for rt in &self.receipt_time {
102            buf.put_u32(*rt);
103        }
104
105        Ok(self.marshal_size())
106    }
107}
108
109impl Unmarshal for PacketReceiptTimesReportBlock {
110    /// Unmarshal decodes the PacketReceiptTimesReportBlock from binary
111    fn unmarshal<B>(raw_packet: &mut B) -> Result<Self>
112    where
113        Self: Sized,
114        B: Buf,
115    {
116        if raw_packet.remaining() < XR_HEADER_LENGTH {
117            return Err(Error::PacketTooShort);
118        }
119
120        let xr_header = XRHeader::unmarshal(raw_packet)?;
121        let block_length = match xr_header.block_length.checked_mul(4) {
122            Some(length) => length,
123            None => return Err(Error::InvalidBlockSize),
124        };
125        if block_length < PRT_REPORT_BLOCK_MIN_LENGTH
126            || !(block_length - PRT_REPORT_BLOCK_MIN_LENGTH).is_multiple_of(4)
127            || raw_packet.remaining() < block_length as usize
128        {
129            return Err(Error::PacketTooShort);
130        }
131
132        let t = xr_header.type_specific & 0x0F;
133
134        let ssrc = raw_packet.get_u32();
135        let begin_seq = raw_packet.get_u16();
136        let end_seq = raw_packet.get_u16();
137
138        let remaining = block_length - PRT_REPORT_BLOCK_MIN_LENGTH;
139        let mut receipt_time = vec![];
140        for _ in 0..remaining / 4 {
141            receipt_time.push(raw_packet.get_u32());
142        }
143
144        Ok(PacketReceiptTimesReportBlock {
145            t,
146
147            ssrc,
148            begin_seq,
149            end_seq,
150            receipt_time,
151        })
152    }
153}