1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
//! Parser and builder for packets formatted per [RFC 3550](https://tools.ietf.org/html/rfc3550), _A Transport
//! Protocol for Real-Time Applications_.
//!
//! Parse a packet
//! ```
//! use rtp_rs::*;
//! // let data = ...acquire UDP packet from the network etc...
//! # let data = &[
//! # 0x80u8, 0xe0u8, 0x27u8, 0x38u8, 0x64u8, 0xe4u8,
//! # 0x05u8, 0xa7u8, 0xa2u8, 0x42u8, 0xafu8, 0x01u8
//! # ];
//! if let Ok(rtp) = RtpReader::new(data) {
//!     println!("Sequence number {:?}", rtp.sequence_number());
//!     println!("Payload length {:?}", rtp.payload().len());
//! }
//! ```
//!
//! Build a packet
//! ```
//! use rtp_rs::*;
//!
//! let payload = vec![0u8, 2, 5, 4, 6];
//! let result = RtpPacketBuilder::new()
//!     .payload_type(111)
//!     .ssrc(1337)
//!     .sequence(Seq::from(1234))
//!     .timestamp(666657)
//!     .padded(Pad::round_to(4))
//!     .marked(true)
//!     .payload(&payload)
//!     .build();
//! if let Ok(packet) = result {
//!     println!("Packet: {:?}", packet);
//! }
//! ```

#![forbid(unsafe_code)]
#![deny(rust_2018_idioms, future_incompatible, missing_docs)]

/// 16 bit RTP sequence number value, as obtained from the `sequence_number()` method of RtpReader.
///
/// ```
/// use rtp_rs::*;
/// let seq = Seq::from(123);
/// ```
///
/// This type's behavior attempts to honour the expected wrap-around of sequence number values
/// from `0xffff` back to `0x0000`.
///
/// You can perform logic over sequences of RTP packets using this type and other helpers from this
/// crate,
/// ```
/// # use rtp_rs::*;
/// let start = Seq::from(0xfffe);
/// let end = Seq::from(0x0002);
/// // produces the Seq values 0xfffe, 0xffff, 0x0000, 0x0001:
/// for seq in (start..end).seq_iter() {
///     // ...inspect some RTP packet you've stored against this sequence number...
/// }
/// ```
///
/// ## Unsoundness
/// **Note** this type has implementations of `Ord` and `PartialOrd`, but those implementations
/// violate the requirement for transitivity which both traits document.
///
/// ```should_panic
/// # use rtp_rs::*;
/// let a = Seq::from(0);
/// let b = a + 0x7fff;
/// let c = b + 0x7fff;
/// assert!(a < b);
/// assert!(b < c);
/// assert!(a < c);  // Assertion fails, in violation of Ord/PartialOrd requirements
/// ```
/// A future release will potentially deprecate `Ord` / `PartialOrd` implementations for `Seq`, and
/// hopefully provide a mechanism for sequence number processing which is sound.
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
pub struct Seq(u16);
impl Seq {
    /// Produce the sequence value which follows this one.
    ///
    /// Sequence numbers wrap back to `0x0000` after reaching the value `0xffff`
    pub fn next(self) -> Seq {
        Seq(self.0.wrapping_add(1))
    }

    /// Returns `true` if this sequence number value is immediately before the given one
    pub fn precedes(self, other: Seq) -> bool {
        self.next() == other
    }
}
impl From<Seq> for u16 {
    fn from(v: Seq) -> Self {
        v.0
    }
}
impl From<u16> for Seq {
    fn from(v: u16) -> Self {
        Seq(v)
    }
}

/// Implements wrapped subtraction such that for instance `Seq(0x0000) - Seq(0xffff)` results in
/// `1` (rather than `-65535`).
///
/// This is for symmetry with addition, where for example `Seq(0xffff) + 1` gives `Seq(0x0000)`
impl std::ops::Sub for Seq {
    type Output = i32;

    fn sub(self, rhs: Seq) -> Self::Output {
        let delta = i32::from(self.0) - i32::from(rhs.0);
        if delta < std::i16::MIN as i32 {
            std::u16::MAX as i32 + 1 + delta
        } else if delta > std::i16::MAX as i32 {
            delta - std::u16::MAX as i32 - 1
        } else {
            delta
        }
    }
}
impl PartialOrd for Seq {
    fn partial_cmp(&self, other: &Seq) -> Option<std::cmp::Ordering> {
        (*self - *other).partial_cmp(&0)
    }
}
impl Ord for Seq {
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
        (*self - *other).cmp(&0)
    }
}

impl std::ops::Add<u16> for Seq {
    type Output = Seq;

    fn add(self, rhs: u16) -> Self::Output {
        Seq(self.0.wrapping_add(rhs))
    }
}

/// Trait for types that can produce a `SeqIter`, with an implementation provided for `Range<Seq>`.
pub trait IntoSeqIterator {
    /// Produce an `Iterator` over sequence number values
    fn seq_iter(self) -> SeqIter;
}
impl IntoSeqIterator for std::ops::Range<Seq> {
    fn seq_iter(self) -> SeqIter {
        SeqIter(self.start, self.end)
    }
}

/// An `Iterator` which can produce values from the given start value to the given end value, inclusive.
///
/// Rather than using this directly, it is convenient to use a range like so,
/// ```
/// use rtp_rs::*;
/// use rtp_rs::IntoSeqIterator;
/// let here = 12.into();
/// let there = 22.into();
/// for seq in (here..there).seq_iter() {
///     println!("{:?}", seq);
/// }
/// ```
pub struct SeqIter(Seq, Seq);
impl Iterator for SeqIter {
    type Item = Seq;

    fn next(&mut self) -> Option<Self::Item> {
        if self.0 >= self.1 {
            None
        } else {
            let res = self.0;
            self.0 = self.0.next();
            Some(res)
        }
    }
}

mod reader;
pub use reader::*;

mod builder;
pub use builder::*;