xref: /webrtc/rtcp/src/reception_report.rs (revision 5d8fe953)
1 use crate::{error::Error, header::*, packet::*, util::*};
2 use util::marshal::{Marshal, MarshalSize, Unmarshal};
3 
4 use bytes::{Buf, BufMut};
5 use std::any::Any;
6 use std::fmt;
7 
8 pub(crate) const RECEPTION_REPORT_LENGTH: usize = 24;
9 pub(crate) const FRACTION_LOST_OFFSET: usize = 4;
10 pub(crate) const TOTAL_LOST_OFFSET: usize = 5;
11 pub(crate) const LAST_SEQ_OFFSET: usize = 8;
12 pub(crate) const JITTER_OFFSET: usize = 12;
13 pub(crate) const LAST_SR_OFFSET: usize = 16;
14 pub(crate) const DELAY_OFFSET: usize = 20;
15 
16 /// A ReceptionReport block conveys statistics on the reception of RTP packets
17 /// from a single synchronization source.
18 #[derive(Debug, PartialEq, Eq, Default, Clone)]
19 pub struct ReceptionReport {
20     /// The SSRC identifier of the source to which the information in this
21     /// reception report block pertains.
22     pub ssrc: u32,
23     /// The fraction of RTP data packets from source SSRC lost since the
24     /// previous SR or RR packet was sent, expressed as a fixed point
25     /// number with the binary point at the left edge of the field.
26     pub fraction_lost: u8,
27     /// The total number of RTP data packets from source SSRC that have
28     /// been lost since the beginning of reception.
29     pub total_lost: u32,
30     /// The least significant 16 bits contain the highest sequence number received
31     /// in an RTP data packet from source SSRC, and the most significant 16 bits extend
32     /// that sequence number with the corresponding count of sequence number cycles.
33     pub last_sequence_number: u32,
34     /// An estimate of the statistical variance of the RTP data packet
35     /// interarrival time, measured in timestamp units and expressed as an
36     /// unsigned integer.
37     pub jitter: u32,
38     /// The middle 32 bits out of 64 in the NTP timestamp received as part of
39     /// the most recent RTCP sender report (SR) packet from source SSRC. If no
40     /// SR has been received yet, the field is set to zero.
41     pub last_sender_report: u32,
42     /// The delay, expressed in units of 1/65536 seconds, between receiving the
43     /// last SR packet from source SSRC and sending this reception report block.
44     /// If no SR packet has been received yet from SSRC, the field is set to zero.
45     pub delay: u32,
46 }
47 
48 impl fmt::Display for ReceptionReport {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result49     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50         write!(f, "{self:?}")
51     }
52 }
53 
54 impl Packet for ReceptionReport {
header(&self) -> Header55     fn header(&self) -> Header {
56         Header::default()
57     }
58 
destination_ssrc(&self) -> Vec<u32>59     fn destination_ssrc(&self) -> Vec<u32> {
60         vec![]
61     }
62 
raw_size(&self) -> usize63     fn raw_size(&self) -> usize {
64         RECEPTION_REPORT_LENGTH
65     }
66 
as_any(&self) -> &(dyn Any + Send + Sync)67     fn as_any(&self) -> &(dyn Any + Send + Sync) {
68         self
69     }
70 
equal(&self, other: &(dyn Packet + Send + Sync)) -> bool71     fn equal(&self, other: &(dyn Packet + Send + Sync)) -> bool {
72         other
73             .as_any()
74             .downcast_ref::<ReceptionReport>()
75             .map_or(false, |a| self == a)
76     }
77 
cloned(&self) -> Box<dyn Packet + Send + Sync>78     fn cloned(&self) -> Box<dyn Packet + Send + Sync> {
79         Box::new(self.clone())
80     }
81 }
82 
83 impl MarshalSize for ReceptionReport {
marshal_size(&self) -> usize84     fn marshal_size(&self) -> usize {
85         let l = self.raw_size();
86         // align to 32-bit boundary
87         l + get_padding_size(l)
88     }
89 }
90 
91 impl Marshal for ReceptionReport {
92     /// marshal_to encodes the ReceptionReport in binary
marshal_to(&self, mut buf: &mut [u8]) -> Result<usize, util::Error>93     fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize, util::Error> {
94         /*
95          *  0                   1                   2                   3
96          *  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
97          * +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
98          * |                              SSRC                             |
99          * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
100          * | fraction lost |       cumulative number of packets lost       |
101          * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
102          * |           extended highest sequence number received           |
103          * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
104          * |                      interarrival jitter                      |
105          * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
106          * |                         last SR (LSR)                         |
107          * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
108          * |                   delay since last SR (DLSR)                  |
109          * +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
110          */
111         if buf.remaining_mut() < self.marshal_size() {
112             return Err(Error::BufferTooShort.into());
113         }
114 
115         buf.put_u32(self.ssrc);
116 
117         buf.put_u8(self.fraction_lost);
118 
119         // pack TotalLost into 24 bits
120         if self.total_lost >= (1 << 25) {
121             return Err(Error::InvalidTotalLost.into());
122         }
123 
124         buf.put_u8(((self.total_lost >> 16) & 0xFF) as u8);
125         buf.put_u8(((self.total_lost >> 8) & 0xFF) as u8);
126         buf.put_u8((self.total_lost & 0xFF) as u8);
127 
128         buf.put_u32(self.last_sequence_number);
129         buf.put_u32(self.jitter);
130         buf.put_u32(self.last_sender_report);
131         buf.put_u32(self.delay);
132 
133         put_padding(buf, self.raw_size());
134 
135         Ok(self.marshal_size())
136     }
137 }
138 
139 impl Unmarshal for ReceptionReport {
140     /// unmarshal decodes the ReceptionReport from binary
unmarshal<B>(raw_packet: &mut B) -> Result<Self, util::Error> where Self: Sized, B: Buf,141     fn unmarshal<B>(raw_packet: &mut B) -> Result<Self, util::Error>
142     where
143         Self: Sized,
144         B: Buf,
145     {
146         let raw_packet_len = raw_packet.remaining();
147         if raw_packet_len < RECEPTION_REPORT_LENGTH {
148             return Err(Error::PacketTooShort.into());
149         }
150 
151         /*
152          *  0                   1                   2                   3
153          *  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
154          * +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
155          * |                              SSRC                             |
156          * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
157          * | fraction lost |       cumulative number of packets lost       |
158          * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
159          * |           extended highest sequence number received           |
160          * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
161          * |                      interarrival jitter                      |
162          * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
163          * |                         last SR (LSR)                         |
164          * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
165          * |                   delay since last SR (DLSR)                  |
166          * +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
167          */
168         let ssrc = raw_packet.get_u32();
169         let fraction_lost = raw_packet.get_u8();
170 
171         let t0 = raw_packet.get_u8();
172         let t1 = raw_packet.get_u8();
173         let t2 = raw_packet.get_u8();
174         // TODO: The type of `total_lost` should be `i32`, per the RFC:
175         // The total number of RTP data packets from source SSRC_n that have
176         // been lost since the beginning of reception.  This number is
177         // defined to be the number of packets expected less the number of
178         // packets actually received, where the number of packets received
179         // includes any which are late or duplicates.  Thus, packets that
180         // arrive late are not counted as lost, and the loss may be negative
181         // if there are duplicates.  The number of packets expected is
182         // defined to be the extended last sequence number received, as
183         // defined next, less the initial sequence number received.  This may
184         // be calculated as shown in Appendix A.3.
185         let total_lost = (t2 as u32) | (t1 as u32) << 8 | (t0 as u32) << 16;
186 
187         let last_sequence_number = raw_packet.get_u32();
188         let jitter = raw_packet.get_u32();
189         let last_sender_report = raw_packet.get_u32();
190         let delay = raw_packet.get_u32();
191 
192         Ok(ReceptionReport {
193             ssrc,
194             fraction_lost,
195             total_lost,
196             last_sequence_number,
197             jitter,
198             last_sender_report,
199             delay,
200         })
201     }
202 }
203