From 5f1a995ac4d0965135a297d3c2cb8c2712765e2c Mon Sep 17 00:00:00 2001 From: metamuffin Date: Sat, 6 Jul 2024 22:43:09 +0200 Subject: sdp and rtp crates --- Cargo.lock | 13 ++++++ Cargo.toml | 3 ++ examples/server.rs | 9 ++-- rtp/Cargo.toml | 6 +++ rtp/src/lib.rs | 3 ++ sdp/Cargo.toml | 7 +++ sdp/src/lib.rs | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 - src/sdp/mod.rs | 128 ----------------------------------------------------- 9 files changed, 164 insertions(+), 134 deletions(-) create mode 100644 rtp/Cargo.toml create mode 100644 rtp/src/lib.rs create mode 100644 sdp/Cargo.toml create mode 100644 sdp/src/lib.rs delete mode 100644 src/sdp/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 7d7e46b..746b07c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -397,6 +397,10 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +[[package]] +name = "rtp" +version = "0.1.0" + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -409,6 +413,13 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sdp" +version = "0.1.0" +dependencies = [ + "anyhow", +] + [[package]] name = "signal-hook-registry" version = "1.4.2" @@ -429,6 +440,8 @@ dependencies = [ "log", "md5", "rand", + "rtp", + "sdp", "tokio", ] diff --git a/Cargo.toml b/Cargo.toml index 826367f..be4a965 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,5 +12,8 @@ base64 = "0.22.1" md5 = "0.7.0" hex = "0.4.3" +sdp = { path = "sdp" } +rtp = { path = "rtp" } + [dev-dependencies] env_logger = "0.11.3" diff --git a/examples/server.rs b/examples/server.rs index b58557a..ef798ce 100644 --- a/examples/server.rs +++ b/examples/server.rs @@ -1,21 +1,20 @@ -use std::net::SocketAddr; - use anyhow::Result; use log::{info, warn}; use sip::{ encoding::{ headermap::HeaderMap, - headers::{Contact, ContentLength, From, To, UserAgent}, + headers::{Contact, From, To, UserAgent}, method::Method, response::Response, status::Status, uri::Uri, }, transaction::TransactionUser, - transport::{tcp::TcpTransport, udp::UdpTransport}, + transport::tcp::TcpTransport, }; +use std::net::SocketAddr; use tokio::{ - net::{TcpListener, TcpStream, UdpSocket}, + net::{TcpListener, TcpStream}, spawn, }; diff --git a/rtp/Cargo.toml b/rtp/Cargo.toml new file mode 100644 index 0000000..07e7123 --- /dev/null +++ b/rtp/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rtp" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/rtp/src/lib.rs b/rtp/src/lib.rs new file mode 100644 index 0000000..b28b04f --- /dev/null +++ b/rtp/src/lib.rs @@ -0,0 +1,3 @@ + + + diff --git a/sdp/Cargo.toml b/sdp/Cargo.toml new file mode 100644 index 0000000..0169645 --- /dev/null +++ b/sdp/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "sdp" +version = "0.1.0" +edition = "2021" + +[dependencies] +anyhow = "*" diff --git a/sdp/src/lib.rs b/sdp/src/lib.rs new file mode 100644 index 0000000..68c3c70 --- /dev/null +++ b/sdp/src/lib.rs @@ -0,0 +1,128 @@ +use anyhow::{anyhow, bail}; +use std::str::FromStr; + +pub struct SessionDescription { + pub version: String, + pub originator: String, + pub session_name: String, + pub session_information: Option, + pub description_uri: Option, + pub email_address: Option, + pub phone_number: Option, + pub connection_information: Option, + pub bandwidth: Vec, + pub time_descriptions: Vec, + pub time_zone_adjustments: Option, + pub encryption_key: Option, + pub attributes: Vec, + pub media_descriptions: Vec, +} + +pub struct TimeDescription { + pub time: String, + pub repeat_times: Vec, +} + +pub struct MediaDescription { + pub name: String, + pub title: Option, + pub connection_information: Option, + pub bandwidth: Vec, + pub encryption_key: Option, + pub attributes: Vec, +} + +impl FromStr for SessionDescription { + type Err = anyhow::Error; + fn from_str(s: &str) -> Result { + let mut version = None; + let mut originator = None; + let mut session_name = None; + let mut session_information = None; + let mut description_uri = None; + let mut email_address = None; + let mut phone_number = None; + let mut connection_information = None; + let mut encryption_key = None; + let mut time_zone_adjustments = None; + let mut bandwidth = Vec::new(); + let mut time_descriptions = Vec::new(); + let mut media_descriptions = Vec::new(); + let mut attributes = Vec::new(); + for line in s.lines() { + let (r#type, value) = line.split_once("=").ok_or(anyhow!("sdp line invalid"))?; + match r#type { + "v" => version = Some(value.to_string()), + "o" => originator = Some(value.to_string()), + "s" => session_name = Some(value.to_string()), + "i" => session_information = Some(value.to_string()), + "u" => description_uri = Some(value.to_string()), + "e" => email_address = Some(value.to_string()), + "p" => phone_number = Some(value.to_string()), + "t" => time_descriptions.push(TimeDescription { + repeat_times: Vec::new(), + time: value.to_string(), + }), + "r" => time_descriptions + .last_mut() + .ok_or(anyhow!("no time desc"))? + .repeat_times + .push(value.to_string()), + "z" => time_zone_adjustments = Some(value.to_string()), + "m" => media_descriptions.push(MediaDescription { + connection_information: None, + name: value.to_string(), + title: None, + encryption_key: None, + attributes: Vec::new(), + bandwidth: Vec::new(), + }), + "a" => { + if let Some(media_desc) = media_descriptions.last_mut() { + media_desc.attributes.push(value.to_string()) + } else { + attributes.push(value.to_string()) + } + } + "b" => { + if let Some(media_desc) = media_descriptions.last_mut() { + media_desc.bandwidth.push(value.to_string()) + } else { + bandwidth.push(value.to_string()) + } + } + "k" => { + if let Some(key) = media_descriptions.last_mut() { + key.encryption_key = Some(value.to_string()) + } else { + encryption_key = Some(value.to_string()) + } + } + "c" => { + if let Some(media_desc) = media_descriptions.last_mut() { + media_desc.connection_information = Some(value.to_string()) + } else { + connection_information = Some(value.to_string()) + } + } + x => bail!("unknown sdp type ({x:?})"), + } + } + Ok(Self { + bandwidth, + connection_information, + attributes, + description_uri, + email_address, + encryption_key, + phone_number, + session_information, + time_zone_adjustments, + media_descriptions, + originator: originator.ok_or(anyhow!("originator missing"))?, + session_name: session_name.ok_or(anyhow!("session name missing"))?, + version: version.ok_or(anyhow!("version missing"))?, + time_descriptions, + }) + } +} diff --git a/src/lib.rs b/src/lib.rs index 905922b..6c6cc3b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,4 +2,3 @@ pub mod encoding; pub mod transport; pub mod transaction; -pub mod sdp; diff --git a/src/sdp/mod.rs b/src/sdp/mod.rs deleted file mode 100644 index 68c3c70..0000000 --- a/src/sdp/mod.rs +++ /dev/null @@ -1,128 +0,0 @@ -use anyhow::{anyhow, bail}; -use std::str::FromStr; - -pub struct SessionDescription { - pub version: String, - pub originator: String, - pub session_name: String, - pub session_information: Option, - pub description_uri: Option, - pub email_address: Option, - pub phone_number: Option, - pub connection_information: Option, - pub bandwidth: Vec, - pub time_descriptions: Vec, - pub time_zone_adjustments: Option, - pub encryption_key: Option, - pub attributes: Vec, - pub media_descriptions: Vec, -} - -pub struct TimeDescription { - pub time: String, - pub repeat_times: Vec, -} - -pub struct MediaDescription { - pub name: String, - pub title: Option, - pub connection_information: Option, - pub bandwidth: Vec, - pub encryption_key: Option, - pub attributes: Vec, -} - -impl FromStr for SessionDescription { - type Err = anyhow::Error; - fn from_str(s: &str) -> Result { - let mut version = None; - let mut originator = None; - let mut session_name = None; - let mut session_information = None; - let mut description_uri = None; - let mut email_address = None; - let mut phone_number = None; - let mut connection_information = None; - let mut encryption_key = None; - let mut time_zone_adjustments = None; - let mut bandwidth = Vec::new(); - let mut time_descriptions = Vec::new(); - let mut media_descriptions = Vec::new(); - let mut attributes = Vec::new(); - for line in s.lines() { - let (r#type, value) = line.split_once("=").ok_or(anyhow!("sdp line invalid"))?; - match r#type { - "v" => version = Some(value.to_string()), - "o" => originator = Some(value.to_string()), - "s" => session_name = Some(value.to_string()), - "i" => session_information = Some(value.to_string()), - "u" => description_uri = Some(value.to_string()), - "e" => email_address = Some(value.to_string()), - "p" => phone_number = Some(value.to_string()), - "t" => time_descriptions.push(TimeDescription { - repeat_times: Vec::new(), - time: value.to_string(), - }), - "r" => time_descriptions - .last_mut() - .ok_or(anyhow!("no time desc"))? - .repeat_times - .push(value.to_string()), - "z" => time_zone_adjustments = Some(value.to_string()), - "m" => media_descriptions.push(MediaDescription { - connection_information: None, - name: value.to_string(), - title: None, - encryption_key: None, - attributes: Vec::new(), - bandwidth: Vec::new(), - }), - "a" => { - if let Some(media_desc) = media_descriptions.last_mut() { - media_desc.attributes.push(value.to_string()) - } else { - attributes.push(value.to_string()) - } - } - "b" => { - if let Some(media_desc) = media_descriptions.last_mut() { - media_desc.bandwidth.push(value.to_string()) - } else { - bandwidth.push(value.to_string()) - } - } - "k" => { - if let Some(key) = media_descriptions.last_mut() { - key.encryption_key = Some(value.to_string()) - } else { - encryption_key = Some(value.to_string()) - } - } - "c" => { - if let Some(media_desc) = media_descriptions.last_mut() { - media_desc.connection_information = Some(value.to_string()) - } else { - connection_information = Some(value.to_string()) - } - } - x => bail!("unknown sdp type ({x:?})"), - } - } - Ok(Self { - bandwidth, - connection_information, - attributes, - description_uri, - email_address, - encryption_key, - phone_number, - session_information, - time_zone_adjustments, - media_descriptions, - originator: originator.ok_or(anyhow!("originator missing"))?, - session_name: session_name.ok_or(anyhow!("session name missing"))?, - version: version.ok_or(anyhow!("version missing"))?, - time_descriptions, - }) - } -} -- cgit v1.2.3-70-g09d2