1 use std::io::{Read, Write}; 2 3 use util::Error; 4 5 use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; 6 7 use super::errors::*; 8 9 // A ReceptionReport block conveys statistics on the reception of RTP packets 10 // from a single synchronization source. 11 #[derive(Debug, PartialEq, Default, Clone)] 12 pub struct ReceptionReport { 13 // The SSRC identifier of the source to which the information in this 14 // reception report block pertains. 15 pub ssrc: u32, 16 // The fraction of RTP data packets from source SSRC lost since the 17 // previous SR or RR packet was sent, expressed as a fixed point 18 // number with the binary point at the left edge of the field. 19 pub fraction_lost: u8, 20 // The total number of RTP data packets from source SSRC that have 21 // been lost since the beginning of reception. 22 pub total_lost: u32, 23 // The low 16 bits contain the highest sequence number received in an 24 // RTP data packet from source SSRC, and the most significant 16 25 // bits extend that sequence number with the corresponding count of 26 // sequence number cycles. 27 pub last_sequence_number: u32, 28 // An estimate of the statistical variance of the RTP data packet 29 // interarrival time, measured in timestamp units and expressed as an 30 // unsigned integer. 31 pub jitter: u32, 32 // The middle 32 bits out of 64 in the NTP timestamp received as part of 33 // the most recent RTCP sender report (SR) packet from source SSRC. If no 34 // SR has been received yet, the field is set to zero. 35 pub last_sender_report: u32, 36 // The delay, expressed in units of 1/65536 seconds, between receiving the 37 // last SR packet from source SSRC and sending this reception report block. 38 // If no SR packet has been received yet from SSRC, the field is set to zero. 39 pub delay: u32, 40 } 41 42 const RECEPTION_REPORT_LENGTH: usize = 24; 43 /*const fractionLostOffset: u8 = 4; 44 const totalLostOffset: u8 = 5; 45 const lastSeqOffset: u8 = 8; 46 const jitterOffset: u8 = 12; 47 const lastSROffset: u8 = 16; 48 const delayOffset: u8 = 20;*/ 49 50 impl ReceptionReport { 51 pub fn size(&self) -> usize { 52 RECEPTION_REPORT_LENGTH 53 } 54 55 // Marshal encodes the ReceptionReport in binary 56 pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<(), Error> { 57 /* 58 * 0 1 2 3 59 * 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 60 * +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 61 * | SSRC | 62 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 63 * | fraction lost | cumulative number of packets lost | 64 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 65 * | extended highest sequence number received | 66 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 67 * | interarrival jitter | 68 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 69 * | last SR (LSR) | 70 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 71 * | delay since last SR (DLSR) | 72 * +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 73 */ 74 writer.write_u32::<BigEndian>(self.ssrc)?; 75 writer.write_u8(self.fraction_lost)?; 76 77 // pack TotalLost into 24 bits 78 if self.total_lost >= (1 << 25) { 79 return Err(ERR_INVALID_TOTAL_LOST.clone()); 80 } 81 writer.write_u8(((self.total_lost >> 16) & 0xFF) as u8)?; 82 writer.write_u8(((self.total_lost >> 8) & 0xFF) as u8)?; 83 writer.write_u8(((self.total_lost) & 0xFF) as u8)?; 84 85 writer.write_u32::<BigEndian>(self.last_sequence_number)?; 86 writer.write_u32::<BigEndian>(self.jitter)?; 87 writer.write_u32::<BigEndian>(self.last_sender_report)?; 88 writer.write_u32::<BigEndian>(self.delay)?; 89 90 Ok(()) 91 } 92 93 // Unmarshal decodes the ReceptionReport from binary 94 pub fn unmarshal<R: Read>(reader: &mut R) -> Result<Self, 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 113 let ssrc = reader.read_u32::<BigEndian>()?; 114 let fraction_lost = reader.read_u8()?; 115 116 let b0 = reader.read_u8()?; 117 let b1 = reader.read_u8()?; 118 let b2 = reader.read_u8()?; 119 let total_lost = b2 as u32 | (b1 as u32) << 8 | (b0 as u32) << 16; 120 121 let last_sequence_number = reader.read_u32::<BigEndian>()?; 122 let jitter = reader.read_u32::<BigEndian>()?; 123 let last_sender_report = reader.read_u32::<BigEndian>()?; 124 let delay = reader.read_u32::<BigEndian>()?; 125 126 Ok(ReceptionReport { 127 ssrc, 128 fraction_lost, 129 total_lost, 130 last_sequence_number, 131 jitter, 132 last_sender_report, 133 delay, 134 }) 135 } 136 } 137