From c2691822809085712a97521a412c1365fedcccda Mon Sep 17 00:00:00 2001 From: metamuffin Date: Sat, 6 Jul 2024 22:06:02 +0200 Subject: sdp parser --- src/sdp/mod.rs | 116 ++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 94 insertions(+), 22 deletions(-) (limited to 'src/sdp/mod.rs') diff --git a/src/sdp/mod.rs b/src/sdp/mod.rs index 635c182..68c3c70 100644 --- a/src/sdp/mod.rs +++ b/src/sdp/mod.rs @@ -2,31 +2,34 @@ use anyhow::{anyhow, bail}; use std::str::FromStr; pub struct SessionDescription { - version: String, - originator: String, - session_name: String, - session_information: Option, - description_uri: Option, - email_address: Option, - phone_number: Option, - connection_information: Vec, - bandwidth: Vec, - time_descriptions: Vec, - time_zone_adjustments: Option, - encryption_key: Option, - session_attribute: Vec, - media_descriptions: Vec, + 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 { - time: String, - repeat_times: Vec, + pub time: String, + pub repeat_times: Vec, } pub struct MediaDescription { - name: String, - title: String, - connection_information: String, + pub name: String, + pub title: Option, + pub connection_information: Option, + pub bandwidth: Vec, + pub encryption_key: Option, + pub attributes: Vec, } impl FromStr for SessionDescription { @@ -39,18 +42,87 @@ impl FromStr for SessionDescription { let mut description_uri = None; let mut email_address = None; let mut phone_number = None; - let mut connection_information = Vec::new(); + 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()), - "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 {}) + 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