1use crate::{Packet, header::*, util::*};
2
3use shared::{
4 error::{Error, Result},
5 marshal::{Marshal, MarshalSize, Unmarshal},
6};
7
8use bytes::{Buf, BufMut, Bytes, BytesMut};
9use std::any::Any;
10use std::fmt;
11
12#[derive(Debug, PartialEq, Eq, Default, Clone)]
15pub struct RawPacket(pub Bytes);
16
17impl fmt::Display for RawPacket {
18 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19 write!(f, "RawPacket: {self:?}")
20 }
21}
22
23impl Packet for RawPacket {
24 fn header(&self) -> Header {
26 Header::unmarshal(&mut self.0.clone()).unwrap_or_default()
27 }
28
29 fn destination_ssrc(&self) -> Vec<u32> {
31 vec![]
32 }
33
34 fn raw_size(&self) -> usize {
35 self.0.len()
36 }
37
38 fn as_any(&self) -> &dyn Any {
39 self
40 }
41
42 fn equal(&self, other: &dyn Packet) -> bool {
43 other.as_any().downcast_ref::<RawPacket>() == Some(self)
44 }
45
46 fn cloned(&self) -> Box<dyn Packet> {
47 Box::new(self.clone())
48 }
49}
50
51impl MarshalSize for RawPacket {
52 fn marshal_size(&self) -> usize {
53 let l = self.raw_size();
54 l + get_padding_size(l)
56 }
57}
58
59impl Marshal for RawPacket {
60 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
62 let h = Header::unmarshal(&mut self.0.clone())?;
63 buf.put(self.0.clone());
64 if h.padding {
65 put_padding(buf, self.raw_size());
66 }
67 Ok(self.marshal_size())
68 }
69}
70
71impl Unmarshal for RawPacket {
72 fn unmarshal<B>(raw_packet: &mut B) -> Result<Self>
74 where
75 Self: Sized,
76 B: Buf,
77 {
78 let raw_packet_len = raw_packet.remaining();
79 if raw_packet_len < HEADER_LENGTH {
80 return Err(Error::PacketTooShort);
81 }
82
83 let h = Header::unmarshal(raw_packet)?;
84
85 let raw_hdr = h.marshal()?;
86 let raw_body = raw_packet.copy_to_bytes(raw_packet.remaining());
87 let mut raw = BytesMut::with_capacity(raw_hdr.len() + raw_body.len());
90 raw.extend_from_slice(&raw_hdr);
91 raw.extend_from_slice(&raw_body);
92
93 Ok(RawPacket(raw.freeze()))
94 }
95}
96
97#[cfg(test)]
98mod test {
99 use super::*;
100
101 #[test]
102 fn test_raw_packet_roundtrip() -> Result<()> {
103 let tests: Vec<(&str, RawPacket, Option<Error>)> = vec![
104 (
105 "valid",
106 RawPacket(Bytes::from_static(&[
107 0x81, 0xcb, 0x00, 0x0c, 0x90, 0x2f, 0x9e, 0x2e, 0x03, 0x46, 0x4f, 0x4f, ])),
111 None,
112 ),
113 (
114 "short header",
115 RawPacket(Bytes::from_static(&[0x80])),
116 Some(Error::PacketTooShort),
117 ),
118 (
119 "invalid header",
120 RawPacket(
121 Bytes::from_static(&[0x00, 0xc9, 0x00, 0x04]),
123 ),
124 Some(Error::BadVersion),
125 ),
126 ];
127
128 for (name, pkt, unmarshal_error) in tests {
129 let result = pkt.marshal();
130 assert_eq!(
131 result.is_err(),
132 unmarshal_error.is_some(),
133 "Unmarshal {name}: err = {result:?}, want {unmarshal_error:?}"
134 );
135
136 if result.is_err() {
137 continue;
138 }
139
140 let mut data = result.unwrap();
141
142 let result = RawPacket::unmarshal(&mut data);
143
144 assert_eq!(
145 result.is_err(),
146 unmarshal_error.is_some(),
147 "Unmarshal {name}: err = {result:?}, want {unmarshal_error:?}"
148 );
149
150 if result.is_err() {
151 continue;
152 }
153
154 let decoded = result.unwrap();
155
156 assert_eq!(
157 decoded, pkt,
158 "{name} raw round trip: got {decoded:?}, want {pkt:?}"
159 )
160 }
161
162 Ok(())
163 }
164}