1 use crate::error::Result;
2 use crate::{
3 error::Error, goodbye::*, header::*, payload_feedbacks::full_intra_request::*,
4 payload_feedbacks::picture_loss_indication::*,
5 payload_feedbacks::receiver_estimated_maximum_bitrate::*,
6 payload_feedbacks::slice_loss_indication::*, raw_packet::*, receiver_report::*,
7 sender_report::*, source_description::*,
8 transport_feedbacks::rapid_resynchronization_request::*,
9 transport_feedbacks::transport_layer_cc::*, transport_feedbacks::transport_layer_nack::*,
10 };
11 use util::marshal::{Marshal, Unmarshal};
12
13 use crate::extended_report::ExtendedReport;
14 use bytes::{Buf, BufMut, Bytes, BytesMut};
15 use std::any::Any;
16 use std::fmt;
17
18 /// Packet represents an RTCP packet, a protocol used for out-of-band statistics and
19 /// control information for an RTP session
20 pub trait Packet: Marshal + Unmarshal + fmt::Display + fmt::Debug {
header(&self) -> Header21 fn header(&self) -> Header;
destination_ssrc(&self) -> Vec<u32>22 fn destination_ssrc(&self) -> Vec<u32>;
raw_size(&self) -> usize23 fn raw_size(&self) -> usize;
as_any(&self) -> &(dyn Any + Send + Sync)24 fn as_any(&self) -> &(dyn Any + Send + Sync);
equal(&self, other: &(dyn Packet + Send + Sync)) -> bool25 fn equal(&self, other: &(dyn Packet + Send + Sync)) -> bool;
cloned(&self) -> Box<dyn Packet + Send + Sync>26 fn cloned(&self) -> Box<dyn Packet + Send + Sync>;
27 }
28
29 impl PartialEq for dyn Packet + Send + Sync {
eq(&self, other: &Self) -> bool30 fn eq(&self, other: &Self) -> bool {
31 self.equal(other)
32 }
33 }
34
35 impl Clone for Box<dyn Packet + Send + Sync> {
clone(&self) -> Box<dyn Packet + Send + Sync>36 fn clone(&self) -> Box<dyn Packet + Send + Sync> {
37 self.cloned()
38 }
39 }
40
41 /// marshal takes an array of Packets and serializes them to a single buffer
marshal(packets: &[Box<dyn Packet + Send + Sync>]) -> Result<Bytes>42 pub fn marshal(packets: &[Box<dyn Packet + Send + Sync>]) -> Result<Bytes> {
43 let mut out = BytesMut::new();
44 for p in packets {
45 let data = p.marshal()?;
46 out.put(data);
47 }
48 Ok(out.freeze())
49 }
50
51 /// Unmarshal takes an entire udp datagram (which may consist of multiple RTCP packets) and
52 /// returns the unmarshaled packets it contains.
53 ///
54 /// If this is a reduced-size RTCP packet a feedback packet (Goodbye, SliceLossIndication, etc)
55 /// will be returned. Otherwise, the underlying type of the returned packet will be
56 /// CompoundPacket.
unmarshal<B>(raw_data: &mut B) -> Result<Vec<Box<dyn Packet + Send + Sync>>> where B: Buf,57 pub fn unmarshal<B>(raw_data: &mut B) -> Result<Vec<Box<dyn Packet + Send + Sync>>>
58 where
59 B: Buf,
60 {
61 let mut packets = vec![];
62
63 while raw_data.has_remaining() {
64 let p = unmarshaller(raw_data)?;
65 packets.push(p);
66 }
67
68 match packets.len() {
69 // Empty Packet
70 0 => Err(Error::InvalidHeader),
71
72 // Multiple Packet
73 _ => Ok(packets),
74 }
75 }
76
77 /// unmarshaller is a factory which pulls the first RTCP packet from a bytestream,
78 /// and returns it's parsed representation, and the amount of data that was processed.
unmarshaller<B>(raw_data: &mut B) -> Result<Box<dyn Packet + Send + Sync>> where B: Buf,79 pub(crate) fn unmarshaller<B>(raw_data: &mut B) -> Result<Box<dyn Packet + Send + Sync>>
80 where
81 B: Buf,
82 {
83 let h = Header::unmarshal(raw_data)?;
84
85 let length = (h.length as usize) * 4;
86 if length > raw_data.remaining() {
87 return Err(Error::PacketTooShort);
88 }
89
90 let mut in_packet = h.marshal()?.chain(raw_data.take(length));
91
92 let p: Box<dyn Packet + Send + Sync> = match h.packet_type {
93 PacketType::SenderReport => Box::new(SenderReport::unmarshal(&mut in_packet)?),
94 PacketType::ReceiverReport => Box::new(ReceiverReport::unmarshal(&mut in_packet)?),
95 PacketType::SourceDescription => Box::new(SourceDescription::unmarshal(&mut in_packet)?),
96 PacketType::Goodbye => Box::new(Goodbye::unmarshal(&mut in_packet)?),
97
98 PacketType::TransportSpecificFeedback => match h.count {
99 FORMAT_TLN => Box::new(TransportLayerNack::unmarshal(&mut in_packet)?),
100 FORMAT_RRR => Box::new(RapidResynchronizationRequest::unmarshal(&mut in_packet)?),
101 FORMAT_TCC => Box::new(TransportLayerCc::unmarshal(&mut in_packet)?),
102 _ => Box::new(RawPacket::unmarshal(&mut in_packet)?),
103 },
104 PacketType::PayloadSpecificFeedback => match h.count {
105 FORMAT_PLI => Box::new(PictureLossIndication::unmarshal(&mut in_packet)?),
106 FORMAT_SLI => Box::new(SliceLossIndication::unmarshal(&mut in_packet)?),
107 FORMAT_REMB => Box::new(ReceiverEstimatedMaximumBitrate::unmarshal(&mut in_packet)?),
108 FORMAT_FIR => Box::new(FullIntraRequest::unmarshal(&mut in_packet)?),
109 _ => Box::new(RawPacket::unmarshal(&mut in_packet)?),
110 },
111 PacketType::ExtendedReport => Box::new(ExtendedReport::unmarshal(&mut in_packet)?),
112 _ => Box::new(RawPacket::unmarshal(&mut in_packet)?),
113 };
114
115 Ok(p)
116 }
117
118 #[cfg(test)]
119 mod test {
120 use super::*;
121 use crate::reception_report::*;
122 use bytes::Bytes;
123
124 #[test]
test_packet_unmarshal()125 fn test_packet_unmarshal() {
126 let mut data = Bytes::from_static(&[
127 // Receiver Report (offset=0)
128 0x81, 0xc9, 0x0, 0x7, // v=2, p=0, count=1, RR, len=7
129 0x90, 0x2f, 0x9e, 0x2e, // ssrc=0x902f9e2e
130 0xbc, 0x5e, 0x9a, 0x40, // ssrc=0xbc5e9a40
131 0x0, 0x0, 0x0, 0x0, // fracLost=0, totalLost=0
132 0x0, 0x0, 0x46, 0xe1, // lastSeq=0x46e1
133 0x0, 0x0, 0x1, 0x11, // jitter=273
134 0x9, 0xf3, 0x64, 0x32, // lsr=0x9f36432
135 0x0, 0x2, 0x4a, 0x79, // delay=150137
136 // Source Description (offset=32)
137 0x81, 0xca, 0x0, 0xc, // v=2, p=0, count=1, SDES, len=12
138 0x90, 0x2f, 0x9e, 0x2e, // ssrc=0x902f9e2e
139 0x1, 0x26, // CNAME, len=38
140 0x7b, 0x39, 0x63, 0x30, 0x30, 0x65, 0x62, 0x39, 0x32, 0x2d, 0x31, 0x61, 0x66, 0x62,
141 0x2d, 0x39, 0x64, 0x34, 0x39, 0x2d, 0x61, 0x34, 0x37, 0x64, 0x2d, 0x39, 0x31, 0x66,
142 0x36, 0x34, 0x65, 0x65, 0x65, 0x36, 0x39, 0x66, 0x35,
143 0x7d, // text="{9c00eb92-1afb-9d49-a47d-91f64eee69f5}"
144 0x0, 0x0, 0x0, 0x0, // END + padding
145 // Goodbye (offset=84)
146 0x81, 0xcb, 0x0, 0x1, // v=2, p=0, count=1, BYE, len=1
147 0x90, 0x2f, 0x9e, 0x2e, // source=0x902f9e2e
148 0x81, 0xce, 0x0, 0x2, // Picture Loss Indication (offset=92)
149 0x90, 0x2f, 0x9e, 0x2e, // sender=0x902f9e2e
150 0x90, 0x2f, 0x9e, 0x2e, // media=0x902f9e2e
151 0x85, 0xcd, 0x0, 0x2, // RapidResynchronizationRequest (offset=104)
152 0x90, 0x2f, 0x9e, 0x2e, // sender=0x902f9e2e
153 0x90, 0x2f, 0x9e, 0x2e, // media=0x902f9e2e
154 ]);
155
156 let packet = unmarshal(&mut data).expect("Error unmarshalling packets");
157
158 let a = ReceiverReport {
159 ssrc: 0x902f9e2e,
160 reports: vec![ReceptionReport {
161 ssrc: 0xbc5e9a40,
162 fraction_lost: 0,
163 total_lost: 0,
164 last_sequence_number: 0x46e1,
165 jitter: 273,
166 last_sender_report: 0x9f36432,
167 delay: 150137,
168 }],
169 ..Default::default()
170 };
171
172 let b = SourceDescription {
173 chunks: vec![SourceDescriptionChunk {
174 source: 0x902f9e2e,
175 items: vec![SourceDescriptionItem {
176 sdes_type: SdesType::SdesCname,
177 text: Bytes::from_static(b"{9c00eb92-1afb-9d49-a47d-91f64eee69f5}"),
178 }],
179 }],
180 };
181
182 let c = Goodbye {
183 sources: vec![0x902f9e2e],
184 ..Default::default()
185 };
186
187 let d = PictureLossIndication {
188 sender_ssrc: 0x902f9e2e,
189 media_ssrc: 0x902f9e2e,
190 };
191
192 let e = RapidResynchronizationRequest {
193 sender_ssrc: 0x902f9e2e,
194 media_ssrc: 0x902f9e2e,
195 };
196
197 let expected: Vec<Box<dyn Packet + Send + Sync>> = vec![
198 Box::new(a),
199 Box::new(b),
200 Box::new(c),
201 Box::new(d),
202 Box::new(e),
203 ];
204
205 assert!(packet == expected, "Invalid packets");
206 }
207
208 #[test]
test_packet_unmarshal_empty() -> Result<()>209 fn test_packet_unmarshal_empty() -> Result<()> {
210 let result = unmarshal(&mut Bytes::new());
211 if let Err(got) = result {
212 let want = Error::InvalidHeader;
213 assert_eq!(got, want, "Unmarshal(nil) err = {got}, want {want}");
214 } else {
215 panic!("want error");
216 }
217
218 Ok(())
219 }
220
221 #[test]
test_packet_invalid_header_length() -> Result<()>222 fn test_packet_invalid_header_length() -> Result<()> {
223 let mut data = Bytes::from_static(&[
224 // Goodbye (offset=84)
225 // v=2, p=0, count=1, BYE, len=100
226 0x81, 0xcb, 0x0, 0x64,
227 ]);
228
229 let result = unmarshal(&mut data);
230 if let Err(got) = result {
231 let want = Error::PacketTooShort;
232 assert_eq!(
233 got, want,
234 "Unmarshal(invalid_header_length) err = {got}, want {want}"
235 );
236 } else {
237 panic!("want error");
238 }
239
240 Ok(())
241 }
242 #[test]
test_packet_unmarshal_firefox() -> Result<()>243 fn test_packet_unmarshal_firefox() -> Result<()> {
244 // issue report from https://github.com/webrtc-rs/srtp/issues/7
245 let tests = vec![
246 Bytes::from_static(&[
247 143, 205, 0, 6, 65, 227, 184, 49, 118, 243, 78, 96, 42, 63, 0, 5, 12, 162, 166, 0,
248 32, 5, 200, 4, 0, 4, 0, 0,
249 ]),
250 Bytes::from_static(&[
251 143, 205, 0, 9, 65, 227, 184, 49, 118, 243, 78, 96, 42, 68, 0, 17, 12, 162, 167, 1,
252 32, 17, 88, 0, 4, 0, 4, 8, 108, 0, 4, 0, 4, 12, 0, 4, 0, 4, 4, 0,
253 ]),
254 Bytes::from_static(&[
255 143, 205, 0, 8, 65, 227, 184, 49, 118, 243, 78, 96, 42, 91, 0, 12, 12, 162, 168, 3,
256 32, 12, 220, 4, 0, 4, 0, 8, 128, 4, 0, 4, 0, 8, 0, 0,
257 ]),
258 Bytes::from_static(&[
259 143, 205, 0, 7, 65, 227, 184, 49, 118, 243, 78, 96, 42, 103, 0, 8, 12, 162, 169, 4,
260 32, 8, 232, 4, 0, 4, 0, 4, 4, 0, 0, 0,
261 ]),
262 ];
263
264 for mut test in tests {
265 unmarshal(&mut test)?;
266 }
267
268 Ok(())
269 }
270 }
271