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,
30
31 pub ssrc: u32,
34 pub begin_seq: u16,
36 pub end_seq: u16,
38 pub receipt_time: Vec<u32>,
40}
41
42impl fmt::Display for PacketReceiptTimesReportBlock {
43 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44 write!(f, "{self:?}")
45 }
46}
47
48impl PacketReceiptTimesReportBlock {
49 pub fn xr_header(&self) -> XRHeader {
51 XRHeader {
52 block_type: BlockType::PacketReceiptTimes,
53 type_specific: self.t & 0x0F,
54 block_length: (self.raw_size() / 4 - 1) as u16,
55 }
56 }
57}
58
59impl Packet for PacketReceiptTimesReportBlock {
60 fn header(&self) -> Header {
61 Header::default()
62 }
63
64 fn destination_ssrc(&self) -> Vec<u32> {
66 vec![self.ssrc]
67 }
68
69 fn raw_size(&self) -> usize {
70 XR_HEADER_LENGTH + PRT_REPORT_BLOCK_MIN_LENGTH as usize + self.receipt_time.len() * 4
71 }
72
73 fn as_any(&self) -> &dyn Any {
74 self
75 }
76 fn equal(&self, other: &dyn Packet) -> bool {
77 other
78 .as_any()
79 .downcast_ref::<PacketReceiptTimesReportBlock>()
80 == Some(self)
81 }
82 fn cloned(&self) -> Box<dyn Packet> {
83 Box::new(self.clone())
84 }
85}
86
87impl MarshalSize for PacketReceiptTimesReportBlock {
88 fn marshal_size(&self) -> usize {
89 self.raw_size()
90 }
91}
92
93impl Marshal for PacketReceiptTimesReportBlock {
94 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
96 if buf.remaining_mut() < self.marshal_size() {
97 return Err(Error::BufferTooShort);
98 }
99
100 let h = self.xr_header();
101 let n = h.marshal_to(buf)?;
102 buf = &mut buf[n..];
103
104 buf.put_u32(self.ssrc);
105 buf.put_u16(self.begin_seq);
106 buf.put_u16(self.end_seq);
107 for rt in &self.receipt_time {
108 buf.put_u32(*rt);
109 }
110
111 Ok(self.marshal_size())
112 }
113}
114
115impl Unmarshal for PacketReceiptTimesReportBlock {
116 fn unmarshal<B>(raw_packet: &mut B) -> Result<Self>
118 where
119 Self: Sized,
120 B: Buf,
121 {
122 if raw_packet.remaining() < XR_HEADER_LENGTH {
123 return Err(Error::PacketTooShort);
124 }
125
126 let xr_header = XRHeader::unmarshal(raw_packet)?;
127 let block_length = match xr_header.block_length.checked_mul(4) {
128 Some(length) => length,
129 None => return Err(Error::InvalidBlockSize),
130 };
131 if block_length < PRT_REPORT_BLOCK_MIN_LENGTH
132 || !(block_length - PRT_REPORT_BLOCK_MIN_LENGTH).is_multiple_of(4)
133 || raw_packet.remaining() < block_length as usize
134 {
135 return Err(Error::PacketTooShort);
136 }
137
138 let t = xr_header.type_specific & 0x0F;
139
140 let ssrc = raw_packet.get_u32();
141 let begin_seq = raw_packet.get_u16();
142 let end_seq = raw_packet.get_u16();
143
144 let remaining = block_length - PRT_REPORT_BLOCK_MIN_LENGTH;
145 let mut receipt_time = vec![];
146 for _ in 0..remaining / 4 {
147 receipt_time.push(raw_packet.get_u32());
148 }
149
150 Ok(PacketReceiptTimesReportBlock {
151 t,
152
153 ssrc,
154 begin_seq,
155 end_seq,
156 receipt_time,
157 })
158 }
159}