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