1 use super::errors::RtcpError; 2 use super::rtcp_header::RtcpHeader; 3 use crate::rtp::utils::Marshal; 4 use crate::rtp::utils::Unmarshal; 5 use byteorder::BigEndian; 6 use bytes::BytesMut; 7 use bytesio::bytes_reader::BytesReader; 8 use bytesio::bytes_writer::BytesWriter; 9 // 0 1 2 3 10 // 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 11 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 12 // |V=2|P| SC | PT=BYE=203 | length | 13 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 14 // | SSRC/CSRC | 15 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 16 // : ... : 17 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 18 // (opt) | length | reason for leaving ... 19 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 20 21 #[derive(Debug, Clone, Default)] 22 pub struct RtcpBye { 23 pub header: RtcpHeader, 24 pub ssrss: Vec<u32>, 25 pub length: u8, 26 pub reason: BytesMut, 27 } 28 29 impl Unmarshal<BytesMut, Result<Self, RtcpError>> for RtcpBye { unmarshal(data: BytesMut) -> Result<Self, RtcpError> where Self: Sized,30 fn unmarshal(data: BytesMut) -> Result<Self, RtcpError> 31 where 32 Self: Sized, 33 { 34 let mut reader = BytesReader::new(data); 35 36 let mut rtcp_bye = RtcpBye { 37 header: RtcpHeader::unmarshal(&mut reader)?, 38 ..Default::default() 39 }; 40 41 for _ in 0..rtcp_bye.header.report_count { 42 let ssrc = reader.read_u32::<BigEndian>()?; 43 rtcp_bye.ssrss.push(ssrc); 44 } 45 46 rtcp_bye.length = reader.read_u8()?; 47 rtcp_bye.reason = reader.read_bytes(rtcp_bye.length as usize)?; 48 49 Ok(rtcp_bye) 50 } 51 } 52 53 impl Marshal<Result<BytesMut, RtcpError>> for RtcpBye { marshal(&self) -> Result<BytesMut, RtcpError>54 fn marshal(&self) -> Result<BytesMut, RtcpError> { 55 let mut writer = BytesWriter::default(); 56 57 let header_bytesmut = self.header.marshal()?; 58 writer.write(&header_bytesmut[..])?; 59 60 for ssrc in &self.ssrss { 61 writer.write_u32::<BigEndian>(*ssrc)?; 62 } 63 64 writer.write_u8(self.length)?; 65 writer.write(&self.reason[..])?; 66 67 Ok(writer.extract_current_bytes()) 68 } 69 } 70