aboutsummaryrefslogtreecommitdiff
path: root/sdp/src/lib.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2024-07-06 22:43:09 +0200
committermetamuffin <metamuffin@disroot.org>2024-07-06 22:43:09 +0200
commit5f1a995ac4d0965135a297d3c2cb8c2712765e2c (patch)
tree7a7a61abc59a4c981aab723063803a8fae568ff3 /sdp/src/lib.rs
parentc2691822809085712a97521a412c1365fedcccda (diff)
downloadsip-rs-5f1a995ac4d0965135a297d3c2cb8c2712765e2c.tar
sip-rs-5f1a995ac4d0965135a297d3c2cb8c2712765e2c.tar.bz2
sip-rs-5f1a995ac4d0965135a297d3c2cb8c2712765e2c.tar.zst
sdp and rtp crates
Diffstat (limited to 'sdp/src/lib.rs')
-rw-r--r--sdp/src/lib.rs128
1 files changed, 128 insertions, 0 deletions
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<String>,
+ pub description_uri: Option<String>,
+ pub email_address: Option<String>,
+ pub phone_number: Option<String>,
+ pub connection_information: Option<String>,
+ pub bandwidth: Vec<String>,
+ pub time_descriptions: Vec<TimeDescription>,
+ pub time_zone_adjustments: Option<String>,
+ pub encryption_key: Option<String>,
+ pub attributes: Vec<String>,
+ pub media_descriptions: Vec<MediaDescription>,
+}
+
+pub struct TimeDescription {
+ pub time: String,
+ pub repeat_times: Vec<String>,
+}
+
+pub struct MediaDescription {
+ pub name: String,
+ pub title: Option<String>,
+ pub connection_information: Option<String>,
+ pub bandwidth: Vec<String>,
+ pub encryption_key: Option<String>,
+ pub attributes: Vec<String>,
+}
+
+impl FromStr for SessionDescription {
+ type Err = anyhow::Error;
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ 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,
+ })
+ }
+}