1 use std::fmt; 2 use std::io::{Read, Write}; 3 4 use util::Error; 5 6 use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; 7 8 use super::errors::*; 9 10 #[cfg(test)] 11 mod header_test; 12 13 // PacketType specifies the type of an RTCP packet 14 // RTCP packet types registered with IANA. See: https://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml#rtp-parameters-4 15 16 #[derive(Debug, Copy, Clone, PartialEq)] 17 pub enum PacketType { 18 Unsupported = 0, 19 SenderReport = 200, // RFC 3550, 6.4.1 20 ReceiverReport = 201, // RFC 3550, 6.4.2 21 SourceDescription = 202, // RFC 3550, 6.5 22 Goodbye = 203, // RFC 3550, 6.6 23 ApplicationDefined = 204, // RFC 3550, 6.7 (unimplemented) 24 TransportSpecificFeedback = 205, // RFC 4585, 6051 25 PayloadSpecificFeedback = 206, // RFC 4585, 6.3 26 } 27 28 impl Default for PacketType { 29 fn default() -> Self { 30 PacketType::Unsupported 31 } 32 } 33 34 // Transport and Payload specific feedback messages overload the count field to act as a message type. those are listed here 35 pub const FORMAT_SLI: u8 = 2; 36 pub const FORMAT_PLI: u8 = 1; 37 pub const FORMAT_FIR: u8 = 4; 38 pub const FORMAT_TLN: u8 = 1; 39 pub const FORMAT_RRR: u8 = 5; 40 pub const FORMAT_REMB: u8 = 15; 41 //https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01#page-5 42 pub const FORMAT_TCC: u8 = 15; 43 44 impl fmt::Display for PacketType { 45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 46 let s = match self { 47 PacketType::Unsupported => "Unsupported", 48 PacketType::SenderReport => "SR", 49 PacketType::ReceiverReport => "RR", 50 PacketType::SourceDescription => "SDES", 51 PacketType::Goodbye => "BYE", 52 PacketType::ApplicationDefined => "APP", 53 PacketType::TransportSpecificFeedback => "TSFB", 54 PacketType::PayloadSpecificFeedback => "PSFB", 55 }; 56 write!(f, "{}", s) 57 } 58 } 59 60 impl From<u8> for PacketType { 61 fn from(b: u8) -> Self { 62 match b { 63 200 => PacketType::SenderReport, // RFC 3550, 6.4.1 64 201 => PacketType::ReceiverReport, // RFC 3550, 6.4.2 65 202 => PacketType::SourceDescription, // RFC 3550, 6.5 66 203 => PacketType::Goodbye, // RFC 3550, 6.6 67 204 => PacketType::ApplicationDefined, // RFC 3550, 6.7 (unimplemented) 68 205 => PacketType::TransportSpecificFeedback, // RFC 4585, 6051 69 206 => PacketType::PayloadSpecificFeedback, // RFC 4585, 6.3 70 _ => PacketType::Unsupported, 71 } 72 } 73 } 74 75 const RTP_VERSION: u8 = 2; 76 77 // A Header is the common header shared by all RTCP packets 78 #[derive(Debug, PartialEq, Default, Clone)] 79 pub struct Header { 80 // If the padding bit is set, this individual RTCP packet contains 81 // some additional padding octets at the end which are not part of 82 // the control information but are included in the length field. 83 pub padding: bool, 84 // The number of reception reports, sources contained or FMT in this packet (depending on the Type) 85 pub count: u8, 86 // The RTCP packet type for this packet 87 pub packet_type: PacketType, 88 // The length of this RTCP packet in 32-bit words minus one, 89 // including the header and any padding. 90 pub length: u16, 91 } 92 93 const VERSION_SHIFT: u8 = 6; 94 const VERSION_MASK: u8 = 0x3; 95 const PADDING_SHIFT: u8 = 5; 96 const PADDING_MASK: u8 = 0x1; 97 const COUNT_SHIFT: u8 = 0; 98 const COUNT_MASK: u8 = 0x1f; 99 100 pub const HEADER_LENGTH: usize = 4; 101 pub const COUNT_MAX: usize = (1 << 5) - 1; 102 pub const SSRC_LENGTH: usize = 4; 103 pub const SDES_MAX_OCTET_COUNT: usize = (1 << 8) - 1; 104 105 // Marshal encodes the Header in binary 106 impl Header { 107 pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<(), Error> { 108 /* 109 * 0 1 2 3 110 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 111 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 112 * |V=2|P| RC | PT=SR=200 | length | 113 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 114 */ 115 116 let mut b0 = RTP_VERSION << VERSION_SHIFT; 117 118 if self.padding { 119 b0 |= 1 << PADDING_SHIFT 120 } 121 122 if self.count > 31 { 123 return Err(ERR_INVALID_HEADER.clone()); 124 } 125 b0 |= self.count << COUNT_SHIFT; 126 writer.write_u8(b0)?; 127 128 let b1 = self.packet_type as u8; 129 writer.write_u8(b1)?; 130 131 writer.write_u16::<BigEndian>(self.length)?; 132 133 Ok(()) 134 } 135 136 // Unmarshal decodes the Header from binary 137 pub fn unmarshal<R: Read>(reader: &mut R) -> Result<Self, Error> { 138 /* 139 * 0 1 2 3 140 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 141 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 142 * |V=2|P| RC | PT | length | 143 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 144 */ 145 let b0 = reader.read_u8()?; 146 let version = b0 >> VERSION_SHIFT & VERSION_MASK; 147 if version != RTP_VERSION { 148 return Err(ERR_BAD_VERSION.clone()); 149 } 150 151 let padding = (b0 >> PADDING_SHIFT & PADDING_MASK) > 0; 152 let count = b0 >> COUNT_SHIFT & COUNT_MASK; 153 154 let b1 = reader.read_u8()?; 155 let packet_type: PacketType = b1.into(); 156 if packet_type == PacketType::Unsupported { 157 return Err(ERR_WRONG_TYPE.clone()); 158 } 159 160 let length = reader.read_u16::<BigEndian>()?; 161 162 Ok(Header { 163 padding, 164 // The number of reception reports, sources contained or FMT in this packet (depending on the Type) 165 count, 166 // The RTCP packet type for this packet 167 packet_type, 168 // The length of this RTCP packet in 32-bit words minus one, 169 // including the header and any padding. 170 length, 171 }) 172 } 173 } 174