rtc_rtcp/compound_packet/
mod.rs1#[cfg(test)]
2mod compound_packet_test;
3
4use crate::{
5 header::*, packet::*, receiver_report::*, sender_report::*, source_description::*, util::*,
6};
7use shared::{
8 error::{Error, Result},
9 marshal::{Marshal, MarshalSize, Unmarshal},
10};
11
12use bytes::{Buf, Bytes};
13use std::any::Any;
14use std::fmt;
15
16#[derive(Debug, Default, PartialEq, Clone)]
29pub struct CompoundPacket(pub Vec<Box<dyn Packet>>);
30
31impl fmt::Display for CompoundPacket {
32 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33 write!(f, "{self:?}")
34 }
35}
36
37impl Packet for CompoundPacket {
38 fn header(&self) -> Header {
39 Header::default()
40 }
41
42 fn destination_ssrc(&self) -> Vec<u32> {
45 if self.0.is_empty() {
46 vec![]
47 } else {
48 self.0[0].destination_ssrc()
49 }
50 }
51
52 fn raw_size(&self) -> usize {
53 let mut l = 0;
54 for packet in &self.0 {
55 l += packet.marshal_size();
56 }
57 l
58 }
59
60 fn as_any(&self) -> &dyn Any {
61 self
62 }
63
64 fn equal(&self, other: &dyn Packet) -> bool {
65 other.as_any().downcast_ref::<CompoundPacket>() == Some(self)
66 }
67
68 fn cloned(&self) -> Box<dyn Packet> {
69 Box::new(self.clone())
70 }
71}
72
73impl MarshalSize for CompoundPacket {
74 fn marshal_size(&self) -> usize {
75 let l = self.raw_size();
76 l + get_padding_size(l)
78 }
79}
80
81impl Marshal for CompoundPacket {
82 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
84 self.validate()?;
85
86 for packet in &self.0 {
87 let n = packet.marshal_to(buf)?;
88 buf = &mut buf[n..];
89 }
90
91 Ok(self.marshal_size())
92 }
93}
94
95impl Unmarshal for CompoundPacket {
96 fn unmarshal<B>(raw_packet: &mut B) -> Result<Self>
97 where
98 Self: Sized,
99 B: Buf,
100 {
101 let mut packets = vec![];
102
103 while raw_packet.has_remaining() {
104 let p = unmarshaller(raw_packet)?;
105 packets.push(p);
106 }
107
108 let c = CompoundPacket(packets);
109 c.validate()?;
110
111 Ok(c)
112 }
113}
114
115impl CompoundPacket {
116 pub fn validate(&self) -> Result<()> {
118 if self.0.is_empty() {
119 return Err(Error::EmptyCompound);
120 }
121
122 if self.0[0].as_any().downcast_ref::<SenderReport>().is_none()
125 && self.0[0]
126 .as_any()
127 .downcast_ref::<ReceiverReport>()
128 .is_none()
129 {
130 return Err(Error::BadFirstPacket);
131 }
132
133 for pkt in &self.0[1..] {
134 if pkt.as_any().downcast_ref::<ReceiverReport>().is_some() {
137 continue;
138 } else if let Some(e) = pkt.as_any().downcast_ref::<SourceDescription>() {
141 let mut has_cname = false;
142 for c in &e.chunks {
143 for it in &c.items {
144 if it.sdes_type == SdesType::SdesCname {
145 has_cname = true
146 }
147 }
148 }
149
150 if !has_cname {
151 return Err(Error::MissingCname);
152 }
153
154 return Ok(());
155
156 } else {
158 return Err(Error::PacketBeforeCname);
159 }
160 }
161
162 Err(Error::MissingCname)
164 }
165
166 pub fn cname(&self) -> Result<Bytes> {
168 if self.0.is_empty() {
169 return Err(Error::EmptyCompound);
170 }
171
172 for pkt in &self.0[1..] {
173 if let Some(sdes) = pkt.as_any().downcast_ref::<SourceDescription>() {
174 for c in &sdes.chunks {
175 for it in &c.items {
176 if it.sdes_type == SdesType::SdesCname {
177 return Ok(it.text.clone());
178 }
179 }
180 }
181 } else if pkt.as_any().downcast_ref::<ReceiverReport>().is_none() {
182 return Err(Error::PacketBeforeCname);
183 }
184 }
185
186 Err(Error::MissingCname)
187 }
188}