From 26cb2783bc4b55411cbe3ca41ed7f87e135ca7f7 Mon Sep 17 00:00:00 2001 From: Takeru Ohta Date: Sun, 26 Mar 2017 02:13:56 -0700 Subject: [PATCH] Add `supports_type` trait method --- src/rfc3550/rtcp.rs | 43 +++++++++++++++++++++++++++++++++++++------ src/rfc3550/rtp.rs | 6 +++++- src/rfc4585.rs | 28 +++++++++++++++++++++++++--- src/rfc5761.rs | 21 ++++++++++----------- src/traits.rs | 9 +++++++-- 5 files changed, 84 insertions(+), 23 deletions(-) diff --git a/src/rfc3550/rtcp.rs b/src/rfc3550/rtcp.rs index 7d5f5ff..1f591c4 100644 --- a/src/rfc3550/rtcp.rs +++ b/src/rfc3550/rtcp.rs @@ -33,7 +33,18 @@ pub enum RtcpPacket { App(RtcpApplicationDefined), } impl Packet for RtcpPacket {} -impl traits::RtcpPacket for RtcpPacket {} +impl traits::RtcpPacket for RtcpPacket { + fn supports_type(ty: u8) -> bool { + match ty { + RTCP_PACKET_TYPE_SR | + RTCP_PACKET_TYPE_RR | + RTCP_PACKET_TYPE_SDES | + RTCP_PACKET_TYPE_BYE | + RTCP_PACKET_TYPE_APP => true, + _ => false, + } + } +} impl ReadFrom for RtcpPacket { fn read_from(reader: &mut R) -> Result { let mut buf = [0; 2]; @@ -175,7 +186,11 @@ impl RtcpSenderReport { } } impl Packet for RtcpSenderReport {} -impl traits::RtcpPacket for RtcpSenderReport {} +impl traits::RtcpPacket for RtcpSenderReport { + fn supports_type(ty: u8) -> bool { + ty == RTCP_PACKET_TYPE_SR + } +} impl ReadFrom for RtcpSenderReport { fn read_from(reader: &mut R) -> Result { let (reception_report_count, payload) = track_try!(read_sctp(reader, RTCP_PACKET_TYPE_SR)); @@ -305,7 +320,11 @@ impl RtcpReceiverReport { } } impl Packet for RtcpReceiverReport {} -impl traits::RtcpPacket for RtcpReceiverReport {} +impl traits::RtcpPacket for RtcpReceiverReport { + fn supports_type(ty: u8) -> bool { + ty == RTCP_PACKET_TYPE_RR + } +} impl ReadFrom for RtcpReceiverReport { fn read_from(reader: &mut R) -> Result { let (reception_report_count, payload) = track_try!(read_sctp(reader, RTCP_PACKET_TYPE_RR)); @@ -356,7 +375,11 @@ impl RtcpSourceDescription { } } impl Packet for RtcpSourceDescription {} -impl traits::RtcpPacket for RtcpSourceDescription {} +impl traits::RtcpPacket for RtcpSourceDescription { + fn supports_type(ty: u8) -> bool { + ty == RTCP_PACKET_TYPE_SDES + } +} impl ReadFrom for RtcpSourceDescription { fn read_from(reader: &mut R) -> Result { let (source_count, payload) = track_try!(read_sctp(reader, RTCP_PACKET_TYPE_SDES)); @@ -507,7 +530,11 @@ impl RtcpGoodbye { } } impl Packet for RtcpGoodbye {} -impl traits::RtcpPacket for RtcpGoodbye {} +impl traits::RtcpPacket for RtcpGoodbye { + fn supports_type(ty: u8) -> bool { + ty == RTCP_PACKET_TYPE_BYE + } +} impl ReadFrom for RtcpGoodbye { fn read_from(reader: &mut R) -> Result { let (source_count, payload) = track_try!(read_sctp(reader, RTCP_PACKET_TYPE_BYE)); @@ -558,7 +585,11 @@ pub struct RtcpApplicationDefined { pub data: Vec, } impl Packet for RtcpApplicationDefined {} -impl traits::RtcpPacket for RtcpApplicationDefined {} +impl traits::RtcpPacket for RtcpApplicationDefined { + fn supports_type(ty: u8) -> bool { + ty == RTCP_PACKET_TYPE_APP + } +} impl ReadFrom for RtcpApplicationDefined { fn read_from(reader: &mut R) -> Result { let (subtype, payload) = track_try!(read_sctp(reader, RTCP_PACKET_TYPE_APP)); diff --git a/src/rfc3550/rtp.rs b/src/rfc3550/rtp.rs index 9376d36..01c18cb 100644 --- a/src/rfc3550/rtp.rs +++ b/src/rfc3550/rtp.rs @@ -15,7 +15,11 @@ pub struct RtpPacket { pub padding: Vec, } impl Packet for RtpPacket {} -impl traits::RtpPacket for RtpPacket {} +impl traits::RtpPacket for RtpPacket { + fn supports_type(_ty: U7) -> bool { + true + } +} impl ReadFrom for RtpPacket { fn read_from(reader: &mut R) -> Result { let header = track_try!(RtpFixedHeader::read_from(reader)); diff --git a/src/rfc4585.rs b/src/rfc4585.rs index ef5d90c..4c9a37c 100644 --- a/src/rfc4585.rs +++ b/src/rfc4585.rs @@ -30,7 +30,20 @@ pub enum RtcpPacket { Psfb(RtcpPayloadSpecificFeedback), } impl Packet for RtcpPacket {} -impl traits::RtcpPacket for RtcpPacket {} +impl traits::RtcpPacket for RtcpPacket { + fn supports_type(ty: u8) -> bool { + match ty { + rfc3550::RTCP_PACKET_TYPE_SR | + rfc3550::RTCP_PACKET_TYPE_RR | + rfc3550::RTCP_PACKET_TYPE_SDES | + rfc3550::RTCP_PACKET_TYPE_BYE | + rfc3550::RTCP_PACKET_TYPE_APP | + RTCP_PACKET_TYPE_RTPFB | + RTCP_PACKET_TYPE_PSFB => true, + _ => false, + } + } +} impl ReadFrom for RtcpPacket { fn read_from(reader: &mut R) -> Result { let mut buf = [0; 2]; @@ -61,6 +74,7 @@ impl ReadFrom for RtcpPacket { track_err!(RtcpPayloadSpecificFeedback::read_from(reader).map(From::from)) } _ => { + track_assert_eq!(buf[0] >> 6, RTP_VERSION, ErrorKind::Invalid); track_panic!(ErrorKind::Unsupported, "Unknown packet type: {}", packet_type) @@ -122,7 +136,11 @@ pub enum RtcpTransportLayerFeedback { Nack(GenericNack), } impl Packet for RtcpTransportLayerFeedback {} -impl traits::RtcpPacket for RtcpTransportLayerFeedback {} +impl traits::RtcpPacket for RtcpTransportLayerFeedback { + fn supports_type(ty: u8) -> bool { + ty == RTCP_PACKET_TYPE_RTPFB + } +} impl ReadFrom for RtcpTransportLayerFeedback { fn read_from(reader: &mut R) -> Result { let (fb_message_type, rest) = track_try!(read_common(reader, RTCP_PACKET_TYPE_RTPFB)); @@ -165,7 +183,11 @@ pub enum RtcpPayloadSpecificFeedback { Afb(ApplicationLayerFeedback), } impl Packet for RtcpPayloadSpecificFeedback {} -impl traits::RtcpPacket for RtcpPayloadSpecificFeedback {} +impl traits::RtcpPacket for RtcpPayloadSpecificFeedback { + fn supports_type(ty: u8) -> bool { + ty == RTCP_PACKET_TYPE_RTPFB + } +} impl ReadFrom for RtcpPayloadSpecificFeedback { fn read_from(reader: &mut R) -> Result { let (fb_message_type, rest) = track_try!(read_common(reader, RTCP_PACKET_TYPE_PSFB)); diff --git a/src/rfc5761.rs b/src/rfc5761.rs index 71ffe01..f5f639a 100644 --- a/src/rfc5761.rs +++ b/src/rfc5761.rs @@ -22,13 +22,18 @@ impl ReadFrom for MuxedPacket fn read_from(reader: &mut R) -> Result { let mut buf = [0; 2]; track_try!(reader.read_exact(&mut buf)); - let marker = (buf[1] & 0b1000_0000) != 0; - if !marker { + + let ty = buf[1]; + if U::supports_type(ty) { + let reader = &mut (&buf[..]).chain(reader); + track_err!(U::read_from(reader).map(MuxedPacket::Rtcp)) + } else if T::supports_type(ty & 0b0111_1111) { let reader = &mut (&buf[..]).chain(reader); track_err!(T::read_from(reader).map(MuxedPacket::Rtp)) } else { - let reader = &mut (&buf[..]).chain(reader); - track_err!(U::read_from(reader).map(MuxedPacket::Rtcp)) + track_panic!(ErrorKind::Unsupported, + "Unknown packet/payload type: {}", + ty) } } } @@ -38,13 +43,7 @@ impl WriteTo for MuxedPacket { fn write_to(&self, writer: &mut W) -> Result<()> { match *self { - MuxedPacket::Rtp(ref p) => { - let mut buf = Vec::new(); - track_try!(p.write_to(&mut buf)); - track_assert!(buf.len() >= 2, ErrorKind::Other); - buf[1] &= 0b0111_1111; - track_try!(writer.write_all(&buf)); - } + MuxedPacket::Rtp(ref p) => track_try!(p.write_to(writer)), MuxedPacket::Rtcp(ref p) => track_try!(p.write_to(writer)), } Ok(()) diff --git a/src/traits.rs b/src/traits.rs index 270d366..ed3e2fd 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -1,4 +1,9 @@ use packet::Packet; +use types::U7; -pub trait RtpPacket: Packet {} -pub trait RtcpPacket: Packet {} +pub trait RtpPacket: Packet { + fn supports_type(payload_type: U7) -> bool; +} +pub trait RtcpPacket: Packet { + fn supports_type(packet_type: u8) -> bool; +}