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::*, transport_feedbacks::cc_feedback_report::*,
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 FORMAT_CCFB => Box::new(CcFeedbackReport::unmarshal(&mut in_packet)?),
125 _ => Box::new(RawPacket::unmarshal(&mut in_packet)?),
126 },
127 PacketType::PayloadSpecificFeedback => match h.count {
128 FORMAT_PLI => Box::new(PictureLossIndication::unmarshal(&mut in_packet)?),
129 FORMAT_SLI => Box::new(SliceLossIndication::unmarshal(&mut in_packet)?),
130 FORMAT_REMB => Box::new(ReceiverEstimatedMaximumBitrate::unmarshal(&mut in_packet)?),
131 FORMAT_FIR => Box::new(FullIntraRequest::unmarshal(&mut in_packet)?),
132 _ => Box::new(RawPacket::unmarshal(&mut in_packet)?),
133 },
134 PacketType::ExtendedReport => Box::new(ExtendedReport::unmarshal(&mut in_packet)?),
135 _ => Box::new(RawPacket::unmarshal(&mut in_packet)?),
136 };
137
138 Ok(p)
139}
140
141#[cfg(test)]
142mod test {
143 use super::*;
144 use crate::reception_report::*;
145 use bytes::Bytes;
146
147 #[test]
148 fn test_packet_unmarshal() {
149 let mut data = Bytes::from_static(&[
150 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,
164 0x2d, 0x39, 0x64, 0x34, 0x39, 0x2d, 0x61, 0x34, 0x37, 0x64, 0x2d, 0x39, 0x31, 0x66,
165 0x36, 0x34, 0x65, 0x65, 0x65, 0x36, 0x39, 0x66, 0x35,
166 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, ]);
178
179 let packet = unmarshal(&mut data).expect("Error unmarshalling packets");
180
181 let a = ReceiverReport {
182 ssrc: 0x902f9e2e,
183 reports: vec![ReceptionReport {
184 ssrc: 0xbc5e9a40,
185 fraction_lost: 0,
186 total_lost: 0,
187 last_sequence_number: 0x46e1,
188 jitter: 273,
189 last_sender_report: 0x9f36432,
190 delay: 150137,
191 }],
192 ..Default::default()
193 };
194
195 let b = SourceDescription {
196 chunks: vec![SourceDescriptionChunk {
197 source: 0x902f9e2e,
198 items: vec![SourceDescriptionItem {
199 sdes_type: SdesType::SdesCname,
200 text: Bytes::from_static(b"{9c00eb92-1afb-9d49-a47d-91f64eee69f5}"),
201 }],
202 }],
203 };
204
205 let c = Goodbye {
206 sources: vec![0x902f9e2e],
207 ..Default::default()
208 };
209
210 let d = PictureLossIndication {
211 sender_ssrc: 0x902f9e2e,
212 media_ssrc: 0x902f9e2e,
213 };
214
215 let e = RapidResynchronizationRequest {
216 sender_ssrc: 0x902f9e2e,
217 media_ssrc: 0x902f9e2e,
218 };
219
220 let expected: Vec<Box<dyn Packet>> = vec![
221 Box::new(a),
222 Box::new(b),
223 Box::new(c),
224 Box::new(d),
225 Box::new(e),
226 ];
227
228 assert!(packet == expected, "Invalid packets");
229 }
230
231 #[test]
232 fn test_packet_unmarshal_empty() -> Result<()> {
233 let result = unmarshal(&mut Bytes::new());
234 if let Err(got) = result {
235 let want = Error::InvalidHeader;
236 assert_eq!(got, want, "Unmarshal(nil) err = {got}, want {want}");
237 } else {
238 panic!("want error");
239 }
240
241 Ok(())
242 }
243
244 #[test]
245 fn test_packet_invalid_header_length() -> Result<()> {
246 let mut data = Bytes::from_static(&[
247 0x81, 0xcb, 0x0, 0x64,
250 ]);
251
252 let result = unmarshal(&mut data);
253 if let Err(got) = result {
254 let want = Error::PacketTooShort;
255 assert_eq!(
256 got, want,
257 "Unmarshal(invalid_header_length) err = {got}, want {want}"
258 );
259 } else {
260 panic!("want error");
261 }
262
263 Ok(())
264 }
265 #[test]
266 fn test_packet_unmarshal_firefox() -> Result<()> {
267 let tests = vec![
269 Bytes::from_static(&[
270 143, 205, 0, 6, 65, 227, 184, 49, 118, 243, 78, 96, 42, 63, 0, 5, 12, 162, 166, 0,
271 32, 5, 200, 4, 0, 4, 0, 0,
272 ]),
273 Bytes::from_static(&[
274 143, 205, 0, 9, 65, 227, 184, 49, 118, 243, 78, 96, 42, 68, 0, 17, 12, 162, 167, 1,
275 32, 17, 88, 0, 4, 0, 4, 8, 108, 0, 4, 0, 4, 12, 0, 4, 0, 4, 4, 0,
276 ]),
277 Bytes::from_static(&[
278 143, 205, 0, 8, 65, 227, 184, 49, 118, 243, 78, 96, 42, 91, 0, 12, 12, 162, 168, 3,
279 32, 12, 220, 4, 0, 4, 0, 8, 128, 4, 0, 4, 0, 8, 0, 0,
280 ]),
281 Bytes::from_static(&[
282 143, 205, 0, 7, 65, 227, 184, 49, 118, 243, 78, 96, 42, 103, 0, 8, 12, 162, 169, 4,
283 32, 8, 232, 4, 0, 4, 0, 4, 4, 0, 0, 0,
284 ]),
285 ];
286
287 for mut test in tests {
288 unmarshal(&mut test)?;
289 }
290
291 Ok(())
292 }
293
294 #[test]
298 fn test_marshal_compound_roundtrip() -> Result<()> {
299 use crate::reception_report::ReceptionReport;
300
301 let rr = ReceiverReport {
302 ssrc: 0x902f9e2e,
303 reports: vec![ReceptionReport {
304 ssrc: 0xbc5e9a40,
305 fraction_lost: 0,
306 total_lost: 0,
307 last_sequence_number: 0x46e1,
308 jitter: 273,
309 last_sender_report: 0x9f36432,
310 delay: 150137,
311 }],
312 ..Default::default()
313 };
314 let pli = PictureLossIndication {
315 sender_ssrc: 0x902f9e2e,
316 media_ssrc: 0x902f9e2e,
317 };
318 let packets: Vec<Box<dyn Packet>> = vec![Box::new(rr), Box::new(pli)];
319
320 let raw1 = marshal(&packets)?;
321 let out = unmarshal(&mut raw1.clone().freeze())?;
322 assert_eq!(out.len(), 2, "expected two sub-packets");
323 let raw2 = marshal(&out)?;
324 assert_eq!(raw1, raw2, "compound marshal/unmarshal round-trip mismatch");
325
326 Ok(())
327 }
328}