2019-10-12 16:17:04 +00:00
|
|
|
// Copyright (c) 2019 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
|
|
|
|
//
|
|
|
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
|
2024-07-09 15:01:42 +00:00
|
|
|
use xso::{AsXml, FromXml};
|
2024-06-29 14:34:27 +00:00
|
|
|
|
|
|
|
use crate::ns;
|
|
|
|
|
2024-08-03 11:04:56 +00:00
|
|
|
/// Source element for the ssrc SDP attribute.
|
|
|
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
|
|
|
#[xml(namespace = ns::JINGLE_SSMA, name = "source")]
|
|
|
|
pub struct Source {
|
|
|
|
/// Maps to the ssrc-id parameter.
|
|
|
|
#[xml(attribute = "ssrc")]
|
|
|
|
pub id: u32,
|
|
|
|
|
|
|
|
/// List of attributes for this source.
|
|
|
|
#[xml(child(n = ..))]
|
|
|
|
pub parameters: Vec<Parameter>,
|
|
|
|
}
|
2019-10-12 16:17:04 +00:00
|
|
|
|
|
|
|
impl Source {
|
|
|
|
/// Create a new SSMA Source element.
|
2021-10-23 13:42:27 +00:00
|
|
|
pub fn new(id: u32) -> Source {
|
2019-10-12 16:17:04 +00:00
|
|
|
Source {
|
|
|
|
id,
|
|
|
|
parameters: Vec::new(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-29 14:34:27 +00:00
|
|
|
/// Parameter associated with a ssrc.
|
2024-07-09 15:01:42 +00:00
|
|
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
2024-06-29 14:34:27 +00:00
|
|
|
#[xml(namespace = ns::JINGLE_SSMA, name = "parameter")]
|
|
|
|
pub struct Parameter {
|
|
|
|
/// The name of the parameter.
|
|
|
|
#[xml(attribute)]
|
|
|
|
pub name: String,
|
2019-10-12 16:17:04 +00:00
|
|
|
|
2024-06-29 14:34:27 +00:00
|
|
|
/// The optional value of the parameter.
|
|
|
|
#[xml(attribute(default))]
|
|
|
|
pub value: Option<String>,
|
|
|
|
}
|
2019-10-12 16:17:04 +00:00
|
|
|
|
2021-10-23 13:56:08 +00:00
|
|
|
generate_attribute!(
|
|
|
|
/// From RFC5888, the list of allowed semantics.
|
|
|
|
Semantics, "semantics", {
|
|
|
|
/// Lip Synchronization, defined in RFC5888.
|
|
|
|
Ls => "LS",
|
|
|
|
|
|
|
|
/// Flow Identification, defined in RFC5888.
|
|
|
|
Fid => "FID",
|
|
|
|
|
|
|
|
/// Single Reservation Flow, defined in RFC3524.
|
|
|
|
Srf => "SRF",
|
|
|
|
|
|
|
|
/// Alternative Network Address Types, defined in RFC4091.
|
|
|
|
Anat => "ANAT",
|
|
|
|
|
|
|
|
/// Forward Error Correction, defined in RFC4756.
|
|
|
|
Fec => "FEC",
|
|
|
|
|
|
|
|
/// Decoding Dependency, defined in RFC5583.
|
|
|
|
Ddp => "DDP",
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
2024-08-03 11:04:56 +00:00
|
|
|
/// Element grouping multiple ssrc.
|
|
|
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
|
|
|
#[xml(namespace = ns::JINGLE_SSMA, name = "ssrc-group")]
|
|
|
|
pub struct Group {
|
|
|
|
/// The semantics of this group.
|
|
|
|
#[xml(attribute)]
|
|
|
|
pub semantics: Semantics,
|
|
|
|
|
|
|
|
/// The various ssrc concerned by this group.
|
|
|
|
#[xml(child(n = ..))]
|
|
|
|
pub sources: Vec<Source>,
|
|
|
|
}
|
2019-10-12 16:17:04 +00:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
2024-07-24 18:28:22 +00:00
|
|
|
use minidom::Element;
|
2019-10-12 16:17:04 +00:00
|
|
|
|
|
|
|
#[cfg(target_pointer_width = "32")]
|
|
|
|
#[test]
|
|
|
|
fn test_size() {
|
2021-10-23 13:42:27 +00:00
|
|
|
assert_size!(Source, 16);
|
2019-10-12 16:17:04 +00:00
|
|
|
assert_size!(Parameter, 24);
|
2021-10-23 13:56:08 +00:00
|
|
|
assert_size!(Semantics, 1);
|
|
|
|
assert_size!(Group, 16);
|
2019-10-12 16:17:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(target_pointer_width = "64")]
|
|
|
|
#[test]
|
|
|
|
fn test_size() {
|
2021-10-23 13:42:27 +00:00
|
|
|
assert_size!(Source, 32);
|
2019-10-12 16:17:04 +00:00
|
|
|
assert_size!(Parameter, 48);
|
2021-10-23 13:56:08 +00:00
|
|
|
assert_size!(Semantics, 1);
|
|
|
|
assert_size!(Group, 32);
|
2019-10-12 16:17:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn parse_source() {
|
2022-03-22 22:29:25 +00:00
|
|
|
let elem: Element = "<source ssrc='1656081975' xmlns='urn:xmpp:jingle:apps:rtp:ssma:0'>
|
2019-10-12 16:17:04 +00:00
|
|
|
<parameter name='cname' value='Yv/wvbCdsDW2Prgd'/>
|
|
|
|
<parameter name='msid' value='MLTJKIHilGn71fNQoszkQ4jlPTuS5vJyKVIv MLTJKIHilGn71fNQoszkQ4jlPTuS5vJyKVIva0'/>
|
|
|
|
</source>"
|
|
|
|
.parse()
|
|
|
|
.unwrap();
|
|
|
|
let mut ssrc = Source::try_from(elem).unwrap();
|
2021-10-23 13:42:27 +00:00
|
|
|
assert_eq!(ssrc.id, 1656081975);
|
2019-10-12 16:17:04 +00:00
|
|
|
assert_eq!(ssrc.parameters.len(), 2);
|
|
|
|
let parameter = ssrc.parameters.pop().unwrap();
|
|
|
|
assert_eq!(parameter.name, "msid");
|
2019-10-22 23:32:41 +00:00
|
|
|
assert_eq!(
|
|
|
|
parameter.value.unwrap(),
|
|
|
|
"MLTJKIHilGn71fNQoszkQ4jlPTuS5vJyKVIv MLTJKIHilGn71fNQoszkQ4jlPTuS5vJyKVIva0"
|
|
|
|
);
|
2019-10-12 16:17:04 +00:00
|
|
|
let parameter = ssrc.parameters.pop().unwrap();
|
|
|
|
assert_eq!(parameter.name, "cname");
|
|
|
|
assert_eq!(parameter.value.unwrap(), "Yv/wvbCdsDW2Prgd");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn parse_source_group() {
|
2022-03-22 22:29:25 +00:00
|
|
|
let elem: Element = "<ssrc-group semantics='FID' xmlns='urn:xmpp:jingle:apps:rtp:ssma:0'>
|
2019-10-12 16:17:04 +00:00
|
|
|
<source ssrc='2301230316'/>
|
|
|
|
<source ssrc='386328120'/>
|
|
|
|
</ssrc-group>"
|
2019-10-22 23:32:41 +00:00
|
|
|
.parse()
|
|
|
|
.unwrap();
|
2019-10-12 16:17:04 +00:00
|
|
|
let mut group = Group::try_from(elem).unwrap();
|
2021-10-23 13:56:08 +00:00
|
|
|
assert_eq!(group.semantics, Semantics::Fid);
|
2019-10-12 16:17:04 +00:00
|
|
|
assert_eq!(group.sources.len(), 2);
|
|
|
|
let source = group.sources.pop().unwrap();
|
2021-10-23 13:42:27 +00:00
|
|
|
assert_eq!(source.id, 386328120);
|
2019-10-12 16:17:04 +00:00
|
|
|
let source = group.sources.pop().unwrap();
|
2021-10-23 13:42:27 +00:00
|
|
|
assert_eq!(source.id, 2301230316);
|
2019-10-12 16:17:04 +00:00
|
|
|
}
|
|
|
|
}
|