1 #[cfg(test)] 2 mod goodbye_test; 3 4 use crate::{error::Error, header::*, packet::*, util::*}; 5 use util::marshal::{Marshal, MarshalSize, Unmarshal}; 6 7 use bytes::{Buf, BufMut, Bytes}; 8 use std::any::Any; 9 use std::fmt; 10 11 type Result<T> = std::result::Result<T, util::Error>; 12 13 /// The Goodbye packet indicates that one or more sources are no longer active. 14 #[derive(Debug, PartialEq, Eq, Default, Clone)] 15 pub struct Goodbye { 16 /// The SSRC/CSRC identifiers that are no longer active 17 pub sources: Vec<u32>, 18 /// Optional text indicating the reason for leaving, e.g., "camera malfunction" or "RTP loop detected" 19 pub reason: Bytes, 20 } 21 22 impl fmt::Display for Goodbye { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result23 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 24 let mut out = "Goodbye:\n\tSources:\n".to_string(); 25 for s in &self.sources { 26 out += format!("\t{}\n", *s).as_str(); 27 } 28 out += format!("\tReason: {:?}\n", self.reason).as_str(); 29 30 write!(f, "{out}") 31 } 32 } 33 34 impl Packet for Goodbye { 35 /// Header returns the Header associated with this packet. header(&self) -> Header36 fn header(&self) -> Header { 37 Header { 38 padding: get_padding_size(self.raw_size()) != 0, 39 count: self.sources.len() as u8, 40 packet_type: PacketType::Goodbye, 41 length: ((self.marshal_size() / 4) - 1) as u16, 42 } 43 } 44 45 /// destination_ssrc returns an array of SSRC values that this packet refers to. destination_ssrc(&self) -> Vec<u32>46 fn destination_ssrc(&self) -> Vec<u32> { 47 self.sources.to_vec() 48 } 49 raw_size(&self) -> usize50 fn raw_size(&self) -> usize { 51 let srcs_length = self.sources.len() * SSRC_LENGTH; 52 let reason_length = self.reason.len() + 1; 53 54 HEADER_LENGTH + srcs_length + reason_length 55 } 56 as_any(&self) -> &(dyn Any + Send + Sync)57 fn as_any(&self) -> &(dyn Any + Send + Sync) { 58 self 59 } 60 equal(&self, other: &(dyn Packet + Send + Sync)) -> bool61 fn equal(&self, other: &(dyn Packet + Send + Sync)) -> bool { 62 other 63 .as_any() 64 .downcast_ref::<Goodbye>() 65 .map_or(false, |a| self == a) 66 } 67 cloned(&self) -> Box<dyn Packet + Send + Sync>68 fn cloned(&self) -> Box<dyn Packet + Send + Sync> { 69 Box::new(self.clone()) 70 } 71 } 72 73 impl MarshalSize for Goodbye { marshal_size(&self) -> usize74 fn marshal_size(&self) -> usize { 75 let l = self.raw_size(); 76 // align to 32-bit boundary 77 l + get_padding_size(l) 78 } 79 } 80 81 impl Marshal for Goodbye { 82 /// marshal_to encodes the packet in binary. marshal_to(&self, mut buf: &mut [u8]) -> Result<usize>83 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> { 84 if self.sources.len() > COUNT_MAX { 85 return Err(Error::TooManySources.into()); 86 } 87 88 if self.reason.len() > SDES_MAX_OCTET_COUNT { 89 return Err(Error::ReasonTooLong.into()); 90 } 91 92 if buf.remaining_mut() < self.marshal_size() { 93 return Err(Error::BufferTooShort.into()); 94 } 95 96 /* 97 * 0 1 2 3 98 * 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 99 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 100 * |V=2|P| SC | PT=BYE=203 | length | 101 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 102 * | SSRC/CSRC | 103 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 104 * : ... : 105 * +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 106 * (opt) | length | reason for leaving ... 107 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 108 */ 109 110 let h = self.header(); 111 let n = h.marshal_to(buf)?; 112 buf = &mut buf[n..]; 113 114 for source in &self.sources { 115 buf.put_u32(*source); 116 } 117 118 buf.put_u8(self.reason.len() as u8); 119 if !self.reason.is_empty() { 120 buf.put(self.reason.clone()); 121 } 122 123 if h.padding { 124 put_padding(buf, self.raw_size()); 125 } 126 127 Ok(self.marshal_size()) 128 } 129 } 130 131 impl Unmarshal for Goodbye { unmarshal<B>(raw_packet: &mut B) -> Result<Self> where Self: Sized, B: Buf,132 fn unmarshal<B>(raw_packet: &mut B) -> Result<Self> 133 where 134 Self: Sized, 135 B: Buf, 136 { 137 /* 138 * 0 1 2 3 139 * 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 140 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 141 * |V=2|P| SC | PT=BYE=203 | length | 142 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 143 * | SSRC/CSRC | 144 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 145 * : ... : 146 * +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 147 * (opt) | length | reason for leaving ... 148 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 149 */ 150 let raw_packet_len = raw_packet.remaining(); 151 152 let header = Header::unmarshal(raw_packet)?; 153 if header.packet_type != PacketType::Goodbye { 154 return Err(Error::WrongType.into()); 155 } 156 157 if get_padding_size(raw_packet_len) != 0 { 158 return Err(Error::PacketTooShort.into()); 159 } 160 161 let reason_offset = HEADER_LENGTH + header.count as usize * SSRC_LENGTH; 162 163 if reason_offset > raw_packet_len { 164 return Err(Error::PacketTooShort.into()); 165 } 166 167 let mut sources = Vec::with_capacity(header.count as usize); 168 for _ in 0..header.count { 169 sources.push(raw_packet.get_u32()); 170 } 171 172 let reason = if reason_offset < raw_packet_len { 173 let reason_len = raw_packet.get_u8() as usize; 174 let reason_end = reason_offset + 1 + reason_len; 175 176 if reason_end > raw_packet_len { 177 return Err(Error::PacketTooShort.into()); 178 } 179 180 raw_packet.copy_to_bytes(reason_len) 181 } else { 182 Bytes::new() 183 }; 184 185 if 186 /*header.padding &&*/ 187 raw_packet.has_remaining() { 188 raw_packet.advance(raw_packet.remaining()); 189 } 190 191 Ok(Goodbye { sources, reason }) 192 } 193 } 194