Add `ReadPacket` and `WritePacket` traits
parent
26cb2783bc
commit
77ad3db255
|
@ -1,13 +1,14 @@
|
|||
#[macro_use]
|
||||
extern crate trackable;
|
||||
extern crate handy_async;
|
||||
extern crate crypto;
|
||||
|
||||
pub use error::{Error, ErrorKind};
|
||||
|
||||
pub mod io;
|
||||
pub mod packet;
|
||||
pub mod traits;
|
||||
pub mod rfc3550;
|
||||
pub mod rfc3711;
|
||||
pub mod rfc4585;
|
||||
pub mod rfc5761;
|
||||
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
use io::{ReadFrom, WriteTo};
|
||||
|
||||
pub trait Packet: ReadFrom + WriteTo {}
|
|
@ -3,8 +3,7 @@ use handy_async::sync_io::{ReadExt, WriteExt};
|
|||
|
||||
use {Result, ErrorKind};
|
||||
use io::{ReadFrom, WriteTo};
|
||||
use packet::Packet;
|
||||
use traits;
|
||||
use traits::{self, Packet};
|
||||
use types::{U5, U24, RtpTimestamp, NtpTimestamp, NtpMiddleTimetamp, Ssrc, SsrcOrCsrc};
|
||||
use constants::RTP_VERSION;
|
||||
|
||||
|
@ -25,16 +24,13 @@ pub const SDES_ITEM_TYPE_NOTE: u8 = 7;
|
|||
pub const SDES_ITEM_TYPE_PRIV: u8 = 8;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum RtcpPacket {
|
||||
Sr(RtcpSenderReport),
|
||||
Rr(RtcpReceiverReport),
|
||||
Sdes(RtcpSourceDescription),
|
||||
Bye(RtcpGoodbye),
|
||||
App(RtcpApplicationDefined),
|
||||
}
|
||||
impl Packet for RtcpPacket {}
|
||||
impl traits::RtcpPacket for RtcpPacket {
|
||||
fn supports_type(ty: u8) -> bool {
|
||||
pub struct RtcpPacketReader;
|
||||
impl traits::ReadPacket for RtcpPacketReader {
|
||||
type Packet = RtcpPacket;
|
||||
fn read_packet<R: Read>(&mut self, reader: &mut R) -> Result<Self::Packet> {
|
||||
RtcpPacket::read_from(reader)
|
||||
}
|
||||
fn supports_type(&self, ty: u8) -> bool {
|
||||
match ty {
|
||||
RTCP_PACKET_TYPE_SR |
|
||||
RTCP_PACKET_TYPE_RR |
|
||||
|
@ -45,6 +41,26 @@ impl traits::RtcpPacket for RtcpPacket {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct RtcpPacketWriter;
|
||||
impl traits::WritePacket for RtcpPacketWriter {
|
||||
type Packet = RtcpPacket;
|
||||
fn write_packet<W: Write>(&mut self, writer: &mut W, packet: &Self::Packet) -> Result<()> {
|
||||
packet.write_to(writer)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum RtcpPacket {
|
||||
Sr(RtcpSenderReport),
|
||||
Rr(RtcpReceiverReport),
|
||||
Sdes(RtcpSourceDescription),
|
||||
Bye(RtcpGoodbye),
|
||||
App(RtcpApplicationDefined),
|
||||
}
|
||||
impl Packet for RtcpPacket {}
|
||||
impl traits::RtcpPacket for RtcpPacket {}
|
||||
impl ReadFrom for RtcpPacket {
|
||||
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
||||
let mut buf = [0; 2];
|
||||
|
@ -186,11 +202,7 @@ impl RtcpSenderReport {
|
|||
}
|
||||
}
|
||||
impl Packet for RtcpSenderReport {}
|
||||
impl traits::RtcpPacket for RtcpSenderReport {
|
||||
fn supports_type(ty: u8) -> bool {
|
||||
ty == RTCP_PACKET_TYPE_SR
|
||||
}
|
||||
}
|
||||
impl traits::RtcpPacket for RtcpSenderReport {}
|
||||
impl ReadFrom for RtcpSenderReport {
|
||||
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
||||
let (reception_report_count, payload) = track_try!(read_sctp(reader, RTCP_PACKET_TYPE_SR));
|
||||
|
@ -320,11 +332,7 @@ impl RtcpReceiverReport {
|
|||
}
|
||||
}
|
||||
impl Packet for RtcpReceiverReport {}
|
||||
impl traits::RtcpPacket for RtcpReceiverReport {
|
||||
fn supports_type(ty: u8) -> bool {
|
||||
ty == RTCP_PACKET_TYPE_RR
|
||||
}
|
||||
}
|
||||
impl traits::RtcpPacket for RtcpReceiverReport {}
|
||||
impl ReadFrom for RtcpReceiverReport {
|
||||
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
||||
let (reception_report_count, payload) = track_try!(read_sctp(reader, RTCP_PACKET_TYPE_RR));
|
||||
|
@ -375,11 +383,7 @@ impl RtcpSourceDescription {
|
|||
}
|
||||
}
|
||||
impl Packet for RtcpSourceDescription {}
|
||||
impl traits::RtcpPacket for RtcpSourceDescription {
|
||||
fn supports_type(ty: u8) -> bool {
|
||||
ty == RTCP_PACKET_TYPE_SDES
|
||||
}
|
||||
}
|
||||
impl traits::RtcpPacket for RtcpSourceDescription {}
|
||||
impl ReadFrom for RtcpSourceDescription {
|
||||
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
||||
let (source_count, payload) = track_try!(read_sctp(reader, RTCP_PACKET_TYPE_SDES));
|
||||
|
@ -530,11 +534,7 @@ impl RtcpGoodbye {
|
|||
}
|
||||
}
|
||||
impl Packet for RtcpGoodbye {}
|
||||
impl traits::RtcpPacket for RtcpGoodbye {
|
||||
fn supports_type(ty: u8) -> bool {
|
||||
ty == RTCP_PACKET_TYPE_BYE
|
||||
}
|
||||
}
|
||||
impl traits::RtcpPacket for RtcpGoodbye {}
|
||||
impl ReadFrom for RtcpGoodbye {
|
||||
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
||||
let (source_count, payload) = track_try!(read_sctp(reader, RTCP_PACKET_TYPE_BYE));
|
||||
|
@ -585,11 +585,7 @@ pub struct RtcpApplicationDefined {
|
|||
pub data: Vec<u8>,
|
||||
}
|
||||
impl Packet for RtcpApplicationDefined {}
|
||||
impl traits::RtcpPacket for RtcpApplicationDefined {
|
||||
fn supports_type(ty: u8) -> bool {
|
||||
ty == RTCP_PACKET_TYPE_APP
|
||||
}
|
||||
}
|
||||
impl traits::RtcpPacket for RtcpApplicationDefined {}
|
||||
impl ReadFrom for RtcpApplicationDefined {
|
||||
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
||||
let (subtype, payload) = track_try!(read_sctp(reader, RTCP_PACKET_TYPE_APP));
|
||||
|
|
|
@ -3,11 +3,31 @@ use handy_async::sync_io::{ReadExt, WriteExt};
|
|||
|
||||
use {Result, ErrorKind};
|
||||
use io::{ReadFrom, WriteTo};
|
||||
use packet::Packet;
|
||||
use traits;
|
||||
use traits::{self, Packet};
|
||||
use types::{U7, RtpTimestamp, Ssrc, Csrc};
|
||||
use constants::RTP_VERSION;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct RtpPacketReader;
|
||||
impl traits::ReadPacket for RtpPacketReader {
|
||||
type Packet = RtpPacket;
|
||||
fn read_packet<R: Read>(&mut self, reader: &mut R) -> Result<Self::Packet> {
|
||||
RtpPacket::read_from(reader)
|
||||
}
|
||||
fn supports_type(&self, _ty: u8) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct RtpPacketWriter;
|
||||
impl traits::WritePacket for RtpPacketWriter {
|
||||
type Packet = RtpPacket;
|
||||
fn write_packet<W: Write>(&mut self, writer: &mut W, packet: &Self::Packet) -> Result<()> {
|
||||
packet.write_to(writer)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct RtpPacket {
|
||||
pub header: RtpFixedHeader,
|
||||
|
@ -15,11 +35,7 @@ pub struct RtpPacket {
|
|||
pub padding: Vec<u8>,
|
||||
}
|
||||
impl Packet for RtpPacket {}
|
||||
impl traits::RtpPacket for RtpPacket {
|
||||
fn supports_type(_ty: U7) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
impl traits::RtpPacket for RtpPacket {}
|
||||
impl ReadFrom for RtpPacket {
|
||||
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
||||
let header = track_try!(RtpFixedHeader::read_from(reader));
|
||||
|
|
|
@ -3,8 +3,7 @@ use handy_async::sync_io::{ReadExt, WriteExt};
|
|||
|
||||
use {Result, ErrorKind};
|
||||
use io::{ReadFrom, WriteTo};
|
||||
use packet::Packet;
|
||||
use traits;
|
||||
use traits::{self, Packet};
|
||||
use types::{U5, U6, U7, U13, Ssrc};
|
||||
use constants::RTP_VERSION;
|
||||
use rfc3550;
|
||||
|
@ -20,18 +19,13 @@ pub const PSFB_MESSAGE_TYPE_RPSI: u8 = 3;
|
|||
pub const PSFB_MESSAGE_TYPE_AFB: u8 = 15;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum RtcpPacket {
|
||||
Sr(rfc3550::RtcpSenderReport),
|
||||
Rr(rfc3550::RtcpReceiverReport),
|
||||
Sdes(rfc3550::RtcpSourceDescription),
|
||||
Bye(rfc3550::RtcpGoodbye),
|
||||
App(rfc3550::RtcpApplicationDefined),
|
||||
Rtpfb(RtcpTransportLayerFeedback),
|
||||
Psfb(RtcpPayloadSpecificFeedback),
|
||||
}
|
||||
impl Packet for RtcpPacket {}
|
||||
impl traits::RtcpPacket for RtcpPacket {
|
||||
fn supports_type(ty: u8) -> bool {
|
||||
pub struct RtcpPacketReader;
|
||||
impl traits::ReadPacket for RtcpPacketReader {
|
||||
type Packet = RtcpPacket;
|
||||
fn read_packet<R: Read>(&mut self, reader: &mut R) -> Result<Self::Packet> {
|
||||
RtcpPacket::read_from(reader)
|
||||
}
|
||||
fn supports_type(&self, ty: u8) -> bool {
|
||||
match ty {
|
||||
rfc3550::RTCP_PACKET_TYPE_SR |
|
||||
rfc3550::RTCP_PACKET_TYPE_RR |
|
||||
|
@ -44,6 +38,28 @@ impl traits::RtcpPacket for RtcpPacket {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct RtcpPacketWriter;
|
||||
impl traits::WritePacket for RtcpPacketWriter {
|
||||
type Packet = RtcpPacket;
|
||||
fn write_packet<W: Write>(&mut self, writer: &mut W, packet: &Self::Packet) -> Result<()> {
|
||||
packet.write_to(writer)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum RtcpPacket {
|
||||
Sr(rfc3550::RtcpSenderReport),
|
||||
Rr(rfc3550::RtcpReceiverReport),
|
||||
Sdes(rfc3550::RtcpSourceDescription),
|
||||
Bye(rfc3550::RtcpGoodbye),
|
||||
App(rfc3550::RtcpApplicationDefined),
|
||||
Rtpfb(RtcpTransportLayerFeedback),
|
||||
Psfb(RtcpPayloadSpecificFeedback),
|
||||
}
|
||||
impl Packet for RtcpPacket {}
|
||||
impl traits::RtcpPacket for RtcpPacket {}
|
||||
impl ReadFrom for RtcpPacket {
|
||||
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
||||
let mut buf = [0; 2];
|
||||
|
@ -136,11 +152,7 @@ pub enum RtcpTransportLayerFeedback {
|
|||
Nack(GenericNack),
|
||||
}
|
||||
impl Packet for RtcpTransportLayerFeedback {}
|
||||
impl traits::RtcpPacket for RtcpTransportLayerFeedback {
|
||||
fn supports_type(ty: u8) -> bool {
|
||||
ty == RTCP_PACKET_TYPE_RTPFB
|
||||
}
|
||||
}
|
||||
impl traits::RtcpPacket for RtcpTransportLayerFeedback {}
|
||||
impl ReadFrom for RtcpTransportLayerFeedback {
|
||||
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
||||
let (fb_message_type, rest) = track_try!(read_common(reader, RTCP_PACKET_TYPE_RTPFB));
|
||||
|
@ -183,11 +195,7 @@ pub enum RtcpPayloadSpecificFeedback {
|
|||
Afb(ApplicationLayerFeedback),
|
||||
}
|
||||
impl Packet for RtcpPayloadSpecificFeedback {}
|
||||
impl traits::RtcpPacket for RtcpPayloadSpecificFeedback {
|
||||
fn supports_type(ty: u8) -> bool {
|
||||
ty == RTCP_PACKET_TYPE_RTPFB
|
||||
}
|
||||
}
|
||||
impl traits::RtcpPacket for RtcpPayloadSpecificFeedback {}
|
||||
impl ReadFrom for RtcpPayloadSpecificFeedback {
|
||||
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
||||
let (fb_message_type, rest) = track_try!(read_common(reader, RTCP_PACKET_TYPE_PSFB));
|
||||
|
|
116
src/rfc5761.rs
116
src/rfc5761.rs
|
@ -1,9 +1,83 @@
|
|||
use std::io::{Read, Write};
|
||||
|
||||
use {Result, ErrorKind};
|
||||
use io::{ReadFrom, WriteTo};
|
||||
use traits::{RtpPacket, RtcpPacket};
|
||||
use packet::Packet;
|
||||
use {Result};
|
||||
use traits::{ReadPacket, WritePacket, RtpPacket, RtcpPacket, Packet};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct MuxPacketReader<T, U> {
|
||||
rtp_reader: T,
|
||||
rtcp_reader: U,
|
||||
}
|
||||
impl<T, U> MuxPacketReader<T, U>
|
||||
where T: ReadPacket,
|
||||
T::Packet: RtpPacket,
|
||||
U: ReadPacket,
|
||||
U::Packet: RtcpPacket
|
||||
{
|
||||
pub fn new(rtp_reader: T, rtcp_reader: U) -> Self {
|
||||
MuxPacketReader {
|
||||
rtp_reader: rtp_reader,
|
||||
rtcp_reader: rtcp_reader,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<T, U> ReadPacket for MuxPacketReader<T, U>
|
||||
where T: ReadPacket,
|
||||
T::Packet: RtpPacket,
|
||||
U: ReadPacket,
|
||||
U::Packet: RtcpPacket
|
||||
{
|
||||
type Packet = MuxedPacket<T::Packet, U::Packet>;
|
||||
fn read_packet<R: Read>(&mut self, reader: &mut R) -> Result<Self::Packet> {
|
||||
let mut buf = [0; 2];
|
||||
track_try!(reader.read_exact(&mut buf));
|
||||
|
||||
let ty = buf[1];
|
||||
if self.rtcp_reader.supports_type(ty) {
|
||||
let reader = &mut (&buf[..]).chain(reader);
|
||||
track_err!(self.rtcp_reader.read_packet(reader).map(MuxedPacket::Rtcp))
|
||||
} else {
|
||||
let reader = &mut (&buf[..]).chain(reader);
|
||||
track_err!(self.rtp_reader.read_packet(reader).map(MuxedPacket::Rtp))
|
||||
}
|
||||
}
|
||||
fn supports_type(&self, ty: u8) -> bool {
|
||||
self.rtp_reader.supports_type(ty) || self.rtcp_reader.supports_type(ty)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct MuxPacketWriter<T, U> {
|
||||
rtp_writer: T,
|
||||
rtcp_writer: U,
|
||||
}
|
||||
impl<T, U> MuxPacketWriter<T, U>
|
||||
where T: WritePacket,
|
||||
T::Packet: RtpPacket,
|
||||
U: WritePacket,
|
||||
U::Packet: RtcpPacket
|
||||
{
|
||||
pub fn new(rtp_writer: T, rtcp_writer: U) -> Self {
|
||||
MuxPacketWriter {
|
||||
rtp_writer: rtp_writer,
|
||||
rtcp_writer: rtcp_writer,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<T, U> WritePacket for MuxPacketWriter<T, U>
|
||||
where T: WritePacket,
|
||||
T::Packet: RtpPacket,
|
||||
U: WritePacket,
|
||||
U::Packet: RtcpPacket
|
||||
{
|
||||
type Packet = MuxedPacket<T::Packet, U::Packet>;
|
||||
fn write_packet<W: Write>(&mut self, writer: &mut W, packet: &Self::Packet) -> Result<()> {
|
||||
match *packet {
|
||||
MuxedPacket::Rtp(ref p) => self.rtp_writer.write_packet(writer, p),
|
||||
MuxedPacket::Rtcp(ref p) => self.rtcp_writer.write_packet(writer, p),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum MuxedPacket<T, U> {
|
||||
|
@ -15,37 +89,3 @@ impl<T, U> Packet for MuxedPacket<T, U>
|
|||
U: RtcpPacket
|
||||
{
|
||||
}
|
||||
impl<T, U> ReadFrom for MuxedPacket<T, U>
|
||||
where T: RtpPacket,
|
||||
U: RtcpPacket
|
||||
{
|
||||
fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
|
||||
let mut buf = [0; 2];
|
||||
track_try!(reader.read_exact(&mut buf));
|
||||
|
||||
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 {
|
||||
track_panic!(ErrorKind::Unsupported,
|
||||
"Unknown packet/payload type: {}",
|
||||
ty)
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<T, U> WriteTo for MuxedPacket<T, U>
|
||||
where T: RtpPacket,
|
||||
U: RtcpPacket
|
||||
{
|
||||
fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
|
||||
match *self {
|
||||
MuxedPacket::Rtp(ref p) => track_try!(p.write_to(writer)),
|
||||
MuxedPacket::Rtcp(ref p) => track_try!(p.write_to(writer)),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,20 @@
|
|||
use packet::Packet;
|
||||
use types::U7;
|
||||
use std::io::{Read, Write};
|
||||
|
||||
pub trait RtpPacket: Packet {
|
||||
fn supports_type(payload_type: U7) -> bool;
|
||||
use Result;
|
||||
|
||||
pub trait Packet {}
|
||||
|
||||
// TODO: DecodePacket(?)
|
||||
pub trait ReadPacket {
|
||||
type Packet: Packet;
|
||||
fn read_packet<R: Read>(&mut self, reader: &mut R) -> Result<Self::Packet>;
|
||||
fn supports_type(&self, packet_type: u8) -> bool;
|
||||
}
|
||||
pub trait RtcpPacket: Packet {
|
||||
fn supports_type(packet_type: u8) -> bool;
|
||||
|
||||
pub trait WritePacket {
|
||||
type Packet: Packet;
|
||||
fn write_packet<W: Write>(&mut self, writer: &mut W, packet: &Self::Packet) -> Result<()>;
|
||||
}
|
||||
|
||||
pub trait RtpPacket: Packet {}
|
||||
pub trait RtcpPacket: Packet {}
|
||||
|
|
Loading…
Reference in New Issue