1use crate::{
2 goodbye::*, header::*, payload_feedbacks::full_intra_request::*,
3 payload_feedbacks::picture_loss_indication::*,
4 payload_feedbacks::receiver_estimated_maximum_bitrate::*,
5 payload_feedbacks::slice_loss_indication::*, raw_packet::*, receiver_report::*,
6 sender_report::*, source_description::*,
7 transport_feedbacks::rapid_resynchronization_request::*,
8 transport_feedbacks::transport_layer_cc::*, transport_feedbacks::transport_layer_nack::*,
9};
10use shared::{
11 error::{Error, Result},
12 marshal::{Marshal, Unmarshal},
13};
14
15use crate::extended_report::ExtendedReport;
16use bytes::{Buf, BytesMut};
17use std::any::Any;
18use std::fmt;
19
20pub trait Packet: Send + Sync + Marshal + Unmarshal + fmt::Display + fmt::Debug {
23 fn header(&self) -> Header;
25 fn destination_ssrc(&self) -> Vec<u32>;
30 fn raw_size(&self) -> usize;
32 fn as_any(&self) -> &dyn Any;
34 fn equal(&self, other: &dyn Packet) -> bool;
36 fn cloned(&self) -> Box<dyn Packet>;
38}
39
40impl PartialEq for dyn Packet {
41 fn eq(&self, other: &Self) -> bool {
42 self.equal(other)
43 }
44}
45
46impl Clone for Box<dyn Packet> {
47 fn clone(&self) -> Box<dyn Packet> {
48 self.cloned()
49 }
50}
51
52pub fn marshal(packets: &[Box<dyn Packet>]) -> Result<BytesMut> {
54 let total: usize = packets.iter().map(|p| p.marshal_size()).sum();
58 let mut out = BytesMut::new();
59 out.resize(total, 0);
60 let mut offset = 0;
61 for p in packets {
62 offset += p.marshal_to(&mut out[offset..])?;
63 }
64 Ok(out)
65}
66
67pub fn unmarshal<B>(raw_data: &mut B) -> Result<Vec<Box<dyn Packet>>>
74where
75 B: Buf,
76{
77 let mut packets = vec![];
78
79 while raw_data.has_remaining() {
80 let p = unmarshaller(raw_data)?;
81 packets.push(p);
82 }
83
84 match packets.len() {
85 0 => Err(Error::InvalidHeader),
87
88 _ => Ok(packets),
90 }
91}
92
93pub(crate) fn unmarshaller<B>(raw_data: &mut B) -> Result<Box<dyn Packet>>
96where
97 B: Buf,
98{
99 let h = Header::unmarshal(raw_data)?;
100
101 let length = (h.length as usize) * 4;
102 if length > raw_data.remaining() {
103 return Err(Error::PacketTooShort);
104 }
105
106 let mut header_buf = [0u8; HEADER_LENGTH];
111 h.marshal_to(&mut header_buf[..])?;
112 let mut in_packet = header_buf.as_slice().chain(raw_data.take(length));
113
114 let p: Box<dyn Packet> = match h.packet_type {
115 PacketType::SenderReport => Box::new(SenderReport::unmarshal(&mut in_packet)?),
116 PacketType::ReceiverReport => Box::new(ReceiverReport::unmarshal(&mut in_packet)?),
117 PacketType::SourceDescription => Box::new(SourceDescription::unmarshal(&mut in_packet)?),
118 PacketType::Goodbye => Box::new(Goodbye::unmarshal(&mut in_packet)?),
119
120 PacketType::TransportSpecificFeedback => match h.count {
121 FORMAT_TLN => Box::new(TransportLayerNack::unmarshal(&mut in_packet)?),
122 FORMAT_RRR => Box::new(RapidResynchronizationRequest::unmarshal(&mut in_packet)?),
123 FORMAT_TCC => Box::new(TransportLayerCc::unmarshal(&mut in_packet)?),
124 _ => Box::new(RawPacket::unmarshal(&mut in_packet)?),
125 },
126 PacketType::PayloadSpecificFeedback => match h.count {
127 FORMAT_PLI => Box::new(PictureLossIndication::unmarshal(&mut in_packet)?),
128 FORMAT_SLI => Box::new(SliceLossIndication::unmarshal(&mut in_packet)?),
129 FORMAT_REMB => Box::new(ReceiverEstimatedMaximumBitrate::unmarshal(&mut in_packet)?),
130 FORMAT_FIR => Box::new(FullIntraRequest::unmarshal(&mut in_packet)?),
131 _ => Box::new(RawPacket::unmarshal(&mut in_packet)?),
132 },
133 PacketType::ExtendedReport => Box::new(ExtendedReport::unmarshal(&mut in_packet)?),
134 _ => Box::new(RawPacket::unmarshal(&mut in_packet)?),
135 };
136
137 Ok(p)
138}
139
140#[cfg(test)]
141mod test {
142 use super::*;
143 use crate::reception_report::*;
144 use bytes::Bytes;
145
146 #[test]
147 fn test_packet_unmarshal() {
148 let mut data = Bytes::from_static(&[
149 0x81, 0xc9, 0x0, 0x7, 0x90, 0x2f, 0x9e, 0x2e, 0xbc, 0x5e, 0x9a, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x46, 0xe1, 0x0, 0x0, 0x1, 0x11, 0x9, 0xf3, 0x64, 0x32, 0x0, 0x2, 0x4a, 0x79, 0x81, 0xca, 0x0, 0xc, 0x90, 0x2f, 0x9e, 0x2e, 0x1, 0x26, 0x7b, 0x39, 0x63, 0x30, 0x30, 0x65, 0x62, 0x39, 0x32, 0x2d, 0x31, 0x61, 0x66, 0x62,
163 0x2d, 0x39, 0x64, 0x34, 0x39, 0x2d, 0x61, 0x34, 0x37, 0x64, 0x2d, 0x39, 0x31, 0x66,
164 0x36, 0x34, 0x65, 0x65, 0x65, 0x36, 0x39, 0x66, 0x35,
165 0x7d, 0x0, 0x0, 0x0, 0x0, 0x81, 0xcb, 0x0, 0x1, 0x90, 0x2f, 0x9e, 0x2e, 0x81, 0xce, 0x0, 0x2, 0x90, 0x2f, 0x9e, 0x2e, 0x90, 0x2f, 0x9e, 0x2e, 0x85, 0xcd, 0x0, 0x2, 0x90, 0x2f, 0x9e, 0x2e, 0x90, 0x2f, 0x9e, 0x2e, ]);
177
178 let packet = unmarshal(&mut data).expect("Error unmarshalling packets");
179
180 let a = ReceiverReport {
181 ssrc: 0x902f9e2e,
182 reports: vec![ReceptionReport {
183 ssrc: 0xbc5e9a40,
184 fraction_lost: 0,
185 total_lost: 0,
186 last_sequence_number: 0x46e1,
187 jitter: 273,
188 last_sender_report: 0x9f36432,
189 delay: 150137,
190 }],
191 ..Default::default()
192 };
193
194 let b = SourceDescription {
195 chunks: vec![SourceDescriptionChunk {
196 source: 0x902f9e2e,
197 items: vec![SourceDescriptionItem {
198 sdes_type: SdesType::SdesCname,
199 text: Bytes::from_static(b"{9c00eb92-1afb-9d49-a47d-91f64eee69f5}"),
200 }],
201 }],
202 };
203
204 let c = Goodbye {
205 sources: vec![0x902f9e2e],
206 ..Default::default()
207 };
208
209 let d = PictureLossIndication {
210 sender_ssrc: 0x902f9e2e,
211 media_ssrc: 0x902f9e2e,
212 };
213
214 let e = RapidResynchronizationRequest {
215 sender_ssrc: 0x902f9e2e,
216 media_ssrc: 0x902f9e2e,
217 };
218
219 let expected: Vec<Box<dyn Packet>> = vec![
220 Box::new(a),
221 Box::new(b),
222 Box::new(c),
223 Box::new(d),
224 Box::new(e),
225 ];
226
227 assert!(packet == expected, "Invalid packets");
228 }
229
230 #[test]
231 fn test_packet_unmarshal_empty() -> Result<()> {
232 let result = unmarshal(&mut Bytes::new());
233 if let Err(got) = result {
234 let want = Error::InvalidHeader;
235 assert_eq!(got, want, "Unmarshal(nil) err = {got}, want {want}");
236 } else {
237 panic!("want error");
238 }
239
240 Ok(())
241 }
242
243 #[test]
244 fn test_packet_invalid_header_length() -> Result<()> {
245 let mut data = Bytes::from_static(&[
246 0x81, 0xcb, 0x0, 0x64,
249 ]);
250
251 let result = unmarshal(&mut data);
252 if let Err(got) = result {
253 let want = Error::PacketTooShort;
254 assert_eq!(
255 got, want,
256 "Unmarshal(invalid_header_length) err = {got}, want {want}"
257 );
258 } else {
259 panic!("want error");
260 }
261
262 Ok(())
263 }
264 #[test]
265 fn test_packet_unmarshal_firefox() -> Result<()> {
266 let tests = vec![
268 Bytes::from_static(&[
269 143, 205, 0, 6, 65, 227, 184, 49, 118, 243, 78, 96, 42, 63, 0, 5, 12, 162, 166, 0,
270 32, 5, 200, 4, 0, 4, 0, 0,
271 ]),
272 Bytes::from_static(&[
273 143, 205, 0, 9, 65, 227, 184, 49, 118, 243, 78, 96, 42, 68, 0, 17, 12, 162, 167, 1,
274 32, 17, 88, 0, 4, 0, 4, 8, 108, 0, 4, 0, 4, 12, 0, 4, 0, 4, 4, 0,
275 ]),
276 Bytes::from_static(&[
277 143, 205, 0, 8, 65, 227, 184, 49, 118, 243, 78, 96, 42, 91, 0, 12, 12, 162, 168, 3,
278 32, 12, 220, 4, 0, 4, 0, 8, 128, 4, 0, 4, 0, 8, 0, 0,
279 ]),
280 Bytes::from_static(&[
281 143, 205, 0, 7, 65, 227, 184, 49, 118, 243, 78, 96, 42, 103, 0, 8, 12, 162, 169, 4,
282 32, 8, 232, 4, 0, 4, 0, 4, 4, 0, 0, 0,
283 ]),
284 ];
285
286 for mut test in tests {
287 unmarshal(&mut test)?;
288 }
289
290 Ok(())
291 }
292
293 #[test]
297 fn test_marshal_compound_roundtrip() -> Result<()> {
298 use crate::reception_report::ReceptionReport;
299
300 let rr = ReceiverReport {
301 ssrc: 0x902f9e2e,
302 reports: vec![ReceptionReport {
303 ssrc: 0xbc5e9a40,
304 fraction_lost: 0,
305 total_lost: 0,
306 last_sequence_number: 0x46e1,
307 jitter: 273,
308 last_sender_report: 0x9f36432,
309 delay: 150137,
310 }],
311 ..Default::default()
312 };
313 let pli = PictureLossIndication {
314 sender_ssrc: 0x902f9e2e,
315 media_ssrc: 0x902f9e2e,
316 };
317 let packets: Vec<Box<dyn Packet>> = vec![Box::new(rr), Box::new(pli)];
318
319 let raw1 = marshal(&packets)?;
320 let out = unmarshal(&mut raw1.clone().freeze())?;
321 assert_eq!(out.len(), 2, "expected two sub-packets");
322 let raw2 = marshal(&out)?;
323 assert_eq!(raw1, raw2, "compound marshal/unmarshal round-trip mismatch");
324
325 Ok(())
326 }
327}