Skip to main content

rtcp/
reception_report.rs

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