1mod bye;
4mod channel;
5mod context;
6mod handler;
7mod report;
8mod sdes;
9mod stats;
10
11use std::ops::Deref;
12
13use bytes::{Buf, Bytes, BytesMut};
14
15use crate::InvalidInput;
16
17pub use self::{
18 bye::ByePacket,
19 channel::RtcpChannel,
20 context::{RtcpContext, RtcpContextHandle},
21 handler::{MuxedRtcpHandler, RtcpHandler, RtcpHandlerOptions},
22 report::{ReceiverReport, ReportBlock, SenderReport},
23 sdes::{SourceDescription, SourceDescriptionPacket},
24};
25
26#[derive(Clone)]
28pub struct CompoundRtcpPacket {
29 inner: Vec<RtcpPacket>,
30}
31
32impl CompoundRtcpPacket {
33 pub fn new<T>(packets: T) -> Self
35 where
36 T: Into<Vec<RtcpPacket>>,
37 {
38 Self {
39 inner: packets.into(),
40 }
41 }
42
43 pub fn decode(mut frame: Bytes) -> Result<Self, InvalidInput> {
45 let mut res = Vec::new();
46
47 while !frame.is_empty() {
48 res.push(RtcpPacket::decode(&mut frame)?);
49 }
50
51 Ok(res.into())
52 }
53
54 pub fn encode(&self, buf: &mut BytesMut) {
56 buf.reserve(self.raw_size());
57
58 for packet in &self.inner {
59 packet.encode(buf);
60 }
61 }
62
63 pub fn raw_size(&self) -> usize {
65 self.inner.iter().map(|packet| packet.length()).sum()
66 }
67}
68
69impl Deref for CompoundRtcpPacket {
70 type Target = [RtcpPacket];
71
72 #[inline]
73 fn deref(&self) -> &Self::Target {
74 &self.inner
75 }
76}
77
78impl From<RtcpPacket> for CompoundRtcpPacket {
79 #[inline]
80 fn from(packet: RtcpPacket) -> Self {
81 Self {
82 inner: vec![packet],
83 }
84 }
85}
86
87impl<T> From<T> for CompoundRtcpPacket
88where
89 T: Into<Vec<RtcpPacket>>,
90{
91 #[inline]
92 fn from(packets: T) -> Self {
93 Self::new(packets)
94 }
95}
96
97#[derive(Debug, Copy, Clone, Eq, PartialEq)]
99pub enum RtcpPacketType {
100 SR,
101 RR,
102 SDES,
103 BYE,
104 Other(u8),
105}
106
107impl RtcpPacketType {
108 #[inline]
110 pub fn raw_id(self) -> u8 {
111 match self {
112 RtcpPacketType::SR => 200,
113 RtcpPacketType::RR => 201,
114 RtcpPacketType::SDES => 202,
115 RtcpPacketType::BYE => 203,
116 RtcpPacketType::Other(id) => id,
117 }
118 }
119}
120
121impl From<u8> for RtcpPacketType {
122 #[inline]
123 fn from(id: u8) -> RtcpPacketType {
124 match id {
125 200 => RtcpPacketType::SR,
126 201 => RtcpPacketType::RR,
127 202 => RtcpPacketType::SDES,
128 203 => RtcpPacketType::BYE,
129 id => RtcpPacketType::Other(id),
130 }
131 }
132}
133
134#[repr(C, packed)]
136struct RawRtcpHeader {
137 options: u8,
138 packet_type: u8,
139 length: u16,
140}
141
142#[derive(Copy, Clone)]
144pub struct RtcpHeader {
145 options: u8,
146 packet_type: RtcpPacketType,
147 length: u16,
148}
149
150impl RtcpHeader {
151 pub const RAW_SIZE: usize = std::mem::size_of::<RawRtcpHeader>();
153
154 #[inline]
156 pub const fn new(packet_type: RtcpPacketType) -> Self {
157 Self {
158 options: 2 << 6,
159 packet_type,
160 length: 0,
161 }
162 }
163
164 pub fn decode(data: &mut Bytes) -> Result<Self, InvalidInput> {
166 if data.len() < std::mem::size_of::<RawRtcpHeader>() {
167 return Err(InvalidInput::new());
168 }
169
170 let ptr = data.as_ptr() as *const RawRtcpHeader;
171
172 let raw = unsafe { ptr.read_unaligned() };
173
174 if (raw.options >> 6) != 2 {
175 return Err(InvalidInput::new());
176 }
177
178 let res = Self {
179 options: raw.options,
180 packet_type: raw.packet_type.into(),
181 length: u16::from_be(raw.length),
182 };
183
184 data.advance(std::mem::size_of::<RawRtcpHeader>());
185
186 Ok(res)
187 }
188
189 pub fn encode(&self, buf: &mut BytesMut) {
191 let raw = RawRtcpHeader {
192 options: self.options,
193 packet_type: self.packet_type.raw_id(),
194 length: self.length.to_be(),
195 };
196
197 let ptr = &raw as *const _ as *const u8;
198
199 let data = unsafe { std::slice::from_raw_parts(ptr, std::mem::size_of::<RawRtcpHeader>()) };
200
201 buf.extend_from_slice(data);
202 }
203
204 #[inline]
206 pub fn padding(&self) -> bool {
207 (self.options & 0x20) != 0
208 }
209
210 #[inline]
212 pub fn with_padding(mut self, padding: bool) -> Self {
213 self.options &= !0x20;
214 self.options |= (padding as u8) << 5;
215 self
216 }
217
218 #[inline]
220 pub fn packet_length(&self) -> usize {
221 ((self.length as usize) + 1) << 2
222 }
223
224 #[inline]
233 pub fn with_packet_length(mut self, length: usize) -> Self {
234 assert!((4..=262_144).contains(&length) && (length & 3) == 0);
235
236 self.length = ((length >> 2) - 1) as u16;
237 self
238 }
239
240 #[inline]
242 pub fn packet_type(&self) -> RtcpPacketType {
243 self.packet_type
244 }
245
246 #[inline]
248 pub fn with_packet_type(mut self, packet_type: RtcpPacketType) -> Self {
249 self.packet_type = packet_type;
250 self
251 }
252
253 #[inline]
257 pub fn item_count(&self) -> u8 {
258 self.options & 0x1f
259 }
260
261 #[inline]
266 pub fn with_item_count(mut self, count: u8) -> Self {
267 assert!(count < 32);
268
269 self.options &= !0x1f;
270 self.options |= count & 0x1f;
271 self
272 }
273
274 #[inline]
276 pub fn raw_size(&self) -> usize {
277 std::mem::size_of::<RawRtcpHeader>()
278 }
279}
280
281#[derive(Clone)]
283pub struct RtcpPacket {
284 header: RtcpHeader,
285 payload: Bytes,
286}
287
288impl RtcpPacket {
289 #[inline]
291 pub const fn new(packet_type: RtcpPacketType) -> Self {
292 Self {
293 header: RtcpHeader::new(packet_type),
294 payload: Bytes::new(),
295 }
296 }
297
298 pub fn from_parts(header: RtcpHeader, payload: Bytes) -> Result<Self, InvalidInput> {
300 if header.padding() {
301 let padding_len = payload.last().copied().ok_or_else(InvalidInput::new)? as usize;
302
303 if padding_len == 0 || payload.len() < padding_len {
304 return Err(InvalidInput::new());
305 }
306 }
307
308 let packet_len = header.packet_length();
309
310 if packet_len != (payload.len() + 4) {
311 return Err(InvalidInput::new());
312 }
313
314 let res = Self { header, payload };
315
316 Ok(res)
317 }
318
319 #[inline]
321 pub fn deconstruct(self) -> (RtcpHeader, Bytes) {
322 (self.header, self.payload)
323 }
324
325 pub fn decode(data: &mut Bytes) -> Result<Self, InvalidInput> {
327 let mut buffer = data.clone();
328
329 let header = RtcpHeader::decode(&mut buffer)?;
330
331 let payload_len = header.packet_length() - 4;
332
333 if buffer.len() < payload_len {
334 return Err(InvalidInput::new());
335 }
336
337 let res = Self::from_parts(header, buffer.split_to(payload_len))?;
338
339 *data = buffer;
340
341 Ok(res)
342 }
343
344 pub fn encode(&self, buf: &mut BytesMut) {
346 buf.reserve(self.header.packet_length());
347
348 self.header.encode(buf);
349
350 buf.extend_from_slice(&self.payload);
351 }
352
353 #[inline]
355 pub fn header(&self) -> &RtcpHeader {
356 &self.header
357 }
358
359 #[inline]
361 pub fn packet_type(&self) -> RtcpPacketType {
362 self.header.packet_type()
363 }
364
365 #[inline]
367 pub fn with_packet_type(mut self, packet_type: RtcpPacketType) -> Self {
368 self.header = self.header.with_packet_type(packet_type);
369 self
370 }
371
372 #[inline]
376 pub fn item_count(&self) -> u8 {
377 self.header.item_count()
378 }
379
380 #[inline]
385 pub fn with_item_count(mut self, count: u8) -> Self {
386 self.header = self.header.with_item_count(count);
387 self
388 }
389
390 #[inline]
392 pub fn length(&self) -> usize {
393 self.header.packet_length()
394 }
395
396 #[inline]
400 pub fn padding(&self) -> u8 {
401 if self.header.padding() {
402 *self.payload.last().unwrap()
403 } else {
404 0
405 }
406 }
407
408 #[inline]
410 pub fn payload(&self) -> &Bytes {
411 &self.payload
412 }
413
414 #[inline]
416 pub fn stripped_payload(&self) -> Bytes {
417 let payload_len = self.payload.len();
418 let padding_len = self.padding() as usize;
419
420 let len = payload_len - padding_len;
421
422 self.payload.slice(..len)
423 }
424
425 pub fn with_payload(mut self, mut payload: Bytes, padding: u8) -> Self {
435 if padding > 0 {
436 let len = payload.len() + (padding as usize);
437
438 let mut buffer = BytesMut::with_capacity(len);
439
440 buffer.extend_from_slice(&payload);
441 buffer.resize(len, 0);
442
443 buffer[len - 1] = padding;
444
445 payload = buffer.freeze();
446
447 self.header = self
448 .header
449 .with_padding(true)
450 .with_packet_length(4 + payload.len());
451 } else {
452 self.header = self
453 .header
454 .with_padding(false)
455 .with_packet_length(4 + payload.len());
456 }
457
458 self.payload = payload;
459
460 self
461 }
462
463 pub fn with_padded_payload(mut self, payload: Bytes) -> Self {
476 let padding_len = payload.last().copied().expect("empty payload") as usize;
477
478 assert!(padding_len > 0 && payload.len() >= padding_len);
479
480 self.header = self
481 .header
482 .with_padding(true)
483 .with_packet_length(payload.len());
484
485 self.payload = payload;
486 self
487 }
488
489 #[inline]
491 pub fn raw_size(&self) -> usize {
492 self.length()
493 }
494}