1#[cfg(test)]
2mod packet_test;
3
4use std::fmt;
5
6use bytes::{Buf, BufMut, Bytes};
7use util::marshal::{Marshal, MarshalSize, Unmarshal};
8
9use crate::error::Error;
10use crate::header::*;
11
12#[derive(Debug, Eq, PartialEq, Default, Clone)]
15pub struct Packet {
16 pub header: Header,
17 pub payload: Bytes,
18}
19
20impl fmt::Display for Packet {
21 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22 let mut out = "RTP PACKET:\n".to_string();
23
24 out += format!("\tVersion: {}\n", self.header.version).as_str();
25 out += format!("\tMarker: {}\n", self.header.marker).as_str();
26 out += format!("\tPayload Type: {}\n", self.header.payload_type).as_str();
27 out += format!("\tSequence Number: {}\n", self.header.sequence_number).as_str();
28 out += format!("\tTimestamp: {}\n", self.header.timestamp).as_str();
29 out += format!("\tSSRC: {} ({:x})\n", self.header.ssrc, self.header.ssrc).as_str();
30 out += format!("\tPayload Length: {}\n", self.payload.len()).as_str();
31
32 write!(f, "{out}")
33 }
34}
35
36impl Unmarshal for Packet {
37 fn unmarshal<B>(raw_packet: &mut B) -> Result<Self, util::Error>
39 where
40 Self: Sized,
41 B: Buf,
42 {
43 let header = Header::unmarshal(raw_packet)?;
44 let payload_len = raw_packet.remaining();
45 let payload = raw_packet.copy_to_bytes(payload_len);
46 if header.padding {
47 if payload_len > 0 {
48 let padding_len = payload[payload_len - 1] as usize;
49 if padding_len <= payload_len {
50 Ok(Packet {
51 header,
52 payload: payload.slice(..payload_len - padding_len),
53 })
54 } else {
55 Err(Error::ErrShortPacket.into())
56 }
57 } else {
58 Err(Error::ErrShortPacket.into())
59 }
60 } else {
61 Ok(Packet { header, payload })
62 }
63 }
64}
65
66impl MarshalSize for Packet {
67 fn marshal_size(&self) -> usize {
69 let payload_len = self.payload.len();
70 let padding_len = if self.header.padding {
71 let padding_len = get_padding(payload_len);
72 if padding_len == 0 {
73 4
74 } else {
75 padding_len
76 }
77 } else {
78 0
79 };
80 self.header.marshal_size() + payload_len + padding_len
81 }
82}
83
84impl Marshal for Packet {
85 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize, util::Error> {
87 if buf.remaining_mut() < self.marshal_size() {
88 return Err(Error::ErrBufferTooSmall.into());
89 }
90
91 let n = self.header.marshal_to(buf)?;
92 buf = &mut buf[n..];
93 buf.put(&*self.payload);
94 let padding_len = if self.header.padding {
95 let mut padding_len = get_padding(self.payload.len());
96 if padding_len == 0 {
97 padding_len = 4;
98 }
99 for i in 0..padding_len {
100 if i != padding_len - 1 {
101 buf.put_u8(0);
102 } else {
103 buf.put_u8(padding_len as u8);
104 }
105 }
106 padding_len
107 } else {
108 0
109 };
110
111 Ok(n + self.payload.len() + padding_len)
112 }
113}
114
115fn get_padding(len: usize) -> usize {
117 if len % 4 == 0 {
118 0
119 } else {
120 4 - (len % 4)
121 }
122}