xref: /webrtc/rtp/src/sequence.rs (revision bc5c52e6)
1ffe74184SMartin Algesten use std::fmt;
2*bc5c52e6Syngrtc use std::sync::atomic::{AtomicU16, AtomicU64, Ordering};
35b79f08aSalexlapa use std::sync::Arc;
45b79f08aSalexlapa 
5ffe74184SMartin Algesten /// Sequencer generates sequential sequence numbers for building RTP packets
6ffe74184SMartin Algesten pub trait Sequencer: fmt::Debug {
next_sequence_number(&self) -> u167ffe74184SMartin Algesten     fn next_sequence_number(&self) -> u16;
roll_over_count(&self) -> u648ffe74184SMartin Algesten     fn roll_over_count(&self) -> u64;
clone_to(&self) -> Box<dyn Sequencer + Send + Sync>9ffe74184SMartin Algesten     fn clone_to(&self) -> Box<dyn Sequencer + Send + Sync>;
10ffe74184SMartin Algesten }
11ffe74184SMartin Algesten 
12ffe74184SMartin Algesten impl Clone for Box<dyn Sequencer + Send + Sync> {
clone(&self) -> Box<dyn Sequencer + Send + Sync>13ffe74184SMartin Algesten     fn clone(&self) -> Box<dyn Sequencer + Send + Sync> {
14ffe74184SMartin Algesten         self.clone_to()
15ffe74184SMartin Algesten     }
16ffe74184SMartin Algesten }
17ffe74184SMartin Algesten 
18ffe74184SMartin Algesten /// NewRandomSequencer returns a new sequencer starting from a random sequence
19ffe74184SMartin Algesten /// number
new_random_sequencer() -> impl Sequencer20ffe74184SMartin Algesten pub fn new_random_sequencer() -> impl Sequencer {
21ffe74184SMartin Algesten     let c = Counters {
22*bc5c52e6Syngrtc         sequence_number: Arc::new(AtomicU16::new(rand::random::<u16>())),
23*bc5c52e6Syngrtc         roll_over_count: Arc::new(AtomicU64::new(0)),
24ffe74184SMartin Algesten     };
25*bc5c52e6Syngrtc     SequencerImpl(c)
26ffe74184SMartin Algesten }
27ffe74184SMartin Algesten 
28ffe74184SMartin Algesten /// NewFixedSequencer returns a new sequencer starting from a specific
29ffe74184SMartin Algesten /// sequence number
new_fixed_sequencer(s: u16) -> impl Sequencer30ffe74184SMartin Algesten pub fn new_fixed_sequencer(s: u16) -> impl Sequencer {
31ffe74184SMartin Algesten     let sequence_number = if s == 0 { u16::MAX } else { s - 1 };
32ffe74184SMartin Algesten 
33ffe74184SMartin Algesten     let c = Counters {
34*bc5c52e6Syngrtc         sequence_number: Arc::new(AtomicU16::new(sequence_number)),
35*bc5c52e6Syngrtc         roll_over_count: Arc::new(AtomicU64::new(0)),
36ffe74184SMartin Algesten     };
37ffe74184SMartin Algesten 
38*bc5c52e6Syngrtc     SequencerImpl(c)
39ffe74184SMartin Algesten }
40ffe74184SMartin Algesten 
41ffe74184SMartin Algesten #[derive(Debug, Clone)]
42*bc5c52e6Syngrtc struct SequencerImpl(Counters);
43ffe74184SMartin Algesten 
44*bc5c52e6Syngrtc #[derive(Debug, Clone)]
45ffe74184SMartin Algesten struct Counters {
46*bc5c52e6Syngrtc     sequence_number: Arc<AtomicU16>,
47*bc5c52e6Syngrtc     roll_over_count: Arc<AtomicU64>,
48ffe74184SMartin Algesten }
49ffe74184SMartin Algesten 
50ffe74184SMartin Algesten impl Sequencer for SequencerImpl {
51ffe74184SMartin Algesten     /// NextSequenceNumber increment and returns a new sequence number for
52ffe74184SMartin Algesten     /// building RTP packets
next_sequence_number(&self) -> u1653ffe74184SMartin Algesten     fn next_sequence_number(&self) -> u16 {
54*bc5c52e6Syngrtc         if self.0.sequence_number.load(Ordering::SeqCst) == u16::MAX {
55*bc5c52e6Syngrtc             self.0.roll_over_count.fetch_add(1, Ordering::SeqCst);
56*bc5c52e6Syngrtc             self.0.sequence_number.store(0, Ordering::SeqCst);
57*bc5c52e6Syngrtc             0
58ffe74184SMartin Algesten         } else {
59*bc5c52e6Syngrtc             self.0.sequence_number.fetch_add(1, Ordering::SeqCst) + 1
60ffe74184SMartin Algesten         }
61ffe74184SMartin Algesten     }
62ffe74184SMartin Algesten 
63ffe74184SMartin Algesten     /// RollOverCount returns the amount of times the 16bit sequence number
64ffe74184SMartin Algesten     /// has wrapped
roll_over_count(&self) -> u6465ffe74184SMartin Algesten     fn roll_over_count(&self) -> u64 {
66*bc5c52e6Syngrtc         self.0.roll_over_count.load(Ordering::SeqCst)
67ffe74184SMartin Algesten     }
68ffe74184SMartin Algesten 
clone_to(&self) -> Box<dyn Sequencer + Send + Sync>69ffe74184SMartin Algesten     fn clone_to(&self) -> Box<dyn Sequencer + Send + Sync> {
70ffe74184SMartin Algesten         Box::new(self.clone())
71ffe74184SMartin Algesten     }
72ffe74184SMartin Algesten }
73