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