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