From ffcb0a86b2307059019d2a08d836be10146359ee Mon Sep 17 00:00:00 2001 From: Sam Willcocks Date: Tue, 12 Jul 2022 10:00:36 +0100 Subject: [PATCH] Add initial 200 and rtp packet framing --- Cargo.lock | 198 ++++++++++++++++++++++++++++++++++------------------ Cargo.toml | 3 +- src/main.rs | 97 ++++++++++++++++++++++--- 3 files changed, 221 insertions(+), 77 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 185928c..e25d580 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,15 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "aho-corasick" -version = "0.7.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" -dependencies = [ - "memchr", -] - [[package]] name = "ansi_term" version = "0.12.1" @@ -20,6 +11,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "async-trait" +version = "0.1.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96cf8829f67d2eab0b2dfa42c5d0ef737e0724e4a82b01b3e292456202b19716" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -58,6 +60,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +[[package]] +name = "cc" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" + [[package]] name = "cfg-if" version = "1.0.0" @@ -130,30 +138,21 @@ dependencies = [ "generic-array", ] -[[package]] -name = "discortp" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524b9439c09174aede2c88d58cfc6b83575b06569d1af4d07562f76595b2896b" -dependencies = [ - "pnet_macros", - "pnet_macros_support", -] - [[package]] name = "discosip" version = "0.1.0" dependencies = [ "bytes", - "discortp", "futures", "rsip", + "rtp", "sdp-rs", "tokio", "tokio-stream", "tokio-util", "tracing", "tracing-subscriber", + "webrtc-util", ] [[package]] @@ -287,6 +286,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +[[package]] +name = "ipnet" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" + [[package]] name = "lazy_static" version = "1.4.0" @@ -335,6 +340,15 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -354,10 +368,16 @@ dependencies = [ ] [[package]] -name = "no-std-net" -version = "0.6.0" +name = "nix" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65" +checksum = "8f17df307904acd05aa8e32e97bb20f2a0df1728bbc2d771ae8f9a90463441e9" +dependencies = [ + "bitflags", + "cfg-if", + "libc", + "memoffset", +] [[package]] name = "nom" @@ -446,34 +466,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] -name = "pnet_base" -version = "0.31.0" +name = "ppv-lite86" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d3a993d49e5fd5d4d854d6999d4addca1f72d86c65adf224a36757161c02b6" -dependencies = [ - "no-std-net", -] - -[[package]] -name = "pnet_macros" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48dd52a5211fac27e7acb14cfc9f30ae16ae0e956b7b779c8214c74559cef4c3" -dependencies = [ - "proc-macro2", - "quote", - "regex", - "syn", -] - -[[package]] -name = "pnet_macros_support" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89de095dc7739349559913aed1ef6a11e73ceade4897dadc77c5e09de6740750" -dependencies = [ - "pnet_base", -] +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "proc-macro2" @@ -493,6 +489,36 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom", +] + [[package]] name = "redox_syscall" version = "0.2.13" @@ -502,29 +528,12 @@ dependencies = [ "bitflags", ] -[[package]] -name = "regex" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - [[package]] name = "regex-automata" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -[[package]] -name = "regex-syntax" -version = "0.6.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" - [[package]] name = "rsip" version = "0.4.0" @@ -552,6 +561,19 @@ dependencies = [ "syn", ] +[[package]] +name = "rtp" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5110c12c9f7d1e76eba80076cce4ccb82ee085bd10a62472468de0663240f8b5" +dependencies = [ + "async-trait", + "bytes", + "rand", + "thiserror", + "webrtc-util", +] + [[package]] name = "scopeguard" version = "1.1.0" @@ -639,6 +661,26 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "thiserror" +version = "1.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "thread_local" version = "1.1.4" @@ -824,6 +866,28 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "webrtc-util" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b3050262ce1f70599ca1a12f446a2e73bae80a3152baae7fca4a9a26b8f0c0f" +dependencies = [ + "async-trait", + "bitflags", + "bytes", + "cc", + "ipnet", + "lazy_static", + "libc", + "log", + "nix", + "parking_lot", + "rand", + "thiserror", + "tokio", + "winapi", +] + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index c18ea31..4b010f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,12 +5,13 @@ edition = "2021" [dependencies] bytes = "1.1.0" -discortp = "0.5.0" futures = "0.3.21" rsip = "0.4.0" +rtp = "0.6.5" sdp-rs = "0.2.1" tokio = { version = "1.19.2", features = ["full"] } tokio-stream = "0.1.9" tokio-util = { version = "0.7.3", features = ["net", "codec"] } tracing = "0.1.35" tracing-subscriber = "0.3.14" +webrtc-util = "0.5.4" diff --git a/src/main.rs b/src/main.rs index ff53310..eeb981c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,16 @@ use bytes::{Bytes, BytesMut}; use futures::{sink::Sink, SinkExt}; +use rtp::packet::Packet as RtpPacket; +use webrtc_util::marshal::Unmarshal; use rsip::common::method::Method as SipMethod; use rsip::headers::header::Header as SipHeader; use rsip::message::{request::Request, response::Response, SipMessage}; use sdp_rs::lines::media::{MediaType, ProtoType}; -use sdp_rs::lines::{attribute::Rtpmap, Attribute}; +use sdp_rs::lines::{attribute::Rtpmap, Attribute, Media}; use sdp_rs::{MediaDescription, SessionDescription}; use std::net::SocketAddr; use std::str; +use std::net::IpAddr; use std::time::Duration; use tokio::net::UdpSocket; use tokio::sync::mpsc; @@ -64,6 +67,24 @@ impl Encoder for SipCodec { } } +struct RtpCodec{} + +impl Decoder for RtpCodec { + type Item = RtpPacket; + type Error = std::io::Error; + + fn decode(&mut self, src: &mut BytesMut) -> Result, Self::Error> { + if src.is_empty() { + Ok(None) + } else { + match RtpPacket::unmarshal(src) { + Ok(p) =>Ok(Some(p)), + Err(e) => Err(Self::Error::new(std::io::ErrorKind::Other, e.to_string())), + } + } + } +} + type StdErr = Result>; struct Server {} @@ -257,7 +278,69 @@ impl Server { let socket = UdpSocket::bind(format!("{}:0", BIND_ADDR)).await?; let rtp_port = socket.local_addr()?.port(); event!(Level::INFO, rtp_port, "Bound RTP port"); - let mut framed = UdpFramed::new(socket, SipCodec {}); + let mut rtp_framed = UdpFramed::new(socket, RtpCodec{}); + let mut res = base_res.clone(); + res.status_code = 180.into(); + responses.send(res).await; + + sleep(Duration::from_millis(2000)).await; + let mut res = base_res.clone(); + res.status_code = 200.into(); + // TODO: fix this lmao + let ip: IpAddr = "10.23.2.134".parse()?; + res.headers.push(SipHeader::Contact(format!("sip:{}:{}", ip, SIP_PORT).into())); + res.headers.push(SipHeader::ContentType("application/sdp".into())); + let md = MediaDescription { + media: Media { + media: MediaType::Audio, + port: rtp_port, + num_of_ports: None, + proto: ProtoType::RtpAvp, + fmt: "101".into(), + }, + connections: vec!(sdp_rs::lines::Connection{ + nettype: "IN".into(), + addrtype: "IP4".into(), + connection_address: ip.into(), + }), + bandwidths: vec!(sdp_rs::lines::Bandwidth{bwtype:"TIAS".into(), bandwidth: 64000}), + attributes: vec!(sdp_rs::lines::Attribute::Other("rtpmap".into(), Some("101 opus/48000/2".into()))), + info: None, + key: None, + }.into(); + let sd: String = SessionDescription { + version: sdp_rs::lines::Version::V0, + origin: sdp_rs::lines::Origin{ + username: "-".into(), + sess_id: "foobar".into(), + sess_version: "foobar".into(), + nettype: "IN".into(), + addrtype: "IP4".into(), + unicast_address: ip.into(), + }, + session_name: "discosip".to_owned().into(), + session_info: None, + uri: None, + emails: vec!(), + phones: vec!(), + connection: None, + bandwidths: vec!(sdp_rs::lines::Bandwidth{bwtype:"AS".into(), bandwidth: 84}), + times: vec!(sdp_rs::Time{ + active: sdp_rs::lines::Active{ + start: 0, + stop: 0, + }, + repeat: vec!(), + zone: None, + }).try_into()?, + key: None, + attributes: vec!(), + media_descriptions: vec!(md), + }.to_string(); + res.body = sd.as_bytes().into(); + res.headers.push(SipHeader::ContentLength((res.body.len() as u32).into())); + responses.send(res).await; + loop { tokio::select! { @@ -273,13 +356,9 @@ impl Server { } }, - _ = sleep(Duration::from_millis(3000)) => { - // Reject call after 3000 seconds - let mut res = base_res.clone(); - res.status_code = 603.into(); - responses.send(res).await; - break - } + Some(rtp_frame) = rtp_framed.next() => { + event!(Level::INFO, "Got RTP Packet!"); + }, } }