--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1729,16 +1729,21 @@ version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rsdparsa"
version = "0.1.0"
+dependencies = [
+ "log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.66 (git+https://github.com/servo/serde?branch=deserialize_from_enums8)",
+]
[[package]]
name = "rsdparsa_capi"
version = "0.1.0"
dependencies = [
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"nserror 0.1.0",
--- a/media/webrtc/signaling/src/sdp/rsdparsa/Cargo.toml
+++ b/media/webrtc/signaling/src/sdp/rsdparsa/Cargo.toml
@@ -1,7 +1,18 @@
[package]
name = "rsdparsa"
version = "0.1.0"
authors = ["Nils Ohlmeier <github@ohlmeier.org>"]
[features]
default = []
+# serializability
+serialize = ["serde", "serde_derive"]
+
+[dependencies]
+# clippy = {version = "*", optional = true}
+log = {version = "*"}
+serde = {version = "1.0" , optional = true}
+serde_derive = {version = "1.0" , optional = true}
+
+[dev-dependencies]
+# serde_json = {version = "1.0"}
--- a/media/webrtc/signaling/src/sdp/rsdparsa/src/attribute_type.rs
+++ b/media/webrtc/signaling/src/sdp/rsdparsa/src/attribute_type.rs
@@ -768,17 +768,16 @@ fn parse_single_direction(to_parse: &str
"send" => Ok(SdpSingleDirection::Send),
"recv" => Ok(SdpSingleDirection::Recv),
x @ _ => Err(SdpParserInternalError::Generic(
format!("Unknown direction description found: '{:}'",x).to_string()
))
}
}
-
fn parse_sctp_port(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> {
let port = to_parse.parse()?;
if port > 65535 {
return Err(SdpParserInternalError::Generic(format!("Sctpport port {} can only be a bit 16bit number",
port)));
}
Ok(SdpAttribute::SctpPort(port))
}
@@ -1097,16 +1096,17 @@ fn parse_fmtp(to_parse: &str) -> Result<
}
}
Ok(SdpAttribute::Fmtp(SdpAttributeFmtp {
payload_type: payload_token.parse::<u8>()?,
parameters: parameters,
}))
}
+
fn parse_group(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> {
let mut tokens = to_parse.split_whitespace();
let semantics = match tokens.next() {
None => {
return Err(SdpParserInternalError::Generic("Group attribute is missing semantics token"
.to_string()))
}
Some(x) => {
@@ -1993,17 +1993,40 @@ fn test_parse_attribute_rtcp() {
assert!(parse_attribute("rtcp:70000").is_err());
assert!(parse_attribute("rtcp:9 IN").is_err());
assert!(parse_attribute("rtcp:9 IN IP4").is_err());
assert!(parse_attribute("rtcp:9 IN IP4 ::1").is_err());
}
#[test]
fn test_parse_attribute_rtcp_fb() {
- assert!(parse_attribute("rtcp-fb:101 ccm fir").is_ok())
+ assert!(parse_attribute("rtcp-fb:101 ack rpsi").is_ok());
+ assert!(parse_attribute("rtcp-fb:101 ack app").is_ok());
+ assert!(parse_attribute("rtcp-fb:101 ccm").is_ok());
+ assert!(parse_attribute("rtcp-fb:101 ccm fir").is_ok());
+ assert!(parse_attribute("rtcp-fb:101 ccm tmmbr").is_ok());
+ assert!(parse_attribute("rtcp-fb:101 ccm tstr").is_ok());
+ assert!(parse_attribute("rtcp-fb:101 ccm vbcm").is_ok());
+ assert!(parse_attribute("rtcp-fb:101 nack").is_ok());
+ assert!(parse_attribute("rtcp-fb:101 nack sli").is_ok());
+ assert!(parse_attribute("rtcp-fb:101 nack pli").is_ok());
+ assert!(parse_attribute("rtcp-fb:101 nack rpsi").is_ok());
+ assert!(parse_attribute("rtcp-fb:101 nack app").is_ok());
+ assert!(parse_attribute("rtcp-fb:101 trr-int 1").is_ok());
+ assert!(parse_attribute("rtcp-fb:101 goog-remb").is_ok());
+ assert!(parse_attribute("rtcp-fb:101 transport-cc").is_ok());
+
+ assert!(parse_attribute("rtcp-fb:101 unknown").is_err());
+ assert!(parse_attribute("rtcp-fb:101 ack").is_err());
+ assert!(parse_attribute("rtcp-fb:101 ccm unknwon").is_err());
+ assert!(parse_attribute("rtcp-fb:101 nack unknown").is_err());
+ assert!(parse_attribute("rtcp-fb:101 trr-int").is_err());
+ assert!(parse_attribute("rtcp-fb:101 trr-int a").is_err());
+ assert!(parse_attribute("rtcp-fb:101 goog-remb unknown").is_err());
+ assert!(parse_attribute("rtcp-fb:101 transport-cc unknown").is_err());
}
#[test]
fn test_parse_attribute_rtcp_mux() {
assert!(parse_attribute("rtcp-mux").is_ok());
assert!(parse_attribute("rtcp-mux foobar").is_err());
}
--- a/media/webrtc/signaling/src/sdp/rsdparsa/src/lib.rs
+++ b/media/webrtc/signaling/src/sdp/rsdparsa/src/lib.rs
@@ -1,10 +1,12 @@
#![cfg_attr(feature="clippy", feature(plugin))]
+#[macro_use]
+extern crate log;
#[cfg(feature="serialize")]
#[macro_use]
extern crate serde_derive;
#[cfg(feature="serialize")]
extern crate serde;
use std::net::IpAddr;
use std::str::FromStr;
@@ -133,17 +135,17 @@ impl SdpSession {
pub fn get_version(&self) -> u64 {
self.version
}
pub fn get_origin(&self) -> &SdpOrigin {
&self.origin
}
- pub fn get_session(&self) -> &String {
+ pub fn get_session(&self) -> &str {
&self.session
}
pub fn get_connection(&self) -> &Option<SdpConnection> {
&self.connection
}
pub fn set_connection(&mut self, c: &SdpConnection) {
@@ -165,32 +167,20 @@ impl SdpSession {
};
Ok(self.attribute.push(a.clone()))
}
pub fn extend_media(&mut self, v: Vec<SdpMedia>) {
self.media.extend(v)
}
- pub fn has_timing(&self) -> bool {
- self.timing.is_some()
- }
-
- pub fn has_attributes(&self) -> bool {
- !self.attribute.is_empty()
- }
-
pub fn get_attribute(&self, t: SdpAttributeType) -> Option<&SdpAttribute> {
self.attribute.iter().filter(|a| SdpAttributeType::from(*a) == t).next()
}
- pub fn has_media(&self) -> bool {
- !self.media.is_empty()
- }
-
pub fn add_media(&mut self, media_type: SdpMediaValue, direction: SdpAttribute, port: u32,
protocol: SdpProtocolValue, addr: String)
-> Result<(),SdpParserInternalError> {
let mut media = SdpMedia::new(SdpMediaLine {
media: media_type,
port,
port_count: 1,
proto: protocol,
@@ -207,33 +197,33 @@ impl SdpSession {
self.media.push(media);
Ok(())
}
}
fn parse_session(value: &str) -> Result<SdpType, SdpParserInternalError> {
- println!("session: {}", value);
+ trace!("session: {}", value);
Ok(SdpType::Session(String::from(value)))
}
#[test]
fn test_session_works() {
assert!(parse_session("topic").is_ok());
}
fn parse_version(value: &str) -> Result<SdpType, SdpParserInternalError> {
let ver = value.parse::<u64>()?;
if ver != 0 {
return Err(SdpParserInternalError::Generic(format!("version type contains unsupported value {}",
ver)));
};
- println!("version: {}", ver);
+ trace!("version: {}", ver);
Ok(SdpType::Version(ver))
}
#[test]
fn test_version_works() {
assert!(parse_version("0").is_ok());
}
@@ -295,17 +285,17 @@ fn parse_origin(value: &str) -> Result<S
.to_string()));
}
let o = SdpOrigin {
username: String::from(username),
session_id,
session_version,
unicast_addr,
};
- println!("{}", o);
+ trace!("origin: {}", o);
Ok(SdpType::Origin(o))
}
#[test]
fn test_origin_works() {
assert!(parse_origin("mozilla 506705521068071134 0 IN IP4 0.0.0.0").is_ok());
assert!(parse_origin("mozilla 506705521068071134 0 IN IP6 ::1").is_ok());
}
@@ -357,17 +347,17 @@ fn parse_connection(value: &str) -> Resu
addr_token = addr_tokens[0];
}
let addr = parse_unicast_addr(addr_token)?;
if !addrtype.same_protocol(&addr) {
return Err(SdpParserInternalError::Generic("connection addrtype does not match address."
.to_string()));
}
let c = SdpConnection { addr, ttl, amount };
- println!("connection: {}", c.addr);
+ trace!("connection: {}", c.addr);
Ok(SdpType::Connection(c))
}
#[test]
fn connection_works() {
assert!(parse_connection("IN IP4 127.0.0.1").is_ok());
assert!(parse_connection("IN IP4 127.0.0.1/10/10").is_ok());
}
@@ -412,17 +402,17 @@ fn parse_bandwidth(value: &str) -> Resul
}
let bandwidth = bv[1].parse::<u32>()?;
let bw = match bv[0].to_uppercase().as_ref() {
"AS" => SdpBandwidth::As(bandwidth),
"CT" => SdpBandwidth::Ct(bandwidth),
"TIAS" => SdpBandwidth::Tias(bandwidth),
_ => SdpBandwidth::Unknown(String::from(bv[0]), bandwidth),
};
- println!("bandwidth: {}, {}", bv[0], bandwidth);
+ trace!("bandwidth: {}, {}", bv[0], bandwidth);
Ok(SdpType::Bandwidth(bw))
}
#[test]
fn bandwidth_works() {
assert!(parse_bandwidth("AS:1").is_ok());
assert!(parse_bandwidth("CT:123").is_ok());
assert!(parse_bandwidth("TIAS:12345").is_ok());
@@ -443,17 +433,17 @@ fn parse_timing(value: &str) -> Result<S
let tv: Vec<&str> = value.split_whitespace().collect();
if tv.len() != 2 {
return Err(SdpParserInternalError::Generic("timing attribute must have two tokens"
.to_string()));
}
let start = tv[0].parse::<u64>()?;
let stop = tv[1].parse::<u64>()?;
let t = SdpTiming { start, stop };
- println!("timing: {}, {}", t.start, t.stop);
+ trace!("timing: {}, {}", t.start, t.stop);
Ok(SdpType::Timing(t))
}
#[test]
fn test_timing_works() {
assert!(parse_timing("0 0").is_ok());
}
@@ -621,33 +611,33 @@ fn test_parse_sdp_line_invalid_a_line()
}
fn sanity_check_sdp_session(session: &SdpSession) -> Result<(), SdpParserError> {
let make_error = |x: &str| SdpParserError::Sequence {
message: x.to_string(),
line_number: 0,
};
- if !session.has_timing() {
+ if !session.timing.is_some() {
return Err(SdpParserError::Sequence {
message: "Missing timing type".to_string(),
line_number: 0,
});
}
- if !session.has_media() {
+ if session.media.is_empty() {
return Err(SdpParserError::Sequence {
- message: "Missing media setion".to_string(),
+ message: "Missing media section".to_string(),
line_number: 0,
});
}
if session.get_connection().is_none() {
for msection in &session.media {
- if !msection.has_connection() {
+ if msection.get_connection().is_none() {
return Err(SdpParserError::Sequence {
message: "Each media section must define a connection
if it is not defined on session level".to_string(),
line_number: 0,
});
}
}
}
@@ -912,17 +902,17 @@ fn parse_sdp_vector(lines: &[SdpLine]) -
SdpType::Email(_) |
SdpType::Information(_) |
SdpType::Key(_) |
SdpType::Phone(_) |
SdpType::Repeat(_) |
SdpType::Uri(_) |
SdpType::Zone(_) => (),
};
- if sdp_session.has_media() {
+ if !sdp_session.media.is_empty() {
break;
};
}
sanity_check_sdp_session(&sdp_session)?;
Ok(sdp_session)
}
pub fn parse_sdp(sdp: &str, fail_on_warning: bool) -> Result<SdpSession, SdpParserError> {
@@ -1001,17 +991,17 @@ pub fn parse_sdp(sdp: &str, fail_on_warn
if let Some(e) = errors.pop() {
return Err(e);
};
let mut session = parse_sdp_vector(&sdp_lines)?;
session.warnings = warnings;
for warning in &session.warnings {
- println!("Warning: {}", &warning);
+ warn!("Warning: {}", &warning);
}
Ok(session)
}
#[test]
fn test_parse_sdp_zero_length_string_fails() {
assert!(parse_sdp("", true).is_err());
--- a/media/webrtc/signaling/src/sdp/rsdparsa/src/media_type.rs
+++ b/media/webrtc/signaling/src/sdp/rsdparsa/src/media_type.rs
@@ -113,32 +113,24 @@ impl SdpMedia {
pub fn get_proto(&self) -> &SdpProtocolValue {
&self.media.proto
}
pub fn get_formats(&self) -> &SdpFormatList {
&self.media.formats
}
- pub fn has_bandwidth(&self) -> bool {
- !self.bandwidth.is_empty()
- }
-
pub fn get_bandwidth(&self) -> &Vec<SdpBandwidth> {
&self.bandwidth
}
pub fn add_bandwidth(&mut self, bw: &SdpBandwidth) {
self.bandwidth.push(bw.clone())
}
- pub fn has_attributes(&self) -> bool {
- !self.attribute.is_empty()
- }
-
pub fn get_attributes(&self) -> &Vec<SdpAttribute> {
&self.attribute
}
pub fn add_attribute(&mut self, attr: &SdpAttribute) -> Result<(), SdpParserInternalError> {
if !attr.allowed_at_media_level() {
return Err(SdpParserInternalError::Generic(format!("{} not allowed at media level",
attr)));
@@ -185,20 +177,16 @@ impl SdpMedia {
self.add_attribute(&SdpAttribute::Rtpmap(rtpmap))?;
Ok(())
}
pub fn get_attributes_of_type(&self, t: SdpAttributeType) -> Vec<&SdpAttribute> {
self.attribute.iter().filter(|a| SdpAttributeType::from(*a) == t).collect()
}
- pub fn has_connection(&self) -> bool {
- self.connection.is_some()
- }
-
pub fn get_connection(&self) -> &Option<SdpConnection> {
&self.connection
}
pub fn set_connection(&mut self, c: &SdpConnection) -> Result<(), SdpParserInternalError> {
if self.connection.is_some() {
return Err(SdpParserInternalError::Generic("connection type already exists at this media level"
.to_string(),
@@ -367,17 +355,17 @@ pub fn parse_media(value: &str) -> Resul
};
let m = SdpMediaLine {
media,
port,
port_count,
proto,
formats,
};
- println!("media: {}, {}, {}, {}", m.media, m.port, m.proto, m.formats);
+ trace!("media: {}, {}, {}, {}", m.media, m.port, m.proto, m.formats);
Ok(SdpType::Media(m))
}
#[test]
fn test_media_works() {
assert!(parse_media("audio 9 UDP/TLS/RTP/SAVPF 109").is_ok());
assert!(parse_media("video 9 UDP/TLS/RTP/SAVPF 126").is_ok());
assert!(parse_media("application 9 DTLS/SCTP 5000").is_ok());
@@ -494,9 +482,102 @@ pub fn parse_media_vector(lines: &[SdpLi
SdpType::Key(_) => (),
};
}
media_sections.push(sdp_media);
Ok(media_sections)
}
-// TODO add unit tests for parse_media_vector
+
+#[test]
+fn test_media_vector_first_line_failure() {
+ let mut sdp_lines: Vec<SdpLine> = Vec::new();
+ let line = SdpLine {
+ line_number: 0,
+ sdp_type: SdpType::Session("hello".to_string())
+ };
+ sdp_lines.push(line);
+ assert!(parse_media_vector(&sdp_lines).is_err());
+}
+
+#[test]
+fn test_media_vector_multiple_connections() {
+ let mut sdp_lines: Vec<SdpLine> = Vec::new();
+ let media_line = SdpMediaLine {
+ media: SdpMediaValue::Audio,
+ port: 9,
+ port_count: 0,
+ proto: SdpProtocolValue::RtpSavpf,
+ formats: SdpFormatList::Integers(Vec::new()),
+ };
+ let media = SdpLine {
+ line_number: 0,
+ sdp_type: SdpType::Media(media_line)
+ };
+ sdp_lines.push(media);
+ use network::{parse_unicast_addr};
+ let addr = parse_unicast_addr("127.0.0.1").unwrap();
+ let c = SdpConnection {
+ addr,
+ ttl: None,
+ amount: None };
+ let c1 = SdpLine {
+ line_number: 1,
+ sdp_type: SdpType::Connection(c.clone())
+ };
+ sdp_lines.push(c1);
+ let c2 = SdpLine {
+ line_number: 2,
+ sdp_type: SdpType::Connection(c)
+ };
+ sdp_lines.push(c2);
+ assert!(parse_media_vector(&sdp_lines).is_err());
+}
+
+#[test]
+fn test_media_vector_invalid_types() {
+ let mut sdp_lines: Vec<SdpLine> = Vec::new();
+ let media_line = SdpMediaLine {
+ media: SdpMediaValue::Audio,
+ port: 9,
+ port_count: 0,
+ proto: SdpProtocolValue::RtpSavpf,
+ formats: SdpFormatList::Integers(Vec::new()),
+ };
+ let media = SdpLine {
+ line_number: 0,
+ sdp_type: SdpType::Media(media_line)
+ };
+ sdp_lines.push(media);
+ use {SdpTiming};
+ let t = SdpTiming { start: 0, stop: 0 };
+ let tline = SdpLine {
+ line_number: 1,
+ sdp_type: SdpType::Timing(t)
+ };
+ sdp_lines.push(tline);
+ assert!(parse_media_vector(&sdp_lines).is_err());
+}
+
+#[test]
+fn test_media_vector_invalid_media_level_attribute() {
+ let mut sdp_lines: Vec<SdpLine> = Vec::new();
+ let media_line = SdpMediaLine {
+ media: SdpMediaValue::Audio,
+ port: 9,
+ port_count: 0,
+ proto: SdpProtocolValue::RtpSavpf,
+ formats: SdpFormatList::Integers(Vec::new()),
+ };
+ let media = SdpLine {
+ line_number: 0,
+ sdp_type: SdpType::Media(media_line)
+ };
+ sdp_lines.push(media);
+ let a = SdpAttribute::IceLite;
+ let aline = SdpLine {
+ line_number: 1,
+ sdp_type: SdpType::Attribute(a)
+ };
+ sdp_lines.push(aline);
+ assert!(parse_media_vector(&sdp_lines).is_err());
+}
--- a/media/webrtc/signaling/src/sdp/rsdparsa/tests/unit_tests.rs
+++ b/media/webrtc/signaling/src/sdp/rsdparsa/tests/unit_tests.rs
@@ -20,19 +20,18 @@ m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n";
assert_eq!(sdp.media.len(), 1);
let msection = &(sdp.media[0]);
assert_eq!(*msection.get_type(),
rsdparsa::media_type::SdpMediaValue::Audio);
assert_eq!(msection.get_port(), 0);
assert_eq!(*msection.get_proto(),
rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf);
- assert!(!msection.has_attributes());
- assert!(!msection.has_bandwidth());
- assert!(!msection.has_connection());
+ assert!(msection.get_attributes().is_empty());
+ assert!(msection.get_bandwidth().is_empty());
assert!(msection.get_connection().is_none());
}
#[test]
fn parse_minimal_sdp_with_emtpy_lines() {
let sdp = "v=0\r\n
\r\n
o=- 0 0 IN IP4 0.0.0.0\r\n
@@ -68,16 +67,50 @@ m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n";
assert!(sdp_opt.is_some());
let sdp = sdp_opt.unwrap();
assert_eq!(sdp.version, 0);
assert_eq!(sdp.session, "-");
assert!(sdp.get_connection().is_some());
}
#[test]
+fn parse_minimal_sdp_with_most_media_types() {
+ let sdp = "v=0\r\n
+o=- 0 0 IN IP4 0.0.0.0\r\n
+s=-\r\n
+t=0 0\r\n
+m=video 0 UDP/TLS/RTP/SAVPF 0\r\n
+b=AS:1\r\n
+b=CT:123\r\n
+b=TIAS:12345\r\n
+c=IN IP4 0.0.0.0\r\n
+a=sendrecv\r\n";
+ let sdp_res = rsdparsa::parse_sdp(sdp, false);
+ assert!(sdp_res.is_ok());
+ let sdp_opt = sdp_res.ok();
+ assert!(sdp_opt.is_some());
+ let sdp = sdp_opt.unwrap();
+ assert_eq!(sdp.version, 0);
+ assert_eq!(sdp.session, "-");
+ assert_eq!(sdp.attribute.len(), 0);
+ assert_eq!(sdp.media.len(), 1);
+
+ let msection = &(sdp.media[0]);
+ assert_eq!(*msection.get_type(),
+ rsdparsa::media_type::SdpMediaValue::Video);
+ assert_eq!(msection.get_port(), 0);
+ assert_eq!(*msection.get_proto(),
+ rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf);
+ assert!(!msection.get_bandwidth().is_empty());
+ assert!(!msection.get_connection().is_none());
+ assert!(!msection.get_attributes().is_empty());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Sendrecv).is_some());
+}
+
+#[test]
fn parse_firefox_audio_offer() {
let sdp = "v=0\r\n
o=mozilla...THIS_IS_SDPARTA-52.0a1 506705521068071134 0 IN IP4 0.0.0.0\r\n
s=-\r\n
t=0 0\r\n
a=fingerprint:sha-256 CD:34:D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC:BF:2F:E3:91:CB:57:A9:9D:4A:A2:0B:40\r\n
a=group:BUNDLE sdparta_0\r\n
a=ice-options:trickle\r\n
@@ -107,20 +140,31 @@ a=ssrc:2655508255 cname:{735484ea-4f6c-f
assert_eq!(sdp.media.len(), 1);
let msection = &(sdp.media[0]);
assert_eq!(*msection.get_type(),
rsdparsa::media_type::SdpMediaValue::Audio);
assert_eq!(msection.get_port(), 9);
assert_eq!(*msection.get_proto(),
rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf);
- assert!(msection.has_attributes());
- assert!(msection.has_connection());
assert!(msection.get_connection().is_some());
- assert!(!msection.has_bandwidth());
+ assert!(msection.get_bandwidth().is_empty());
+ assert!(!msection.get_attributes().is_empty());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Sendrecv).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Extmap).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Fmtp).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::IcePwd).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::IceUfrag).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Mid).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Mid).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Msid).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::RtcpMux).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Rtpmap).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Setup).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Ssrc).is_some());
}
#[test]
fn parse_firefox_video_offer() {
let sdp = "v=0\r\n
o=mozilla...THIS_IS_SDPARTA-52.0a1 506705521068071134 0 IN IP4 0.0.0.0\r\n
s=-\r\n
t=0 0\r\n
@@ -164,16 +208,32 @@ a=ssrc:2709871439 cname:{735484ea-4f6c-f
assert_eq!(sdp.media.len(), 1);
let msection = &(sdp.media[0]);
assert_eq!(*msection.get_type(),
rsdparsa::media_type::SdpMediaValue::Video);
assert_eq!(msection.get_port(), 9);
assert_eq!(*msection.get_proto(),
rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf);
+ assert!(msection.get_connection().is_some());
+ assert!(msection.get_bandwidth().is_empty());
+ assert!(!msection.get_attributes().is_empty());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Recvonly).is_some());
+ assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Extmap).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Fmtp).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::IcePwd).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::IceUfrag).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Mid).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Mid).is_some());
+ assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Msid).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Rtcpfb).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::RtcpMux).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Rtpmap).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Setup).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Ssrc).is_some());
}
#[test]
fn parse_firefox_datachannel_offer() {
let sdp = "v=0\r\n
o=mozilla...THIS_IS_SDPARTA-52.0a2 3327975756663609975 0 IN IP4 0.0.0.0\r\n
s=-\r\n
t=0 0\r\n
@@ -201,16 +261,32 @@ a=ssrc:3376683177 cname:{62f78ee0-620f-a
assert_eq!(sdp.media.len(), 1);
let msection = &(sdp.media[0]);
assert_eq!(*msection.get_type(),
rsdparsa::media_type::SdpMediaValue::Application);
assert_eq!(msection.get_port(), 49760);
assert_eq!(*msection.get_proto(),
rsdparsa::media_type::SdpProtocolValue::DtlsSctp);
+ assert!(msection.get_connection().is_some());
+ assert!(msection.get_bandwidth().is_empty());
+ assert!(!msection.get_attributes().is_empty());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Sendrecv).is_some());
+ assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Extmap).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::IcePwd).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::IceUfrag).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::EndOfCandidates).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Mid).is_some());
+ assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Msid).is_some());
+ assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Rtcpfb).is_some());
+ assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::RtcpMux).is_some());
+ assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Rtpmap).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Sctpmap).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Setup).is_some());
+ assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Ssrc).is_some());
}
#[test]
fn parse_chrome_audio_video_offer() {
let sdp = "v=0\r\n
o=- 3836772544440436510 2 IN IP4 127.0.0.1\r\n
s=-\r\n
t=0 0\r\n
@@ -306,29 +382,29 @@ a=ssrc:2673335628 label:b6ec5178-c611-40
assert_eq!(sdp.media.len(), 2);
let msection1 = &(sdp.media[0]);
assert_eq!(*msection1.get_type(),
rsdparsa::media_type::SdpMediaValue::Audio);
assert_eq!(msection1.get_port(), 9);
assert_eq!(*msection1.get_proto(),
rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf);
- assert!(msection1.has_attributes());
- assert!(msection1.has_connection());
- assert!(!msection1.has_bandwidth());
+ assert!(!msection1.get_attributes().is_empty());
+ assert!(msection1.get_connection().is_some());
+ assert!(msection1.get_bandwidth().is_empty());
let msection2 = &(sdp.media[1]);
assert_eq!(*msection2.get_type(),
rsdparsa::media_type::SdpMediaValue::Video);
assert_eq!(msection2.get_port(), 9);
assert_eq!(*msection2.get_proto(),
rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf);
- assert!(msection2.has_attributes());
- assert!(msection2.has_connection());
- assert!(!msection2.has_bandwidth());
+ assert!(!msection2.get_attributes().is_empty());
+ assert!(msection2.get_connection().is_some());
+ assert!(msection2.get_bandwidth().is_empty());
}
#[test]
fn parse_firefox_simulcast_offer() {
let sdp = "v=0\r\n
o=mozilla...THIS_IS_SDPARTA-55.0a1 983028567300715536 0 IN IP4 0.0.0.0\r\n
s=-\r\n
t=0 0\r\n
--- a/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/lib.rs
+++ b/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/lib.rs
@@ -104,17 +104,17 @@ pub unsafe extern "C" fn get_version(ses
#[no_mangle]
pub unsafe extern "C" fn sdp_get_origin(session: *const SdpSession) -> RustSdpOrigin {
origin_view_helper((*session).get_origin())
}
#[no_mangle]
pub unsafe extern "C" fn session_view(session: *const SdpSession) -> StringView {
- StringView::from((*session).get_session().as_str())
+ StringView::from((*session).get_session())
}
#[no_mangle]
pub unsafe extern "C" fn sdp_session_has_connection(session: *const SdpSession) -> bool {
(*session).connection.is_some()
}
#[no_mangle]
--- a/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/media_section.rs
+++ b/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/media_section.rs
@@ -129,17 +129,17 @@ pub unsafe extern "C" fn sdp_get_media_b
#[no_mangle]
pub unsafe extern "C" fn sdp_get_media_bandwidth_vec(sdp_media: *const SdpMedia) -> *const Vec<SdpBandwidth> {
(*sdp_media).get_bandwidth()
}
#[no_mangle]
pub unsafe extern "C" fn sdp_media_has_connection(sdp_media: *const SdpMedia) -> bool {
- (*sdp_media).has_connection()
+ (*sdp_media).get_connection().is_some()
}
#[no_mangle]
pub unsafe extern "C" fn sdp_get_media_connection(sdp_media: *const SdpMedia, ret: *mut RustSdpConnection) -> nsresult {
if let &Some(ref connection) = (*sdp_media).get_connection() {
*ret = RustSdpConnection::from(connection);
return NS_OK;
}