rtc_rtcp/reception_report.rs
1use crate::{header::*, packet::*, util::*};
2use shared::{
3 error::{Error, Result},
4 marshal::{Marshal, MarshalSize, Unmarshal},
5};
6
7use bytes::{Buf, BufMut};
8use std::any::Any;
9use std::fmt;
10
11pub(crate) const RECEPTION_REPORT_LENGTH: usize = 24;
12pub(crate) const FRACTION_LOST_OFFSET: usize = 4;
13pub(crate) const TOTAL_LOST_OFFSET: usize = 5;
14pub(crate) const LAST_SEQ_OFFSET: usize = 8;
15pub(crate) const JITTER_OFFSET: usize = 12;
16pub(crate) const LAST_SR_OFFSET: usize = 16;
17pub(crate) const DELAY_OFFSET: usize = 20;
18
19/// A ReceptionReport block conveys statistics on the reception of RTP packets
20/// from a single synchronization source.
21#[derive(Debug, PartialEq, Eq, Default, Clone)]
22pub struct ReceptionReport {
23 /// The SSRC identifier of the source to which the information in this
24 /// reception report block pertains.
25 pub ssrc: u32,
26 /// The fraction of RTP data packets from source SSRC lost since the
27 /// previous SR or RR packet was sent, expressed as a fixed point
28 /// number with the binary point at the left edge of the field.
29 pub fraction_lost: u8,
30 /// The total number of RTP data packets from source SSRC that have
31 /// been lost since the beginning of reception.
32 pub total_lost: u32,
33 /// The least significant 16 bits contain the highest sequence number received
34 /// in an RTP data packet from source SSRC, and the most significant 16 bits extend
35 /// that sequence number with the corresponding count of sequence number cycles.
36 pub last_sequence_number: u32,
37 /// An estimate of the statistical variance of the RTP data packet
38 /// interarrival time, measured in timestamp units and expressed as an
39 /// unsigned integer.
40 pub jitter: u32,
41 /// The middle 32 bits out of 64 in the NTP timestamp received as part of
42 /// the most recent RTCP sender report (SR) packet from source SSRC. If no
43 /// SR has been received yet, the field is set to zero.
44 pub last_sender_report: u32,
45 /// The delay, expressed in units of 1/65536 seconds, between receiving the
46 /// last SR packet from source SSRC and sending this reception report block.
47 /// If no SR packet has been received yet from SSRC, the field is set to zero.
48 pub delay: u32,
49}
50
51impl fmt::Display for ReceptionReport {
52 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53 write!(f, "{self:?}")
54 }
55}
56
57impl Packet for ReceptionReport {
58 fn header(&self) -> Header {
59 Header::default()
60 }
61
62 fn destination_ssrc(&self) -> Vec<u32> {
63 vec![]
64 }
65
66 fn raw_size(&self) -> usize {
67 RECEPTION_REPORT_LENGTH
68 }
69
70 fn as_any(&self) -> &dyn Any {
71 self
72 }
73
74 fn equal(&self, other: &dyn Packet) -> bool {
75 other.as_any().downcast_ref::<ReceptionReport>() == Some(self)
76 }
77
78 fn cloned(&self) -> Box<dyn Packet> {
79 Box::new(self.clone())
80 }
81}
82
83impl MarshalSize for ReceptionReport {
84 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
91impl Marshal for ReceptionReport {
92 /// marshal_to encodes the ReceptionReport in binary
93 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
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);
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);
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
139impl Unmarshal for ReceptionReport {
140 /// unmarshal decodes the ReceptionReport from binary
141 fn unmarshal<B>(raw_packet: &mut B) -> Result<Self>
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);
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}