diff options
author | metamuffin <metamuffin@disroot.org> | 2024-12-06 16:01:18 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-12-06 16:01:18 +0100 |
commit | 8e19859996eee29ba28c4e4a933ba396924ac163 (patch) | |
tree | cc9c44f6e19d3a18ad57782f11b760abab15bca1 | |
parent | 8d02c52f770e5626a67dfdc47214fc23b744ac47 (diff) | |
download | sip-rs-8e19859996eee29ba28c4e4a933ba396924ac163.tar sip-rs-8e19859996eee29ba28c4e4a933ba396924ac163.tar.bz2 sip-rs-8e19859996eee29ba28c4e4a933ba396924ac163.tar.zst |
a
-rw-r--r-- | Cargo.lock | 1 | ||||
-rw-r--r-- | rtp/Cargo.toml | 1 | ||||
-rw-r--r-- | rtp/src/lib.rs | 52 | ||||
-rw-r--r-- | rtp/src/rtcp.rs | 86 |
4 files changed, 107 insertions, 33 deletions
@@ -395,6 +395,7 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" name = "rtp" version = "0.1.0" dependencies = [ + "log", "thiserror", ] diff --git a/rtp/Cargo.toml b/rtp/Cargo.toml index 84f0116..462f52e 100644 --- a/rtp/Cargo.toml +++ b/rtp/Cargo.toml @@ -5,3 +5,4 @@ edition = "2021" [dependencies] thiserror = "2.0.3" +log = "0.4.22" diff --git a/rtp/src/lib.rs b/rtp/src/lib.rs index 0c80412..d7d8d6a 100644 --- a/rtp/src/lib.rs +++ b/rtp/src/lib.rs @@ -5,7 +5,8 @@ use std::{ time::{Duration, Instant}, }; -use rtcp::RtcpPacket; +use log::debug; +use rtcp::{RtcpPacket, RtcpPart}; use rtp::SSRC; pub mod rtcp; @@ -24,6 +25,7 @@ pub struct Session { initial: bool, member_table: HashSet<SSRC>, + sender_table: HashSet<SSRC>, } impl Session { @@ -51,6 +53,7 @@ impl Session { let td = tmin.max(n as f32 * c); let t = td * ((random::<u16>() as f32) / (u16::MAX as f32) + 0.5); let t = t / 1.5f32.exp(); + debug!("RTCP transmission interval is {t:.02}s"); Duration::from_secs_f32(t) } @@ -65,6 +68,7 @@ impl Session { members: 1, we_sent: false, initial: true, + sender_table: HashSet::new(), member_table: HashSet::new(), // TODO add own ssrc to members rtcp_bw: 1000., // TODO set rtcp bandwidth from params avg_rtcp_size: 1000., // TODO set to next likely rtcp packet size @@ -73,6 +77,48 @@ impl Session { se } - /// RFC 3550, Section 6.3.3 - pub fn on_receive(&mut self, packet: RtcpPacket) {} + pub fn tt_expire(&mut self) { + let t = self.compute_rtcp_transmission_interval(); + if self.tp + t < self.tc { + self.send_rtcp(); + self.tp = self.tc; + let t = self.compute_rtcp_transmission_interval(); + self.tn = self.tc + t; + if self.tp + t > self.tc { + self.tn = self.tp + t; + } + self.pmembers = self.members; + } + } + + pub fn send_rtcp(&mut self) { + + } + + /// RFC 3550, Section 6.3.3 / 6.3.4 + pub fn on_receive(&mut self, packet_raw: &[u8]) { + let packet = RtcpPacket::parse(packet_raw).unwrap(); // TODO + + let bye = packet.parts.iter().find_map(|p| match p { + RtcpPart::Bye(b) => Some(b), + _ => None, + }); + if let Some(bye) = bye { + for s in &bye.ssrcs { + if self.member_table.remove(s) { + self.members -= 1; + } + if self.sender_table.remove(s) { + self.senders -= 1; + } + } + let f_mem = self.members as f32 / self.pmembers as f32; + self.tn = self.tc + (self.tn - self.tc).mul_f32(f_mem); + self.tp = self.tc - (self.tc - self.tp).mul_f32(f_mem); + self.pmembers = self.members + } else { + self.avg_rtcp_size = + (1. / 16.) * packet_raw.len() as f32 + (15. / 16.) * self.avg_rtcp_size; + } + } } diff --git a/rtp/src/rtcp.rs b/rtp/src/rtcp.rs index da0a683..371aa85 100644 --- a/rtp/src/rtcp.rs +++ b/rtp/src/rtcp.rs @@ -9,46 +9,63 @@ pub enum Error { } pub struct RtcpPacket<'a> { - parts: Vec<RtcpPart<'a>>, + pub parts: Vec<RtcpPart<'a>>, } pub enum RtcpPart<'a> { SenderReport(SenderReport<'a>), ReceiverReport(ReceiverReport), SourceDescription(SourceDescription), - Bye(Bye), + Bye(Bye<'a>), Application(Application<'a>), } -struct SenderReport<'a> { - ssrc: SSRC, - sender_info: SenderInfo, - reports: Vec<ReportBlock>, - extension: &'a [u8], +pub struct SenderReport<'a> { + pub ssrc: SSRC, + pub sender_info: SenderInfo, + pub reports: Vec<ReportBlock>, + pub extension: &'a [u8], } -struct ReceiverReport { - sender_ssrc: SSRC, - reports: Vec<ReportBlock>, +pub struct ReceiverReport { + pub sender_ssrc: SSRC, + pub reports: Vec<ReportBlock>, } -struct SourceDescription {} -struct Bye {} -struct Application<'a> { - data: &'a [u8], +pub struct SourceDescription { + sources: Vec<(SSRC, Vec<SourceDescriptionItem>)>, } -struct SenderInfo { - ntp_ts: u64, - rtp_ts: u32, - packet_count: u32, - octet_count: u32, +pub enum SourceDescriptionItem { + CanonicalName(String), + Name(String), + Email(String), + Phone(String), + Location(String), + Tool(String), + Notice(String), + PrivateExtension(String), } -struct ReportBlock { - ssrc: SSRC, - fraction_lost: u8, - cumulative_packets_lost: u32, - ext_max_seq_num_recv: u32, - interarrical_jitter: u32, - lsr: u32, - dlsr: u32, +pub struct Bye<'a> { + pub ssrcs: Vec<SSRC>, + pub reason: &'a [u8], +} +pub struct Application<'a> { + pub subtype: u8, + pub name: [u8; 4], + pub data: &'a [u8], +} +pub struct SenderInfo { + pub ntp_ts: u64, + pub rtp_ts: u32, + pub packet_count: u32, + pub octet_count: u32, +} +pub struct ReportBlock { + pub ssrc: SSRC, + pub fraction_lost: u8, + pub cumulative_packets_lost: u32, + pub ext_max_seq_num_recv: u32, + pub interarrical_jitter: u32, + pub lsr: u32, + pub dlsr: u32, } impl<'a> RtcpPacket<'a> { @@ -69,7 +86,7 @@ impl<'a> RtcpPacket<'a> { match packet_type { 200 => { - // Sender Report + // sender seport if packet.len() < 28 + 24 * num_reports as usize { return Err(Error::Truncated); } @@ -89,7 +106,17 @@ impl<'a> RtcpPacket<'a> { extension, })) } - 201 => { // Receiver Report + 201 => { + // receiver report + } + 202 => { + // source description + } + 203 => { + // bye + } + 204 => { + // application defined } _ => {} } @@ -107,7 +134,6 @@ impl<'a> RtcpPacket<'a> { version << 6 | (padding as u8) << 5 | sender_report.reports.len() as u8, ); out.push(200); - } RtcpPart::ReceiverReport(receiver_report) => todo!(), RtcpPart::SourceDescription(source_description) => todo!(), |