rtcp/receiver_report/
mod.rs

1#[cfg(test)]
2mod receiver_report_test;
3
4use std::any::Any;
5use std::fmt;
6
7use bytes::{Buf, BufMut, Bytes};
8use util::marshal::{Marshal, MarshalSize, Unmarshal};
9
10use crate::error::Error;
11use crate::header::*;
12use crate::packet::*;
13use crate::reception_report::*;
14use crate::util::*;
15
16type Result<T> = std::result::Result<T, util::Error>;
17
18pub(super) const RR_SSRC_OFFSET: usize = HEADER_LENGTH;
19pub(super) const RR_REPORT_OFFSET: usize = RR_SSRC_OFFSET + SSRC_LENGTH;
20
21/// A ReceiverReport (RR) packet provides reception quality feedback for an RTP stream
22#[derive(Debug, PartialEq, Eq, Default, Clone)]
23pub struct ReceiverReport {
24    /// The synchronization source identifier for the originator of this RR packet.
25    pub ssrc: u32,
26    /// Zero or more reception report blocks depending on the number of other
27    /// sources heard by this sender since the last report. Each reception report
28    /// block conveys statistics on the reception of RTP packets from a
29    /// single synchronization source.
30    pub reports: Vec<ReceptionReport>,
31    /// Extension contains additional, payload-specific information that needs to
32    /// be reported regularly about the receiver.
33    pub profile_extensions: Bytes,
34}
35
36impl fmt::Display for ReceiverReport {
37    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38        let mut out = format!("ReceiverReport from {}\n", self.ssrc);
39        out += "\tSSRC    \tLost\tLastSequence\n";
40        for rep in &self.reports {
41            out += format!(
42                "\t{:x}\t{}/{}\t{}\n",
43                rep.ssrc, rep.fraction_lost, rep.total_lost, rep.last_sequence_number
44            )
45            .as_str();
46        }
47        out += format!("\tProfile Extension Data: {:?}\n", self.profile_extensions).as_str();
48
49        write!(f, "{out}")
50    }
51}
52
53impl Packet for ReceiverReport {
54    /// Header returns the Header associated with this packet.
55    fn header(&self) -> Header {
56        Header {
57            padding: get_padding_size(self.raw_size()) != 0,
58            count: self.reports.len() as u8,
59            packet_type: PacketType::ReceiverReport,
60            length: ((self.marshal_size() / 4) - 1) as u16,
61        }
62    }
63
64    /// destination_ssrc returns an array of SSRC values that this packet refers to.
65    fn destination_ssrc(&self) -> Vec<u32> {
66        self.reports.iter().map(|x| x.ssrc).collect()
67    }
68
69    fn raw_size(&self) -> usize {
70        let mut reps_length = 0;
71        for rep in &self.reports {
72            reps_length += rep.marshal_size();
73        }
74
75        HEADER_LENGTH + SSRC_LENGTH + reps_length + self.profile_extensions.len()
76    }
77
78    fn as_any(&self) -> &(dyn Any + Send + Sync) {
79        self
80    }
81
82    fn equal(&self, other: &(dyn Packet + Send + Sync)) -> bool {
83        other
84            .as_any()
85            .downcast_ref::<ReceiverReport>()
86            .map_or(false, |a| self == a)
87    }
88
89    fn cloned(&self) -> Box<dyn Packet + Send + Sync> {
90        Box::new(self.clone())
91    }
92}
93
94impl MarshalSize for ReceiverReport {
95    fn marshal_size(&self) -> usize {
96        let l = self.raw_size();
97        // align to 32-bit boundary
98        l + get_padding_size(l)
99    }
100}
101
102impl Marshal for ReceiverReport {
103    /// marshal_to encodes the packet in binary.
104    fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
105        if self.reports.len() > COUNT_MAX {
106            return Err(Error::TooManyReports.into());
107        }
108
109        if buf.remaining_mut() < self.marshal_size() {
110            return Err(Error::BufferTooShort.into());
111        }
112
113        /*
114         *         0                   1                   2                   3
115         *         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
116         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
117         * header |V=2|P|    RC   |   PT=RR=201   |             length            |
118         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
119         *        |                     SSRC of packet sender                     |
120         *        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
121         * report |                 SSRC_1 (SSRC of first source)                 |
122         * block  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
123         *   1    | fraction lost |       cumulative number of packets lost       |
124         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
125         *        |           extended highest sequence number received           |
126         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
127         *        |                      interarrival jitter                      |
128         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
129         *        |                         last SR (LSR)                         |
130         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
131         *        |                   delay since last SR (DLSR)                  |
132         *        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
133         * report |                 SSRC_2 (SSRC of second source)                |
134         * block  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
135         *   2    :                               ...                             :
136         *        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
137         *        |                  profile-specific extensions                  |
138         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
139         */
140        let h = self.header();
141        let n = h.marshal_to(buf)?;
142        buf = &mut buf[n..];
143
144        buf.put_u32(self.ssrc);
145
146        for report in &self.reports {
147            let n = report.marshal_to(buf)?;
148            buf = &mut buf[n..];
149        }
150
151        buf.put(self.profile_extensions.clone());
152
153        if h.padding {
154            put_padding(buf, self.raw_size());
155        }
156
157        Ok(self.marshal_size())
158    }
159}
160
161impl Unmarshal for ReceiverReport {
162    /// Unmarshal decodes the ReceiverReport from binary
163    fn unmarshal<B>(raw_packet: &mut B) -> Result<Self>
164    where
165        Self: Sized,
166        B: Buf,
167    {
168        /*
169         *         0                   1                   2                   3
170         *         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
171         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
172         * header |V=2|P|    RC   |   PT=RR=201   |             length            |
173         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
174         *        |                     SSRC of packet sender                     |
175         *        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
176         * report |                 SSRC_1 (SSRC of first source)                 |
177         * block  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
178         *   1    | fraction lost |       cumulative number of packets lost       |
179         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
180         *        |           extended highest sequence number received           |
181         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
182         *        |                      interarrival jitter                      |
183         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
184         *        |                         last SR (LSR)                         |
185         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
186         *        |                   delay since last SR (DLSR)                  |
187         *        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
188         * report |                 SSRC_2 (SSRC of second source)                |
189         * block  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
190         *   2    :                               ...                             :
191         *        +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
192         *        |                  profile-specific extensions                  |
193         *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
194         */
195        let raw_packet_len = raw_packet.remaining();
196        if raw_packet_len < (HEADER_LENGTH + SSRC_LENGTH) {
197            return Err(Error::PacketTooShort.into());
198        }
199
200        let header = Header::unmarshal(raw_packet)?;
201        if header.packet_type != PacketType::ReceiverReport {
202            return Err(Error::WrongType.into());
203        }
204
205        let ssrc = raw_packet.get_u32();
206
207        let mut offset = RR_REPORT_OFFSET;
208        let mut reports = Vec::with_capacity(header.count as usize);
209        for _ in 0..header.count {
210            if offset + RECEPTION_REPORT_LENGTH > raw_packet_len {
211                return Err(Error::PacketTooShort.into());
212            }
213            let reception_report = ReceptionReport::unmarshal(raw_packet)?;
214            reports.push(reception_report);
215            offset += RECEPTION_REPORT_LENGTH;
216        }
217        let profile_extensions = raw_packet.copy_to_bytes(raw_packet.remaining());
218        /*
219        if header.padding && raw_packet.has_remaining() {
220            raw_packet.advance(raw_packet.remaining());
221        }
222         */
223
224        Ok(ReceiverReport {
225            ssrc,
226            reports,
227            profile_extensions,
228        })
229    }
230}