1 use super::*; 2 3 const PRT_REPORT_BLOCK_MIN_LENGTH: u16 = 8; 4 5 /// PacketReceiptTimesReportBlock represents a Packet Receipt Times 6 /// report block, as described in RFC 3611 section 4.3. 7 /// 8 /// 0 1 2 3 9 /// 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 10 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 11 /// | BT=3 | rsvd. | t | block length | 12 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 13 /// | ssrc of source | 14 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 15 /// | begin_seq | end_seq | 16 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 17 /// | Receipt time of packet begin_seq | 18 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 19 /// | Receipt time of packet (begin_seq + 1) mod 65536 | 20 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 21 /// : ... : 22 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23 /// | Receipt time of packet (end_seq - 1) mod 65536 | 24 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 25 #[derive(Debug, Default, PartialEq, Eq, Clone)] 26 pub struct PacketReceiptTimesReportBlock { 27 //not included in marshal/unmarshal 28 pub t: u8, 29 30 //marshal/unmarshal 31 pub ssrc: u32, 32 pub begin_seq: u16, 33 pub end_seq: u16, 34 pub receipt_time: Vec<u32>, 35 } 36 37 impl fmt::Display for PacketReceiptTimesReportBlock { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 39 write!(f, "{self:?}") 40 } 41 } 42 43 impl PacketReceiptTimesReportBlock { xr_header(&self) -> XRHeader44 pub fn xr_header(&self) -> XRHeader { 45 XRHeader { 46 block_type: BlockType::PacketReceiptTimes, 47 type_specific: self.t & 0x0F, 48 block_length: (self.raw_size() / 4 - 1) as u16, 49 } 50 } 51 } 52 53 impl Packet for PacketReceiptTimesReportBlock { header(&self) -> Header54 fn header(&self) -> Header { 55 Header::default() 56 } 57 58 /// destination_ssrc returns an array of ssrc values that this report block refers to. destination_ssrc(&self) -> Vec<u32>59 fn destination_ssrc(&self) -> Vec<u32> { 60 vec![self.ssrc] 61 } 62 raw_size(&self) -> usize63 fn raw_size(&self) -> usize { 64 XR_HEADER_LENGTH + PRT_REPORT_BLOCK_MIN_LENGTH as usize + self.receipt_time.len() * 4 65 } 66 as_any(&self) -> &(dyn Any + Send + Sync)67 fn as_any(&self) -> &(dyn Any + Send + Sync) { 68 self 69 } equal(&self, other: &(dyn Packet + Send + Sync)) -> bool70 fn equal(&self, other: &(dyn Packet + Send + Sync)) -> bool { 71 other 72 .as_any() 73 .downcast_ref::<PacketReceiptTimesReportBlock>() 74 .map_or(false, |a| self == a) 75 } cloned(&self) -> Box<dyn Packet + Send + Sync>76 fn cloned(&self) -> Box<dyn Packet + Send + Sync> { 77 Box::new(self.clone()) 78 } 79 } 80 81 impl MarshalSize for PacketReceiptTimesReportBlock { marshal_size(&self) -> usize82 fn marshal_size(&self) -> usize { 83 self.raw_size() 84 } 85 } 86 87 impl Marshal for PacketReceiptTimesReportBlock { 88 /// marshal_to encodes the PacketReceiptTimesReportBlock in binary marshal_to(&self, mut buf: &mut [u8]) -> Result<usize>89 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> { 90 if buf.remaining_mut() < self.marshal_size() { 91 return Err(error::Error::BufferTooShort.into()); 92 } 93 94 let h = self.xr_header(); 95 let n = h.marshal_to(buf)?; 96 buf = &mut buf[n..]; 97 98 buf.put_u32(self.ssrc); 99 buf.put_u16(self.begin_seq); 100 buf.put_u16(self.end_seq); 101 for rt in &self.receipt_time { 102 buf.put_u32(*rt); 103 } 104 105 Ok(self.marshal_size()) 106 } 107 } 108 109 impl Unmarshal for PacketReceiptTimesReportBlock { 110 /// Unmarshal decodes the PacketReceiptTimesReportBlock from binary unmarshal<B>(raw_packet: &mut B) -> Result<Self> where Self: Sized, B: Buf,111 fn unmarshal<B>(raw_packet: &mut B) -> Result<Self> 112 where 113 Self: Sized, 114 B: Buf, 115 { 116 if raw_packet.remaining() < XR_HEADER_LENGTH { 117 return Err(error::Error::PacketTooShort.into()); 118 } 119 120 let xr_header = XRHeader::unmarshal(raw_packet)?; 121 let block_length = xr_header.block_length * 4; 122 if block_length < PRT_REPORT_BLOCK_MIN_LENGTH 123 || (block_length - PRT_REPORT_BLOCK_MIN_LENGTH) % 4 != 0 124 || raw_packet.remaining() < block_length as usize 125 { 126 return Err(error::Error::PacketTooShort.into()); 127 } 128 129 let t = xr_header.type_specific & 0x0F; 130 131 let ssrc = raw_packet.get_u32(); 132 let begin_seq = raw_packet.get_u16(); 133 let end_seq = raw_packet.get_u16(); 134 135 let remaining = block_length - PRT_REPORT_BLOCK_MIN_LENGTH; 136 let mut receipt_time = vec![]; 137 for _ in 0..remaining / 4 { 138 receipt_time.push(raw_packet.get_u32()); 139 } 140 141 Ok(PacketReceiptTimesReportBlock { 142 t, 143 144 ssrc, 145 begin_seq, 146 end_seq, 147 receipt_time, 148 }) 149 } 150 } 151