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};
14use zerocopy::{
15 byteorder::network_endian::U16, FromBytes, Immutable, IntoBytes, KnownLayout, SizeError,
16 Unaligned,
17};
18
19use crate::InvalidInput;
20
21pub use self::{
22 bye::ByePacket,
23 channel::RtcpChannel,
24 context::{RtcpContext, RtcpContextHandle},
25 handler::{MuxedRtcpHandler, RtcpHandler, RtcpHandlerOptions},
26 report::{ReceiverReport, ReportBlock, SenderReport},
27 sdes::{SourceDescription, SourceDescriptionPacket},
28};
29
30#[derive(Clone)]
32pub struct CompoundRtcpPacket {
33 inner: Vec<RtcpPacket>,
34}
35
36impl CompoundRtcpPacket {
37 pub fn new<T>(packets: T) -> Self
39 where
40 T: Into<Vec<RtcpPacket>>,
41 {
42 Self {
43 inner: packets.into(),
44 }
45 }
46
47 pub fn decode(mut frame: Bytes) -> Result<Self, InvalidInput> {
49 let mut res = Vec::new();
50
51 while !frame.is_empty() {
52 res.push(RtcpPacket::decode(&mut frame)?);
53 }
54
55 Ok(res.into())
56 }
57
58 pub fn encode(&self, buf: &mut BytesMut) {
60 buf.reserve(self.raw_size());
61
62 for packet in &self.inner {
63 packet.encode(buf);
64 }
65 }
66
67 pub fn raw_size(&self) -> usize {
69 self.inner.iter().map(|packet| packet.length()).sum()
70 }
71}
72
73impl Deref for CompoundRtcpPacket {
74 type Target = [RtcpPacket];
75
76 #[inline]
77 fn deref(&self) -> &Self::Target {
78 &self.inner
79 }
80}
81
82impl From<RtcpPacket> for CompoundRtcpPacket {
83 #[inline]
84 fn from(packet: RtcpPacket) -> Self {
85 Self {
86 inner: vec![packet],
87 }
88 }
89}
90
91impl<T> From<T> for CompoundRtcpPacket
92where
93 T: Into<Vec<RtcpPacket>>,
94{
95 #[inline]
96 fn from(packets: T) -> Self {
97 Self::new(packets)
98 }
99}
100
101#[derive(Debug, Copy, Clone, Eq, PartialEq)]
103pub enum RtcpPacketType {
104 SR,
105 RR,
106 SDES,
107 BYE,
108 Other(u8),
109}
110
111impl RtcpPacketType {
112 #[inline]
114 pub fn raw_id(self) -> u8 {
115 match self {
116 RtcpPacketType::SR => 200,
117 RtcpPacketType::RR => 201,
118 RtcpPacketType::SDES => 202,
119 RtcpPacketType::BYE => 203,
120 RtcpPacketType::Other(id) => id,
121 }
122 }
123}
124
125impl From<u8> for RtcpPacketType {
126 #[inline]
127 fn from(id: u8) -> RtcpPacketType {
128 match id {
129 200 => RtcpPacketType::SR,
130 201 => RtcpPacketType::RR,
131 202 => RtcpPacketType::SDES,
132 203 => RtcpPacketType::BYE,
133 id => RtcpPacketType::Other(id),
134 }
135 }
136}
137
138#[derive(Copy, Clone, KnownLayout, Immutable, Unaligned, IntoBytes, FromBytes)]
140#[repr(C)]
141struct RawRtcpHeader {
142 options: u8,
143 packet_type: u8,
144 length: U16,
145}
146
147#[derive(Copy, Clone)]
149pub struct RtcpHeader {
150 options: u8,
151 packet_type: RtcpPacketType,
152 length: u16,
153}
154
155impl RtcpHeader {
156 pub const RAW_SIZE: usize = std::mem::size_of::<RawRtcpHeader>();
158
159 #[inline]
161 pub const fn new(packet_type: RtcpPacketType) -> Self {
162 Self {
163 options: 2 << 6,
164 packet_type,
165 length: 0,
166 }
167 }
168
169 pub fn decode(data: &mut Bytes) -> Result<Self, InvalidInput> {
171 let (raw, _) = RawRtcpHeader::ref_from_prefix(data)
172 .map_err(SizeError::from)
173 .map_err(|_| InvalidInput::new())?;
174
175 if (raw.options >> 6) != 2 {
176 return Err(InvalidInput::new());
177 }
178
179 let res = Self {
180 options: raw.options,
181 packet_type: raw.packet_type.into(),
182 length: raw.length.get(),
183 };
184
185 data.advance(std::mem::size_of::<RawRtcpHeader>());
186
187 Ok(res)
188 }
189
190 pub fn encode(&self, buf: &mut BytesMut) {
192 let raw = RawRtcpHeader {
193 options: self.options,
194 packet_type: self.packet_type.raw_id(),
195 length: U16::new(self.length),
196 };
197
198 buf.extend_from_slice(raw.as_bytes());
199 }
200
201 #[inline]
203 pub fn padding(&self) -> bool {
204 (self.options & 0x20) != 0
205 }
206
207 #[inline]
209 pub fn with_padding(mut self, padding: bool) -> Self {
210 self.options &= !0x20;
211 self.options |= (padding as u8) << 5;
212 self
213 }
214
215 #[inline]
217 pub fn packet_length(&self) -> usize {
218 ((self.length as usize) + 1) << 2
219 }
220
221 #[inline]
230 pub fn with_packet_length(mut self, length: usize) -> Self {
231 assert!((4..=262_144).contains(&length) && (length & 3) == 0);
232
233 self.length = ((length >> 2) - 1) as u16;
234 self
235 }
236
237 #[inline]
239 pub fn packet_type(&self) -> RtcpPacketType {
240 self.packet_type
241 }
242
243 #[inline]
245 pub fn with_packet_type(mut self, packet_type: RtcpPacketType) -> Self {
246 self.packet_type = packet_type;
247 self
248 }
249
250 #[inline]
254 pub fn item_count(&self) -> u8 {
255 self.options & 0x1f
256 }
257
258 #[inline]
263 pub fn with_item_count(mut self, count: u8) -> Self {
264 assert!(count < 32);
265
266 self.options &= !0x1f;
267 self.options |= count & 0x1f;
268 self
269 }
270
271 #[inline]
273 pub fn raw_size(&self) -> usize {
274 std::mem::size_of::<RawRtcpHeader>()
275 }
276}
277
278#[derive(Clone)]
280pub struct RtcpPacket {
281 header: RtcpHeader,
282 payload: Bytes,
283}
284
285impl RtcpPacket {
286 #[inline]
288 pub const fn new(packet_type: RtcpPacketType) -> Self {
289 Self {
290 header: RtcpHeader::new(packet_type),
291 payload: Bytes::new(),
292 }
293 }
294
295 pub fn from_parts(header: RtcpHeader, payload: Bytes) -> Result<Self, InvalidInput> {
297 if header.padding() {
298 let padding_len = payload.last().copied().ok_or_else(InvalidInput::new)? as usize;
299
300 if padding_len == 0 || payload.len() < padding_len {
301 return Err(InvalidInput::new());
302 }
303 }
304
305 let packet_len = header.packet_length();
306
307 if packet_len != (payload.len() + 4) {
308 return Err(InvalidInput::new());
309 }
310
311 let res = Self { header, payload };
312
313 Ok(res)
314 }
315
316 #[inline]
318 pub fn deconstruct(self) -> (RtcpHeader, Bytes) {
319 (self.header, self.payload)
320 }
321
322 pub fn decode(data: &mut Bytes) -> Result<Self, InvalidInput> {
324 let mut buffer = data.clone();
325
326 let header = RtcpHeader::decode(&mut buffer)?;
327
328 let payload_len = header.packet_length() - 4;
329
330 if buffer.len() < payload_len {
331 return Err(InvalidInput::new());
332 }
333
334 let res = Self::from_parts(header, buffer.split_to(payload_len))?;
335
336 *data = buffer;
337
338 Ok(res)
339 }
340
341 pub fn encode(&self, buf: &mut BytesMut) {
343 buf.reserve(self.header.packet_length());
344
345 self.header.encode(buf);
346
347 buf.extend_from_slice(&self.payload);
348 }
349
350 #[inline]
352 pub fn header(&self) -> &RtcpHeader {
353 &self.header
354 }
355
356 #[inline]
358 pub fn packet_type(&self) -> RtcpPacketType {
359 self.header.packet_type()
360 }
361
362 #[inline]
364 pub fn with_packet_type(mut self, packet_type: RtcpPacketType) -> Self {
365 self.header = self.header.with_packet_type(packet_type);
366 self
367 }
368
369 #[inline]
373 pub fn item_count(&self) -> u8 {
374 self.header.item_count()
375 }
376
377 #[inline]
382 pub fn with_item_count(mut self, count: u8) -> Self {
383 self.header = self.header.with_item_count(count);
384 self
385 }
386
387 #[inline]
389 pub fn length(&self) -> usize {
390 self.header.packet_length()
391 }
392
393 #[inline]
397 pub fn padding(&self) -> u8 {
398 if self.header.padding() {
399 *self.payload.last().unwrap()
400 } else {
401 0
402 }
403 }
404
405 #[inline]
407 pub fn payload(&self) -> &Bytes {
408 &self.payload
409 }
410
411 #[inline]
413 pub fn stripped_payload(&self) -> Bytes {
414 let payload_len = self.payload.len();
415 let padding_len = self.padding() as usize;
416
417 let len = payload_len - padding_len;
418
419 self.payload.slice(..len)
420 }
421
422 pub fn with_payload(mut self, mut payload: Bytes, padding: u8) -> Self {
432 if padding > 0 {
433 let len = payload.len() + (padding as usize);
434
435 let mut buffer = BytesMut::with_capacity(len);
436
437 buffer.extend_from_slice(&payload);
438 buffer.resize(len, 0);
439
440 buffer[len - 1] = padding;
441
442 payload = buffer.freeze();
443
444 self.header = self
445 .header
446 .with_padding(true)
447 .with_packet_length(4 + payload.len());
448 } else {
449 self.header = self
450 .header
451 .with_padding(false)
452 .with_packet_length(4 + payload.len());
453 }
454
455 self.payload = payload;
456
457 self
458 }
459
460 pub fn with_padded_payload(mut self, payload: Bytes) -> Self {
473 let padding_len = payload.last().copied().expect("empty payload") as usize;
474
475 assert!(padding_len > 0 && payload.len() >= padding_len);
476
477 self.header = self
478 .header
479 .with_padding(true)
480 .with_packet_length(payload.len());
481
482 self.payload = payload;
483 self
484 }
485
486 #[inline]
488 pub fn raw_size(&self) -> usize {
489 self.length()
490 }
491}