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