rtc_rtcp/extended_report/
prt.rs1use super::*;
2
3const PRT_REPORT_BLOCK_MIN_LENGTH: u16 = 8;
4
5#[derive(Debug, Default, PartialEq, Eq, Clone)]
26pub struct PacketReceiptTimesReportBlock {
27 pub t: u8,
29
30 pub ssrc: u32,
32 pub begin_seq: u16,
33 pub end_seq: u16,
34 pub receipt_time: Vec<u32>,
35}
36
37impl fmt::Display for PacketReceiptTimesReportBlock {
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39 write!(f, "{self:?}")
40 }
41}
42
43impl PacketReceiptTimesReportBlock {
44 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
53impl Packet for PacketReceiptTimesReportBlock {
54 fn header(&self) -> Header {
55 Header::default()
56 }
57
58 fn destination_ssrc(&self) -> Vec<u32> {
60 vec![self.ssrc]
61 }
62
63 fn raw_size(&self) -> usize {
64 XR_HEADER_LENGTH + PRT_REPORT_BLOCK_MIN_LENGTH as usize + self.receipt_time.len() * 4
65 }
66
67 fn as_any(&self) -> &dyn Any {
68 self
69 }
70 fn equal(&self, other: &dyn Packet) -> bool {
71 other
72 .as_any()
73 .downcast_ref::<PacketReceiptTimesReportBlock>()
74 == Some(self)
75 }
76 fn cloned(&self) -> Box<dyn Packet> {
77 Box::new(self.clone())
78 }
79}
80
81impl MarshalSize for PacketReceiptTimesReportBlock {
82 fn marshal_size(&self) -> usize {
83 self.raw_size()
84 }
85}
86
87impl Marshal for PacketReceiptTimesReportBlock {
88 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
90 if buf.remaining_mut() < self.marshal_size() {
91 return Err(Error::BufferTooShort);
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
109impl Unmarshal for PacketReceiptTimesReportBlock {
110 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::PacketTooShort);
118 }
119
120 let xr_header = XRHeader::unmarshal(raw_packet)?;
121 let block_length = match xr_header.block_length.checked_mul(4) {
122 Some(length) => length,
123 None => return Err(Error::InvalidBlockSize),
124 };
125 if block_length < PRT_REPORT_BLOCK_MIN_LENGTH
126 || !(block_length - PRT_REPORT_BLOCK_MIN_LENGTH).is_multiple_of(4)
127 || raw_packet.remaining() < block_length as usize
128 {
129 return Err(Error::PacketTooShort);
130 }
131
132 let t = xr_header.type_specific & 0x0F;
133
134 let ssrc = raw_packet.get_u32();
135 let begin_seq = raw_packet.get_u16();
136 let end_seq = raw_packet.get_u16();
137
138 let remaining = block_length - PRT_REPORT_BLOCK_MIN_LENGTH;
139 let mut receipt_time = vec![];
140 for _ in 0..remaining / 4 {
141 receipt_time.push(raw_packet.get_u32());
142 }
143
144 Ok(PacketReceiptTimesReportBlock {
145 t,
146
147 ssrc,
148 begin_seq,
149 end_seq,
150 receipt_time,
151 })
152 }
153}